patch_realtek.c revision ad93ffe6e4fc02993987008e4a5dcdcf4c926cd5
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_spec { 303 /* codec parameterization */ 304 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */ 305 unsigned int num_mixers; 306 struct snd_kcontrol_new *cap_mixer; /* capture mixer */ 307 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */ 308 309 const struct hda_verb *init_verbs[10]; /* initialization verbs 310 * don't forget NULL 311 * termination! 312 */ 313 unsigned int num_init_verbs; 314 315 char stream_name_analog[32]; /* analog PCM stream */ 316 struct hda_pcm_stream *stream_analog_playback; 317 struct hda_pcm_stream *stream_analog_capture; 318 struct hda_pcm_stream *stream_analog_alt_playback; 319 struct hda_pcm_stream *stream_analog_alt_capture; 320 321 char stream_name_digital[32]; /* digital PCM stream */ 322 struct hda_pcm_stream *stream_digital_playback; 323 struct hda_pcm_stream *stream_digital_capture; 324 325 /* playback */ 326 struct hda_multi_out multiout; /* playback set-up 327 * max_channels, dacs must be set 328 * dig_out_nid and hp_nid are optional 329 */ 330 hda_nid_t alt_dac_nid; 331 hda_nid_t slave_dig_outs[3]; /* optional - for auto-parsing */ 332 int dig_out_type; 333 334 /* capture */ 335 unsigned int num_adc_nids; 336 hda_nid_t *adc_nids; 337 hda_nid_t *capsrc_nids; 338 hda_nid_t dig_in_nid; /* digital-in NID; optional */ 339 340 /* capture setup for dynamic dual-adc switch */ 341 unsigned int cur_adc_idx; 342 hda_nid_t cur_adc; 343 unsigned int cur_adc_stream_tag; 344 unsigned int cur_adc_format; 345 346 /* capture source */ 347 unsigned int num_mux_defs; 348 const struct hda_input_mux *input_mux; 349 unsigned int cur_mux[3]; 350 struct alc_mic_route ext_mic; 351 struct alc_mic_route int_mic; 352 353 /* channel model */ 354 const struct hda_channel_mode *channel_mode; 355 int num_channel_mode; 356 int need_dac_fix; 357 int const_channel_count; 358 int ext_channel_count; 359 360 /* PCM information */ 361 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */ 362 363 /* dynamic controls, init_verbs and input_mux */ 364 struct auto_pin_cfg autocfg; 365 struct alc_customize_define cdefine; 366 struct snd_array kctls; 367 struct hda_input_mux private_imux[3]; 368 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; 369 hda_nid_t private_adc_nids[AUTO_CFG_MAX_OUTS]; 370 hda_nid_t private_capsrc_nids[AUTO_CFG_MAX_OUTS]; 371 372 /* hooks */ 373 void (*init_hook)(struct hda_codec *codec); 374 void (*unsol_event)(struct hda_codec *codec, unsigned int res); 375#ifdef CONFIG_SND_HDA_POWER_SAVE 376 void (*power_hook)(struct hda_codec *codec); 377#endif 378 void (*shutup)(struct hda_codec *codec); 379 380 /* for pin sensing */ 381 unsigned int sense_updated: 1; 382 unsigned int jack_present: 1; 383 unsigned int master_sw: 1; 384 unsigned int auto_mic:1; 385 386 /* other flags */ 387 unsigned int no_analog :1; /* digital I/O only */ 388 unsigned int dual_adc_switch:1; /* switch ADCs (for ALC275) */ 389 unsigned int single_input_src:1; 390 int init_amp; 391 int codec_variant; /* flag for other variants */ 392 393 /* for virtual master */ 394 hda_nid_t vmaster_nid; 395#ifdef CONFIG_SND_HDA_POWER_SAVE 396 struct hda_loopback_check loopback; 397#endif 398 399 /* for PLL fix */ 400 hda_nid_t pll_nid; 401 unsigned int pll_coef_idx, pll_coef_bit; 402 403 /* fix-up list */ 404 int fixup_id; 405 const struct alc_fixup *fixup_list; 406 const char *fixup_name; 407}; 408 409/* 410 * configuration template - to be copied to the spec instance 411 */ 412struct alc_config_preset { 413 struct snd_kcontrol_new *mixers[5]; /* should be identical size 414 * with spec 415 */ 416 struct snd_kcontrol_new *cap_mixer; /* capture mixer */ 417 const struct hda_verb *init_verbs[5]; 418 unsigned int num_dacs; 419 hda_nid_t *dac_nids; 420 hda_nid_t dig_out_nid; /* optional */ 421 hda_nid_t hp_nid; /* optional */ 422 hda_nid_t *slave_dig_outs; 423 unsigned int num_adc_nids; 424 hda_nid_t *adc_nids; 425 hda_nid_t *capsrc_nids; 426 hda_nid_t dig_in_nid; 427 unsigned int num_channel_mode; 428 const struct hda_channel_mode *channel_mode; 429 int need_dac_fix; 430 int const_channel_count; 431 unsigned int num_mux_defs; 432 const struct hda_input_mux *input_mux; 433 void (*unsol_event)(struct hda_codec *, unsigned int); 434 void (*setup)(struct hda_codec *); 435 void (*init_hook)(struct hda_codec *); 436#ifdef CONFIG_SND_HDA_POWER_SAVE 437 struct hda_amp_list *loopbacks; 438 void (*power_hook)(struct hda_codec *codec); 439#endif 440}; 441 442 443/* 444 * input MUX handling 445 */ 446static int alc_mux_enum_info(struct snd_kcontrol *kcontrol, 447 struct snd_ctl_elem_info *uinfo) 448{ 449 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 450 struct alc_spec *spec = codec->spec; 451 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id); 452 if (mux_idx >= spec->num_mux_defs) 453 mux_idx = 0; 454 if (!spec->input_mux[mux_idx].num_items && mux_idx > 0) 455 mux_idx = 0; 456 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo); 457} 458 459static int alc_mux_enum_get(struct snd_kcontrol *kcontrol, 460 struct snd_ctl_elem_value *ucontrol) 461{ 462 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 463 struct alc_spec *spec = codec->spec; 464 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 465 466 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx]; 467 return 0; 468} 469 470static int alc_mux_enum_put(struct snd_kcontrol *kcontrol, 471 struct snd_ctl_elem_value *ucontrol) 472{ 473 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 474 struct alc_spec *spec = codec->spec; 475 const struct hda_input_mux *imux; 476 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 477 unsigned int mux_idx; 478 hda_nid_t nid = spec->capsrc_nids ? 479 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx]; 480 unsigned int type; 481 482 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx; 483 imux = &spec->input_mux[mux_idx]; 484 if (!imux->num_items && mux_idx > 0) 485 imux = &spec->input_mux[0]; 486 487 type = get_wcaps_type(get_wcaps(codec, nid)); 488 if (type == AC_WID_AUD_MIX) { 489 /* Matrix-mixer style (e.g. ALC882) */ 490 unsigned int *cur_val = &spec->cur_mux[adc_idx]; 491 unsigned int i, idx; 492 493 idx = ucontrol->value.enumerated.item[0]; 494 if (idx >= imux->num_items) 495 idx = imux->num_items - 1; 496 if (*cur_val == idx) 497 return 0; 498 for (i = 0; i < imux->num_items; i++) { 499 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE; 500 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 501 imux->items[i].index, 502 HDA_AMP_MUTE, v); 503 } 504 *cur_val = idx; 505 return 1; 506 } else { 507 /* MUX style (e.g. ALC880) */ 508 return snd_hda_input_mux_put(codec, imux, ucontrol, nid, 509 &spec->cur_mux[adc_idx]); 510 } 511} 512 513/* 514 * channel mode setting 515 */ 516static int alc_ch_mode_info(struct snd_kcontrol *kcontrol, 517 struct snd_ctl_elem_info *uinfo) 518{ 519 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 520 struct alc_spec *spec = codec->spec; 521 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode, 522 spec->num_channel_mode); 523} 524 525static int alc_ch_mode_get(struct snd_kcontrol *kcontrol, 526 struct snd_ctl_elem_value *ucontrol) 527{ 528 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 529 struct alc_spec *spec = codec->spec; 530 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode, 531 spec->num_channel_mode, 532 spec->ext_channel_count); 533} 534 535static int alc_ch_mode_put(struct snd_kcontrol *kcontrol, 536 struct snd_ctl_elem_value *ucontrol) 537{ 538 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 539 struct alc_spec *spec = codec->spec; 540 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode, 541 spec->num_channel_mode, 542 &spec->ext_channel_count); 543 if (err >= 0 && !spec->const_channel_count) { 544 spec->multiout.max_channels = spec->ext_channel_count; 545 if (spec->need_dac_fix) 546 spec->multiout.num_dacs = spec->multiout.max_channels / 2; 547 } 548 return err; 549} 550 551/* 552 * Control the mode of pin widget settings via the mixer. "pc" is used 553 * instead of "%" to avoid consequences of accidently treating the % as 554 * being part of a format specifier. Maximum allowed length of a value is 555 * 63 characters plus NULL terminator. 556 * 557 * Note: some retasking pin complexes seem to ignore requests for input 558 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these 559 * are requested. Therefore order this list so that this behaviour will not 560 * cause problems when mixer clients move through the enum sequentially. 561 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of 562 * March 2006. 563 */ 564static char *alc_pin_mode_names[] = { 565 "Mic 50pc bias", "Mic 80pc bias", 566 "Line in", "Line out", "Headphone out", 567}; 568static unsigned char alc_pin_mode_values[] = { 569 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP, 570}; 571/* The control can present all 5 options, or it can limit the options based 572 * in the pin being assumed to be exclusively an input or an output pin. In 573 * addition, "input" pins may or may not process the mic bias option 574 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to 575 * accept requests for bias as of chip versions up to March 2006) and/or 576 * wiring in the computer. 577 */ 578#define ALC_PIN_DIR_IN 0x00 579#define ALC_PIN_DIR_OUT 0x01 580#define ALC_PIN_DIR_INOUT 0x02 581#define ALC_PIN_DIR_IN_NOMICBIAS 0x03 582#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04 583 584/* Info about the pin modes supported by the different pin direction modes. 585 * For each direction the minimum and maximum values are given. 586 */ 587static signed char alc_pin_mode_dir_info[5][2] = { 588 { 0, 2 }, /* ALC_PIN_DIR_IN */ 589 { 3, 4 }, /* ALC_PIN_DIR_OUT */ 590 { 0, 4 }, /* ALC_PIN_DIR_INOUT */ 591 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */ 592 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */ 593}; 594#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0]) 595#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1]) 596#define alc_pin_mode_n_items(_dir) \ 597 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1) 598 599static int alc_pin_mode_info(struct snd_kcontrol *kcontrol, 600 struct snd_ctl_elem_info *uinfo) 601{ 602 unsigned int item_num = uinfo->value.enumerated.item; 603 unsigned char dir = (kcontrol->private_value >> 16) & 0xff; 604 605 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 606 uinfo->count = 1; 607 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir); 608 609 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir)) 610 item_num = alc_pin_mode_min(dir); 611 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]); 612 return 0; 613} 614 615static int alc_pin_mode_get(struct snd_kcontrol *kcontrol, 616 struct snd_ctl_elem_value *ucontrol) 617{ 618 unsigned int i; 619 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 620 hda_nid_t nid = kcontrol->private_value & 0xffff; 621 unsigned char dir = (kcontrol->private_value >> 16) & 0xff; 622 long *valp = ucontrol->value.integer.value; 623 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0, 624 AC_VERB_GET_PIN_WIDGET_CONTROL, 625 0x00); 626 627 /* Find enumerated value for current pinctl setting */ 628 i = alc_pin_mode_min(dir); 629 while (i <= alc_pin_mode_max(dir) && alc_pin_mode_values[i] != pinctl) 630 i++; 631 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir); 632 return 0; 633} 634 635static int alc_pin_mode_put(struct snd_kcontrol *kcontrol, 636 struct snd_ctl_elem_value *ucontrol) 637{ 638 signed int change; 639 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 640 hda_nid_t nid = kcontrol->private_value & 0xffff; 641 unsigned char dir = (kcontrol->private_value >> 16) & 0xff; 642 long val = *ucontrol->value.integer.value; 643 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0, 644 AC_VERB_GET_PIN_WIDGET_CONTROL, 645 0x00); 646 647 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir)) 648 val = alc_pin_mode_min(dir); 649 650 change = pinctl != alc_pin_mode_values[val]; 651 if (change) { 652 /* Set pin mode to that requested */ 653 snd_hda_codec_write_cache(codec, nid, 0, 654 AC_VERB_SET_PIN_WIDGET_CONTROL, 655 alc_pin_mode_values[val]); 656 657 /* Also enable the retasking pin's input/output as required 658 * for the requested pin mode. Enum values of 2 or less are 659 * input modes. 660 * 661 * Dynamically switching the input/output buffers probably 662 * reduces noise slightly (particularly on input) so we'll 663 * do it. However, having both input and output buffers 664 * enabled simultaneously doesn't seem to be problematic if 665 * this turns out to be necessary in the future. 666 */ 667 if (val <= 2) { 668 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, 669 HDA_AMP_MUTE, HDA_AMP_MUTE); 670 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0, 671 HDA_AMP_MUTE, 0); 672 } else { 673 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0, 674 HDA_AMP_MUTE, HDA_AMP_MUTE); 675 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, 676 HDA_AMP_MUTE, 0); 677 } 678 } 679 return change; 680} 681 682#define ALC_PIN_MODE(xname, nid, dir) \ 683 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 684 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \ 685 .info = alc_pin_mode_info, \ 686 .get = alc_pin_mode_get, \ 687 .put = alc_pin_mode_put, \ 688 .private_value = nid | (dir<<16) } 689 690/* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged 691 * together using a mask with more than one bit set. This control is 692 * currently used only by the ALC260 test model. At this stage they are not 693 * needed for any "production" models. 694 */ 695#ifdef CONFIG_SND_DEBUG 696#define alc_gpio_data_info snd_ctl_boolean_mono_info 697 698static int alc_gpio_data_get(struct snd_kcontrol *kcontrol, 699 struct snd_ctl_elem_value *ucontrol) 700{ 701 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 702 hda_nid_t nid = kcontrol->private_value & 0xffff; 703 unsigned char mask = (kcontrol->private_value >> 16) & 0xff; 704 long *valp = ucontrol->value.integer.value; 705 unsigned int val = snd_hda_codec_read(codec, nid, 0, 706 AC_VERB_GET_GPIO_DATA, 0x00); 707 708 *valp = (val & mask) != 0; 709 return 0; 710} 711static int alc_gpio_data_put(struct snd_kcontrol *kcontrol, 712 struct snd_ctl_elem_value *ucontrol) 713{ 714 signed int change; 715 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 716 hda_nid_t nid = kcontrol->private_value & 0xffff; 717 unsigned char mask = (kcontrol->private_value >> 16) & 0xff; 718 long val = *ucontrol->value.integer.value; 719 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0, 720 AC_VERB_GET_GPIO_DATA, 721 0x00); 722 723 /* Set/unset the masked GPIO bit(s) as needed */ 724 change = (val == 0 ? 0 : mask) != (gpio_data & mask); 725 if (val == 0) 726 gpio_data &= ~mask; 727 else 728 gpio_data |= mask; 729 snd_hda_codec_write_cache(codec, nid, 0, 730 AC_VERB_SET_GPIO_DATA, gpio_data); 731 732 return change; 733} 734#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \ 735 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 736 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \ 737 .info = alc_gpio_data_info, \ 738 .get = alc_gpio_data_get, \ 739 .put = alc_gpio_data_put, \ 740 .private_value = nid | (mask<<16) } 741#endif /* CONFIG_SND_DEBUG */ 742 743/* A switch control to allow the enabling of the digital IO pins on the 744 * ALC260. This is incredibly simplistic; the intention of this control is 745 * to provide something in the test model allowing digital outputs to be 746 * identified if present. If models are found which can utilise these 747 * outputs a more complete mixer control can be devised for those models if 748 * necessary. 749 */ 750#ifdef CONFIG_SND_DEBUG 751#define alc_spdif_ctrl_info snd_ctl_boolean_mono_info 752 753static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol, 754 struct snd_ctl_elem_value *ucontrol) 755{ 756 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 757 hda_nid_t nid = kcontrol->private_value & 0xffff; 758 unsigned char mask = (kcontrol->private_value >> 16) & 0xff; 759 long *valp = ucontrol->value.integer.value; 760 unsigned int val = snd_hda_codec_read(codec, nid, 0, 761 AC_VERB_GET_DIGI_CONVERT_1, 0x00); 762 763 *valp = (val & mask) != 0; 764 return 0; 765} 766static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol, 767 struct snd_ctl_elem_value *ucontrol) 768{ 769 signed int change; 770 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 771 hda_nid_t nid = kcontrol->private_value & 0xffff; 772 unsigned char mask = (kcontrol->private_value >> 16) & 0xff; 773 long val = *ucontrol->value.integer.value; 774 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0, 775 AC_VERB_GET_DIGI_CONVERT_1, 776 0x00); 777 778 /* Set/unset the masked control bit(s) as needed */ 779 change = (val == 0 ? 0 : mask) != (ctrl_data & mask); 780 if (val==0) 781 ctrl_data &= ~mask; 782 else 783 ctrl_data |= mask; 784 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, 785 ctrl_data); 786 787 return change; 788} 789#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \ 790 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 791 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \ 792 .info = alc_spdif_ctrl_info, \ 793 .get = alc_spdif_ctrl_get, \ 794 .put = alc_spdif_ctrl_put, \ 795 .private_value = nid | (mask<<16) } 796#endif /* CONFIG_SND_DEBUG */ 797 798/* A switch control to allow the enabling EAPD digital outputs on the ALC26x. 799 * Again, this is only used in the ALC26x test models to help identify when 800 * the EAPD line must be asserted for features to work. 801 */ 802#ifdef CONFIG_SND_DEBUG 803#define alc_eapd_ctrl_info snd_ctl_boolean_mono_info 804 805static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol, 806 struct snd_ctl_elem_value *ucontrol) 807{ 808 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 809 hda_nid_t nid = kcontrol->private_value & 0xffff; 810 unsigned char mask = (kcontrol->private_value >> 16) & 0xff; 811 long *valp = ucontrol->value.integer.value; 812 unsigned int val = snd_hda_codec_read(codec, nid, 0, 813 AC_VERB_GET_EAPD_BTLENABLE, 0x00); 814 815 *valp = (val & mask) != 0; 816 return 0; 817} 818 819static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol, 820 struct snd_ctl_elem_value *ucontrol) 821{ 822 int change; 823 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 824 hda_nid_t nid = kcontrol->private_value & 0xffff; 825 unsigned char mask = (kcontrol->private_value >> 16) & 0xff; 826 long val = *ucontrol->value.integer.value; 827 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0, 828 AC_VERB_GET_EAPD_BTLENABLE, 829 0x00); 830 831 /* Set/unset the masked control bit(s) as needed */ 832 change = (!val ? 0 : mask) != (ctrl_data & mask); 833 if (!val) 834 ctrl_data &= ~mask; 835 else 836 ctrl_data |= mask; 837 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE, 838 ctrl_data); 839 840 return change; 841} 842 843#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \ 844 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 845 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \ 846 .info = alc_eapd_ctrl_info, \ 847 .get = alc_eapd_ctrl_get, \ 848 .put = alc_eapd_ctrl_put, \ 849 .private_value = nid | (mask<<16) } 850#endif /* CONFIG_SND_DEBUG */ 851 852/* 853 * set up the input pin config (depending on the given auto-pin type) 854 */ 855static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid, 856 int auto_pin_type) 857{ 858 unsigned int val = PIN_IN; 859 860 if (auto_pin_type == AUTO_PIN_MIC) { 861 unsigned int pincap; 862 unsigned int oldval; 863 oldval = snd_hda_codec_read(codec, nid, 0, 864 AC_VERB_GET_PIN_WIDGET_CONTROL, 0); 865 pincap = snd_hda_query_pin_caps(codec, nid); 866 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT; 867 /* if the default pin setup is vref50, we give it priority */ 868 if ((pincap & AC_PINCAP_VREF_80) && oldval != PIN_VREF50) 869 val = PIN_VREF80; 870 else if (pincap & AC_PINCAP_VREF_50) 871 val = PIN_VREF50; 872 else if (pincap & AC_PINCAP_VREF_100) 873 val = PIN_VREF100; 874 else if (pincap & AC_PINCAP_VREF_GRD) 875 val = PIN_VREFGRD; 876 } 877 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val); 878} 879 880static void alc_fixup_autocfg_pin_nums(struct hda_codec *codec) 881{ 882 struct alc_spec *spec = codec->spec; 883 struct auto_pin_cfg *cfg = &spec->autocfg; 884 885 if (!cfg->line_outs) { 886 while (cfg->line_outs < AUTO_CFG_MAX_OUTS && 887 cfg->line_out_pins[cfg->line_outs]) 888 cfg->line_outs++; 889 } 890 if (!cfg->speaker_outs) { 891 while (cfg->speaker_outs < AUTO_CFG_MAX_OUTS && 892 cfg->speaker_pins[cfg->speaker_outs]) 893 cfg->speaker_outs++; 894 } 895 if (!cfg->hp_outs) { 896 while (cfg->hp_outs < AUTO_CFG_MAX_OUTS && 897 cfg->hp_pins[cfg->hp_outs]) 898 cfg->hp_outs++; 899 } 900} 901 902/* 903 */ 904static void add_mixer(struct alc_spec *spec, struct snd_kcontrol_new *mix) 905{ 906 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers))) 907 return; 908 spec->mixers[spec->num_mixers++] = mix; 909} 910 911static void add_verb(struct alc_spec *spec, const struct hda_verb *verb) 912{ 913 if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs))) 914 return; 915 spec->init_verbs[spec->num_init_verbs++] = verb; 916} 917 918/* 919 * set up from the preset table 920 */ 921static void setup_preset(struct hda_codec *codec, 922 const struct alc_config_preset *preset) 923{ 924 struct alc_spec *spec = codec->spec; 925 int i; 926 927 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++) 928 add_mixer(spec, preset->mixers[i]); 929 spec->cap_mixer = preset->cap_mixer; 930 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i]; 931 i++) 932 add_verb(spec, preset->init_verbs[i]); 933 934 spec->channel_mode = preset->channel_mode; 935 spec->num_channel_mode = preset->num_channel_mode; 936 spec->need_dac_fix = preset->need_dac_fix; 937 spec->const_channel_count = preset->const_channel_count; 938 939 if (preset->const_channel_count) 940 spec->multiout.max_channels = preset->const_channel_count; 941 else 942 spec->multiout.max_channels = spec->channel_mode[0].channels; 943 spec->ext_channel_count = spec->channel_mode[0].channels; 944 945 spec->multiout.num_dacs = preset->num_dacs; 946 spec->multiout.dac_nids = preset->dac_nids; 947 spec->multiout.dig_out_nid = preset->dig_out_nid; 948 spec->multiout.slave_dig_outs = preset->slave_dig_outs; 949 spec->multiout.hp_nid = preset->hp_nid; 950 951 spec->num_mux_defs = preset->num_mux_defs; 952 if (!spec->num_mux_defs) 953 spec->num_mux_defs = 1; 954 spec->input_mux = preset->input_mux; 955 956 spec->num_adc_nids = preset->num_adc_nids; 957 spec->adc_nids = preset->adc_nids; 958 spec->capsrc_nids = preset->capsrc_nids; 959 spec->dig_in_nid = preset->dig_in_nid; 960 961 spec->unsol_event = preset->unsol_event; 962 spec->init_hook = preset->init_hook; 963#ifdef CONFIG_SND_HDA_POWER_SAVE 964 spec->power_hook = preset->power_hook; 965 spec->loopback.amplist = preset->loopbacks; 966#endif 967 968 if (preset->setup) 969 preset->setup(codec); 970 971 alc_fixup_autocfg_pin_nums(codec); 972} 973 974/* Enable GPIO mask and set output */ 975static struct hda_verb alc_gpio1_init_verbs[] = { 976 {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, 977 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, 978 {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, 979 { } 980}; 981 982static struct hda_verb alc_gpio2_init_verbs[] = { 983 {0x01, AC_VERB_SET_GPIO_MASK, 0x02}, 984 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02}, 985 {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, 986 { } 987}; 988 989static struct hda_verb alc_gpio3_init_verbs[] = { 990 {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, 991 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03}, 992 {0x01, AC_VERB_SET_GPIO_DATA, 0x03}, 993 { } 994}; 995 996/* 997 * Fix hardware PLL issue 998 * On some codecs, the analog PLL gating control must be off while 999 * the default value is 1. 1000 */ 1001static void alc_fix_pll(struct hda_codec *codec) 1002{ 1003 struct alc_spec *spec = codec->spec; 1004 unsigned int val; 1005 1006 if (!spec->pll_nid) 1007 return; 1008 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX, 1009 spec->pll_coef_idx); 1010 val = snd_hda_codec_read(codec, spec->pll_nid, 0, 1011 AC_VERB_GET_PROC_COEF, 0); 1012 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX, 1013 spec->pll_coef_idx); 1014 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF, 1015 val & ~(1 << spec->pll_coef_bit)); 1016} 1017 1018static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid, 1019 unsigned int coef_idx, unsigned int coef_bit) 1020{ 1021 struct alc_spec *spec = codec->spec; 1022 spec->pll_nid = nid; 1023 spec->pll_coef_idx = coef_idx; 1024 spec->pll_coef_bit = coef_bit; 1025 alc_fix_pll(codec); 1026} 1027 1028static int alc_init_jacks(struct hda_codec *codec) 1029{ 1030#ifdef CONFIG_SND_HDA_INPUT_JACK 1031 struct alc_spec *spec = codec->spec; 1032 int err; 1033 unsigned int hp_nid = spec->autocfg.hp_pins[0]; 1034 unsigned int mic_nid = spec->ext_mic.pin; 1035 1036 if (hp_nid) { 1037 err = snd_hda_input_jack_add(codec, hp_nid, 1038 SND_JACK_HEADPHONE, NULL); 1039 if (err < 0) 1040 return err; 1041 snd_hda_input_jack_report(codec, hp_nid); 1042 } 1043 1044 if (mic_nid) { 1045 err = snd_hda_input_jack_add(codec, mic_nid, 1046 SND_JACK_MICROPHONE, NULL); 1047 if (err < 0) 1048 return err; 1049 snd_hda_input_jack_report(codec, mic_nid); 1050 } 1051#endif /* CONFIG_SND_HDA_INPUT_JACK */ 1052 return 0; 1053} 1054 1055static void alc_automute_speaker(struct hda_codec *codec, int pinctl) 1056{ 1057 struct alc_spec *spec = codec->spec; 1058 unsigned int mute; 1059 hda_nid_t nid; 1060 int i; 1061 1062 spec->jack_present = 0; 1063 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) { 1064 nid = spec->autocfg.hp_pins[i]; 1065 if (!nid) 1066 break; 1067 snd_hda_input_jack_report(codec, nid); 1068 spec->jack_present |= snd_hda_jack_detect(codec, nid); 1069 } 1070 1071 mute = spec->jack_present ? HDA_AMP_MUTE : 0; 1072 /* Toggle internal speakers muting */ 1073 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) { 1074 nid = spec->autocfg.speaker_pins[i]; 1075 if (!nid) 1076 break; 1077 if (pinctl) { 1078 snd_hda_codec_write(codec, nid, 0, 1079 AC_VERB_SET_PIN_WIDGET_CONTROL, 1080 spec->jack_present ? 0 : PIN_OUT); 1081 } else { 1082 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, 1083 HDA_AMP_MUTE, mute); 1084 } 1085 } 1086} 1087 1088static void alc_automute_pin(struct hda_codec *codec) 1089{ 1090 alc_automute_speaker(codec, 1); 1091} 1092 1093static int get_connection_index(struct hda_codec *codec, hda_nid_t mux, 1094 hda_nid_t nid) 1095{ 1096 hda_nid_t conn[HDA_MAX_NUM_INPUTS]; 1097 int i, nums; 1098 1099 nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn)); 1100 for (i = 0; i < nums; i++) 1101 if (conn[i] == nid) 1102 return i; 1103 return -1; 1104} 1105 1106/* switch the current ADC according to the jack state */ 1107static void alc_dual_mic_adc_auto_switch(struct hda_codec *codec) 1108{ 1109 struct alc_spec *spec = codec->spec; 1110 unsigned int present; 1111 hda_nid_t new_adc; 1112 1113 present = snd_hda_jack_detect(codec, spec->ext_mic.pin); 1114 if (present) 1115 spec->cur_adc_idx = 1; 1116 else 1117 spec->cur_adc_idx = 0; 1118 new_adc = spec->adc_nids[spec->cur_adc_idx]; 1119 if (spec->cur_adc && spec->cur_adc != new_adc) { 1120 /* stream is running, let's swap the current ADC */ 1121 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1); 1122 spec->cur_adc = new_adc; 1123 snd_hda_codec_setup_stream(codec, new_adc, 1124 spec->cur_adc_stream_tag, 0, 1125 spec->cur_adc_format); 1126 } 1127} 1128 1129static void alc_mic_automute(struct hda_codec *codec) 1130{ 1131 struct alc_spec *spec = codec->spec; 1132 struct alc_mic_route *dead, *alive; 1133 unsigned int present, type; 1134 hda_nid_t cap_nid; 1135 1136 if (!spec->auto_mic) 1137 return; 1138 if (!spec->int_mic.pin || !spec->ext_mic.pin) 1139 return; 1140 if (snd_BUG_ON(!spec->adc_nids)) 1141 return; 1142 1143 if (spec->dual_adc_switch) { 1144 alc_dual_mic_adc_auto_switch(codec); 1145 return; 1146 } 1147 1148 cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0]; 1149 1150 present = snd_hda_jack_detect(codec, spec->ext_mic.pin); 1151 if (present) { 1152 alive = &spec->ext_mic; 1153 dead = &spec->int_mic; 1154 } else { 1155 alive = &spec->int_mic; 1156 dead = &spec->ext_mic; 1157 } 1158 1159 type = get_wcaps_type(get_wcaps(codec, cap_nid)); 1160 if (type == AC_WID_AUD_MIX) { 1161 /* Matrix-mixer style (e.g. ALC882) */ 1162 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT, 1163 alive->mux_idx, 1164 HDA_AMP_MUTE, 0); 1165 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT, 1166 dead->mux_idx, 1167 HDA_AMP_MUTE, HDA_AMP_MUTE); 1168 } else { 1169 /* MUX style (e.g. ALC880) */ 1170 snd_hda_codec_write_cache(codec, cap_nid, 0, 1171 AC_VERB_SET_CONNECT_SEL, 1172 alive->mux_idx); 1173 } 1174 snd_hda_input_jack_report(codec, spec->ext_mic.pin); 1175 1176 /* FIXME: analog mixer */ 1177} 1178 1179/* unsolicited event for HP jack sensing */ 1180static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res) 1181{ 1182 if (codec->vendor_id == 0x10ec0880) 1183 res >>= 28; 1184 else 1185 res >>= 26; 1186 switch (res) { 1187 case ALC880_HP_EVENT: 1188 alc_automute_pin(codec); 1189 break; 1190 case ALC880_MIC_EVENT: 1191 alc_mic_automute(codec); 1192 break; 1193 } 1194} 1195 1196static void alc_inithook(struct hda_codec *codec) 1197{ 1198 alc_automute_pin(codec); 1199 alc_mic_automute(codec); 1200} 1201 1202/* additional initialization for ALC888 variants */ 1203static void alc888_coef_init(struct hda_codec *codec) 1204{ 1205 unsigned int tmp; 1206 1207 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0); 1208 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0); 1209 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7); 1210 if ((tmp & 0xf0) == 0x20) 1211 /* alc888S-VC */ 1212 snd_hda_codec_read(codec, 0x20, 0, 1213 AC_VERB_SET_PROC_COEF, 0x830); 1214 else 1215 /* alc888-VB */ 1216 snd_hda_codec_read(codec, 0x20, 0, 1217 AC_VERB_SET_PROC_COEF, 0x3030); 1218} 1219 1220static void alc889_coef_init(struct hda_codec *codec) 1221{ 1222 unsigned int tmp; 1223 1224 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7); 1225 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0); 1226 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7); 1227 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, tmp|0x2010); 1228} 1229 1230/* turn on/off EAPD control (only if available) */ 1231static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on) 1232{ 1233 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN) 1234 return; 1235 if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD) 1236 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE, 1237 on ? 2 : 0); 1238} 1239 1240/* turn on/off EAPD controls of the codec */ 1241static void alc_auto_setup_eapd(struct hda_codec *codec, bool on) 1242{ 1243 /* We currently only handle front, HP */ 1244 switch (codec->vendor_id) { 1245 case 0x10ec0260: 1246 set_eapd(codec, 0x0f, on); 1247 set_eapd(codec, 0x10, on); 1248 break; 1249 case 0x10ec0262: 1250 case 0x10ec0267: 1251 case 0x10ec0268: 1252 case 0x10ec0269: 1253 case 0x10ec0270: 1254 case 0x10ec0272: 1255 case 0x10ec0660: 1256 case 0x10ec0662: 1257 case 0x10ec0663: 1258 case 0x10ec0665: 1259 case 0x10ec0862: 1260 case 0x10ec0889: 1261 case 0x10ec0892: 1262 set_eapd(codec, 0x14, on); 1263 set_eapd(codec, 0x15, on); 1264 break; 1265 } 1266} 1267 1268/* generic shutup callback; 1269 * just turning off EPAD and a little pause for avoiding pop-noise 1270 */ 1271static void alc_eapd_shutup(struct hda_codec *codec) 1272{ 1273 alc_auto_setup_eapd(codec, false); 1274 msleep(200); 1275} 1276 1277static void alc_auto_init_amp(struct hda_codec *codec, int type) 1278{ 1279 unsigned int tmp; 1280 1281 switch (type) { 1282 case ALC_INIT_GPIO1: 1283 snd_hda_sequence_write(codec, alc_gpio1_init_verbs); 1284 break; 1285 case ALC_INIT_GPIO2: 1286 snd_hda_sequence_write(codec, alc_gpio2_init_verbs); 1287 break; 1288 case ALC_INIT_GPIO3: 1289 snd_hda_sequence_write(codec, alc_gpio3_init_verbs); 1290 break; 1291 case ALC_INIT_DEFAULT: 1292 alc_auto_setup_eapd(codec, true); 1293 switch (codec->vendor_id) { 1294 case 0x10ec0260: 1295 snd_hda_codec_write(codec, 0x1a, 0, 1296 AC_VERB_SET_COEF_INDEX, 7); 1297 tmp = snd_hda_codec_read(codec, 0x1a, 0, 1298 AC_VERB_GET_PROC_COEF, 0); 1299 snd_hda_codec_write(codec, 0x1a, 0, 1300 AC_VERB_SET_COEF_INDEX, 7); 1301 snd_hda_codec_write(codec, 0x1a, 0, 1302 AC_VERB_SET_PROC_COEF, 1303 tmp | 0x2010); 1304 break; 1305 case 0x10ec0262: 1306 case 0x10ec0880: 1307 case 0x10ec0882: 1308 case 0x10ec0883: 1309 case 0x10ec0885: 1310 case 0x10ec0887: 1311 /*case 0x10ec0889:*/ /* this causes an SPDIF problem */ 1312 alc889_coef_init(codec); 1313 break; 1314 case 0x10ec0888: 1315 alc888_coef_init(codec); 1316 break; 1317#if 0 /* XXX: This may cause the silent output on speaker on some machines */ 1318 case 0x10ec0267: 1319 case 0x10ec0268: 1320 snd_hda_codec_write(codec, 0x20, 0, 1321 AC_VERB_SET_COEF_INDEX, 7); 1322 tmp = snd_hda_codec_read(codec, 0x20, 0, 1323 AC_VERB_GET_PROC_COEF, 0); 1324 snd_hda_codec_write(codec, 0x20, 0, 1325 AC_VERB_SET_COEF_INDEX, 7); 1326 snd_hda_codec_write(codec, 0x20, 0, 1327 AC_VERB_SET_PROC_COEF, 1328 tmp | 0x3000); 1329 break; 1330#endif /* XXX */ 1331 } 1332 break; 1333 } 1334} 1335 1336static void alc_init_auto_hp(struct hda_codec *codec) 1337{ 1338 struct alc_spec *spec = codec->spec; 1339 struct auto_pin_cfg *cfg = &spec->autocfg; 1340 int i; 1341 1342 if (!cfg->hp_pins[0]) { 1343 if (cfg->line_out_type != AUTO_PIN_HP_OUT) 1344 return; 1345 } 1346 1347 if (!cfg->speaker_pins[0]) { 1348 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) 1349 return; 1350 memcpy(cfg->speaker_pins, cfg->line_out_pins, 1351 sizeof(cfg->speaker_pins)); 1352 cfg->speaker_outs = cfg->line_outs; 1353 } 1354 1355 if (!cfg->hp_pins[0]) { 1356 memcpy(cfg->hp_pins, cfg->line_out_pins, 1357 sizeof(cfg->hp_pins)); 1358 cfg->hp_outs = cfg->line_outs; 1359 } 1360 1361 for (i = 0; i < cfg->hp_outs; i++) { 1362 snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n", 1363 cfg->hp_pins[i]); 1364 snd_hda_codec_write_cache(codec, cfg->hp_pins[i], 0, 1365 AC_VERB_SET_UNSOLICITED_ENABLE, 1366 AC_USRSP_EN | ALC880_HP_EVENT); 1367 } 1368 spec->unsol_event = alc_sku_unsol_event; 1369} 1370 1371static void alc_init_auto_mic(struct hda_codec *codec) 1372{ 1373 struct alc_spec *spec = codec->spec; 1374 struct auto_pin_cfg *cfg = &spec->autocfg; 1375 hda_nid_t fixed, ext; 1376 int i; 1377 1378 /* there must be only two mic inputs exclusively */ 1379 for (i = 0; i < cfg->num_inputs; i++) 1380 if (cfg->inputs[i].type >= AUTO_PIN_LINE_IN) 1381 return; 1382 1383 fixed = ext = 0; 1384 for (i = 0; i < cfg->num_inputs; i++) { 1385 hda_nid_t nid = cfg->inputs[i].pin; 1386 unsigned int defcfg; 1387 defcfg = snd_hda_codec_get_pincfg(codec, nid); 1388 switch (snd_hda_get_input_pin_attr(defcfg)) { 1389 case INPUT_PIN_ATTR_INT: 1390 if (fixed) 1391 return; /* already occupied */ 1392 fixed = nid; 1393 break; 1394 case INPUT_PIN_ATTR_UNUSED: 1395 return; /* invalid entry */ 1396 default: 1397 if (ext) 1398 return; /* already occupied */ 1399 ext = nid; 1400 break; 1401 } 1402 } 1403 if (!ext || !fixed) 1404 return; 1405 if (!(get_wcaps(codec, ext) & AC_WCAP_UNSOL_CAP)) 1406 return; /* no unsol support */ 1407 snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x\n", 1408 ext, fixed); 1409 spec->ext_mic.pin = ext; 1410 spec->int_mic.pin = fixed; 1411 spec->ext_mic.mux_idx = MUX_IDX_UNDEF; /* set later */ 1412 spec->int_mic.mux_idx = MUX_IDX_UNDEF; /* set later */ 1413 spec->auto_mic = 1; 1414 snd_hda_codec_write_cache(codec, spec->ext_mic.pin, 0, 1415 AC_VERB_SET_UNSOLICITED_ENABLE, 1416 AC_USRSP_EN | ALC880_MIC_EVENT); 1417 spec->unsol_event = alc_sku_unsol_event; 1418} 1419 1420/* Could be any non-zero and even value. When used as fixup, tells 1421 * the driver to ignore any present sku defines. 1422 */ 1423#define ALC_FIXUP_SKU_IGNORE (2) 1424 1425static int alc_auto_parse_customize_define(struct hda_codec *codec) 1426{ 1427 unsigned int ass, tmp, i; 1428 unsigned nid = 0; 1429 struct alc_spec *spec = codec->spec; 1430 1431 spec->cdefine.enable_pcbeep = 1; /* assume always enabled */ 1432 1433 if (spec->cdefine.fixup) { 1434 ass = spec->cdefine.sku_cfg; 1435 if (ass == ALC_FIXUP_SKU_IGNORE) 1436 return -1; 1437 goto do_sku; 1438 } 1439 1440 ass = codec->subsystem_id & 0xffff; 1441 if (ass != codec->bus->pci->subsystem_device && (ass & 1)) 1442 goto do_sku; 1443 1444 nid = 0x1d; 1445 if (codec->vendor_id == 0x10ec0260) 1446 nid = 0x17; 1447 ass = snd_hda_codec_get_pincfg(codec, nid); 1448 1449 if (!(ass & 1)) { 1450 printk(KERN_INFO "hda_codec: %s: SKU not ready 0x%08x\n", 1451 codec->chip_name, ass); 1452 return -1; 1453 } 1454 1455 /* check sum */ 1456 tmp = 0; 1457 for (i = 1; i < 16; i++) { 1458 if ((ass >> i) & 1) 1459 tmp++; 1460 } 1461 if (((ass >> 16) & 0xf) != tmp) 1462 return -1; 1463 1464 spec->cdefine.port_connectivity = ass >> 30; 1465 spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20; 1466 spec->cdefine.check_sum = (ass >> 16) & 0xf; 1467 spec->cdefine.customization = ass >> 8; 1468do_sku: 1469 spec->cdefine.sku_cfg = ass; 1470 spec->cdefine.external_amp = (ass & 0x38) >> 3; 1471 spec->cdefine.platform_type = (ass & 0x4) >> 2; 1472 spec->cdefine.swap = (ass & 0x2) >> 1; 1473 spec->cdefine.override = ass & 0x1; 1474 1475 snd_printd("SKU: Nid=0x%x sku_cfg=0x%08x\n", 1476 nid, spec->cdefine.sku_cfg); 1477 snd_printd("SKU: port_connectivity=0x%x\n", 1478 spec->cdefine.port_connectivity); 1479 snd_printd("SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep); 1480 snd_printd("SKU: check_sum=0x%08x\n", spec->cdefine.check_sum); 1481 snd_printd("SKU: customization=0x%08x\n", spec->cdefine.customization); 1482 snd_printd("SKU: external_amp=0x%x\n", spec->cdefine.external_amp); 1483 snd_printd("SKU: platform_type=0x%x\n", spec->cdefine.platform_type); 1484 snd_printd("SKU: swap=0x%x\n", spec->cdefine.swap); 1485 snd_printd("SKU: override=0x%x\n", spec->cdefine.override); 1486 1487 return 0; 1488} 1489 1490/* check subsystem ID and set up device-specific initialization; 1491 * return 1 if initialized, 0 if invalid SSID 1492 */ 1493/* 32-bit subsystem ID for BIOS loading in HD Audio codec. 1494 * 31 ~ 16 : Manufacture ID 1495 * 15 ~ 8 : SKU ID 1496 * 7 ~ 0 : Assembly ID 1497 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36 1498 */ 1499static int alc_subsystem_id(struct hda_codec *codec, 1500 hda_nid_t porta, hda_nid_t porte, 1501 hda_nid_t portd, hda_nid_t porti) 1502{ 1503 unsigned int ass, tmp, i; 1504 unsigned nid; 1505 struct alc_spec *spec = codec->spec; 1506 1507 if (spec->cdefine.fixup) { 1508 ass = spec->cdefine.sku_cfg; 1509 if (ass == ALC_FIXUP_SKU_IGNORE) 1510 return 0; 1511 goto do_sku; 1512 } 1513 1514 ass = codec->subsystem_id & 0xffff; 1515 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1)) 1516 goto do_sku; 1517 1518 /* invalid SSID, check the special NID pin defcfg instead */ 1519 /* 1520 * 31~30 : port connectivity 1521 * 29~21 : reserve 1522 * 20 : PCBEEP input 1523 * 19~16 : Check sum (15:1) 1524 * 15~1 : Custom 1525 * 0 : override 1526 */ 1527 nid = 0x1d; 1528 if (codec->vendor_id == 0x10ec0260) 1529 nid = 0x17; 1530 ass = snd_hda_codec_get_pincfg(codec, nid); 1531 snd_printd("realtek: No valid SSID, " 1532 "checking pincfg 0x%08x for NID 0x%x\n", 1533 ass, nid); 1534 if (!(ass & 1)) 1535 return 0; 1536 if ((ass >> 30) != 1) /* no physical connection */ 1537 return 0; 1538 1539 /* check sum */ 1540 tmp = 0; 1541 for (i = 1; i < 16; i++) { 1542 if ((ass >> i) & 1) 1543 tmp++; 1544 } 1545 if (((ass >> 16) & 0xf) != tmp) 1546 return 0; 1547do_sku: 1548 snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n", 1549 ass & 0xffff, codec->vendor_id); 1550 /* 1551 * 0 : override 1552 * 1 : Swap Jack 1553 * 2 : 0 --> Desktop, 1 --> Laptop 1554 * 3~5 : External Amplifier control 1555 * 7~6 : Reserved 1556 */ 1557 tmp = (ass & 0x38) >> 3; /* external Amp control */ 1558 switch (tmp) { 1559 case 1: 1560 spec->init_amp = ALC_INIT_GPIO1; 1561 break; 1562 case 3: 1563 spec->init_amp = ALC_INIT_GPIO2; 1564 break; 1565 case 7: 1566 spec->init_amp = ALC_INIT_GPIO3; 1567 break; 1568 case 5: 1569 default: 1570 spec->init_amp = ALC_INIT_DEFAULT; 1571 break; 1572 } 1573 1574 /* is laptop or Desktop and enable the function "Mute internal speaker 1575 * when the external headphone out jack is plugged" 1576 */ 1577 if (!(ass & 0x8000)) 1578 return 1; 1579 /* 1580 * 10~8 : Jack location 1581 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered 1582 * 14~13: Resvered 1583 * 15 : 1 --> enable the function "Mute internal speaker 1584 * when the external headphone out jack is plugged" 1585 */ 1586 if (!spec->autocfg.hp_pins[0]) { 1587 hda_nid_t nid; 1588 tmp = (ass >> 11) & 0x3; /* HP to chassis */ 1589 if (tmp == 0) 1590 nid = porta; 1591 else if (tmp == 1) 1592 nid = porte; 1593 else if (tmp == 2) 1594 nid = portd; 1595 else if (tmp == 3) 1596 nid = porti; 1597 else 1598 return 1; 1599 for (i = 0; i < spec->autocfg.line_outs; i++) 1600 if (spec->autocfg.line_out_pins[i] == nid) 1601 return 1; 1602 spec->autocfg.hp_pins[0] = nid; 1603 } 1604 1605 alc_init_auto_hp(codec); 1606 alc_init_auto_mic(codec); 1607 return 1; 1608} 1609 1610static void alc_ssid_check(struct hda_codec *codec, 1611 hda_nid_t porta, hda_nid_t porte, 1612 hda_nid_t portd, hda_nid_t porti) 1613{ 1614 if (!alc_subsystem_id(codec, porta, porte, portd, porti)) { 1615 struct alc_spec *spec = codec->spec; 1616 snd_printd("realtek: " 1617 "Enable default setup for auto mode as fallback\n"); 1618 spec->init_amp = ALC_INIT_DEFAULT; 1619 alc_init_auto_hp(codec); 1620 alc_init_auto_mic(codec); 1621 } 1622} 1623 1624/* 1625 * Fix-up pin default configurations and add default verbs 1626 */ 1627 1628struct alc_pincfg { 1629 hda_nid_t nid; 1630 u32 val; 1631}; 1632 1633struct alc_model_fixup { 1634 const int id; 1635 const char *name; 1636}; 1637 1638struct alc_fixup { 1639 int type; 1640 bool chained; 1641 int chain_id; 1642 union { 1643 unsigned int sku; 1644 const struct alc_pincfg *pins; 1645 const struct hda_verb *verbs; 1646 void (*func)(struct hda_codec *codec, 1647 const struct alc_fixup *fix, 1648 int action); 1649 } v; 1650}; 1651 1652enum { 1653 ALC_FIXUP_INVALID, 1654 ALC_FIXUP_SKU, 1655 ALC_FIXUP_PINS, 1656 ALC_FIXUP_VERBS, 1657 ALC_FIXUP_FUNC, 1658}; 1659 1660enum { 1661 ALC_FIXUP_ACT_PRE_PROBE, 1662 ALC_FIXUP_ACT_PROBE, 1663 ALC_FIXUP_ACT_INIT, 1664}; 1665 1666static void alc_apply_fixup(struct hda_codec *codec, int action) 1667{ 1668 struct alc_spec *spec = codec->spec; 1669 int id = spec->fixup_id; 1670#ifdef CONFIG_SND_DEBUG_VERBOSE 1671 const char *modelname = spec->fixup_name; 1672#endif 1673 int depth = 0; 1674 1675 if (!spec->fixup_list) 1676 return; 1677 1678 while (id >= 0) { 1679 const struct alc_fixup *fix = spec->fixup_list + id; 1680 const struct alc_pincfg *cfg; 1681 1682 switch (fix->type) { 1683 case ALC_FIXUP_SKU: 1684 if (action != ALC_FIXUP_ACT_PRE_PROBE || !fix->v.sku) 1685 break;; 1686 snd_printdd(KERN_INFO "hda_codec: %s: " 1687 "Apply sku override for %s\n", 1688 codec->chip_name, modelname); 1689 spec->cdefine.sku_cfg = fix->v.sku; 1690 spec->cdefine.fixup = 1; 1691 break; 1692 case ALC_FIXUP_PINS: 1693 cfg = fix->v.pins; 1694 if (action != ALC_FIXUP_ACT_PRE_PROBE || !cfg) 1695 break; 1696 snd_printdd(KERN_INFO "hda_codec: %s: " 1697 "Apply pincfg for %s\n", 1698 codec->chip_name, modelname); 1699 for (; cfg->nid; cfg++) 1700 snd_hda_codec_set_pincfg(codec, cfg->nid, 1701 cfg->val); 1702 break; 1703 case ALC_FIXUP_VERBS: 1704 if (action != ALC_FIXUP_ACT_PROBE || !fix->v.verbs) 1705 break; 1706 snd_printdd(KERN_INFO "hda_codec: %s: " 1707 "Apply fix-verbs for %s\n", 1708 codec->chip_name, modelname); 1709 add_verb(codec->spec, fix->v.verbs); 1710 break; 1711 case ALC_FIXUP_FUNC: 1712 if (!fix->v.func) 1713 break; 1714 snd_printdd(KERN_INFO "hda_codec: %s: " 1715 "Apply fix-func for %s\n", 1716 codec->chip_name, modelname); 1717 fix->v.func(codec, fix, action); 1718 break; 1719 default: 1720 snd_printk(KERN_ERR "hda_codec: %s: " 1721 "Invalid fixup type %d\n", 1722 codec->chip_name, fix->type); 1723 break; 1724 } 1725 if (!fix[id].chained) 1726 break; 1727 if (++depth > 10) 1728 break; 1729 id = fix[id].chain_id; 1730 } 1731} 1732 1733static void alc_pick_fixup(struct hda_codec *codec, 1734 const struct alc_model_fixup *models, 1735 const struct snd_pci_quirk *quirk, 1736 const struct alc_fixup *fixlist) 1737{ 1738 struct alc_spec *spec = codec->spec; 1739 int id = -1; 1740 const char *name = NULL; 1741 1742 if (codec->modelname && models) { 1743 while (models->name) { 1744 if (!strcmp(codec->modelname, models->name)) { 1745 id = models->id; 1746 name = models->name; 1747 break; 1748 } 1749 models++; 1750 } 1751 } 1752 if (id < 0) { 1753 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk); 1754 if (quirk) { 1755 id = quirk->value; 1756#ifdef CONFIG_SND_DEBUG_VERBOSE 1757 name = quirk->name; 1758#endif 1759 } 1760 } 1761 1762 spec->fixup_id = id; 1763 if (id >= 0) { 1764 spec->fixup_list = fixlist; 1765 spec->fixup_name = name; 1766 } 1767} 1768 1769static int alc_read_coef_idx(struct hda_codec *codec, 1770 unsigned int coef_idx) 1771{ 1772 unsigned int val; 1773 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 1774 coef_idx); 1775 val = snd_hda_codec_read(codec, 0x20, 0, 1776 AC_VERB_GET_PROC_COEF, 0); 1777 return val; 1778} 1779 1780static void alc_write_coef_idx(struct hda_codec *codec, unsigned int coef_idx, 1781 unsigned int coef_val) 1782{ 1783 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 1784 coef_idx); 1785 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, 1786 coef_val); 1787} 1788 1789/* set right pin controls for digital I/O */ 1790static void alc_auto_init_digital(struct hda_codec *codec) 1791{ 1792 struct alc_spec *spec = codec->spec; 1793 int i; 1794 hda_nid_t pin; 1795 1796 for (i = 0; i < spec->autocfg.dig_outs; i++) { 1797 pin = spec->autocfg.dig_out_pins[i]; 1798 if (pin) { 1799 snd_hda_codec_write(codec, pin, 0, 1800 AC_VERB_SET_PIN_WIDGET_CONTROL, 1801 PIN_OUT); 1802 } 1803 } 1804 pin = spec->autocfg.dig_in_pin; 1805 if (pin) 1806 snd_hda_codec_write(codec, pin, 0, 1807 AC_VERB_SET_PIN_WIDGET_CONTROL, 1808 PIN_IN); 1809} 1810 1811/* parse digital I/Os and set up NIDs in BIOS auto-parse mode */ 1812static void alc_auto_parse_digital(struct hda_codec *codec) 1813{ 1814 struct alc_spec *spec = codec->spec; 1815 int i, err; 1816 hda_nid_t dig_nid; 1817 1818 /* support multiple SPDIFs; the secondary is set up as a slave */ 1819 for (i = 0; i < spec->autocfg.dig_outs; i++) { 1820 err = snd_hda_get_connections(codec, 1821 spec->autocfg.dig_out_pins[i], 1822 &dig_nid, 1); 1823 if (err < 0) 1824 continue; 1825 if (!i) { 1826 spec->multiout.dig_out_nid = dig_nid; 1827 spec->dig_out_type = spec->autocfg.dig_out_type[0]; 1828 } else { 1829 spec->multiout.slave_dig_outs = spec->slave_dig_outs; 1830 if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1) 1831 break; 1832 spec->slave_dig_outs[i - 1] = dig_nid; 1833 } 1834 } 1835 1836 if (spec->autocfg.dig_in_pin) { 1837 dig_nid = codec->start_nid; 1838 for (i = 0; i < codec->num_nodes; i++, dig_nid++) { 1839 unsigned int wcaps = get_wcaps(codec, dig_nid); 1840 if (get_wcaps_type(wcaps) != AC_WID_AUD_IN) 1841 continue; 1842 if (!(wcaps & AC_WCAP_DIGITAL)) 1843 continue; 1844 if (!(wcaps & AC_WCAP_CONN_LIST)) 1845 continue; 1846 err = get_connection_index(codec, dig_nid, 1847 spec->autocfg.dig_in_pin); 1848 if (err >= 0) { 1849 spec->dig_in_nid = dig_nid; 1850 break; 1851 } 1852 } 1853 } 1854} 1855 1856/* 1857 * ALC888 1858 */ 1859 1860/* 1861 * 2ch mode 1862 */ 1863static struct hda_verb alc888_4ST_ch2_intel_init[] = { 1864/* Mic-in jack as mic in */ 1865 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 1866 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 1867/* Line-in jack as Line in */ 1868 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 1869 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 1870/* Line-Out as Front */ 1871 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00}, 1872 { } /* end */ 1873}; 1874 1875/* 1876 * 4ch mode 1877 */ 1878static struct hda_verb alc888_4ST_ch4_intel_init[] = { 1879/* Mic-in jack as mic in */ 1880 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 1881 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 1882/* Line-in jack as Surround */ 1883 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 1884 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 1885/* Line-Out as Front */ 1886 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00}, 1887 { } /* end */ 1888}; 1889 1890/* 1891 * 6ch mode 1892 */ 1893static struct hda_verb alc888_4ST_ch6_intel_init[] = { 1894/* Mic-in jack as CLFE */ 1895 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 1896 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 1897/* Line-in jack as Surround */ 1898 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 1899 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 1900/* Line-Out as CLFE (workaround because Mic-in is not loud enough) */ 1901 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, 1902 { } /* end */ 1903}; 1904 1905/* 1906 * 8ch mode 1907 */ 1908static struct hda_verb alc888_4ST_ch8_intel_init[] = { 1909/* Mic-in jack as CLFE */ 1910 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 1911 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 1912/* Line-in jack as Surround */ 1913 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 1914 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 1915/* Line-Out as Side */ 1916 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, 1917 { } /* end */ 1918}; 1919 1920static struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = { 1921 { 2, alc888_4ST_ch2_intel_init }, 1922 { 4, alc888_4ST_ch4_intel_init }, 1923 { 6, alc888_4ST_ch6_intel_init }, 1924 { 8, alc888_4ST_ch8_intel_init }, 1925}; 1926 1927/* 1928 * ALC888 Fujitsu Siemens Amillo xa3530 1929 */ 1930 1931static struct hda_verb alc888_fujitsu_xa3530_verbs[] = { 1932/* Front Mic: set to PIN_IN (empty by default) */ 1933 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1934/* Connect Internal HP to Front */ 1935 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1936 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1937 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 1938/* Connect Bass HP to Front */ 1939 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1940 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1941 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 1942/* Connect Line-Out side jack (SPDIF) to Side */ 1943 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1944 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1945 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, 1946/* Connect Mic jack to CLFE */ 1947 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1948 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1949 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, 1950/* Connect Line-in jack to Surround */ 1951 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1952 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1953 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, 1954/* Connect HP out jack to Front */ 1955 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1956 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1957 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 1958/* Enable unsolicited event for HP jack and Line-out jack */ 1959 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 1960 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 1961 {} 1962}; 1963 1964static void alc_automute_amp(struct hda_codec *codec) 1965{ 1966 alc_automute_speaker(codec, 0); 1967} 1968 1969static void alc_automute_amp_unsol_event(struct hda_codec *codec, 1970 unsigned int res) 1971{ 1972 if (codec->vendor_id == 0x10ec0880) 1973 res >>= 28; 1974 else 1975 res >>= 26; 1976 if (res == ALC880_HP_EVENT) 1977 alc_automute_amp(codec); 1978} 1979 1980static void alc889_automute_setup(struct hda_codec *codec) 1981{ 1982 struct alc_spec *spec = codec->spec; 1983 1984 spec->autocfg.hp_pins[0] = 0x15; 1985 spec->autocfg.speaker_pins[0] = 0x14; 1986 spec->autocfg.speaker_pins[1] = 0x16; 1987 spec->autocfg.speaker_pins[2] = 0x17; 1988 spec->autocfg.speaker_pins[3] = 0x19; 1989 spec->autocfg.speaker_pins[4] = 0x1a; 1990} 1991 1992static void alc889_intel_init_hook(struct hda_codec *codec) 1993{ 1994 alc889_coef_init(codec); 1995 alc_automute_amp(codec); 1996} 1997 1998static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec) 1999{ 2000 struct alc_spec *spec = codec->spec; 2001 2002 spec->autocfg.hp_pins[0] = 0x17; /* line-out */ 2003 spec->autocfg.hp_pins[1] = 0x1b; /* hp */ 2004 spec->autocfg.speaker_pins[0] = 0x14; /* speaker */ 2005 spec->autocfg.speaker_pins[1] = 0x15; /* bass */ 2006} 2007 2008/* 2009 * ALC888 Acer Aspire 4930G model 2010 */ 2011 2012static struct hda_verb alc888_acer_aspire_4930g_verbs[] = { 2013/* Front Mic: set to PIN_IN (empty by default) */ 2014 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2015/* Unselect Front Mic by default in input mixer 3 */ 2016 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)}, 2017/* Enable unsolicited event for HP jack */ 2018 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 2019/* Connect Internal HP to front */ 2020 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2021 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2022 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 2023/* Connect HP out to front */ 2024 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2025 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2026 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 2027 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, 2028 { } 2029}; 2030 2031/* 2032 * ALC888 Acer Aspire 6530G model 2033 */ 2034 2035static struct hda_verb alc888_acer_aspire_6530g_verbs[] = { 2036/* Route to built-in subwoofer as well as speakers */ 2037 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 2038 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 2039 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 2040 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 2041/* Bias voltage on for external mic port */ 2042 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80}, 2043/* Front Mic: set to PIN_IN (empty by default) */ 2044 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2045/* Unselect Front Mic by default in input mixer 3 */ 2046 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)}, 2047/* Enable unsolicited event for HP jack */ 2048 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 2049/* Enable speaker output */ 2050 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2051 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2052 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 2053/* Enable headphone output */ 2054 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP}, 2055 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2056 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 2057 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, 2058 { } 2059}; 2060 2061/* 2062 *ALC888 Acer Aspire 7730G model 2063 */ 2064 2065static struct hda_verb alc888_acer_aspire_7730G_verbs[] = { 2066/* Bias voltage on for external mic port */ 2067 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80}, 2068/* Front Mic: set to PIN_IN (empty by default) */ 2069 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2070/* Unselect Front Mic by default in input mixer 3 */ 2071 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)}, 2072/* Enable unsolicited event for HP jack */ 2073 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 2074/* Enable speaker output */ 2075 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2076 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2077 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 2078/* Enable headphone output */ 2079 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP}, 2080 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2081 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 2082 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, 2083/*Enable internal subwoofer */ 2084 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2085 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2086 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02}, 2087 {0x17, AC_VERB_SET_EAPD_BTLENABLE, 2}, 2088 { } 2089}; 2090 2091/* 2092 * ALC889 Acer Aspire 8930G model 2093 */ 2094 2095static struct hda_verb alc889_acer_aspire_8930g_verbs[] = { 2096/* Front Mic: set to PIN_IN (empty by default) */ 2097 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2098/* Unselect Front Mic by default in input mixer 3 */ 2099 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)}, 2100/* Enable unsolicited event for HP jack */ 2101 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 2102/* Connect Internal Front to Front */ 2103 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2104 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2105 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 2106/* Connect Internal Rear to Rear */ 2107 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2108 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2109 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, 2110/* Connect Internal CLFE to CLFE */ 2111 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2112 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2113 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, 2114/* Connect HP out to Front */ 2115 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP}, 2116 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2117 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 2118/* Enable all DACs */ 2119/* DAC DISABLE/MUTE 1? */ 2120/* setting bits 1-5 disables DAC nids 0x02-0x06 apparently. Init=0x38 */ 2121 {0x20, AC_VERB_SET_COEF_INDEX, 0x03}, 2122 {0x20, AC_VERB_SET_PROC_COEF, 0x0000}, 2123/* DAC DISABLE/MUTE 2? */ 2124/* some bit here disables the other DACs. Init=0x4900 */ 2125 {0x20, AC_VERB_SET_COEF_INDEX, 0x08}, 2126 {0x20, AC_VERB_SET_PROC_COEF, 0x0000}, 2127/* DMIC fix 2128 * This laptop has a stereo digital microphone. The mics are only 1cm apart 2129 * which makes the stereo useless. However, either the mic or the ALC889 2130 * makes the signal become a difference/sum signal instead of standard 2131 * stereo, which is annoying. So instead we flip this bit which makes the 2132 * codec replicate the sum signal to both channels, turning it into a 2133 * normal mono mic. 2134 */ 2135/* DMIC_CONTROL? Init value = 0x0001 */ 2136 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b}, 2137 {0x20, AC_VERB_SET_PROC_COEF, 0x0003}, 2138 { } 2139}; 2140 2141static struct hda_input_mux alc888_2_capture_sources[2] = { 2142 /* Front mic only available on one ADC */ 2143 { 2144 .num_items = 4, 2145 .items = { 2146 { "Mic", 0x0 }, 2147 { "Line", 0x2 }, 2148 { "CD", 0x4 }, 2149 { "Front Mic", 0xb }, 2150 }, 2151 }, 2152 { 2153 .num_items = 3, 2154 .items = { 2155 { "Mic", 0x0 }, 2156 { "Line", 0x2 }, 2157 { "CD", 0x4 }, 2158 }, 2159 } 2160}; 2161 2162static struct hda_input_mux alc888_acer_aspire_6530_sources[2] = { 2163 /* Interal mic only available on one ADC */ 2164 { 2165 .num_items = 5, 2166 .items = { 2167 { "Mic", 0x0 }, 2168 { "Line In", 0x2 }, 2169 { "CD", 0x4 }, 2170 { "Input Mix", 0xa }, 2171 { "Internal Mic", 0xb }, 2172 }, 2173 }, 2174 { 2175 .num_items = 4, 2176 .items = { 2177 { "Mic", 0x0 }, 2178 { "Line In", 0x2 }, 2179 { "CD", 0x4 }, 2180 { "Input Mix", 0xa }, 2181 }, 2182 } 2183}; 2184 2185static struct hda_input_mux alc889_capture_sources[3] = { 2186 /* Digital mic only available on first "ADC" */ 2187 { 2188 .num_items = 5, 2189 .items = { 2190 { "Mic", 0x0 }, 2191 { "Line", 0x2 }, 2192 { "CD", 0x4 }, 2193 { "Front Mic", 0xb }, 2194 { "Input Mix", 0xa }, 2195 }, 2196 }, 2197 { 2198 .num_items = 4, 2199 .items = { 2200 { "Mic", 0x0 }, 2201 { "Line", 0x2 }, 2202 { "CD", 0x4 }, 2203 { "Input Mix", 0xa }, 2204 }, 2205 }, 2206 { 2207 .num_items = 4, 2208 .items = { 2209 { "Mic", 0x0 }, 2210 { "Line", 0x2 }, 2211 { "CD", 0x4 }, 2212 { "Input Mix", 0xa }, 2213 }, 2214 } 2215}; 2216 2217static struct snd_kcontrol_new alc888_base_mixer[] = { 2218 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2219 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 2220 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2221 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 2222 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, 2223 HDA_OUTPUT), 2224 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 2225 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 2226 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 2227 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 2228 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 2229 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 2230 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 2231 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 2232 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 2233 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 2234 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 2235 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 2236 { } /* end */ 2237}; 2238 2239static struct snd_kcontrol_new alc888_acer_aspire_4930g_mixer[] = { 2240 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2241 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 2242 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2243 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 2244 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, 2245 HDA_OUTPUT), 2246 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 2247 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 2248 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 2249 HDA_CODEC_VOLUME_MONO("Internal LFE Playback Volume", 0x0f, 1, 0x0, HDA_OUTPUT), 2250 HDA_BIND_MUTE_MONO("Internal LFE Playback Switch", 0x0f, 1, 2, HDA_INPUT), 2251 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 2252 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 2253 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 2254 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 2255 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 2256 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 2257 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 2258 { } /* end */ 2259}; 2260 2261static struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = { 2262 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2263 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 2264 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2265 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 2266 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, 2267 HDA_OUTPUT), 2268 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 2269 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 2270 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 2271 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 2272 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 2273 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 2274 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 2275 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 2276 { } /* end */ 2277}; 2278 2279 2280static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec) 2281{ 2282 struct alc_spec *spec = codec->spec; 2283 2284 spec->autocfg.hp_pins[0] = 0x15; 2285 spec->autocfg.speaker_pins[0] = 0x14; 2286 spec->autocfg.speaker_pins[1] = 0x16; 2287 spec->autocfg.speaker_pins[2] = 0x17; 2288} 2289 2290static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec) 2291{ 2292 struct alc_spec *spec = codec->spec; 2293 2294 spec->autocfg.hp_pins[0] = 0x15; 2295 spec->autocfg.speaker_pins[0] = 0x14; 2296 spec->autocfg.speaker_pins[1] = 0x16; 2297 spec->autocfg.speaker_pins[2] = 0x17; 2298} 2299 2300static void alc888_acer_aspire_7730g_setup(struct hda_codec *codec) 2301{ 2302 struct alc_spec *spec = codec->spec; 2303 2304 spec->autocfg.hp_pins[0] = 0x15; 2305 spec->autocfg.speaker_pins[0] = 0x14; 2306 spec->autocfg.speaker_pins[1] = 0x16; 2307 spec->autocfg.speaker_pins[2] = 0x17; 2308} 2309 2310static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec) 2311{ 2312 struct alc_spec *spec = codec->spec; 2313 2314 spec->autocfg.hp_pins[0] = 0x15; 2315 spec->autocfg.speaker_pins[0] = 0x14; 2316 spec->autocfg.speaker_pins[1] = 0x16; 2317 spec->autocfg.speaker_pins[2] = 0x1b; 2318} 2319 2320/* 2321 * ALC880 3-stack model 2322 * 2323 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e) 2324 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18, 2325 * F-Mic = 0x1b, HP = 0x19 2326 */ 2327 2328static hda_nid_t alc880_dac_nids[4] = { 2329 /* front, rear, clfe, rear_surr */ 2330 0x02, 0x05, 0x04, 0x03 2331}; 2332 2333static hda_nid_t alc880_adc_nids[3] = { 2334 /* ADC0-2 */ 2335 0x07, 0x08, 0x09, 2336}; 2337 2338/* The datasheet says the node 0x07 is connected from inputs, 2339 * but it shows zero connection in the real implementation on some devices. 2340 * Note: this is a 915GAV bug, fixed on 915GLV 2341 */ 2342static hda_nid_t alc880_adc_nids_alt[2] = { 2343 /* ADC1-2 */ 2344 0x08, 0x09, 2345}; 2346 2347#define ALC880_DIGOUT_NID 0x06 2348#define ALC880_DIGIN_NID 0x0a 2349 2350static struct hda_input_mux alc880_capture_source = { 2351 .num_items = 4, 2352 .items = { 2353 { "Mic", 0x0 }, 2354 { "Front Mic", 0x3 }, 2355 { "Line", 0x2 }, 2356 { "CD", 0x4 }, 2357 }, 2358}; 2359 2360/* channel source setting (2/6 channel selection for 3-stack) */ 2361/* 2ch mode */ 2362static struct hda_verb alc880_threestack_ch2_init[] = { 2363 /* set line-in to input, mute it */ 2364 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 2365 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 2366 /* set mic-in to input vref 80%, mute it */ 2367 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 2368 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 2369 { } /* end */ 2370}; 2371 2372/* 6ch mode */ 2373static struct hda_verb alc880_threestack_ch6_init[] = { 2374 /* set line-in to output, unmute it */ 2375 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 2376 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 2377 /* set mic-in to output, unmute it */ 2378 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 2379 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 2380 { } /* end */ 2381}; 2382 2383static struct hda_channel_mode alc880_threestack_modes[2] = { 2384 { 2, alc880_threestack_ch2_init }, 2385 { 6, alc880_threestack_ch6_init }, 2386}; 2387 2388static struct snd_kcontrol_new alc880_three_stack_mixer[] = { 2389 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2390 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 2391 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 2392 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT), 2393 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 2394 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 2395 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 2396 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 2397 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 2398 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 2399 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 2400 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 2401 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 2402 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 2403 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT), 2404 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT), 2405 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT), 2406 { 2407 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2408 .name = "Channel Mode", 2409 .info = alc_ch_mode_info, 2410 .get = alc_ch_mode_get, 2411 .put = alc_ch_mode_put, 2412 }, 2413 { } /* end */ 2414}; 2415 2416/* capture mixer elements */ 2417static int alc_cap_vol_info(struct snd_kcontrol *kcontrol, 2418 struct snd_ctl_elem_info *uinfo) 2419{ 2420 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2421 struct alc_spec *spec = codec->spec; 2422 int err; 2423 2424 mutex_lock(&codec->control_mutex); 2425 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0, 2426 HDA_INPUT); 2427 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo); 2428 mutex_unlock(&codec->control_mutex); 2429 return err; 2430} 2431 2432static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag, 2433 unsigned int size, unsigned int __user *tlv) 2434{ 2435 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2436 struct alc_spec *spec = codec->spec; 2437 int err; 2438 2439 mutex_lock(&codec->control_mutex); 2440 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0, 2441 HDA_INPUT); 2442 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv); 2443 mutex_unlock(&codec->control_mutex); 2444 return err; 2445} 2446 2447typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol, 2448 struct snd_ctl_elem_value *ucontrol); 2449 2450static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol, 2451 struct snd_ctl_elem_value *ucontrol, 2452 getput_call_t func) 2453{ 2454 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2455 struct alc_spec *spec = codec->spec; 2456 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 2457 int err; 2458 2459 mutex_lock(&codec->control_mutex); 2460 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx], 2461 3, 0, HDA_INPUT); 2462 err = func(kcontrol, ucontrol); 2463 mutex_unlock(&codec->control_mutex); 2464 return err; 2465} 2466 2467static int alc_cap_vol_get(struct snd_kcontrol *kcontrol, 2468 struct snd_ctl_elem_value *ucontrol) 2469{ 2470 return alc_cap_getput_caller(kcontrol, ucontrol, 2471 snd_hda_mixer_amp_volume_get); 2472} 2473 2474static int alc_cap_vol_put(struct snd_kcontrol *kcontrol, 2475 struct snd_ctl_elem_value *ucontrol) 2476{ 2477 return alc_cap_getput_caller(kcontrol, ucontrol, 2478 snd_hda_mixer_amp_volume_put); 2479} 2480 2481/* capture mixer elements */ 2482#define alc_cap_sw_info snd_ctl_boolean_stereo_info 2483 2484static int alc_cap_sw_get(struct snd_kcontrol *kcontrol, 2485 struct snd_ctl_elem_value *ucontrol) 2486{ 2487 return alc_cap_getput_caller(kcontrol, ucontrol, 2488 snd_hda_mixer_amp_switch_get); 2489} 2490 2491static int alc_cap_sw_put(struct snd_kcontrol *kcontrol, 2492 struct snd_ctl_elem_value *ucontrol) 2493{ 2494 return alc_cap_getput_caller(kcontrol, ucontrol, 2495 snd_hda_mixer_amp_switch_put); 2496} 2497 2498#define _DEFINE_CAPMIX(num) \ 2499 { \ 2500 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 2501 .name = "Capture Switch", \ 2502 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \ 2503 .count = num, \ 2504 .info = alc_cap_sw_info, \ 2505 .get = alc_cap_sw_get, \ 2506 .put = alc_cap_sw_put, \ 2507 }, \ 2508 { \ 2509 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 2510 .name = "Capture Volume", \ 2511 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \ 2512 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \ 2513 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \ 2514 .count = num, \ 2515 .info = alc_cap_vol_info, \ 2516 .get = alc_cap_vol_get, \ 2517 .put = alc_cap_vol_put, \ 2518 .tlv = { .c = alc_cap_vol_tlv }, \ 2519 } 2520 2521#define _DEFINE_CAPSRC(num) \ 2522 { \ 2523 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 2524 /* .name = "Capture Source", */ \ 2525 .name = "Input Source", \ 2526 .count = num, \ 2527 .info = alc_mux_enum_info, \ 2528 .get = alc_mux_enum_get, \ 2529 .put = alc_mux_enum_put, \ 2530 } 2531 2532#define DEFINE_CAPMIX(num) \ 2533static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \ 2534 _DEFINE_CAPMIX(num), \ 2535 _DEFINE_CAPSRC(num), \ 2536 { } /* end */ \ 2537} 2538 2539#define DEFINE_CAPMIX_NOSRC(num) \ 2540static struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \ 2541 _DEFINE_CAPMIX(num), \ 2542 { } /* end */ \ 2543} 2544 2545/* up to three ADCs */ 2546DEFINE_CAPMIX(1); 2547DEFINE_CAPMIX(2); 2548DEFINE_CAPMIX(3); 2549DEFINE_CAPMIX_NOSRC(1); 2550DEFINE_CAPMIX_NOSRC(2); 2551DEFINE_CAPMIX_NOSRC(3); 2552 2553/* 2554 * ALC880 5-stack model 2555 * 2556 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d), 2557 * Side = 0x02 (0xd) 2558 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16 2559 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19 2560 */ 2561 2562/* additional mixers to alc880_three_stack_mixer */ 2563static struct snd_kcontrol_new alc880_five_stack_mixer[] = { 2564 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2565 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT), 2566 { } /* end */ 2567}; 2568 2569/* channel source setting (6/8 channel selection for 5-stack) */ 2570/* 6ch mode */ 2571static struct hda_verb alc880_fivestack_ch6_init[] = { 2572 /* set line-in to input, mute it */ 2573 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 2574 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 2575 { } /* end */ 2576}; 2577 2578/* 8ch mode */ 2579static struct hda_verb alc880_fivestack_ch8_init[] = { 2580 /* set line-in to output, unmute it */ 2581 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 2582 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 2583 { } /* end */ 2584}; 2585 2586static struct hda_channel_mode alc880_fivestack_modes[2] = { 2587 { 6, alc880_fivestack_ch6_init }, 2588 { 8, alc880_fivestack_ch8_init }, 2589}; 2590 2591 2592/* 2593 * ALC880 6-stack model 2594 * 2595 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e), 2596 * Side = 0x05 (0x0f) 2597 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17, 2598 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b 2599 */ 2600 2601static hda_nid_t alc880_6st_dac_nids[4] = { 2602 /* front, rear, clfe, rear_surr */ 2603 0x02, 0x03, 0x04, 0x05 2604}; 2605 2606static struct hda_input_mux alc880_6stack_capture_source = { 2607 .num_items = 4, 2608 .items = { 2609 { "Mic", 0x0 }, 2610 { "Front Mic", 0x1 }, 2611 { "Line", 0x2 }, 2612 { "CD", 0x4 }, 2613 }, 2614}; 2615 2616/* fixed 8-channels */ 2617static struct hda_channel_mode alc880_sixstack_modes[1] = { 2618 { 8, NULL }, 2619}; 2620 2621static struct snd_kcontrol_new alc880_six_stack_mixer[] = { 2622 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2623 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 2624 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2625 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 2626 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 2627 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 2628 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 2629 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 2630 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 2631 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 2632 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 2633 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 2634 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 2635 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 2636 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 2637 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 2638 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 2639 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 2640 { 2641 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2642 .name = "Channel Mode", 2643 .info = alc_ch_mode_info, 2644 .get = alc_ch_mode_get, 2645 .put = alc_ch_mode_put, 2646 }, 2647 { } /* end */ 2648}; 2649 2650 2651/* 2652 * ALC880 W810 model 2653 * 2654 * W810 has rear IO for: 2655 * Front (DAC 02) 2656 * Surround (DAC 03) 2657 * Center/LFE (DAC 04) 2658 * Digital out (06) 2659 * 2660 * The system also has a pair of internal speakers, and a headphone jack. 2661 * These are both connected to Line2 on the codec, hence to DAC 02. 2662 * 2663 * There is a variable resistor to control the speaker or headphone 2664 * volume. This is a hardware-only device without a software API. 2665 * 2666 * Plugging headphones in will disable the internal speakers. This is 2667 * implemented in hardware, not via the driver using jack sense. In 2668 * a similar fashion, plugging into the rear socket marked "front" will 2669 * disable both the speakers and headphones. 2670 * 2671 * For input, there's a microphone jack, and an "audio in" jack. 2672 * These may not do anything useful with this driver yet, because I 2673 * haven't setup any initialization verbs for these yet... 2674 */ 2675 2676static hda_nid_t alc880_w810_dac_nids[3] = { 2677 /* front, rear/surround, clfe */ 2678 0x02, 0x03, 0x04 2679}; 2680 2681/* fixed 6 channels */ 2682static struct hda_channel_mode alc880_w810_modes[1] = { 2683 { 6, NULL } 2684}; 2685 2686/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */ 2687static struct snd_kcontrol_new alc880_w810_base_mixer[] = { 2688 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2689 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 2690 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2691 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 2692 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 2693 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 2694 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 2695 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 2696 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 2697 { } /* end */ 2698}; 2699 2700 2701/* 2702 * Z710V model 2703 * 2704 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d) 2705 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?), 2706 * Line = 0x1a 2707 */ 2708 2709static hda_nid_t alc880_z71v_dac_nids[1] = { 2710 0x02 2711}; 2712#define ALC880_Z71V_HP_DAC 0x03 2713 2714/* fixed 2 channels */ 2715static struct hda_channel_mode alc880_2_jack_modes[1] = { 2716 { 2, NULL } 2717}; 2718 2719static struct snd_kcontrol_new alc880_z71v_mixer[] = { 2720 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2721 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 2722 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2723 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT), 2724 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 2725 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 2726 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 2727 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 2728 { } /* end */ 2729}; 2730 2731 2732/* 2733 * ALC880 F1734 model 2734 * 2735 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d) 2736 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18 2737 */ 2738 2739static hda_nid_t alc880_f1734_dac_nids[1] = { 2740 0x03 2741}; 2742#define ALC880_F1734_HP_DAC 0x02 2743 2744static struct snd_kcontrol_new alc880_f1734_mixer[] = { 2745 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2746 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), 2747 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2748 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 2749 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 2750 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 2751 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 2752 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 2753 { } /* end */ 2754}; 2755 2756static struct hda_input_mux alc880_f1734_capture_source = { 2757 .num_items = 2, 2758 .items = { 2759 { "Mic", 0x1 }, 2760 { "CD", 0x4 }, 2761 }, 2762}; 2763 2764 2765/* 2766 * ALC880 ASUS model 2767 * 2768 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e) 2769 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16, 2770 * Mic = 0x18, Line = 0x1a 2771 */ 2772 2773#define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */ 2774#define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */ 2775 2776static struct snd_kcontrol_new alc880_asus_mixer[] = { 2777 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2778 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 2779 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2780 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 2781 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 2782 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 2783 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 2784 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 2785 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 2786 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 2787 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 2788 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 2789 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 2790 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 2791 { 2792 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2793 .name = "Channel Mode", 2794 .info = alc_ch_mode_info, 2795 .get = alc_ch_mode_get, 2796 .put = alc_ch_mode_put, 2797 }, 2798 { } /* end */ 2799}; 2800 2801/* 2802 * ALC880 ASUS W1V model 2803 * 2804 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e) 2805 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16, 2806 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b 2807 */ 2808 2809/* additional mixers to alc880_asus_mixer */ 2810static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = { 2811 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT), 2812 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT), 2813 { } /* end */ 2814}; 2815 2816/* TCL S700 */ 2817static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = { 2818 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2819 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 2820 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 2821 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT), 2822 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT), 2823 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT), 2824 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT), 2825 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 2826 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 2827 { } /* end */ 2828}; 2829 2830/* Uniwill */ 2831static struct snd_kcontrol_new alc880_uniwill_mixer[] = { 2832 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2833 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), 2834 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2835 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 2836 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 2837 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 2838 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 2839 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 2840 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 2841 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 2842 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 2843 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 2844 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 2845 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 2846 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 2847 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 2848 { 2849 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2850 .name = "Channel Mode", 2851 .info = alc_ch_mode_info, 2852 .get = alc_ch_mode_get, 2853 .put = alc_ch_mode_put, 2854 }, 2855 { } /* end */ 2856}; 2857 2858static struct snd_kcontrol_new alc880_fujitsu_mixer[] = { 2859 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2860 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), 2861 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2862 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 2863 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 2864 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 2865 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 2866 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 2867 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 2868 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 2869 { } /* end */ 2870}; 2871 2872static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = { 2873 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2874 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), 2875 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2876 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 2877 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 2878 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 2879 { } /* end */ 2880}; 2881 2882/* 2883 * virtual master controls 2884 */ 2885 2886/* 2887 * slave controls for virtual master 2888 */ 2889static const char * const alc_slave_vols[] = { 2890 "Front Playback Volume", 2891 "Surround Playback Volume", 2892 "Center Playback Volume", 2893 "LFE Playback Volume", 2894 "Side Playback Volume", 2895 "Headphone Playback Volume", 2896 "Speaker Playback Volume", 2897 "Mono Playback Volume", 2898 "Line-Out Playback Volume", 2899 "PCM Playback Volume", 2900 NULL, 2901}; 2902 2903static const char * const alc_slave_sws[] = { 2904 "Front Playback Switch", 2905 "Surround Playback Switch", 2906 "Center Playback Switch", 2907 "LFE Playback Switch", 2908 "Side Playback Switch", 2909 "Headphone Playback Switch", 2910 "Speaker Playback Switch", 2911 "Mono Playback Switch", 2912 "IEC958 Playback Switch", 2913 "Line-Out Playback Switch", 2914 "PCM Playback Switch", 2915 NULL, 2916}; 2917 2918/* 2919 * build control elements 2920 */ 2921 2922#define NID_MAPPING (-1) 2923 2924#define SUBDEV_SPEAKER_ (0 << 6) 2925#define SUBDEV_HP_ (1 << 6) 2926#define SUBDEV_LINE_ (2 << 6) 2927#define SUBDEV_SPEAKER(x) (SUBDEV_SPEAKER_ | ((x) & 0x3f)) 2928#define SUBDEV_HP(x) (SUBDEV_HP_ | ((x) & 0x3f)) 2929#define SUBDEV_LINE(x) (SUBDEV_LINE_ | ((x) & 0x3f)) 2930 2931static void alc_free_kctls(struct hda_codec *codec); 2932 2933#ifdef CONFIG_SND_HDA_INPUT_BEEP 2934/* additional beep mixers; the actual parameters are overwritten at build */ 2935static struct snd_kcontrol_new alc_beep_mixer[] = { 2936 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT), 2937 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT), 2938 { } /* end */ 2939}; 2940#endif 2941 2942static int alc_build_controls(struct hda_codec *codec) 2943{ 2944 struct alc_spec *spec = codec->spec; 2945 struct snd_kcontrol *kctl = NULL; 2946 struct snd_kcontrol_new *knew; 2947 int i, j, err; 2948 unsigned int u; 2949 hda_nid_t nid; 2950 2951 for (i = 0; i < spec->num_mixers; i++) { 2952 err = snd_hda_add_new_ctls(codec, spec->mixers[i]); 2953 if (err < 0) 2954 return err; 2955 } 2956 if (spec->cap_mixer) { 2957 err = snd_hda_add_new_ctls(codec, spec->cap_mixer); 2958 if (err < 0) 2959 return err; 2960 } 2961 if (spec->multiout.dig_out_nid) { 2962 err = snd_hda_create_spdif_out_ctls(codec, 2963 spec->multiout.dig_out_nid); 2964 if (err < 0) 2965 return err; 2966 if (!spec->no_analog) { 2967 err = snd_hda_create_spdif_share_sw(codec, 2968 &spec->multiout); 2969 if (err < 0) 2970 return err; 2971 spec->multiout.share_spdif = 1; 2972 } 2973 } 2974 if (spec->dig_in_nid) { 2975 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid); 2976 if (err < 0) 2977 return err; 2978 } 2979 2980#ifdef CONFIG_SND_HDA_INPUT_BEEP 2981 /* create beep controls if needed */ 2982 if (spec->beep_amp) { 2983 struct snd_kcontrol_new *knew; 2984 for (knew = alc_beep_mixer; knew->name; knew++) { 2985 struct snd_kcontrol *kctl; 2986 kctl = snd_ctl_new1(knew, codec); 2987 if (!kctl) 2988 return -ENOMEM; 2989 kctl->private_value = spec->beep_amp; 2990 err = snd_hda_ctl_add(codec, 0, kctl); 2991 if (err < 0) 2992 return err; 2993 } 2994 } 2995#endif 2996 2997 /* if we have no master control, let's create it */ 2998 if (!spec->no_analog && 2999 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) { 3000 unsigned int vmaster_tlv[4]; 3001 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid, 3002 HDA_OUTPUT, vmaster_tlv); 3003 err = snd_hda_add_vmaster(codec, "Master Playback Volume", 3004 vmaster_tlv, alc_slave_vols); 3005 if (err < 0) 3006 return err; 3007 } 3008 if (!spec->no_analog && 3009 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) { 3010 err = snd_hda_add_vmaster(codec, "Master Playback Switch", 3011 NULL, alc_slave_sws); 3012 if (err < 0) 3013 return err; 3014 } 3015 3016 /* assign Capture Source enums to NID */ 3017 if (spec->capsrc_nids || spec->adc_nids) { 3018 kctl = snd_hda_find_mixer_ctl(codec, "Capture Source"); 3019 if (!kctl) 3020 kctl = snd_hda_find_mixer_ctl(codec, "Input Source"); 3021 for (i = 0; kctl && i < kctl->count; i++) { 3022 hda_nid_t *nids = spec->capsrc_nids; 3023 if (!nids) 3024 nids = spec->adc_nids; 3025 err = snd_hda_add_nid(codec, kctl, i, nids[i]); 3026 if (err < 0) 3027 return err; 3028 } 3029 } 3030 if (spec->cap_mixer) { 3031 const char *kname = kctl ? kctl->id.name : NULL; 3032 for (knew = spec->cap_mixer; knew->name; knew++) { 3033 if (kname && strcmp(knew->name, kname) == 0) 3034 continue; 3035 kctl = snd_hda_find_mixer_ctl(codec, knew->name); 3036 for (i = 0; kctl && i < kctl->count; i++) { 3037 err = snd_hda_add_nid(codec, kctl, i, 3038 spec->adc_nids[i]); 3039 if (err < 0) 3040 return err; 3041 } 3042 } 3043 } 3044 3045 /* other nid->control mapping */ 3046 for (i = 0; i < spec->num_mixers; i++) { 3047 for (knew = spec->mixers[i]; knew->name; knew++) { 3048 if (knew->iface != NID_MAPPING) 3049 continue; 3050 kctl = snd_hda_find_mixer_ctl(codec, knew->name); 3051 if (kctl == NULL) 3052 continue; 3053 u = knew->subdevice; 3054 for (j = 0; j < 4; j++, u >>= 8) { 3055 nid = u & 0x3f; 3056 if (nid == 0) 3057 continue; 3058 switch (u & 0xc0) { 3059 case SUBDEV_SPEAKER_: 3060 nid = spec->autocfg.speaker_pins[nid]; 3061 break; 3062 case SUBDEV_LINE_: 3063 nid = spec->autocfg.line_out_pins[nid]; 3064 break; 3065 case SUBDEV_HP_: 3066 nid = spec->autocfg.hp_pins[nid]; 3067 break; 3068 default: 3069 continue; 3070 } 3071 err = snd_hda_add_nid(codec, kctl, 0, nid); 3072 if (err < 0) 3073 return err; 3074 } 3075 u = knew->private_value; 3076 for (j = 0; j < 4; j++, u >>= 8) { 3077 nid = u & 0xff; 3078 if (nid == 0) 3079 continue; 3080 err = snd_hda_add_nid(codec, kctl, 0, nid); 3081 if (err < 0) 3082 return err; 3083 } 3084 } 3085 } 3086 3087 alc_free_kctls(codec); /* no longer needed */ 3088 3089 return 0; 3090} 3091 3092 3093/* 3094 * initialize the codec volumes, etc 3095 */ 3096 3097/* 3098 * generic initialization of ADC, input mixers and output mixers 3099 */ 3100static struct hda_verb alc880_volume_init_verbs[] = { 3101 /* 3102 * Unmute ADC0-2 and set the default input to mic-in 3103 */ 3104 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 3105 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3106 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 3107 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3108 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 3109 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3110 3111 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 3112 * mixer widget 3113 * Note: PASD motherboards uses the Line In 2 as the input for front 3114 * panel mic (mic 2) 3115 */ 3116 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 3117 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3118 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 3119 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 3120 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 3121 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 3122 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, 3123 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, 3124 3125 /* 3126 * Set up output mixers (0x0c - 0x0f) 3127 */ 3128 /* set vol=0 to output mixers */ 3129 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3130 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3131 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3132 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3133 /* set up input amps for analog loopback */ 3134 /* Amp Indices: DAC = 0, mixer = 1 */ 3135 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3136 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 3137 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3138 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 3139 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3140 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 3141 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3142 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 3143 3144 { } 3145}; 3146 3147/* 3148 * 3-stack pin configuration: 3149 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b 3150 */ 3151static struct hda_verb alc880_pin_3stack_init_verbs[] = { 3152 /* 3153 * preset connection lists of input pins 3154 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround 3155 */ 3156 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ 3157 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 3158 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */ 3159 3160 /* 3161 * Set pin mode and muting 3162 */ 3163 /* set front pin widgets 0x14 for output */ 3164 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3165 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3166 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 3167 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3168 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3169 /* Mic2 (as headphone out) for HP output */ 3170 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3171 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3172 /* Line In pin widget for input */ 3173 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3174 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3175 /* Line2 (as front mic) pin widget for input and vref at 80% */ 3176 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3177 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3178 /* CD pin widget for input */ 3179 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3180 3181 { } 3182}; 3183 3184/* 3185 * 5-stack pin configuration: 3186 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19, 3187 * line-in/side = 0x1a, f-mic = 0x1b 3188 */ 3189static struct hda_verb alc880_pin_5stack_init_verbs[] = { 3190 /* 3191 * preset connection lists of input pins 3192 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround 3193 */ 3194 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 3195 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */ 3196 3197 /* 3198 * Set pin mode and muting 3199 */ 3200 /* set pin widgets 0x14-0x17 for output */ 3201 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3202 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3203 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3204 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3205 /* unmute pins for output (no gain on this amp) */ 3206 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3207 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3208 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3209 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3210 3211 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 3212 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3213 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3214 /* Mic2 (as headphone out) for HP output */ 3215 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3216 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3217 /* Line In pin widget for input */ 3218 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3219 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3220 /* Line2 (as front mic) pin widget for input and vref at 80% */ 3221 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3222 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3223 /* CD pin widget for input */ 3224 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3225 3226 { } 3227}; 3228 3229/* 3230 * W810 pin configuration: 3231 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b 3232 */ 3233static struct hda_verb alc880_pin_w810_init_verbs[] = { 3234 /* hphone/speaker input selector: front DAC */ 3235 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0}, 3236 3237 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3238 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3239 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3240 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3241 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3242 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3243 3244 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3245 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3246 3247 { } 3248}; 3249 3250/* 3251 * Z71V pin configuration: 3252 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?) 3253 */ 3254static struct hda_verb alc880_pin_z71v_init_verbs[] = { 3255 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3256 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3257 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3258 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3259 3260 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3261 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3262 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3263 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3264 3265 { } 3266}; 3267 3268/* 3269 * 6-stack pin configuration: 3270 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18, 3271 * f-mic = 0x19, line = 0x1a, HP = 0x1b 3272 */ 3273static struct hda_verb alc880_pin_6stack_init_verbs[] = { 3274 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 3275 3276 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3277 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3278 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3279 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3280 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3281 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3282 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3283 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3284 3285 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3286 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3287 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3288 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3289 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3290 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3291 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3292 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3293 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3294 3295 { } 3296}; 3297 3298/* 3299 * Uniwill pin configuration: 3300 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19, 3301 * line = 0x1a 3302 */ 3303static struct hda_verb alc880_uniwill_init_verbs[] = { 3304 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 3305 3306 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3307 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3308 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3309 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3310 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3311 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3312 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3313 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3314 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 3315 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 3316 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 3317 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 3318 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 3319 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 3320 3321 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3322 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3323 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3324 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3325 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3326 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3327 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */ 3328 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */ 3329 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3330 3331 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 3332 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 3333 3334 { } 3335}; 3336 3337/* 3338* Uniwill P53 3339* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19, 3340 */ 3341static struct hda_verb alc880_uniwill_p53_init_verbs[] = { 3342 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 3343 3344 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3345 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3346 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3347 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3348 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3349 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3350 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 3351 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 3352 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 3353 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 3354 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 3355 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 3356 3357 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3358 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3359 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3360 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3361 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3362 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3363 3364 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 3365 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT}, 3366 3367 { } 3368}; 3369 3370static struct hda_verb alc880_beep_init_verbs[] = { 3371 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) }, 3372 { } 3373}; 3374 3375/* auto-toggle front mic */ 3376static void alc88x_simple_mic_automute(struct hda_codec *codec) 3377{ 3378 unsigned int present; 3379 unsigned char bits; 3380 3381 present = snd_hda_jack_detect(codec, 0x18); 3382 bits = present ? HDA_AMP_MUTE : 0; 3383 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits); 3384} 3385 3386static void alc880_uniwill_setup(struct hda_codec *codec) 3387{ 3388 struct alc_spec *spec = codec->spec; 3389 3390 spec->autocfg.hp_pins[0] = 0x14; 3391 spec->autocfg.speaker_pins[0] = 0x15; 3392 spec->autocfg.speaker_pins[0] = 0x16; 3393} 3394 3395static void alc880_uniwill_init_hook(struct hda_codec *codec) 3396{ 3397 alc_automute_amp(codec); 3398 alc88x_simple_mic_automute(codec); 3399} 3400 3401static void alc880_uniwill_unsol_event(struct hda_codec *codec, 3402 unsigned int res) 3403{ 3404 /* Looks like the unsol event is incompatible with the standard 3405 * definition. 4bit tag is placed at 28 bit! 3406 */ 3407 switch (res >> 28) { 3408 case ALC880_MIC_EVENT: 3409 alc88x_simple_mic_automute(codec); 3410 break; 3411 default: 3412 alc_automute_amp_unsol_event(codec, res); 3413 break; 3414 } 3415} 3416 3417static void alc880_uniwill_p53_setup(struct hda_codec *codec) 3418{ 3419 struct alc_spec *spec = codec->spec; 3420 3421 spec->autocfg.hp_pins[0] = 0x14; 3422 spec->autocfg.speaker_pins[0] = 0x15; 3423} 3424 3425static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec) 3426{ 3427 unsigned int present; 3428 3429 present = snd_hda_codec_read(codec, 0x21, 0, 3430 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0); 3431 present &= HDA_AMP_VOLMASK; 3432 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0, 3433 HDA_AMP_VOLMASK, present); 3434 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0, 3435 HDA_AMP_VOLMASK, present); 3436} 3437 3438static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec, 3439 unsigned int res) 3440{ 3441 /* Looks like the unsol event is incompatible with the standard 3442 * definition. 4bit tag is placed at 28 bit! 3443 */ 3444 if ((res >> 28) == ALC880_DCVOL_EVENT) 3445 alc880_uniwill_p53_dcvol_automute(codec); 3446 else 3447 alc_automute_amp_unsol_event(codec, res); 3448} 3449 3450/* 3451 * F1734 pin configuration: 3452 * HP = 0x14, speaker-out = 0x15, mic = 0x18 3453 */ 3454static struct hda_verb alc880_pin_f1734_init_verbs[] = { 3455 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01}, 3456 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, 3457 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, 3458 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, 3459 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, 3460 3461 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3462 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3463 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3464 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3465 3466 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3467 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3468 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, 3469 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3470 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3471 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3472 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3473 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3474 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3475 3476 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT}, 3477 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT}, 3478 3479 { } 3480}; 3481 3482/* 3483 * ASUS pin configuration: 3484 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a 3485 */ 3486static struct hda_verb alc880_pin_asus_init_verbs[] = { 3487 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, 3488 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, 3489 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, 3490 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, 3491 3492 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3493 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3494 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3495 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3496 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3497 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3498 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3499 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3500 3501 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3502 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3503 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3504 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3505 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3506 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3507 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3508 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3509 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3510 3511 { } 3512}; 3513 3514/* Enable GPIO mask and set output */ 3515#define alc880_gpio1_init_verbs alc_gpio1_init_verbs 3516#define alc880_gpio2_init_verbs alc_gpio2_init_verbs 3517#define alc880_gpio3_init_verbs alc_gpio3_init_verbs 3518 3519/* Clevo m520g init */ 3520static struct hda_verb alc880_pin_clevo_init_verbs[] = { 3521 /* headphone output */ 3522 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01}, 3523 /* line-out */ 3524 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3525 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3526 /* Line-in */ 3527 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3528 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3529 /* CD */ 3530 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3531 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3532 /* Mic1 (rear panel) */ 3533 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3534 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3535 /* Mic2 (front panel) */ 3536 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3537 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3538 /* headphone */ 3539 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3540 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3541 /* change to EAPD mode */ 3542 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 3543 {0x20, AC_VERB_SET_PROC_COEF, 0x3060}, 3544 3545 { } 3546}; 3547 3548static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = { 3549 /* change to EAPD mode */ 3550 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 3551 {0x20, AC_VERB_SET_PROC_COEF, 0x3060}, 3552 3553 /* Headphone output */ 3554 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3555 /* Front output*/ 3556 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3557 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 3558 3559 /* Line In pin widget for input */ 3560 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3561 /* CD pin widget for input */ 3562 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3563 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 3564 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3565 3566 /* change to EAPD mode */ 3567 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 3568 {0x20, AC_VERB_SET_PROC_COEF, 0x3070}, 3569 3570 { } 3571}; 3572 3573/* 3574 * LG m1 express dual 3575 * 3576 * Pin assignment: 3577 * Rear Line-In/Out (blue): 0x14 3578 * Build-in Mic-In: 0x15 3579 * Speaker-out: 0x17 3580 * HP-Out (green): 0x1b 3581 * Mic-In/Out (red): 0x19 3582 * SPDIF-Out: 0x1e 3583 */ 3584 3585/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */ 3586static hda_nid_t alc880_lg_dac_nids[3] = { 3587 0x05, 0x02, 0x03 3588}; 3589 3590/* seems analog CD is not working */ 3591static struct hda_input_mux alc880_lg_capture_source = { 3592 .num_items = 3, 3593 .items = { 3594 { "Mic", 0x1 }, 3595 { "Line", 0x5 }, 3596 { "Internal Mic", 0x6 }, 3597 }, 3598}; 3599 3600/* 2,4,6 channel modes */ 3601static struct hda_verb alc880_lg_ch2_init[] = { 3602 /* set line-in and mic-in to input */ 3603 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 3604 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 3605 { } 3606}; 3607 3608static struct hda_verb alc880_lg_ch4_init[] = { 3609 /* set line-in to out and mic-in to input */ 3610 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, 3611 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 3612 { } 3613}; 3614 3615static struct hda_verb alc880_lg_ch6_init[] = { 3616 /* set line-in and mic-in to output */ 3617 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, 3618 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, 3619 { } 3620}; 3621 3622static struct hda_channel_mode alc880_lg_ch_modes[3] = { 3623 { 2, alc880_lg_ch2_init }, 3624 { 4, alc880_lg_ch4_init }, 3625 { 6, alc880_lg_ch6_init }, 3626}; 3627 3628static struct snd_kcontrol_new alc880_lg_mixer[] = { 3629 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 3630 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT), 3631 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 3632 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT), 3633 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT), 3634 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT), 3635 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT), 3636 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT), 3637 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 3638 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 3639 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT), 3640 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT), 3641 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT), 3642 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT), 3643 { 3644 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 3645 .name = "Channel Mode", 3646 .info = alc_ch_mode_info, 3647 .get = alc_ch_mode_get, 3648 .put = alc_ch_mode_put, 3649 }, 3650 { } /* end */ 3651}; 3652 3653static struct hda_verb alc880_lg_init_verbs[] = { 3654 /* set capture source to mic-in */ 3655 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 3656 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 3657 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 3658 /* mute all amp mixer inputs */ 3659 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)}, 3660 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, 3661 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, 3662 /* line-in to input */ 3663 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3664 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3665 /* built-in mic */ 3666 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3667 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3668 /* speaker-out */ 3669 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3670 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3671 /* mic-in to input */ 3672 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01}, 3673 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3674 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3675 /* HP-out */ 3676 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03}, 3677 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3678 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3679 /* jack sense */ 3680 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 3681 { } 3682}; 3683 3684/* toggle speaker-output according to the hp-jack state */ 3685static void alc880_lg_setup(struct hda_codec *codec) 3686{ 3687 struct alc_spec *spec = codec->spec; 3688 3689 spec->autocfg.hp_pins[0] = 0x1b; 3690 spec->autocfg.speaker_pins[0] = 0x17; 3691} 3692 3693/* 3694 * LG LW20 3695 * 3696 * Pin assignment: 3697 * Speaker-out: 0x14 3698 * Mic-In: 0x18 3699 * Built-in Mic-In: 0x19 3700 * Line-In: 0x1b 3701 * HP-Out: 0x1a 3702 * SPDIF-Out: 0x1e 3703 */ 3704 3705static struct hda_input_mux alc880_lg_lw_capture_source = { 3706 .num_items = 3, 3707 .items = { 3708 { "Mic", 0x0 }, 3709 { "Internal Mic", 0x1 }, 3710 { "Line In", 0x2 }, 3711 }, 3712}; 3713 3714#define alc880_lg_lw_modes alc880_threestack_modes 3715 3716static struct snd_kcontrol_new alc880_lg_lw_mixer[] = { 3717 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 3718 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 3719 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 3720 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT), 3721 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 3722 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 3723 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 3724 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 3725 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 3726 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 3727 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 3728 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 3729 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 3730 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 3731 { 3732 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 3733 .name = "Channel Mode", 3734 .info = alc_ch_mode_info, 3735 .get = alc_ch_mode_get, 3736 .put = alc_ch_mode_put, 3737 }, 3738 { } /* end */ 3739}; 3740 3741static struct hda_verb alc880_lg_lw_init_verbs[] = { 3742 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 3743 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ 3744 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */ 3745 3746 /* set capture source to mic-in */ 3747 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3748 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3749 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3750 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, 3751 /* speaker-out */ 3752 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3753 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3754 /* HP-out */ 3755 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3756 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3757 /* mic-in to input */ 3758 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3759 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3760 /* built-in mic */ 3761 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3762 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3763 /* jack sense */ 3764 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 3765 { } 3766}; 3767 3768/* toggle speaker-output according to the hp-jack state */ 3769static void alc880_lg_lw_setup(struct hda_codec *codec) 3770{ 3771 struct alc_spec *spec = codec->spec; 3772 3773 spec->autocfg.hp_pins[0] = 0x1b; 3774 spec->autocfg.speaker_pins[0] = 0x14; 3775} 3776 3777static struct snd_kcontrol_new alc880_medion_rim_mixer[] = { 3778 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 3779 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT), 3780 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 3781 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 3782 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 3783 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT), 3784 { } /* end */ 3785}; 3786 3787static struct hda_input_mux alc880_medion_rim_capture_source = { 3788 .num_items = 2, 3789 .items = { 3790 { "Mic", 0x0 }, 3791 { "Internal Mic", 0x1 }, 3792 }, 3793}; 3794 3795static struct hda_verb alc880_medion_rim_init_verbs[] = { 3796 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 3797 3798 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3799 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3800 3801 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 3802 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3803 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3804 /* Mic2 (as headphone out) for HP output */ 3805 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3806 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3807 /* Internal Speaker */ 3808 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3809 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3810 3811 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 3812 {0x20, AC_VERB_SET_PROC_COEF, 0x3060}, 3813 3814 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 3815 { } 3816}; 3817 3818/* toggle speaker-output according to the hp-jack state */ 3819static void alc880_medion_rim_automute(struct hda_codec *codec) 3820{ 3821 struct alc_spec *spec = codec->spec; 3822 alc_automute_amp(codec); 3823 /* toggle EAPD */ 3824 if (spec->jack_present) 3825 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0); 3826 else 3827 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2); 3828} 3829 3830static void alc880_medion_rim_unsol_event(struct hda_codec *codec, 3831 unsigned int res) 3832{ 3833 /* Looks like the unsol event is incompatible with the standard 3834 * definition. 4bit tag is placed at 28 bit! 3835 */ 3836 if ((res >> 28) == ALC880_HP_EVENT) 3837 alc880_medion_rim_automute(codec); 3838} 3839 3840static void alc880_medion_rim_setup(struct hda_codec *codec) 3841{ 3842 struct alc_spec *spec = codec->spec; 3843 3844 spec->autocfg.hp_pins[0] = 0x14; 3845 spec->autocfg.speaker_pins[0] = 0x1b; 3846} 3847 3848#ifdef CONFIG_SND_HDA_POWER_SAVE 3849static struct hda_amp_list alc880_loopbacks[] = { 3850 { 0x0b, HDA_INPUT, 0 }, 3851 { 0x0b, HDA_INPUT, 1 }, 3852 { 0x0b, HDA_INPUT, 2 }, 3853 { 0x0b, HDA_INPUT, 3 }, 3854 { 0x0b, HDA_INPUT, 4 }, 3855 { } /* end */ 3856}; 3857 3858static struct hda_amp_list alc880_lg_loopbacks[] = { 3859 { 0x0b, HDA_INPUT, 1 }, 3860 { 0x0b, HDA_INPUT, 6 }, 3861 { 0x0b, HDA_INPUT, 7 }, 3862 { } /* end */ 3863}; 3864#endif 3865 3866/* 3867 * Common callbacks 3868 */ 3869 3870static void alc_init_special_input_src(struct hda_codec *codec); 3871 3872static int alc_init(struct hda_codec *codec) 3873{ 3874 struct alc_spec *spec = codec->spec; 3875 unsigned int i; 3876 3877 alc_fix_pll(codec); 3878 alc_auto_init_amp(codec, spec->init_amp); 3879 3880 for (i = 0; i < spec->num_init_verbs; i++) 3881 snd_hda_sequence_write(codec, spec->init_verbs[i]); 3882 alc_init_special_input_src(codec); 3883 3884 if (spec->init_hook) 3885 spec->init_hook(codec); 3886 3887 alc_apply_fixup(codec, ALC_FIXUP_ACT_INIT); 3888 3889 hda_call_check_power_status(codec, 0x01); 3890 return 0; 3891} 3892 3893static void alc_unsol_event(struct hda_codec *codec, unsigned int res) 3894{ 3895 struct alc_spec *spec = codec->spec; 3896 3897 if (spec->unsol_event) 3898 spec->unsol_event(codec, res); 3899} 3900 3901#ifdef CONFIG_SND_HDA_POWER_SAVE 3902static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid) 3903{ 3904 struct alc_spec *spec = codec->spec; 3905 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid); 3906} 3907#endif 3908 3909/* 3910 * Analog playback callbacks 3911 */ 3912static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo, 3913 struct hda_codec *codec, 3914 struct snd_pcm_substream *substream) 3915{ 3916 struct alc_spec *spec = codec->spec; 3917 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream, 3918 hinfo); 3919} 3920 3921static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo, 3922 struct hda_codec *codec, 3923 unsigned int stream_tag, 3924 unsigned int format, 3925 struct snd_pcm_substream *substream) 3926{ 3927 struct alc_spec *spec = codec->spec; 3928 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, 3929 stream_tag, format, substream); 3930} 3931 3932static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, 3933 struct hda_codec *codec, 3934 struct snd_pcm_substream *substream) 3935{ 3936 struct alc_spec *spec = codec->spec; 3937 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); 3938} 3939 3940/* 3941 * Digital out 3942 */ 3943static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo, 3944 struct hda_codec *codec, 3945 struct snd_pcm_substream *substream) 3946{ 3947 struct alc_spec *spec = codec->spec; 3948 return snd_hda_multi_out_dig_open(codec, &spec->multiout); 3949} 3950 3951static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, 3952 struct hda_codec *codec, 3953 unsigned int stream_tag, 3954 unsigned int format, 3955 struct snd_pcm_substream *substream) 3956{ 3957 struct alc_spec *spec = codec->spec; 3958 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, 3959 stream_tag, format, substream); 3960} 3961 3962static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, 3963 struct hda_codec *codec, 3964 struct snd_pcm_substream *substream) 3965{ 3966 struct alc_spec *spec = codec->spec; 3967 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout); 3968} 3969 3970static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, 3971 struct hda_codec *codec, 3972 struct snd_pcm_substream *substream) 3973{ 3974 struct alc_spec *spec = codec->spec; 3975 return snd_hda_multi_out_dig_close(codec, &spec->multiout); 3976} 3977 3978/* 3979 * Analog capture 3980 */ 3981static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo, 3982 struct hda_codec *codec, 3983 unsigned int stream_tag, 3984 unsigned int format, 3985 struct snd_pcm_substream *substream) 3986{ 3987 struct alc_spec *spec = codec->spec; 3988 3989 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1], 3990 stream_tag, 0, format); 3991 return 0; 3992} 3993 3994static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, 3995 struct hda_codec *codec, 3996 struct snd_pcm_substream *substream) 3997{ 3998 struct alc_spec *spec = codec->spec; 3999 4000 snd_hda_codec_cleanup_stream(codec, 4001 spec->adc_nids[substream->number + 1]); 4002 return 0; 4003} 4004 4005/* analog capture with dynamic dual-adc changes */ 4006static int dualmic_capture_pcm_prepare(struct hda_pcm_stream *hinfo, 4007 struct hda_codec *codec, 4008 unsigned int stream_tag, 4009 unsigned int format, 4010 struct snd_pcm_substream *substream) 4011{ 4012 struct alc_spec *spec = codec->spec; 4013 spec->cur_adc = spec->adc_nids[spec->cur_adc_idx]; 4014 spec->cur_adc_stream_tag = stream_tag; 4015 spec->cur_adc_format = format; 4016 snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format); 4017 return 0; 4018} 4019 4020static int dualmic_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, 4021 struct hda_codec *codec, 4022 struct snd_pcm_substream *substream) 4023{ 4024 struct alc_spec *spec = codec->spec; 4025 snd_hda_codec_cleanup_stream(codec, spec->cur_adc); 4026 spec->cur_adc = 0; 4027 return 0; 4028} 4029 4030static struct hda_pcm_stream dualmic_pcm_analog_capture = { 4031 .substreams = 1, 4032 .channels_min = 2, 4033 .channels_max = 2, 4034 .nid = 0, /* fill later */ 4035 .ops = { 4036 .prepare = dualmic_capture_pcm_prepare, 4037 .cleanup = dualmic_capture_pcm_cleanup 4038 }, 4039}; 4040 4041/* 4042 */ 4043static struct hda_pcm_stream alc880_pcm_analog_playback = { 4044 .substreams = 1, 4045 .channels_min = 2, 4046 .channels_max = 8, 4047 /* NID is set in alc_build_pcms */ 4048 .ops = { 4049 .open = alc880_playback_pcm_open, 4050 .prepare = alc880_playback_pcm_prepare, 4051 .cleanup = alc880_playback_pcm_cleanup 4052 }, 4053}; 4054 4055static struct hda_pcm_stream alc880_pcm_analog_capture = { 4056 .substreams = 1, 4057 .channels_min = 2, 4058 .channels_max = 2, 4059 /* NID is set in alc_build_pcms */ 4060}; 4061 4062static struct hda_pcm_stream alc880_pcm_analog_alt_playback = { 4063 .substreams = 1, 4064 .channels_min = 2, 4065 .channels_max = 2, 4066 /* NID is set in alc_build_pcms */ 4067}; 4068 4069static struct hda_pcm_stream alc880_pcm_analog_alt_capture = { 4070 .substreams = 2, /* can be overridden */ 4071 .channels_min = 2, 4072 .channels_max = 2, 4073 /* NID is set in alc_build_pcms */ 4074 .ops = { 4075 .prepare = alc880_alt_capture_pcm_prepare, 4076 .cleanup = alc880_alt_capture_pcm_cleanup 4077 }, 4078}; 4079 4080static struct hda_pcm_stream alc880_pcm_digital_playback = { 4081 .substreams = 1, 4082 .channels_min = 2, 4083 .channels_max = 2, 4084 /* NID is set in alc_build_pcms */ 4085 .ops = { 4086 .open = alc880_dig_playback_pcm_open, 4087 .close = alc880_dig_playback_pcm_close, 4088 .prepare = alc880_dig_playback_pcm_prepare, 4089 .cleanup = alc880_dig_playback_pcm_cleanup 4090 }, 4091}; 4092 4093static struct hda_pcm_stream alc880_pcm_digital_capture = { 4094 .substreams = 1, 4095 .channels_min = 2, 4096 .channels_max = 2, 4097 /* NID is set in alc_build_pcms */ 4098}; 4099 4100/* Used by alc_build_pcms to flag that a PCM has no playback stream */ 4101static struct hda_pcm_stream alc_pcm_null_stream = { 4102 .substreams = 0, 4103 .channels_min = 0, 4104 .channels_max = 0, 4105}; 4106 4107static int alc_build_pcms(struct hda_codec *codec) 4108{ 4109 struct alc_spec *spec = codec->spec; 4110 struct hda_pcm *info = spec->pcm_rec; 4111 int i; 4112 4113 codec->num_pcms = 1; 4114 codec->pcm_info = info; 4115 4116 if (spec->no_analog) 4117 goto skip_analog; 4118 4119 snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog), 4120 "%s Analog", codec->chip_name); 4121 info->name = spec->stream_name_analog; 4122 4123 if (spec->stream_analog_playback) { 4124 if (snd_BUG_ON(!spec->multiout.dac_nids)) 4125 return -EINVAL; 4126 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback); 4127 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0]; 4128 } 4129 if (spec->stream_analog_capture) { 4130 if (snd_BUG_ON(!spec->adc_nids)) 4131 return -EINVAL; 4132 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture); 4133 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0]; 4134 } 4135 4136 if (spec->channel_mode) { 4137 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0; 4138 for (i = 0; i < spec->num_channel_mode; i++) { 4139 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) { 4140 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels; 4141 } 4142 } 4143 } 4144 4145 skip_analog: 4146 /* SPDIF for stream index #1 */ 4147 if (spec->multiout.dig_out_nid || spec->dig_in_nid) { 4148 snprintf(spec->stream_name_digital, 4149 sizeof(spec->stream_name_digital), 4150 "%s Digital", codec->chip_name); 4151 codec->num_pcms = 2; 4152 codec->slave_dig_outs = spec->multiout.slave_dig_outs; 4153 info = spec->pcm_rec + 1; 4154 info->name = spec->stream_name_digital; 4155 if (spec->dig_out_type) 4156 info->pcm_type = spec->dig_out_type; 4157 else 4158 info->pcm_type = HDA_PCM_TYPE_SPDIF; 4159 if (spec->multiout.dig_out_nid && 4160 spec->stream_digital_playback) { 4161 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback); 4162 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid; 4163 } 4164 if (spec->dig_in_nid && 4165 spec->stream_digital_capture) { 4166 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture); 4167 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid; 4168 } 4169 /* FIXME: do we need this for all Realtek codec models? */ 4170 codec->spdif_status_reset = 1; 4171 } 4172 4173 if (spec->no_analog) 4174 return 0; 4175 4176 /* If the use of more than one ADC is requested for the current 4177 * model, configure a second analog capture-only PCM. 4178 */ 4179 /* Additional Analaog capture for index #2 */ 4180 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) || 4181 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) { 4182 codec->num_pcms = 3; 4183 info = spec->pcm_rec + 2; 4184 info->name = spec->stream_name_analog; 4185 if (spec->alt_dac_nid) { 4186 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = 4187 *spec->stream_analog_alt_playback; 4188 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 4189 spec->alt_dac_nid; 4190 } else { 4191 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = 4192 alc_pcm_null_stream; 4193 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0; 4194 } 4195 if (spec->num_adc_nids > 1) { 4196 info->stream[SNDRV_PCM_STREAM_CAPTURE] = 4197 *spec->stream_analog_alt_capture; 4198 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 4199 spec->adc_nids[1]; 4200 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = 4201 spec->num_adc_nids - 1; 4202 } else { 4203 info->stream[SNDRV_PCM_STREAM_CAPTURE] = 4204 alc_pcm_null_stream; 4205 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0; 4206 } 4207 } 4208 4209 return 0; 4210} 4211 4212static inline void alc_shutup(struct hda_codec *codec) 4213{ 4214 struct alc_spec *spec = codec->spec; 4215 4216 if (spec && spec->shutup) 4217 spec->shutup(codec); 4218 snd_hda_shutup_pins(codec); 4219} 4220 4221static void alc_free_kctls(struct hda_codec *codec) 4222{ 4223 struct alc_spec *spec = codec->spec; 4224 4225 if (spec->kctls.list) { 4226 struct snd_kcontrol_new *kctl = spec->kctls.list; 4227 int i; 4228 for (i = 0; i < spec->kctls.used; i++) 4229 kfree(kctl[i].name); 4230 } 4231 snd_array_free(&spec->kctls); 4232} 4233 4234static void alc_free(struct hda_codec *codec) 4235{ 4236 struct alc_spec *spec = codec->spec; 4237 4238 if (!spec) 4239 return; 4240 4241 alc_shutup(codec); 4242 snd_hda_input_jack_free(codec); 4243 alc_free_kctls(codec); 4244 kfree(spec); 4245 snd_hda_detach_beep_device(codec); 4246} 4247 4248#ifdef CONFIG_SND_HDA_POWER_SAVE 4249static void alc_power_eapd(struct hda_codec *codec) 4250{ 4251 alc_auto_setup_eapd(codec, false); 4252} 4253 4254static int alc_suspend(struct hda_codec *codec, pm_message_t state) 4255{ 4256 struct alc_spec *spec = codec->spec; 4257 alc_shutup(codec); 4258 if (spec && spec->power_hook) 4259 spec->power_hook(codec); 4260 return 0; 4261} 4262#endif 4263 4264#ifdef SND_HDA_NEEDS_RESUME 4265static int alc_resume(struct hda_codec *codec) 4266{ 4267 msleep(150); /* to avoid pop noise */ 4268 codec->patch_ops.init(codec); 4269 snd_hda_codec_resume_amp(codec); 4270 snd_hda_codec_resume_cache(codec); 4271 hda_call_check_power_status(codec, 0x01); 4272 return 0; 4273} 4274#endif 4275 4276/* 4277 */ 4278static struct hda_codec_ops alc_patch_ops = { 4279 .build_controls = alc_build_controls, 4280 .build_pcms = alc_build_pcms, 4281 .init = alc_init, 4282 .free = alc_free, 4283 .unsol_event = alc_unsol_event, 4284#ifdef SND_HDA_NEEDS_RESUME 4285 .resume = alc_resume, 4286#endif 4287#ifdef CONFIG_SND_HDA_POWER_SAVE 4288 .suspend = alc_suspend, 4289 .check_power_status = alc_check_power_status, 4290#endif 4291 .reboot_notify = alc_shutup, 4292}; 4293 4294/* replace the codec chip_name with the given string */ 4295static int alc_codec_rename(struct hda_codec *codec, const char *name) 4296{ 4297 kfree(codec->chip_name); 4298 codec->chip_name = kstrdup(name, GFP_KERNEL); 4299 if (!codec->chip_name) { 4300 alc_free(codec); 4301 return -ENOMEM; 4302 } 4303 return 0; 4304} 4305 4306/* 4307 * Test configuration for debugging 4308 * 4309 * Almost all inputs/outputs are enabled. I/O pins can be configured via 4310 * enum controls. 4311 */ 4312#ifdef CONFIG_SND_DEBUG 4313static hda_nid_t alc880_test_dac_nids[4] = { 4314 0x02, 0x03, 0x04, 0x05 4315}; 4316 4317static struct hda_input_mux alc880_test_capture_source = { 4318 .num_items = 7, 4319 .items = { 4320 { "In-1", 0x0 }, 4321 { "In-2", 0x1 }, 4322 { "In-3", 0x2 }, 4323 { "In-4", 0x3 }, 4324 { "CD", 0x4 }, 4325 { "Front", 0x5 }, 4326 { "Surround", 0x6 }, 4327 }, 4328}; 4329 4330static struct hda_channel_mode alc880_test_modes[4] = { 4331 { 2, NULL }, 4332 { 4, NULL }, 4333 { 6, NULL }, 4334 { 8, NULL }, 4335}; 4336 4337static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol, 4338 struct snd_ctl_elem_info *uinfo) 4339{ 4340 static char *texts[] = { 4341 "N/A", "Line Out", "HP Out", 4342 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%" 4343 }; 4344 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 4345 uinfo->count = 1; 4346 uinfo->value.enumerated.items = 8; 4347 if (uinfo->value.enumerated.item >= 8) 4348 uinfo->value.enumerated.item = 7; 4349 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); 4350 return 0; 4351} 4352 4353static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol, 4354 struct snd_ctl_elem_value *ucontrol) 4355{ 4356 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 4357 hda_nid_t nid = (hda_nid_t)kcontrol->private_value; 4358 unsigned int pin_ctl, item = 0; 4359 4360 pin_ctl = snd_hda_codec_read(codec, nid, 0, 4361 AC_VERB_GET_PIN_WIDGET_CONTROL, 0); 4362 if (pin_ctl & AC_PINCTL_OUT_EN) { 4363 if (pin_ctl & AC_PINCTL_HP_EN) 4364 item = 2; 4365 else 4366 item = 1; 4367 } else if (pin_ctl & AC_PINCTL_IN_EN) { 4368 switch (pin_ctl & AC_PINCTL_VREFEN) { 4369 case AC_PINCTL_VREF_HIZ: item = 3; break; 4370 case AC_PINCTL_VREF_50: item = 4; break; 4371 case AC_PINCTL_VREF_GRD: item = 5; break; 4372 case AC_PINCTL_VREF_80: item = 6; break; 4373 case AC_PINCTL_VREF_100: item = 7; break; 4374 } 4375 } 4376 ucontrol->value.enumerated.item[0] = item; 4377 return 0; 4378} 4379 4380static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol, 4381 struct snd_ctl_elem_value *ucontrol) 4382{ 4383 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 4384 hda_nid_t nid = (hda_nid_t)kcontrol->private_value; 4385 static unsigned int ctls[] = { 4386 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN, 4387 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ, 4388 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50, 4389 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD, 4390 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80, 4391 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100, 4392 }; 4393 unsigned int old_ctl, new_ctl; 4394 4395 old_ctl = snd_hda_codec_read(codec, nid, 0, 4396 AC_VERB_GET_PIN_WIDGET_CONTROL, 0); 4397 new_ctl = ctls[ucontrol->value.enumerated.item[0]]; 4398 if (old_ctl != new_ctl) { 4399 int val; 4400 snd_hda_codec_write_cache(codec, nid, 0, 4401 AC_VERB_SET_PIN_WIDGET_CONTROL, 4402 new_ctl); 4403 val = ucontrol->value.enumerated.item[0] >= 3 ? 4404 HDA_AMP_MUTE : 0; 4405 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, 4406 HDA_AMP_MUTE, val); 4407 return 1; 4408 } 4409 return 0; 4410} 4411 4412static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol, 4413 struct snd_ctl_elem_info *uinfo) 4414{ 4415 static char *texts[] = { 4416 "Front", "Surround", "CLFE", "Side" 4417 }; 4418 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 4419 uinfo->count = 1; 4420 uinfo->value.enumerated.items = 4; 4421 if (uinfo->value.enumerated.item >= 4) 4422 uinfo->value.enumerated.item = 3; 4423 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); 4424 return 0; 4425} 4426 4427static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol, 4428 struct snd_ctl_elem_value *ucontrol) 4429{ 4430 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 4431 hda_nid_t nid = (hda_nid_t)kcontrol->private_value; 4432 unsigned int sel; 4433 4434 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0); 4435 ucontrol->value.enumerated.item[0] = sel & 3; 4436 return 0; 4437} 4438 4439static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol, 4440 struct snd_ctl_elem_value *ucontrol) 4441{ 4442 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 4443 hda_nid_t nid = (hda_nid_t)kcontrol->private_value; 4444 unsigned int sel; 4445 4446 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3; 4447 if (ucontrol->value.enumerated.item[0] != sel) { 4448 sel = ucontrol->value.enumerated.item[0] & 3; 4449 snd_hda_codec_write_cache(codec, nid, 0, 4450 AC_VERB_SET_CONNECT_SEL, sel); 4451 return 1; 4452 } 4453 return 0; 4454} 4455 4456#define PIN_CTL_TEST(xname,nid) { \ 4457 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 4458 .name = xname, \ 4459 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \ 4460 .info = alc_test_pin_ctl_info, \ 4461 .get = alc_test_pin_ctl_get, \ 4462 .put = alc_test_pin_ctl_put, \ 4463 .private_value = nid \ 4464 } 4465 4466#define PIN_SRC_TEST(xname,nid) { \ 4467 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 4468 .name = xname, \ 4469 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \ 4470 .info = alc_test_pin_src_info, \ 4471 .get = alc_test_pin_src_get, \ 4472 .put = alc_test_pin_src_put, \ 4473 .private_value = nid \ 4474 } 4475 4476static struct snd_kcontrol_new alc880_test_mixer[] = { 4477 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 4478 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 4479 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT), 4480 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 4481 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 4482 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 4483 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT), 4484 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 4485 PIN_CTL_TEST("Front Pin Mode", 0x14), 4486 PIN_CTL_TEST("Surround Pin Mode", 0x15), 4487 PIN_CTL_TEST("CLFE Pin Mode", 0x16), 4488 PIN_CTL_TEST("Side Pin Mode", 0x17), 4489 PIN_CTL_TEST("In-1 Pin Mode", 0x18), 4490 PIN_CTL_TEST("In-2 Pin Mode", 0x19), 4491 PIN_CTL_TEST("In-3 Pin Mode", 0x1a), 4492 PIN_CTL_TEST("In-4 Pin Mode", 0x1b), 4493 PIN_SRC_TEST("In-1 Pin Source", 0x18), 4494 PIN_SRC_TEST("In-2 Pin Source", 0x19), 4495 PIN_SRC_TEST("In-3 Pin Source", 0x1a), 4496 PIN_SRC_TEST("In-4 Pin Source", 0x1b), 4497 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT), 4498 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT), 4499 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT), 4500 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT), 4501 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT), 4502 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT), 4503 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT), 4504 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT), 4505 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT), 4506 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT), 4507 { 4508 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 4509 .name = "Channel Mode", 4510 .info = alc_ch_mode_info, 4511 .get = alc_ch_mode_get, 4512 .put = alc_ch_mode_put, 4513 }, 4514 { } /* end */ 4515}; 4516 4517static struct hda_verb alc880_test_init_verbs[] = { 4518 /* Unmute inputs of 0x0c - 0x0f */ 4519 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4520 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4521 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4522 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4523 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4524 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4525 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4526 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4527 /* Vol output for 0x0c-0x0f */ 4528 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4529 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4530 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4531 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4532 /* Set output pins 0x14-0x17 */ 4533 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4534 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4535 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4536 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4537 /* Unmute output pins 0x14-0x17 */ 4538 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4539 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4540 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4541 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4542 /* Set input pins 0x18-0x1c */ 4543 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 4544 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 4545 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 4546 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 4547 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 4548 /* Mute input pins 0x18-0x1b */ 4549 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 4550 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 4551 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 4552 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 4553 /* ADC set up */ 4554 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4555 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 4556 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4557 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 4558 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4559 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 4560 /* Analog input/passthru */ 4561 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4562 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4563 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 4564 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 4565 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 4566 { } 4567}; 4568#endif 4569 4570/* 4571 */ 4572 4573static const char * const alc880_models[ALC880_MODEL_LAST] = { 4574 [ALC880_3ST] = "3stack", 4575 [ALC880_TCL_S700] = "tcl", 4576 [ALC880_3ST_DIG] = "3stack-digout", 4577 [ALC880_CLEVO] = "clevo", 4578 [ALC880_5ST] = "5stack", 4579 [ALC880_5ST_DIG] = "5stack-digout", 4580 [ALC880_W810] = "w810", 4581 [ALC880_Z71V] = "z71v", 4582 [ALC880_6ST] = "6stack", 4583 [ALC880_6ST_DIG] = "6stack-digout", 4584 [ALC880_ASUS] = "asus", 4585 [ALC880_ASUS_W1V] = "asus-w1v", 4586 [ALC880_ASUS_DIG] = "asus-dig", 4587 [ALC880_ASUS_DIG2] = "asus-dig2", 4588 [ALC880_UNIWILL_DIG] = "uniwill", 4589 [ALC880_UNIWILL_P53] = "uniwill-p53", 4590 [ALC880_FUJITSU] = "fujitsu", 4591 [ALC880_F1734] = "F1734", 4592 [ALC880_LG] = "lg", 4593 [ALC880_LG_LW] = "lg-lw", 4594 [ALC880_MEDION_RIM] = "medion", 4595#ifdef CONFIG_SND_DEBUG 4596 [ALC880_TEST] = "test", 4597#endif 4598 [ALC880_AUTO] = "auto", 4599}; 4600 4601static struct snd_pci_quirk alc880_cfg_tbl[] = { 4602 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810), 4603 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG), 4604 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST), 4605 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG), 4606 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG), 4607 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG), 4608 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG), 4609 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG), 4610 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST), 4611 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG), 4612 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST), 4613 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V), 4614 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG), 4615 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG), 4616 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG), 4617 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG), 4618 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG), 4619 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V), 4620 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */ 4621 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG), 4622 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG), 4623 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG), 4624 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG), 4625 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST), 4626 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST), 4627 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */ 4628 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST), 4629 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST), 4630 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST), 4631 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST), 4632 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST), 4633 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG), 4634 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG), 4635 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG), 4636 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG), 4637 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO), 4638 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO), 4639 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2), 4640 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG), 4641 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG), 4642 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwill", ALC880_F1734), 4643 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL), 4644 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53), 4645 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810), 4646 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM), 4647 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG), 4648 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG), 4649 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734), 4650 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU), 4651 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_F1734), 4652 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU), 4653 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW), 4654 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG), 4655 SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_LG), 4656 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG), 4657 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW), 4658 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700), 4659 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */ 4660 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG), 4661 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG), 4662 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG), 4663 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG), 4664 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG), 4665 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG), 4666 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG), 4667 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG), 4668 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG), 4669 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG), 4670 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG), 4671 /* default Intel */ 4672 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST), 4673 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG), 4674 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG), 4675 {} 4676}; 4677 4678/* 4679 * ALC880 codec presets 4680 */ 4681static struct alc_config_preset alc880_presets[] = { 4682 [ALC880_3ST] = { 4683 .mixers = { alc880_three_stack_mixer }, 4684 .init_verbs = { alc880_volume_init_verbs, 4685 alc880_pin_3stack_init_verbs }, 4686 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 4687 .dac_nids = alc880_dac_nids, 4688 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), 4689 .channel_mode = alc880_threestack_modes, 4690 .need_dac_fix = 1, 4691 .input_mux = &alc880_capture_source, 4692 }, 4693 [ALC880_3ST_DIG] = { 4694 .mixers = { alc880_three_stack_mixer }, 4695 .init_verbs = { alc880_volume_init_verbs, 4696 alc880_pin_3stack_init_verbs }, 4697 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 4698 .dac_nids = alc880_dac_nids, 4699 .dig_out_nid = ALC880_DIGOUT_NID, 4700 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), 4701 .channel_mode = alc880_threestack_modes, 4702 .need_dac_fix = 1, 4703 .input_mux = &alc880_capture_source, 4704 }, 4705 [ALC880_TCL_S700] = { 4706 .mixers = { alc880_tcl_s700_mixer }, 4707 .init_verbs = { alc880_volume_init_verbs, 4708 alc880_pin_tcl_S700_init_verbs, 4709 alc880_gpio2_init_verbs }, 4710 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 4711 .dac_nids = alc880_dac_nids, 4712 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */ 4713 .num_adc_nids = 1, /* single ADC */ 4714 .hp_nid = 0x03, 4715 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), 4716 .channel_mode = alc880_2_jack_modes, 4717 .input_mux = &alc880_capture_source, 4718 }, 4719 [ALC880_5ST] = { 4720 .mixers = { alc880_three_stack_mixer, 4721 alc880_five_stack_mixer}, 4722 .init_verbs = { alc880_volume_init_verbs, 4723 alc880_pin_5stack_init_verbs }, 4724 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 4725 .dac_nids = alc880_dac_nids, 4726 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes), 4727 .channel_mode = alc880_fivestack_modes, 4728 .input_mux = &alc880_capture_source, 4729 }, 4730 [ALC880_5ST_DIG] = { 4731 .mixers = { alc880_three_stack_mixer, 4732 alc880_five_stack_mixer }, 4733 .init_verbs = { alc880_volume_init_verbs, 4734 alc880_pin_5stack_init_verbs }, 4735 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 4736 .dac_nids = alc880_dac_nids, 4737 .dig_out_nid = ALC880_DIGOUT_NID, 4738 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes), 4739 .channel_mode = alc880_fivestack_modes, 4740 .input_mux = &alc880_capture_source, 4741 }, 4742 [ALC880_6ST] = { 4743 .mixers = { alc880_six_stack_mixer }, 4744 .init_verbs = { alc880_volume_init_verbs, 4745 alc880_pin_6stack_init_verbs }, 4746 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids), 4747 .dac_nids = alc880_6st_dac_nids, 4748 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes), 4749 .channel_mode = alc880_sixstack_modes, 4750 .input_mux = &alc880_6stack_capture_source, 4751 }, 4752 [ALC880_6ST_DIG] = { 4753 .mixers = { alc880_six_stack_mixer }, 4754 .init_verbs = { alc880_volume_init_verbs, 4755 alc880_pin_6stack_init_verbs }, 4756 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids), 4757 .dac_nids = alc880_6st_dac_nids, 4758 .dig_out_nid = ALC880_DIGOUT_NID, 4759 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes), 4760 .channel_mode = alc880_sixstack_modes, 4761 .input_mux = &alc880_6stack_capture_source, 4762 }, 4763 [ALC880_W810] = { 4764 .mixers = { alc880_w810_base_mixer }, 4765 .init_verbs = { alc880_volume_init_verbs, 4766 alc880_pin_w810_init_verbs, 4767 alc880_gpio2_init_verbs }, 4768 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids), 4769 .dac_nids = alc880_w810_dac_nids, 4770 .dig_out_nid = ALC880_DIGOUT_NID, 4771 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes), 4772 .channel_mode = alc880_w810_modes, 4773 .input_mux = &alc880_capture_source, 4774 }, 4775 [ALC880_Z71V] = { 4776 .mixers = { alc880_z71v_mixer }, 4777 .init_verbs = { alc880_volume_init_verbs, 4778 alc880_pin_z71v_init_verbs }, 4779 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids), 4780 .dac_nids = alc880_z71v_dac_nids, 4781 .dig_out_nid = ALC880_DIGOUT_NID, 4782 .hp_nid = 0x03, 4783 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), 4784 .channel_mode = alc880_2_jack_modes, 4785 .input_mux = &alc880_capture_source, 4786 }, 4787 [ALC880_F1734] = { 4788 .mixers = { alc880_f1734_mixer }, 4789 .init_verbs = { alc880_volume_init_verbs, 4790 alc880_pin_f1734_init_verbs }, 4791 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids), 4792 .dac_nids = alc880_f1734_dac_nids, 4793 .hp_nid = 0x02, 4794 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), 4795 .channel_mode = alc880_2_jack_modes, 4796 .input_mux = &alc880_f1734_capture_source, 4797 .unsol_event = alc880_uniwill_p53_unsol_event, 4798 .setup = alc880_uniwill_p53_setup, 4799 .init_hook = alc_automute_amp, 4800 }, 4801 [ALC880_ASUS] = { 4802 .mixers = { alc880_asus_mixer }, 4803 .init_verbs = { alc880_volume_init_verbs, 4804 alc880_pin_asus_init_verbs, 4805 alc880_gpio1_init_verbs }, 4806 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 4807 .dac_nids = alc880_asus_dac_nids, 4808 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), 4809 .channel_mode = alc880_asus_modes, 4810 .need_dac_fix = 1, 4811 .input_mux = &alc880_capture_source, 4812 }, 4813 [ALC880_ASUS_DIG] = { 4814 .mixers = { alc880_asus_mixer }, 4815 .init_verbs = { alc880_volume_init_verbs, 4816 alc880_pin_asus_init_verbs, 4817 alc880_gpio1_init_verbs }, 4818 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 4819 .dac_nids = alc880_asus_dac_nids, 4820 .dig_out_nid = ALC880_DIGOUT_NID, 4821 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), 4822 .channel_mode = alc880_asus_modes, 4823 .need_dac_fix = 1, 4824 .input_mux = &alc880_capture_source, 4825 }, 4826 [ALC880_ASUS_DIG2] = { 4827 .mixers = { alc880_asus_mixer }, 4828 .init_verbs = { alc880_volume_init_verbs, 4829 alc880_pin_asus_init_verbs, 4830 alc880_gpio2_init_verbs }, /* use GPIO2 */ 4831 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 4832 .dac_nids = alc880_asus_dac_nids, 4833 .dig_out_nid = ALC880_DIGOUT_NID, 4834 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), 4835 .channel_mode = alc880_asus_modes, 4836 .need_dac_fix = 1, 4837 .input_mux = &alc880_capture_source, 4838 }, 4839 [ALC880_ASUS_W1V] = { 4840 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer }, 4841 .init_verbs = { alc880_volume_init_verbs, 4842 alc880_pin_asus_init_verbs, 4843 alc880_gpio1_init_verbs }, 4844 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 4845 .dac_nids = alc880_asus_dac_nids, 4846 .dig_out_nid = ALC880_DIGOUT_NID, 4847 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), 4848 .channel_mode = alc880_asus_modes, 4849 .need_dac_fix = 1, 4850 .input_mux = &alc880_capture_source, 4851 }, 4852 [ALC880_UNIWILL_DIG] = { 4853 .mixers = { alc880_asus_mixer }, 4854 .init_verbs = { alc880_volume_init_verbs, 4855 alc880_pin_asus_init_verbs }, 4856 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 4857 .dac_nids = alc880_asus_dac_nids, 4858 .dig_out_nid = ALC880_DIGOUT_NID, 4859 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), 4860 .channel_mode = alc880_asus_modes, 4861 .need_dac_fix = 1, 4862 .input_mux = &alc880_capture_source, 4863 }, 4864 [ALC880_UNIWILL] = { 4865 .mixers = { alc880_uniwill_mixer }, 4866 .init_verbs = { alc880_volume_init_verbs, 4867 alc880_uniwill_init_verbs }, 4868 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 4869 .dac_nids = alc880_asus_dac_nids, 4870 .dig_out_nid = ALC880_DIGOUT_NID, 4871 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), 4872 .channel_mode = alc880_threestack_modes, 4873 .need_dac_fix = 1, 4874 .input_mux = &alc880_capture_source, 4875 .unsol_event = alc880_uniwill_unsol_event, 4876 .setup = alc880_uniwill_setup, 4877 .init_hook = alc880_uniwill_init_hook, 4878 }, 4879 [ALC880_UNIWILL_P53] = { 4880 .mixers = { alc880_uniwill_p53_mixer }, 4881 .init_verbs = { alc880_volume_init_verbs, 4882 alc880_uniwill_p53_init_verbs }, 4883 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 4884 .dac_nids = alc880_asus_dac_nids, 4885 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes), 4886 .channel_mode = alc880_threestack_modes, 4887 .input_mux = &alc880_capture_source, 4888 .unsol_event = alc880_uniwill_p53_unsol_event, 4889 .setup = alc880_uniwill_p53_setup, 4890 .init_hook = alc_automute_amp, 4891 }, 4892 [ALC880_FUJITSU] = { 4893 .mixers = { alc880_fujitsu_mixer }, 4894 .init_verbs = { alc880_volume_init_verbs, 4895 alc880_uniwill_p53_init_verbs, 4896 alc880_beep_init_verbs }, 4897 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 4898 .dac_nids = alc880_dac_nids, 4899 .dig_out_nid = ALC880_DIGOUT_NID, 4900 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), 4901 .channel_mode = alc880_2_jack_modes, 4902 .input_mux = &alc880_capture_source, 4903 .unsol_event = alc880_uniwill_p53_unsol_event, 4904 .setup = alc880_uniwill_p53_setup, 4905 .init_hook = alc_automute_amp, 4906 }, 4907 [ALC880_CLEVO] = { 4908 .mixers = { alc880_three_stack_mixer }, 4909 .init_verbs = { alc880_volume_init_verbs, 4910 alc880_pin_clevo_init_verbs }, 4911 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 4912 .dac_nids = alc880_dac_nids, 4913 .hp_nid = 0x03, 4914 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), 4915 .channel_mode = alc880_threestack_modes, 4916 .need_dac_fix = 1, 4917 .input_mux = &alc880_capture_source, 4918 }, 4919 [ALC880_LG] = { 4920 .mixers = { alc880_lg_mixer }, 4921 .init_verbs = { alc880_volume_init_verbs, 4922 alc880_lg_init_verbs }, 4923 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids), 4924 .dac_nids = alc880_lg_dac_nids, 4925 .dig_out_nid = ALC880_DIGOUT_NID, 4926 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes), 4927 .channel_mode = alc880_lg_ch_modes, 4928 .need_dac_fix = 1, 4929 .input_mux = &alc880_lg_capture_source, 4930 .unsol_event = alc_automute_amp_unsol_event, 4931 .setup = alc880_lg_setup, 4932 .init_hook = alc_automute_amp, 4933#ifdef CONFIG_SND_HDA_POWER_SAVE 4934 .loopbacks = alc880_lg_loopbacks, 4935#endif 4936 }, 4937 [ALC880_LG_LW] = { 4938 .mixers = { alc880_lg_lw_mixer }, 4939 .init_verbs = { alc880_volume_init_verbs, 4940 alc880_lg_lw_init_verbs }, 4941 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 4942 .dac_nids = alc880_dac_nids, 4943 .dig_out_nid = ALC880_DIGOUT_NID, 4944 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes), 4945 .channel_mode = alc880_lg_lw_modes, 4946 .input_mux = &alc880_lg_lw_capture_source, 4947 .unsol_event = alc_automute_amp_unsol_event, 4948 .setup = alc880_lg_lw_setup, 4949 .init_hook = alc_automute_amp, 4950 }, 4951 [ALC880_MEDION_RIM] = { 4952 .mixers = { alc880_medion_rim_mixer }, 4953 .init_verbs = { alc880_volume_init_verbs, 4954 alc880_medion_rim_init_verbs, 4955 alc_gpio2_init_verbs }, 4956 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 4957 .dac_nids = alc880_dac_nids, 4958 .dig_out_nid = ALC880_DIGOUT_NID, 4959 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), 4960 .channel_mode = alc880_2_jack_modes, 4961 .input_mux = &alc880_medion_rim_capture_source, 4962 .unsol_event = alc880_medion_rim_unsol_event, 4963 .setup = alc880_medion_rim_setup, 4964 .init_hook = alc880_medion_rim_automute, 4965 }, 4966#ifdef CONFIG_SND_DEBUG 4967 [ALC880_TEST] = { 4968 .mixers = { alc880_test_mixer }, 4969 .init_verbs = { alc880_test_init_verbs }, 4970 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids), 4971 .dac_nids = alc880_test_dac_nids, 4972 .dig_out_nid = ALC880_DIGOUT_NID, 4973 .num_channel_mode = ARRAY_SIZE(alc880_test_modes), 4974 .channel_mode = alc880_test_modes, 4975 .input_mux = &alc880_test_capture_source, 4976 }, 4977#endif 4978}; 4979 4980/* 4981 * Automatic parse of I/O pins from the BIOS configuration 4982 */ 4983 4984enum { 4985 ALC_CTL_WIDGET_VOL, 4986 ALC_CTL_WIDGET_MUTE, 4987 ALC_CTL_BIND_MUTE, 4988}; 4989static struct snd_kcontrol_new alc880_control_templates[] = { 4990 HDA_CODEC_VOLUME(NULL, 0, 0, 0), 4991 HDA_CODEC_MUTE(NULL, 0, 0, 0), 4992 HDA_BIND_MUTE(NULL, 0, 0, 0), 4993}; 4994 4995/* add dynamic controls */ 4996static int add_control(struct alc_spec *spec, int type, const char *name, 4997 int cidx, unsigned long val) 4998{ 4999 struct snd_kcontrol_new *knew; 5000 5001 snd_array_init(&spec->kctls, sizeof(*knew), 32); 5002 knew = snd_array_new(&spec->kctls); 5003 if (!knew) 5004 return -ENOMEM; 5005 *knew = alc880_control_templates[type]; 5006 knew->name = kstrdup(name, GFP_KERNEL); 5007 if (!knew->name) 5008 return -ENOMEM; 5009 knew->index = cidx; 5010 if (get_amp_nid_(val)) 5011 knew->subdevice = HDA_SUBDEV_AMP_FLAG; 5012 knew->private_value = val; 5013 return 0; 5014} 5015 5016static int add_control_with_pfx(struct alc_spec *spec, int type, 5017 const char *pfx, const char *dir, 5018 const char *sfx, int cidx, unsigned long val) 5019{ 5020 char name[32]; 5021 snprintf(name, sizeof(name), "%s %s %s", pfx, dir, sfx); 5022 return add_control(spec, type, name, cidx, val); 5023} 5024 5025#define add_pb_vol_ctrl(spec, type, pfx, val) \ 5026 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", 0, val) 5027#define add_pb_sw_ctrl(spec, type, pfx, val) \ 5028 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", 0, val) 5029#define __add_pb_vol_ctrl(spec, type, pfx, cidx, val) \ 5030 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", cidx, val) 5031#define __add_pb_sw_ctrl(spec, type, pfx, cidx, val) \ 5032 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", cidx, val) 5033 5034#define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17) 5035#define alc880_fixed_pin_idx(nid) ((nid) - 0x14) 5036#define alc880_is_multi_pin(nid) ((nid) >= 0x18) 5037#define alc880_multi_pin_idx(nid) ((nid) - 0x18) 5038#define alc880_idx_to_dac(nid) ((nid) + 0x02) 5039#define alc880_dac_to_idx(nid) ((nid) - 0x02) 5040#define alc880_idx_to_mixer(nid) ((nid) + 0x0c) 5041#define alc880_idx_to_selector(nid) ((nid) + 0x10) 5042#define ALC880_PIN_CD_NID 0x1c 5043 5044/* fill in the dac_nids table from the parsed pin configuration */ 5045static int alc880_auto_fill_dac_nids(struct alc_spec *spec, 5046 const struct auto_pin_cfg *cfg) 5047{ 5048 hda_nid_t nid; 5049 int assigned[4]; 5050 int i, j; 5051 5052 memset(assigned, 0, sizeof(assigned)); 5053 spec->multiout.dac_nids = spec->private_dac_nids; 5054 5055 /* check the pins hardwired to audio widget */ 5056 for (i = 0; i < cfg->line_outs; i++) { 5057 nid = cfg->line_out_pins[i]; 5058 if (alc880_is_fixed_pin(nid)) { 5059 int idx = alc880_fixed_pin_idx(nid); 5060 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx); 5061 assigned[idx] = 1; 5062 } 5063 } 5064 /* left pins can be connect to any audio widget */ 5065 for (i = 0; i < cfg->line_outs; i++) { 5066 nid = cfg->line_out_pins[i]; 5067 if (alc880_is_fixed_pin(nid)) 5068 continue; 5069 /* search for an empty channel */ 5070 for (j = 0; j < cfg->line_outs; j++) { 5071 if (!assigned[j]) { 5072 spec->multiout.dac_nids[i] = 5073 alc880_idx_to_dac(j); 5074 assigned[j] = 1; 5075 break; 5076 } 5077 } 5078 } 5079 spec->multiout.num_dacs = cfg->line_outs; 5080 return 0; 5081} 5082 5083static const char *alc_get_line_out_pfx(const struct auto_pin_cfg *cfg, 5084 bool can_be_master) 5085{ 5086 if (!cfg->hp_outs && !cfg->speaker_outs && can_be_master) 5087 return "Master"; 5088 5089 switch (cfg->line_out_type) { 5090 case AUTO_PIN_SPEAKER_OUT: 5091 if (cfg->line_outs == 1) 5092 return "Speaker"; 5093 break; 5094 case AUTO_PIN_HP_OUT: 5095 return "Headphone"; 5096 default: 5097 if (cfg->line_outs == 1) 5098 return "PCM"; 5099 break; 5100 } 5101 return NULL; 5102} 5103 5104/* add playback controls from the parsed DAC table */ 5105static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec, 5106 const struct auto_pin_cfg *cfg) 5107{ 5108 static const char * const chname[4] = { 5109 "Front", "Surround", NULL /*CLFE*/, "Side" 5110 }; 5111 const char *pfx = alc_get_line_out_pfx(cfg, false); 5112 hda_nid_t nid; 5113 int i, err; 5114 5115 for (i = 0; i < cfg->line_outs; i++) { 5116 if (!spec->multiout.dac_nids[i]) 5117 continue; 5118 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i])); 5119 if (!pfx && i == 2) { 5120 /* Center/LFE */ 5121 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, 5122 "Center", 5123 HDA_COMPOSE_AMP_VAL(nid, 1, 0, 5124 HDA_OUTPUT)); 5125 if (err < 0) 5126 return err; 5127 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, 5128 "LFE", 5129 HDA_COMPOSE_AMP_VAL(nid, 2, 0, 5130 HDA_OUTPUT)); 5131 if (err < 0) 5132 return err; 5133 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, 5134 "Center", 5135 HDA_COMPOSE_AMP_VAL(nid, 1, 2, 5136 HDA_INPUT)); 5137 if (err < 0) 5138 return err; 5139 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, 5140 "LFE", 5141 HDA_COMPOSE_AMP_VAL(nid, 2, 2, 5142 HDA_INPUT)); 5143 if (err < 0) 5144 return err; 5145 } else { 5146 const char *name = pfx; 5147 int index = i; 5148 if (!name) { 5149 name = chname[i]; 5150 index = 0; 5151 } 5152 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, 5153 name, index, 5154 HDA_COMPOSE_AMP_VAL(nid, 3, 0, 5155 HDA_OUTPUT)); 5156 if (err < 0) 5157 return err; 5158 err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, 5159 name, index, 5160 HDA_COMPOSE_AMP_VAL(nid, 3, 2, 5161 HDA_INPUT)); 5162 if (err < 0) 5163 return err; 5164 } 5165 } 5166 return 0; 5167} 5168 5169/* add playback controls for speaker and HP outputs */ 5170static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin, 5171 const char *pfx) 5172{ 5173 hda_nid_t nid; 5174 int err; 5175 5176 if (!pin) 5177 return 0; 5178 5179 if (alc880_is_fixed_pin(pin)) { 5180 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); 5181 /* specify the DAC as the extra output */ 5182 if (!spec->multiout.hp_nid) 5183 spec->multiout.hp_nid = nid; 5184 else 5185 spec->multiout.extra_out_nid[0] = nid; 5186 /* control HP volume/switch on the output mixer amp */ 5187 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin)); 5188 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, 5189 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); 5190 if (err < 0) 5191 return err; 5192 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx, 5193 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT)); 5194 if (err < 0) 5195 return err; 5196 } else if (alc880_is_multi_pin(pin)) { 5197 /* set manual connection */ 5198 /* we have only a switch on HP-out PIN */ 5199 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, 5200 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); 5201 if (err < 0) 5202 return err; 5203 } 5204 return 0; 5205} 5206 5207/* create input playback/capture controls for the given pin */ 5208static int new_analog_input(struct alc_spec *spec, hda_nid_t pin, 5209 const char *ctlname, int ctlidx, 5210 int idx, hda_nid_t mix_nid) 5211{ 5212 int err; 5213 5214 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname, ctlidx, 5215 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT)); 5216 if (err < 0) 5217 return err; 5218 err = __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname, ctlidx, 5219 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT)); 5220 if (err < 0) 5221 return err; 5222 return 0; 5223} 5224 5225static int alc_is_input_pin(struct hda_codec *codec, hda_nid_t nid) 5226{ 5227 unsigned int pincap = snd_hda_query_pin_caps(codec, nid); 5228 return (pincap & AC_PINCAP_IN) != 0; 5229} 5230 5231/* create playback/capture controls for input pins */ 5232static int alc_auto_create_input_ctls(struct hda_codec *codec, 5233 const struct auto_pin_cfg *cfg, 5234 hda_nid_t mixer, 5235 hda_nid_t cap1, hda_nid_t cap2) 5236{ 5237 struct alc_spec *spec = codec->spec; 5238 struct hda_input_mux *imux = &spec->private_imux[0]; 5239 int i, err, idx, type_idx = 0; 5240 const char *prev_label = NULL; 5241 5242 for (i = 0; i < cfg->num_inputs; i++) { 5243 hda_nid_t pin; 5244 const char *label; 5245 5246 pin = cfg->inputs[i].pin; 5247 if (!alc_is_input_pin(codec, pin)) 5248 continue; 5249 5250 label = hda_get_autocfg_input_label(codec, cfg, i); 5251 if (prev_label && !strcmp(label, prev_label)) 5252 type_idx++; 5253 else 5254 type_idx = 0; 5255 prev_label = label; 5256 5257 if (mixer) { 5258 idx = get_connection_index(codec, mixer, pin); 5259 if (idx >= 0) { 5260 err = new_analog_input(spec, pin, 5261 label, type_idx, 5262 idx, mixer); 5263 if (err < 0) 5264 return err; 5265 } 5266 } 5267 5268 if (!cap1) 5269 continue; 5270 idx = get_connection_index(codec, cap1, pin); 5271 if (idx < 0 && cap2) 5272 idx = get_connection_index(codec, cap2, pin); 5273 if (idx >= 0) 5274 snd_hda_add_imux_item(imux, label, idx, NULL); 5275 } 5276 return 0; 5277} 5278 5279static int alc880_auto_create_input_ctls(struct hda_codec *codec, 5280 const struct auto_pin_cfg *cfg) 5281{ 5282 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x08, 0x09); 5283} 5284 5285static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid, 5286 unsigned int pin_type) 5287{ 5288 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 5289 pin_type); 5290 /* unmute pin */ 5291 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, 5292 AMP_OUT_UNMUTE); 5293} 5294 5295static void alc880_auto_set_output_and_unmute(struct hda_codec *codec, 5296 hda_nid_t nid, int pin_type, 5297 int dac_idx) 5298{ 5299 alc_set_pin_output(codec, nid, pin_type); 5300 /* need the manual connection? */ 5301 if (alc880_is_multi_pin(nid)) { 5302 struct alc_spec *spec = codec->spec; 5303 int idx = alc880_multi_pin_idx(nid); 5304 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0, 5305 AC_VERB_SET_CONNECT_SEL, 5306 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx])); 5307 } 5308} 5309 5310static int get_pin_type(int line_out_type) 5311{ 5312 if (line_out_type == AUTO_PIN_HP_OUT) 5313 return PIN_HP; 5314 else 5315 return PIN_OUT; 5316} 5317 5318static void alc880_auto_init_multi_out(struct hda_codec *codec) 5319{ 5320 struct alc_spec *spec = codec->spec; 5321 int i; 5322 5323 for (i = 0; i < spec->autocfg.line_outs; i++) { 5324 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 5325 int pin_type = get_pin_type(spec->autocfg.line_out_type); 5326 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i); 5327 } 5328} 5329 5330static void alc880_auto_init_extra_out(struct hda_codec *codec) 5331{ 5332 struct alc_spec *spec = codec->spec; 5333 hda_nid_t pin; 5334 5335 pin = spec->autocfg.speaker_pins[0]; 5336 if (pin) /* connect to front */ 5337 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0); 5338 pin = spec->autocfg.hp_pins[0]; 5339 if (pin) /* connect to front */ 5340 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); 5341} 5342 5343static void alc880_auto_init_analog_input(struct hda_codec *codec) 5344{ 5345 struct alc_spec *spec = codec->spec; 5346 struct auto_pin_cfg *cfg = &spec->autocfg; 5347 int i; 5348 5349 for (i = 0; i < cfg->num_inputs; i++) { 5350 hda_nid_t nid = cfg->inputs[i].pin; 5351 if (alc_is_input_pin(codec, nid)) { 5352 alc_set_input_pin(codec, nid, cfg->inputs[i].type); 5353 if (nid != ALC880_PIN_CD_NID && 5354 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)) 5355 snd_hda_codec_write(codec, nid, 0, 5356 AC_VERB_SET_AMP_GAIN_MUTE, 5357 AMP_OUT_MUTE); 5358 } 5359 } 5360} 5361 5362static void alc880_auto_init_input_src(struct hda_codec *codec) 5363{ 5364 struct alc_spec *spec = codec->spec; 5365 int c; 5366 5367 for (c = 0; c < spec->num_adc_nids; c++) { 5368 unsigned int mux_idx; 5369 const struct hda_input_mux *imux; 5370 mux_idx = c >= spec->num_mux_defs ? 0 : c; 5371 imux = &spec->input_mux[mux_idx]; 5372 if (!imux->num_items && mux_idx > 0) 5373 imux = &spec->input_mux[0]; 5374 if (imux) 5375 snd_hda_codec_write(codec, spec->adc_nids[c], 0, 5376 AC_VERB_SET_CONNECT_SEL, 5377 imux->items[0].index); 5378 } 5379} 5380 5381/* parse the BIOS configuration and set up the alc_spec */ 5382/* return 1 if successful, 0 if the proper config is not found, 5383 * or a negative error code 5384 */ 5385static int alc880_parse_auto_config(struct hda_codec *codec) 5386{ 5387 struct alc_spec *spec = codec->spec; 5388 int err; 5389 static hda_nid_t alc880_ignore[] = { 0x1d, 0 }; 5390 5391 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 5392 alc880_ignore); 5393 if (err < 0) 5394 return err; 5395 if (!spec->autocfg.line_outs) 5396 return 0; /* can't find valid BIOS pin config */ 5397 5398 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); 5399 if (err < 0) 5400 return err; 5401 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg); 5402 if (err < 0) 5403 return err; 5404 err = alc880_auto_create_extra_out(spec, 5405 spec->autocfg.speaker_pins[0], 5406 "Speaker"); 5407 if (err < 0) 5408 return err; 5409 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0], 5410 "Headphone"); 5411 if (err < 0) 5412 return err; 5413 err = alc880_auto_create_input_ctls(codec, &spec->autocfg); 5414 if (err < 0) 5415 return err; 5416 5417 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 5418 5419 alc_auto_parse_digital(codec); 5420 5421 if (spec->kctls.list) 5422 add_mixer(spec, spec->kctls.list); 5423 5424 add_verb(spec, alc880_volume_init_verbs); 5425 5426 spec->num_mux_defs = 1; 5427 spec->input_mux = &spec->private_imux[0]; 5428 5429 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); 5430 5431 return 1; 5432} 5433 5434/* additional initialization for auto-configuration model */ 5435static void alc880_auto_init(struct hda_codec *codec) 5436{ 5437 struct alc_spec *spec = codec->spec; 5438 alc880_auto_init_multi_out(codec); 5439 alc880_auto_init_extra_out(codec); 5440 alc880_auto_init_analog_input(codec); 5441 alc880_auto_init_input_src(codec); 5442 alc_auto_init_digital(codec); 5443 if (spec->unsol_event) 5444 alc_inithook(codec); 5445} 5446 5447/* check the ADC/MUX contains all input pins; some ADC/MUX contains only 5448 * one of two digital mic pins, e.g. on ALC272 5449 */ 5450static void fixup_automic_adc(struct hda_codec *codec) 5451{ 5452 struct alc_spec *spec = codec->spec; 5453 int i; 5454 5455 for (i = 0; i < spec->num_adc_nids; i++) { 5456 hda_nid_t cap = spec->capsrc_nids ? 5457 spec->capsrc_nids[i] : spec->adc_nids[i]; 5458 int iidx, eidx; 5459 5460 iidx = get_connection_index(codec, cap, spec->int_mic.pin); 5461 if (iidx < 0) 5462 continue; 5463 eidx = get_connection_index(codec, cap, spec->ext_mic.pin); 5464 if (eidx < 0) 5465 continue; 5466 spec->int_mic.mux_idx = iidx; 5467 spec->ext_mic.mux_idx = eidx; 5468 if (spec->capsrc_nids) 5469 spec->capsrc_nids += i; 5470 spec->adc_nids += i; 5471 spec->num_adc_nids = 1; 5472 return; 5473 } 5474 snd_printd(KERN_INFO "hda_codec: %s: " 5475 "No ADC/MUX containing both 0x%x and 0x%x pins\n", 5476 codec->chip_name, spec->int_mic.pin, spec->ext_mic.pin); 5477 spec->auto_mic = 0; /* disable auto-mic to be sure */ 5478} 5479 5480/* select or unmute the given capsrc route */ 5481static void select_or_unmute_capsrc(struct hda_codec *codec, hda_nid_t cap, 5482 int idx) 5483{ 5484 if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) { 5485 snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx, 5486 HDA_AMP_MUTE, 0); 5487 } else { 5488 snd_hda_codec_write_cache(codec, cap, 0, 5489 AC_VERB_SET_CONNECT_SEL, idx); 5490 } 5491} 5492 5493/* set the default connection to that pin */ 5494static int init_capsrc_for_pin(struct hda_codec *codec, hda_nid_t pin) 5495{ 5496 struct alc_spec *spec = codec->spec; 5497 int i; 5498 5499 for (i = 0; i < spec->num_adc_nids; i++) { 5500 hda_nid_t cap = spec->capsrc_nids ? 5501 spec->capsrc_nids[i] : spec->adc_nids[i]; 5502 int idx; 5503 5504 idx = get_connection_index(codec, cap, pin); 5505 if (idx < 0) 5506 continue; 5507 select_or_unmute_capsrc(codec, cap, idx); 5508 return i; /* return the found index */ 5509 } 5510 return -1; /* not found */ 5511} 5512 5513/* choose the ADC/MUX containing the input pin and initialize the setup */ 5514static void fixup_single_adc(struct hda_codec *codec) 5515{ 5516 struct alc_spec *spec = codec->spec; 5517 struct auto_pin_cfg *cfg = &spec->autocfg; 5518 int i; 5519 5520 /* search for the input pin; there must be only one */ 5521 if (cfg->num_inputs != 1) 5522 return; 5523 i = init_capsrc_for_pin(codec, cfg->inputs[0].pin); 5524 if (i >= 0) { 5525 /* use only this ADC */ 5526 if (spec->capsrc_nids) 5527 spec->capsrc_nids += i; 5528 spec->adc_nids += i; 5529 spec->num_adc_nids = 1; 5530 spec->single_input_src = 1; 5531 } 5532} 5533 5534/* initialize dual adcs */ 5535static void fixup_dual_adc_switch(struct hda_codec *codec) 5536{ 5537 struct alc_spec *spec = codec->spec; 5538 init_capsrc_for_pin(codec, spec->ext_mic.pin); 5539 init_capsrc_for_pin(codec, spec->int_mic.pin); 5540} 5541 5542/* initialize some special cases for input sources */ 5543static void alc_init_special_input_src(struct hda_codec *codec) 5544{ 5545 struct alc_spec *spec = codec->spec; 5546 if (spec->dual_adc_switch) 5547 fixup_dual_adc_switch(codec); 5548 else if (spec->single_input_src) 5549 init_capsrc_for_pin(codec, spec->autocfg.inputs[0].pin); 5550} 5551 5552static void set_capture_mixer(struct hda_codec *codec) 5553{ 5554 struct alc_spec *spec = codec->spec; 5555 static struct snd_kcontrol_new *caps[2][3] = { 5556 { alc_capture_mixer_nosrc1, 5557 alc_capture_mixer_nosrc2, 5558 alc_capture_mixer_nosrc3 }, 5559 { alc_capture_mixer1, 5560 alc_capture_mixer2, 5561 alc_capture_mixer3 }, 5562 }; 5563 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) { 5564 int mux = 0; 5565 int num_adcs = spec->num_adc_nids; 5566 if (spec->dual_adc_switch) 5567 num_adcs = 1; 5568 else if (spec->auto_mic) 5569 fixup_automic_adc(codec); 5570 else if (spec->input_mux) { 5571 if (spec->input_mux->num_items > 1) 5572 mux = 1; 5573 else if (spec->input_mux->num_items == 1) 5574 fixup_single_adc(codec); 5575 } 5576 spec->cap_mixer = caps[mux][num_adcs - 1]; 5577 } 5578} 5579 5580/* fill adc_nids (and capsrc_nids) containing all active input pins */ 5581static void fillup_priv_adc_nids(struct hda_codec *codec, hda_nid_t *nids, 5582 int num_nids) 5583{ 5584 struct alc_spec *spec = codec->spec; 5585 struct auto_pin_cfg *cfg = &spec->autocfg; 5586 int n; 5587 hda_nid_t fallback_adc = 0, fallback_cap = 0; 5588 5589 for (n = 0; n < num_nids; n++) { 5590 hda_nid_t adc, cap; 5591 hda_nid_t conn[HDA_MAX_NUM_INPUTS]; 5592 int nconns, i, j; 5593 5594 adc = nids[n]; 5595 if (get_wcaps_type(get_wcaps(codec, adc)) != AC_WID_AUD_IN) 5596 continue; 5597 cap = adc; 5598 nconns = snd_hda_get_connections(codec, cap, conn, 5599 ARRAY_SIZE(conn)); 5600 if (nconns == 1) { 5601 cap = conn[0]; 5602 nconns = snd_hda_get_connections(codec, cap, conn, 5603 ARRAY_SIZE(conn)); 5604 } 5605 if (nconns <= 0) 5606 continue; 5607 if (!fallback_adc) { 5608 fallback_adc = adc; 5609 fallback_cap = cap; 5610 } 5611 for (i = 0; i < cfg->num_inputs; i++) { 5612 hda_nid_t nid = cfg->inputs[i].pin; 5613 for (j = 0; j < nconns; j++) { 5614 if (conn[j] == nid) 5615 break; 5616 } 5617 if (j >= nconns) 5618 break; 5619 } 5620 if (i >= cfg->num_inputs) { 5621 int num_adcs = spec->num_adc_nids; 5622 spec->private_adc_nids[num_adcs] = adc; 5623 spec->private_capsrc_nids[num_adcs] = cap; 5624 spec->num_adc_nids++; 5625 spec->adc_nids = spec->private_adc_nids; 5626 if (adc != cap) 5627 spec->capsrc_nids = spec->private_capsrc_nids; 5628 } 5629 } 5630 if (!spec->num_adc_nids) { 5631 printk(KERN_WARNING "hda_codec: %s: no valid ADC found;" 5632 " using fallback 0x%x\n", 5633 codec->chip_name, fallback_adc); 5634 spec->private_adc_nids[0] = fallback_adc; 5635 spec->adc_nids = spec->private_adc_nids; 5636 if (fallback_adc != fallback_cap) { 5637 spec->private_capsrc_nids[0] = fallback_cap; 5638 spec->capsrc_nids = spec->private_adc_nids; 5639 } 5640 } 5641} 5642 5643#ifdef CONFIG_SND_HDA_INPUT_BEEP 5644#define set_beep_amp(spec, nid, idx, dir) \ 5645 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir)) 5646 5647static struct snd_pci_quirk beep_white_list[] = { 5648 SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1), 5649 SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1), 5650 SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1), 5651 {} 5652}; 5653 5654static inline int has_cdefine_beep(struct hda_codec *codec) 5655{ 5656 struct alc_spec *spec = codec->spec; 5657 const struct snd_pci_quirk *q; 5658 q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list); 5659 if (q) 5660 return q->value; 5661 return spec->cdefine.enable_pcbeep; 5662} 5663#else 5664#define set_beep_amp(spec, nid, idx, dir) /* NOP */ 5665#define has_cdefine_beep(codec) 0 5666#endif 5667 5668/* 5669 * OK, here we have finally the patch for ALC880 5670 */ 5671 5672static int patch_alc880(struct hda_codec *codec) 5673{ 5674 struct alc_spec *spec; 5675 int board_config; 5676 int err; 5677 5678 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 5679 if (spec == NULL) 5680 return -ENOMEM; 5681 5682 codec->spec = spec; 5683 5684 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST, 5685 alc880_models, 5686 alc880_cfg_tbl); 5687 if (board_config < 0) { 5688 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 5689 codec->chip_name); 5690 board_config = ALC880_AUTO; 5691 } 5692 5693 if (board_config == ALC880_AUTO) { 5694 /* automatic parse from the BIOS config */ 5695 err = alc880_parse_auto_config(codec); 5696 if (err < 0) { 5697 alc_free(codec); 5698 return err; 5699 } else if (!err) { 5700 printk(KERN_INFO 5701 "hda_codec: Cannot set up configuration " 5702 "from BIOS. Using 3-stack mode...\n"); 5703 board_config = ALC880_3ST; 5704 } 5705 } 5706 5707 err = snd_hda_attach_beep_device(codec, 0x1); 5708 if (err < 0) { 5709 alc_free(codec); 5710 return err; 5711 } 5712 5713 if (board_config != ALC880_AUTO) 5714 setup_preset(codec, &alc880_presets[board_config]); 5715 5716 spec->stream_analog_playback = &alc880_pcm_analog_playback; 5717 spec->stream_analog_capture = &alc880_pcm_analog_capture; 5718 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture; 5719 5720 spec->stream_digital_playback = &alc880_pcm_digital_playback; 5721 spec->stream_digital_capture = &alc880_pcm_digital_capture; 5722 5723 if (!spec->adc_nids && spec->input_mux) { 5724 /* check whether NID 0x07 is valid */ 5725 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]); 5726 /* get type */ 5727 wcap = get_wcaps_type(wcap); 5728 if (wcap != AC_WID_AUD_IN) { 5729 spec->adc_nids = alc880_adc_nids_alt; 5730 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt); 5731 } else { 5732 spec->adc_nids = alc880_adc_nids; 5733 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids); 5734 } 5735 } 5736 set_capture_mixer(codec); 5737 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 5738 5739 spec->vmaster_nid = 0x0c; 5740 5741 codec->patch_ops = alc_patch_ops; 5742 if (board_config == ALC880_AUTO) 5743 spec->init_hook = alc880_auto_init; 5744#ifdef CONFIG_SND_HDA_POWER_SAVE 5745 if (!spec->loopback.amplist) 5746 spec->loopback.amplist = alc880_loopbacks; 5747#endif 5748 5749 return 0; 5750} 5751 5752 5753/* 5754 * ALC260 support 5755 */ 5756 5757static hda_nid_t alc260_dac_nids[1] = { 5758 /* front */ 5759 0x02, 5760}; 5761 5762static hda_nid_t alc260_adc_nids[1] = { 5763 /* ADC0 */ 5764 0x04, 5765}; 5766 5767static hda_nid_t alc260_adc_nids_alt[1] = { 5768 /* ADC1 */ 5769 0x05, 5770}; 5771 5772/* NIDs used when simultaneous access to both ADCs makes sense. Note that 5773 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC. 5774 */ 5775static hda_nid_t alc260_dual_adc_nids[2] = { 5776 /* ADC0, ADC1 */ 5777 0x04, 0x05 5778}; 5779 5780#define ALC260_DIGOUT_NID 0x03 5781#define ALC260_DIGIN_NID 0x06 5782 5783static struct hda_input_mux alc260_capture_source = { 5784 .num_items = 4, 5785 .items = { 5786 { "Mic", 0x0 }, 5787 { "Front Mic", 0x1 }, 5788 { "Line", 0x2 }, 5789 { "CD", 0x4 }, 5790 }, 5791}; 5792 5793/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack, 5794 * headphone jack and the internal CD lines since these are the only pins at 5795 * which audio can appear. For flexibility, also allow the option of 5796 * recording the mixer output on the second ADC (ADC0 doesn't have a 5797 * connection to the mixer output). 5798 */ 5799static struct hda_input_mux alc260_fujitsu_capture_sources[2] = { 5800 { 5801 .num_items = 3, 5802 .items = { 5803 { "Mic/Line", 0x0 }, 5804 { "CD", 0x4 }, 5805 { "Headphone", 0x2 }, 5806 }, 5807 }, 5808 { 5809 .num_items = 4, 5810 .items = { 5811 { "Mic/Line", 0x0 }, 5812 { "CD", 0x4 }, 5813 { "Headphone", 0x2 }, 5814 { "Mixer", 0x5 }, 5815 }, 5816 }, 5817 5818}; 5819 5820/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to 5821 * the Fujitsu S702x, but jacks are marked differently. 5822 */ 5823static struct hda_input_mux alc260_acer_capture_sources[2] = { 5824 { 5825 .num_items = 4, 5826 .items = { 5827 { "Mic", 0x0 }, 5828 { "Line", 0x2 }, 5829 { "CD", 0x4 }, 5830 { "Headphone", 0x5 }, 5831 }, 5832 }, 5833 { 5834 .num_items = 5, 5835 .items = { 5836 { "Mic", 0x0 }, 5837 { "Line", 0x2 }, 5838 { "CD", 0x4 }, 5839 { "Headphone", 0x6 }, 5840 { "Mixer", 0x5 }, 5841 }, 5842 }, 5843}; 5844 5845/* Maxdata Favorit 100XS */ 5846static struct hda_input_mux alc260_favorit100_capture_sources[2] = { 5847 { 5848 .num_items = 2, 5849 .items = { 5850 { "Line/Mic", 0x0 }, 5851 { "CD", 0x4 }, 5852 }, 5853 }, 5854 { 5855 .num_items = 3, 5856 .items = { 5857 { "Line/Mic", 0x0 }, 5858 { "CD", 0x4 }, 5859 { "Mixer", 0x5 }, 5860 }, 5861 }, 5862}; 5863 5864/* 5865 * This is just place-holder, so there's something for alc_build_pcms to look 5866 * at when it calculates the maximum number of channels. ALC260 has no mixer 5867 * element which allows changing the channel mode, so the verb list is 5868 * never used. 5869 */ 5870static struct hda_channel_mode alc260_modes[1] = { 5871 { 2, NULL }, 5872}; 5873 5874 5875/* Mixer combinations 5876 * 5877 * basic: base_output + input + pc_beep + capture 5878 * HP: base_output + input + capture_alt 5879 * HP_3013: hp_3013 + input + capture 5880 * fujitsu: fujitsu + capture 5881 * acer: acer + capture 5882 */ 5883 5884static struct snd_kcontrol_new alc260_base_output_mixer[] = { 5885 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT), 5886 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT), 5887 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT), 5888 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT), 5889 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), 5890 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT), 5891 { } /* end */ 5892}; 5893 5894static struct snd_kcontrol_new alc260_input_mixer[] = { 5895 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), 5896 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), 5897 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), 5898 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT), 5899 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), 5900 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT), 5901 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT), 5902 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT), 5903 { } /* end */ 5904}; 5905 5906/* update HP, line and mono out pins according to the master switch */ 5907static void alc260_hp_master_update(struct hda_codec *codec, 5908 hda_nid_t hp, hda_nid_t line, 5909 hda_nid_t mono) 5910{ 5911 struct alc_spec *spec = codec->spec; 5912 unsigned int val = spec->master_sw ? PIN_HP : 0; 5913 /* change HP and line-out pins */ 5914 snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 5915 val); 5916 snd_hda_codec_write(codec, line, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 5917 val); 5918 /* mono (speaker) depending on the HP jack sense */ 5919 val = (val && !spec->jack_present) ? PIN_OUT : 0; 5920 snd_hda_codec_write(codec, mono, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 5921 val); 5922} 5923 5924static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol, 5925 struct snd_ctl_elem_value *ucontrol) 5926{ 5927 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 5928 struct alc_spec *spec = codec->spec; 5929 *ucontrol->value.integer.value = spec->master_sw; 5930 return 0; 5931} 5932 5933static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol, 5934 struct snd_ctl_elem_value *ucontrol) 5935{ 5936 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 5937 struct alc_spec *spec = codec->spec; 5938 int val = !!*ucontrol->value.integer.value; 5939 hda_nid_t hp, line, mono; 5940 5941 if (val == spec->master_sw) 5942 return 0; 5943 spec->master_sw = val; 5944 hp = (kcontrol->private_value >> 16) & 0xff; 5945 line = (kcontrol->private_value >> 8) & 0xff; 5946 mono = kcontrol->private_value & 0xff; 5947 alc260_hp_master_update(codec, hp, line, mono); 5948 return 1; 5949} 5950 5951static struct snd_kcontrol_new alc260_hp_output_mixer[] = { 5952 { 5953 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 5954 .name = "Master Playback Switch", 5955 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11, 5956 .info = snd_ctl_boolean_mono_info, 5957 .get = alc260_hp_master_sw_get, 5958 .put = alc260_hp_master_sw_put, 5959 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11 5960 }, 5961 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT), 5962 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT), 5963 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT), 5964 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT), 5965 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, 5966 HDA_OUTPUT), 5967 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT), 5968 { } /* end */ 5969}; 5970 5971static struct hda_verb alc260_hp_unsol_verbs[] = { 5972 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 5973 {}, 5974}; 5975 5976static void alc260_hp_automute(struct hda_codec *codec) 5977{ 5978 struct alc_spec *spec = codec->spec; 5979 5980 spec->jack_present = snd_hda_jack_detect(codec, 0x10); 5981 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11); 5982} 5983 5984static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res) 5985{ 5986 if ((res >> 26) == ALC880_HP_EVENT) 5987 alc260_hp_automute(codec); 5988} 5989 5990static struct snd_kcontrol_new alc260_hp_3013_mixer[] = { 5991 { 5992 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 5993 .name = "Master Playback Switch", 5994 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11, 5995 .info = snd_ctl_boolean_mono_info, 5996 .get = alc260_hp_master_sw_get, 5997 .put = alc260_hp_master_sw_put, 5998 .private_value = (0x15 << 16) | (0x10 << 8) | 0x11 5999 }, 6000 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT), 6001 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT), 6002 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT), 6003 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT), 6004 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT), 6005 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 6006 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), 6007 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT), 6008 { } /* end */ 6009}; 6010 6011static struct hda_bind_ctls alc260_dc7600_bind_master_vol = { 6012 .ops = &snd_hda_bind_vol, 6013 .values = { 6014 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT), 6015 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT), 6016 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT), 6017 0 6018 }, 6019}; 6020 6021static struct hda_bind_ctls alc260_dc7600_bind_switch = { 6022 .ops = &snd_hda_bind_sw, 6023 .values = { 6024 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT), 6025 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT), 6026 0 6027 }, 6028}; 6029 6030static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = { 6031 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol), 6032 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch), 6033 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT), 6034 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT), 6035 { } /* end */ 6036}; 6037 6038static struct hda_verb alc260_hp_3013_unsol_verbs[] = { 6039 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 6040 {}, 6041}; 6042 6043static void alc260_hp_3013_automute(struct hda_codec *codec) 6044{ 6045 struct alc_spec *spec = codec->spec; 6046 6047 spec->jack_present = snd_hda_jack_detect(codec, 0x15); 6048 alc260_hp_master_update(codec, 0x15, 0x10, 0x11); 6049} 6050 6051static void alc260_hp_3013_unsol_event(struct hda_codec *codec, 6052 unsigned int res) 6053{ 6054 if ((res >> 26) == ALC880_HP_EVENT) 6055 alc260_hp_3013_automute(codec); 6056} 6057 6058static void alc260_hp_3012_automute(struct hda_codec *codec) 6059{ 6060 unsigned int bits = snd_hda_jack_detect(codec, 0x10) ? 0 : PIN_OUT; 6061 6062 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 6063 bits); 6064 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 6065 bits); 6066 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 6067 bits); 6068} 6069 6070static void alc260_hp_3012_unsol_event(struct hda_codec *codec, 6071 unsigned int res) 6072{ 6073 if ((res >> 26) == ALC880_HP_EVENT) 6074 alc260_hp_3012_automute(codec); 6075} 6076 6077/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12, 6078 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10. 6079 */ 6080static struct snd_kcontrol_new alc260_fujitsu_mixer[] = { 6081 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT), 6082 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT), 6083 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT), 6084 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), 6085 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), 6086 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT), 6087 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT), 6088 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN), 6089 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT), 6090 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT), 6091 { } /* end */ 6092}; 6093 6094/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current 6095 * versions of the ALC260 don't act on requests to enable mic bias from NID 6096 * 0x0f (used to drive the headphone jack in these laptops). The ALC260 6097 * datasheet doesn't mention this restriction. At this stage it's not clear 6098 * whether this behaviour is intentional or is a hardware bug in chip 6099 * revisions available in early 2006. Therefore for now allow the 6100 * "Headphone Jack Mode" control to span all choices, but if it turns out 6101 * that the lack of mic bias for this NID is intentional we could change the 6102 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS. 6103 * 6104 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006 6105 * don't appear to make the mic bias available from the "line" jack, even 6106 * though the NID used for this jack (0x14) can supply it. The theory is 6107 * that perhaps Acer have included blocking capacitors between the ALC260 6108 * and the output jack. If this turns out to be the case for all such 6109 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT 6110 * to ALC_PIN_DIR_INOUT_NOMICBIAS. 6111 * 6112 * The C20x Tablet series have a mono internal speaker which is controlled 6113 * via the chip's Mono sum widget and pin complex, so include the necessary 6114 * controls for such models. On models without a "mono speaker" the control 6115 * won't do anything. 6116 */ 6117static struct snd_kcontrol_new alc260_acer_mixer[] = { 6118 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), 6119 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT), 6120 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT), 6121 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, 6122 HDA_OUTPUT), 6123 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, 6124 HDA_INPUT), 6125 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), 6126 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), 6127 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), 6128 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT), 6129 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN), 6130 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), 6131 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT), 6132 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT), 6133 { } /* end */ 6134}; 6135 6136/* Maxdata Favorit 100XS: one output and one input (0x12) jack 6137 */ 6138static struct snd_kcontrol_new alc260_favorit100_mixer[] = { 6139 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), 6140 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT), 6141 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT), 6142 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT), 6143 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT), 6144 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN), 6145 { } /* end */ 6146}; 6147 6148/* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12, 6149 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17. 6150 */ 6151static struct snd_kcontrol_new alc260_will_mixer[] = { 6152 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), 6153 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT), 6154 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), 6155 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT), 6156 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN), 6157 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), 6158 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT), 6159 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT), 6160 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), 6161 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), 6162 { } /* end */ 6163}; 6164 6165/* Replacer 672V ALC260 pin usage: Mic jack = 0x12, 6166 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f. 6167 */ 6168static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = { 6169 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), 6170 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT), 6171 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), 6172 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT), 6173 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN), 6174 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT), 6175 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT), 6176 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), 6177 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT), 6178 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT), 6179 { } /* end */ 6180}; 6181 6182/* 6183 * initialization verbs 6184 */ 6185static struct hda_verb alc260_init_verbs[] = { 6186 /* Line In pin widget for input */ 6187 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 6188 /* CD pin widget for input */ 6189 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 6190 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 6191 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 6192 /* Mic2 (front panel) pin widget for input and vref at 80% */ 6193 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 6194 /* LINE-2 is used for line-out in rear */ 6195 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6196 /* select line-out */ 6197 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00}, 6198 /* LINE-OUT pin */ 6199 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6200 /* enable HP */ 6201 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6202 /* enable Mono */ 6203 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6204 /* mute capture amp left and right */ 6205 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6206 /* set connection select to line in (default select for this ADC) */ 6207 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02}, 6208 /* mute capture amp left and right */ 6209 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6210 /* set connection select to line in (default select for this ADC) */ 6211 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02}, 6212 /* set vol=0 Line-Out mixer amp left and right */ 6213 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6214 /* unmute pin widget amp left and right (no gain on this amp) */ 6215 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6216 /* set vol=0 HP mixer amp left and right */ 6217 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6218 /* unmute pin widget amp left and right (no gain on this amp) */ 6219 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6220 /* set vol=0 Mono mixer amp left and right */ 6221 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6222 /* unmute pin widget amp left and right (no gain on this amp) */ 6223 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6224 /* unmute LINE-2 out pin */ 6225 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6226 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & 6227 * Line In 2 = 0x03 6228 */ 6229 /* mute analog inputs */ 6230 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6231 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6232 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 6233 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 6234 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 6235 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */ 6236 /* mute Front out path */ 6237 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6238 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6239 /* mute Headphone out path */ 6240 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6241 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6242 /* mute Mono out path */ 6243 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6244 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6245 { } 6246}; 6247 6248#if 0 /* should be identical with alc260_init_verbs? */ 6249static struct hda_verb alc260_hp_init_verbs[] = { 6250 /* Headphone and output */ 6251 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 6252 /* mono output */ 6253 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 6254 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 6255 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 6256 /* Mic2 (front panel) pin widget for input and vref at 80% */ 6257 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 6258 /* Line In pin widget for input */ 6259 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 6260 /* Line-2 pin widget for output */ 6261 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 6262 /* CD pin widget for input */ 6263 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 6264 /* unmute amp left and right */ 6265 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000}, 6266 /* set connection select to line in (default select for this ADC) */ 6267 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02}, 6268 /* unmute Line-Out mixer amp left and right (volume = 0) */ 6269 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 6270 /* mute pin widget amp left and right (no gain on this amp) */ 6271 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 6272 /* unmute HP mixer amp left and right (volume = 0) */ 6273 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 6274 /* mute pin widget amp left and right (no gain on this amp) */ 6275 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 6276 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & 6277 * Line In 2 = 0x03 6278 */ 6279 /* mute analog inputs */ 6280 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6281 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6282 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 6283 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 6284 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 6285 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */ 6286 /* Unmute Front out path */ 6287 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 6288 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 6289 /* Unmute Headphone out path */ 6290 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 6291 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 6292 /* Unmute Mono out path */ 6293 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 6294 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 6295 { } 6296}; 6297#endif 6298 6299static struct hda_verb alc260_hp_3013_init_verbs[] = { 6300 /* Line out and output */ 6301 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 6302 /* mono output */ 6303 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 6304 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 6305 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 6306 /* Mic2 (front panel) pin widget for input and vref at 80% */ 6307 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 6308 /* Line In pin widget for input */ 6309 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 6310 /* Headphone pin widget for output */ 6311 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 6312 /* CD pin widget for input */ 6313 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 6314 /* unmute amp left and right */ 6315 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000}, 6316 /* set connection select to line in (default select for this ADC) */ 6317 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02}, 6318 /* unmute Line-Out mixer amp left and right (volume = 0) */ 6319 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 6320 /* mute pin widget amp left and right (no gain on this amp) */ 6321 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 6322 /* unmute HP mixer amp left and right (volume = 0) */ 6323 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 6324 /* mute pin widget amp left and right (no gain on this amp) */ 6325 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 6326 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & 6327 * Line In 2 = 0x03 6328 */ 6329 /* mute analog inputs */ 6330 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6331 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6332 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 6333 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 6334 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 6335 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */ 6336 /* Unmute Front out path */ 6337 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 6338 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 6339 /* Unmute Headphone out path */ 6340 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 6341 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 6342 /* Unmute Mono out path */ 6343 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 6344 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 6345 { } 6346}; 6347 6348/* Initialisation sequence for ALC260 as configured in Fujitsu S702x 6349 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD 6350 * audio = 0x16, internal speaker = 0x10. 6351 */ 6352static struct hda_verb alc260_fujitsu_init_verbs[] = { 6353 /* Disable all GPIOs */ 6354 {0x01, AC_VERB_SET_GPIO_MASK, 0}, 6355 /* Internal speaker is connected to headphone pin */ 6356 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6357 /* Headphone/Line-out jack connects to Line1 pin; make it an output */ 6358 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6359 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */ 6360 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 6361 /* Ensure all other unused pins are disabled and muted. */ 6362 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6363 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6364 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6365 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6366 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6367 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6368 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6369 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6370 6371 /* Disable digital (SPDIF) pins */ 6372 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0}, 6373 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0}, 6374 6375 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus 6376 * when acting as an output. 6377 */ 6378 {0x0d, AC_VERB_SET_CONNECT_SEL, 0}, 6379 6380 /* Start with output sum widgets muted and their output gains at min */ 6381 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6382 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6383 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6384 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6385 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6386 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6387 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6388 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6389 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6390 6391 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */ 6392 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6393 /* Unmute Line1 pin widget output buffer since it starts as an output. 6394 * If the pin mode is changed by the user the pin mode control will 6395 * take care of enabling the pin's input/output buffers as needed. 6396 * Therefore there's no need to enable the input buffer at this 6397 * stage. 6398 */ 6399 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6400 /* Unmute input buffer of pin widget used for Line-in (no equiv 6401 * mixer ctrl) 6402 */ 6403 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6404 6405 /* Mute capture amp left and right */ 6406 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6407 /* Set ADC connection select to match default mixer setting - line 6408 * in (on mic1 pin) 6409 */ 6410 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, 6411 6412 /* Do the same for the second ADC: mute capture input amp and 6413 * set ADC connection to line in (on mic1 pin) 6414 */ 6415 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6416 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, 6417 6418 /* Mute all inputs to mixer widget (even unconnected ones) */ 6419 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */ 6420 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */ 6421 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */ 6422 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */ 6423 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */ 6424 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */ 6425 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */ 6426 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */ 6427 6428 { } 6429}; 6430 6431/* Initialisation sequence for ALC260 as configured in Acer TravelMate and 6432 * similar laptops (adapted from Fujitsu init verbs). 6433 */ 6434static struct hda_verb alc260_acer_init_verbs[] = { 6435 /* On TravelMate laptops, GPIO 0 enables the internal speaker and 6436 * the headphone jack. Turn this on and rely on the standard mute 6437 * methods whenever the user wants to turn these outputs off. 6438 */ 6439 {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, 6440 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, 6441 {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, 6442 /* Internal speaker/Headphone jack is connected to Line-out pin */ 6443 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6444 /* Internal microphone/Mic jack is connected to Mic1 pin */ 6445 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, 6446 /* Line In jack is connected to Line1 pin */ 6447 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 6448 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */ 6449 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6450 /* Ensure all other unused pins are disabled and muted. */ 6451 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6452 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6453 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6454 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6455 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6456 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6457 /* Disable digital (SPDIF) pins */ 6458 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0}, 6459 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0}, 6460 6461 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum 6462 * bus when acting as outputs. 6463 */ 6464 {0x0b, AC_VERB_SET_CONNECT_SEL, 0}, 6465 {0x0d, AC_VERB_SET_CONNECT_SEL, 0}, 6466 6467 /* Start with output sum widgets muted and their output gains at min */ 6468 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6469 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6470 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6471 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6472 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6473 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6474 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6475 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6476 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6477 6478 /* Unmute Line-out pin widget amp left and right 6479 * (no equiv mixer ctrl) 6480 */ 6481 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6482 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */ 6483 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6484 /* Unmute Mic1 and Line1 pin widget input buffers since they start as 6485 * inputs. If the pin mode is changed by the user the pin mode control 6486 * will take care of enabling the pin's input/output buffers as needed. 6487 * Therefore there's no need to enable the input buffer at this 6488 * stage. 6489 */ 6490 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6491 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6492 6493 /* Mute capture amp left and right */ 6494 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6495 /* Set ADC connection select to match default mixer setting - mic 6496 * (on mic1 pin) 6497 */ 6498 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, 6499 6500 /* Do similar with the second ADC: mute capture input amp and 6501 * set ADC connection to mic to match ALSA's default state. 6502 */ 6503 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6504 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, 6505 6506 /* Mute all inputs to mixer widget (even unconnected ones) */ 6507 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */ 6508 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */ 6509 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */ 6510 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */ 6511 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */ 6512 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */ 6513 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */ 6514 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */ 6515 6516 { } 6517}; 6518 6519/* Initialisation sequence for Maxdata Favorit 100XS 6520 * (adapted from Acer init verbs). 6521 */ 6522static struct hda_verb alc260_favorit100_init_verbs[] = { 6523 /* GPIO 0 enables the output jack. 6524 * Turn this on and rely on the standard mute 6525 * methods whenever the user wants to turn these outputs off. 6526 */ 6527 {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, 6528 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, 6529 {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, 6530 /* Line/Mic input jack is connected to Mic1 pin */ 6531 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, 6532 /* Ensure all other unused pins are disabled and muted. */ 6533 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6534 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6535 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6536 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6537 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6538 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6539 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6540 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6541 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6542 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6543 /* Disable digital (SPDIF) pins */ 6544 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0}, 6545 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0}, 6546 6547 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum 6548 * bus when acting as outputs. 6549 */ 6550 {0x0b, AC_VERB_SET_CONNECT_SEL, 0}, 6551 {0x0d, AC_VERB_SET_CONNECT_SEL, 0}, 6552 6553 /* Start with output sum widgets muted and their output gains at min */ 6554 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6555 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6556 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6557 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6558 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6559 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6560 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6561 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6562 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6563 6564 /* Unmute Line-out pin widget amp left and right 6565 * (no equiv mixer ctrl) 6566 */ 6567 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6568 /* Unmute Mic1 and Line1 pin widget input buffers since they start as 6569 * inputs. If the pin mode is changed by the user the pin mode control 6570 * will take care of enabling the pin's input/output buffers as needed. 6571 * Therefore there's no need to enable the input buffer at this 6572 * stage. 6573 */ 6574 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6575 6576 /* Mute capture amp left and right */ 6577 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6578 /* Set ADC connection select to match default mixer setting - mic 6579 * (on mic1 pin) 6580 */ 6581 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, 6582 6583 /* Do similar with the second ADC: mute capture input amp and 6584 * set ADC connection to mic to match ALSA's default state. 6585 */ 6586 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6587 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, 6588 6589 /* Mute all inputs to mixer widget (even unconnected ones) */ 6590 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */ 6591 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */ 6592 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */ 6593 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */ 6594 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */ 6595 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */ 6596 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */ 6597 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */ 6598 6599 { } 6600}; 6601 6602static struct hda_verb alc260_will_verbs[] = { 6603 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6604 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00}, 6605 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00}, 6606 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02}, 6607 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07}, 6608 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040}, 6609 {} 6610}; 6611 6612static struct hda_verb alc260_replacer_672v_verbs[] = { 6613 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02}, 6614 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07}, 6615 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050}, 6616 6617 {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, 6618 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, 6619 {0x01, AC_VERB_SET_GPIO_DATA, 0x00}, 6620 6621 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 6622 {} 6623}; 6624 6625/* toggle speaker-output according to the hp-jack state */ 6626static void alc260_replacer_672v_automute(struct hda_codec *codec) 6627{ 6628 unsigned int present; 6629 6630 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */ 6631 present = snd_hda_jack_detect(codec, 0x0f); 6632 if (present) { 6633 snd_hda_codec_write_cache(codec, 0x01, 0, 6634 AC_VERB_SET_GPIO_DATA, 1); 6635 snd_hda_codec_write_cache(codec, 0x0f, 0, 6636 AC_VERB_SET_PIN_WIDGET_CONTROL, 6637 PIN_HP); 6638 } else { 6639 snd_hda_codec_write_cache(codec, 0x01, 0, 6640 AC_VERB_SET_GPIO_DATA, 0); 6641 snd_hda_codec_write_cache(codec, 0x0f, 0, 6642 AC_VERB_SET_PIN_WIDGET_CONTROL, 6643 PIN_OUT); 6644 } 6645} 6646 6647static void alc260_replacer_672v_unsol_event(struct hda_codec *codec, 6648 unsigned int res) 6649{ 6650 if ((res >> 26) == ALC880_HP_EVENT) 6651 alc260_replacer_672v_automute(codec); 6652} 6653 6654static struct hda_verb alc260_hp_dc7600_verbs[] = { 6655 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01}, 6656 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 6657 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6658 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6659 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6660 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6661 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 6662 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 6663 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 6664 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 6665 {} 6666}; 6667 6668/* Test configuration for debugging, modelled after the ALC880 test 6669 * configuration. 6670 */ 6671#ifdef CONFIG_SND_DEBUG 6672static hda_nid_t alc260_test_dac_nids[1] = { 6673 0x02, 6674}; 6675static hda_nid_t alc260_test_adc_nids[2] = { 6676 0x04, 0x05, 6677}; 6678/* For testing the ALC260, each input MUX needs its own definition since 6679 * the signal assignments are different. This assumes that the first ADC 6680 * is NID 0x04. 6681 */ 6682static struct hda_input_mux alc260_test_capture_sources[2] = { 6683 { 6684 .num_items = 7, 6685 .items = { 6686 { "MIC1 pin", 0x0 }, 6687 { "MIC2 pin", 0x1 }, 6688 { "LINE1 pin", 0x2 }, 6689 { "LINE2 pin", 0x3 }, 6690 { "CD pin", 0x4 }, 6691 { "LINE-OUT pin", 0x5 }, 6692 { "HP-OUT pin", 0x6 }, 6693 }, 6694 }, 6695 { 6696 .num_items = 8, 6697 .items = { 6698 { "MIC1 pin", 0x0 }, 6699 { "MIC2 pin", 0x1 }, 6700 { "LINE1 pin", 0x2 }, 6701 { "LINE2 pin", 0x3 }, 6702 { "CD pin", 0x4 }, 6703 { "Mixer", 0x5 }, 6704 { "LINE-OUT pin", 0x6 }, 6705 { "HP-OUT pin", 0x7 }, 6706 }, 6707 }, 6708}; 6709static struct snd_kcontrol_new alc260_test_mixer[] = { 6710 /* Output driver widgets */ 6711 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), 6712 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT), 6713 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT), 6714 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT), 6715 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT), 6716 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT), 6717 6718 /* Modes for retasking pin widgets 6719 * Note: the ALC260 doesn't seem to act on requests to enable mic 6720 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't 6721 * mention this restriction. At this stage it's not clear whether 6722 * this behaviour is intentional or is a hardware bug in chip 6723 * revisions available at least up until early 2006. Therefore for 6724 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all 6725 * choices, but if it turns out that the lack of mic bias for these 6726 * NIDs is intentional we could change their modes from 6727 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS. 6728 */ 6729 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT), 6730 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT), 6731 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT), 6732 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT), 6733 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT), 6734 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT), 6735 6736 /* Loopback mixer controls */ 6737 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT), 6738 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT), 6739 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT), 6740 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT), 6741 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT), 6742 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT), 6743 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT), 6744 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT), 6745 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), 6746 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), 6747 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT), 6748 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT), 6749 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT), 6750 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT), 6751 6752 /* Controls for GPIO pins, assuming they are configured as outputs */ 6753 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01), 6754 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02), 6755 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04), 6756 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08), 6757 6758 /* Switches to allow the digital IO pins to be enabled. The datasheet 6759 * is ambigious as to which NID is which; testing on laptops which 6760 * make this output available should provide clarification. 6761 */ 6762 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01), 6763 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01), 6764 6765 /* A switch allowing EAPD to be enabled. Some laptops seem to use 6766 * this output to turn on an external amplifier. 6767 */ 6768 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02), 6769 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02), 6770 6771 { } /* end */ 6772}; 6773static struct hda_verb alc260_test_init_verbs[] = { 6774 /* Enable all GPIOs as outputs with an initial value of 0 */ 6775 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f}, 6776 {0x01, AC_VERB_SET_GPIO_DATA, 0x00}, 6777 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f}, 6778 6779 /* Enable retasking pins as output, initially without power amp */ 6780 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6781 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6782 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6783 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6784 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6785 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6786 6787 /* Disable digital (SPDIF) pins initially, but users can enable 6788 * them via a mixer switch. In the case of SPDIF-out, this initverb 6789 * payload also sets the generation to 0, output to be in "consumer" 6790 * PCM format, copyright asserted, no pre-emphasis and no validity 6791 * control. 6792 */ 6793 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0}, 6794 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0}, 6795 6796 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the 6797 * OUT1 sum bus when acting as an output. 6798 */ 6799 {0x0b, AC_VERB_SET_CONNECT_SEL, 0}, 6800 {0x0c, AC_VERB_SET_CONNECT_SEL, 0}, 6801 {0x0d, AC_VERB_SET_CONNECT_SEL, 0}, 6802 {0x0e, AC_VERB_SET_CONNECT_SEL, 0}, 6803 6804 /* Start with output sum widgets muted and their output gains at min */ 6805 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6806 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6807 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6808 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6809 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6810 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6811 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6812 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6813 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6814 6815 /* Unmute retasking pin widget output buffers since the default 6816 * state appears to be output. As the pin mode is changed by the 6817 * user the pin mode control will take care of enabling the pin's 6818 * input/output buffers as needed. 6819 */ 6820 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6821 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6822 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6823 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6824 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6825 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6826 /* Also unmute the mono-out pin widget */ 6827 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6828 6829 /* Mute capture amp left and right */ 6830 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6831 /* Set ADC connection select to match default mixer setting (mic1 6832 * pin) 6833 */ 6834 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, 6835 6836 /* Do the same for the second ADC: mute capture input amp and 6837 * set ADC connection to mic1 pin 6838 */ 6839 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6840 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, 6841 6842 /* Mute all inputs to mixer widget (even unconnected ones) */ 6843 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */ 6844 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */ 6845 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */ 6846 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */ 6847 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */ 6848 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */ 6849 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */ 6850 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */ 6851 6852 { } 6853}; 6854#endif 6855 6856#define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback 6857#define alc260_pcm_analog_capture alc880_pcm_analog_capture 6858 6859#define alc260_pcm_digital_playback alc880_pcm_digital_playback 6860#define alc260_pcm_digital_capture alc880_pcm_digital_capture 6861 6862/* 6863 * for BIOS auto-configuration 6864 */ 6865 6866static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid, 6867 const char *pfx, int *vol_bits) 6868{ 6869 hda_nid_t nid_vol; 6870 unsigned long vol_val, sw_val; 6871 int err; 6872 6873 if (nid >= 0x0f && nid < 0x11) { 6874 nid_vol = nid - 0x7; 6875 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT); 6876 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT); 6877 } else if (nid == 0x11) { 6878 nid_vol = nid - 0x7; 6879 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT); 6880 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT); 6881 } else if (nid >= 0x12 && nid <= 0x15) { 6882 nid_vol = 0x08; 6883 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT); 6884 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT); 6885 } else 6886 return 0; /* N/A */ 6887 6888 if (!(*vol_bits & (1 << nid_vol))) { 6889 /* first control for the volume widget */ 6890 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, vol_val); 6891 if (err < 0) 6892 return err; 6893 *vol_bits |= (1 << nid_vol); 6894 } 6895 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, sw_val); 6896 if (err < 0) 6897 return err; 6898 return 1; 6899} 6900 6901/* add playback controls from the parsed DAC table */ 6902static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec, 6903 const struct auto_pin_cfg *cfg) 6904{ 6905 hda_nid_t nid; 6906 int err; 6907 int vols = 0; 6908 6909 spec->multiout.num_dacs = 1; 6910 spec->multiout.dac_nids = spec->private_dac_nids; 6911 spec->multiout.dac_nids[0] = 0x02; 6912 6913 nid = cfg->line_out_pins[0]; 6914 if (nid) { 6915 const char *pfx; 6916 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0]) 6917 pfx = "Master"; 6918 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) 6919 pfx = "Speaker"; 6920 else 6921 pfx = "Front"; 6922 err = alc260_add_playback_controls(spec, nid, pfx, &vols); 6923 if (err < 0) 6924 return err; 6925 } 6926 6927 nid = cfg->speaker_pins[0]; 6928 if (nid) { 6929 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols); 6930 if (err < 0) 6931 return err; 6932 } 6933 6934 nid = cfg->hp_pins[0]; 6935 if (nid) { 6936 err = alc260_add_playback_controls(spec, nid, "Headphone", 6937 &vols); 6938 if (err < 0) 6939 return err; 6940 } 6941 return 0; 6942} 6943 6944/* create playback/capture controls for input pins */ 6945static int alc260_auto_create_input_ctls(struct hda_codec *codec, 6946 const struct auto_pin_cfg *cfg) 6947{ 6948 return alc_auto_create_input_ctls(codec, cfg, 0x07, 0x04, 0x05); 6949} 6950 6951static void alc260_auto_set_output_and_unmute(struct hda_codec *codec, 6952 hda_nid_t nid, int pin_type, 6953 int sel_idx) 6954{ 6955 alc_set_pin_output(codec, nid, pin_type); 6956 /* need the manual connection? */ 6957 if (nid >= 0x12) { 6958 int idx = nid - 0x12; 6959 snd_hda_codec_write(codec, idx + 0x0b, 0, 6960 AC_VERB_SET_CONNECT_SEL, sel_idx); 6961 } 6962} 6963 6964static void alc260_auto_init_multi_out(struct hda_codec *codec) 6965{ 6966 struct alc_spec *spec = codec->spec; 6967 hda_nid_t nid; 6968 6969 nid = spec->autocfg.line_out_pins[0]; 6970 if (nid) { 6971 int pin_type = get_pin_type(spec->autocfg.line_out_type); 6972 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0); 6973 } 6974 6975 nid = spec->autocfg.speaker_pins[0]; 6976 if (nid) 6977 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0); 6978 6979 nid = spec->autocfg.hp_pins[0]; 6980 if (nid) 6981 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0); 6982} 6983 6984#define ALC260_PIN_CD_NID 0x16 6985static void alc260_auto_init_analog_input(struct hda_codec *codec) 6986{ 6987 struct alc_spec *spec = codec->spec; 6988 struct auto_pin_cfg *cfg = &spec->autocfg; 6989 int i; 6990 6991 for (i = 0; i < cfg->num_inputs; i++) { 6992 hda_nid_t nid = cfg->inputs[i].pin; 6993 if (nid >= 0x12) { 6994 alc_set_input_pin(codec, nid, cfg->inputs[i].type); 6995 if (nid != ALC260_PIN_CD_NID && 6996 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)) 6997 snd_hda_codec_write(codec, nid, 0, 6998 AC_VERB_SET_AMP_GAIN_MUTE, 6999 AMP_OUT_MUTE); 7000 } 7001 } 7002} 7003 7004#define alc260_auto_init_input_src alc880_auto_init_input_src 7005 7006/* 7007 * generic initialization of ADC, input mixers and output mixers 7008 */ 7009static struct hda_verb alc260_volume_init_verbs[] = { 7010 /* 7011 * Unmute ADC0-1 and set the default input to mic-in 7012 */ 7013 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, 7014 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7015 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, 7016 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7017 7018 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 7019 * mixer widget 7020 * Note: PASD motherboards uses the Line In 2 as the input for 7021 * front panel mic (mic 2) 7022 */ 7023 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 7024 /* mute analog inputs */ 7025 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7026 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7027 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 7028 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 7029 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 7030 7031 /* 7032 * Set up output mixers (0x08 - 0x0a) 7033 */ 7034 /* set vol=0 to output mixers */ 7035 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 7036 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 7037 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 7038 /* set up input amps for analog loopback */ 7039 /* Amp Indices: DAC = 0, mixer = 1 */ 7040 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7041 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 7042 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7043 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 7044 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7045 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 7046 7047 { } 7048}; 7049 7050static int alc260_parse_auto_config(struct hda_codec *codec) 7051{ 7052 struct alc_spec *spec = codec->spec; 7053 int err; 7054 static hda_nid_t alc260_ignore[] = { 0x17, 0 }; 7055 7056 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 7057 alc260_ignore); 7058 if (err < 0) 7059 return err; 7060 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg); 7061 if (err < 0) 7062 return err; 7063 if (!spec->kctls.list) 7064 return 0; /* can't find valid BIOS pin config */ 7065 err = alc260_auto_create_input_ctls(codec, &spec->autocfg); 7066 if (err < 0) 7067 return err; 7068 7069 spec->multiout.max_channels = 2; 7070 7071 if (spec->autocfg.dig_outs) 7072 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID; 7073 if (spec->kctls.list) 7074 add_mixer(spec, spec->kctls.list); 7075 7076 add_verb(spec, alc260_volume_init_verbs); 7077 7078 spec->num_mux_defs = 1; 7079 spec->input_mux = &spec->private_imux[0]; 7080 7081 alc_ssid_check(codec, 0x10, 0x15, 0x0f, 0); 7082 7083 return 1; 7084} 7085 7086/* additional initialization for auto-configuration model */ 7087static void alc260_auto_init(struct hda_codec *codec) 7088{ 7089 struct alc_spec *spec = codec->spec; 7090 alc260_auto_init_multi_out(codec); 7091 alc260_auto_init_analog_input(codec); 7092 alc260_auto_init_input_src(codec); 7093 alc_auto_init_digital(codec); 7094 if (spec->unsol_event) 7095 alc_inithook(codec); 7096} 7097 7098#ifdef CONFIG_SND_HDA_POWER_SAVE 7099static struct hda_amp_list alc260_loopbacks[] = { 7100 { 0x07, HDA_INPUT, 0 }, 7101 { 0x07, HDA_INPUT, 1 }, 7102 { 0x07, HDA_INPUT, 2 }, 7103 { 0x07, HDA_INPUT, 3 }, 7104 { 0x07, HDA_INPUT, 4 }, 7105 { } /* end */ 7106}; 7107#endif 7108 7109/* 7110 * Pin config fixes 7111 */ 7112enum { 7113 PINFIX_HP_DC5750, 7114}; 7115 7116static const struct alc_fixup alc260_fixups[] = { 7117 [PINFIX_HP_DC5750] = { 7118 .type = ALC_FIXUP_PINS, 7119 .v.pins = (const struct alc_pincfg[]) { 7120 { 0x11, 0x90130110 }, /* speaker */ 7121 { } 7122 } 7123 }, 7124}; 7125 7126static struct snd_pci_quirk alc260_fixup_tbl[] = { 7127 SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", PINFIX_HP_DC5750), 7128 {} 7129}; 7130 7131/* 7132 * ALC260 configurations 7133 */ 7134static const char * const alc260_models[ALC260_MODEL_LAST] = { 7135 [ALC260_BASIC] = "basic", 7136 [ALC260_HP] = "hp", 7137 [ALC260_HP_3013] = "hp-3013", 7138 [ALC260_HP_DC7600] = "hp-dc7600", 7139 [ALC260_FUJITSU_S702X] = "fujitsu", 7140 [ALC260_ACER] = "acer", 7141 [ALC260_WILL] = "will", 7142 [ALC260_REPLACER_672V] = "replacer", 7143 [ALC260_FAVORIT100] = "favorit100", 7144#ifdef CONFIG_SND_DEBUG 7145 [ALC260_TEST] = "test", 7146#endif 7147 [ALC260_AUTO] = "auto", 7148}; 7149 7150static struct snd_pci_quirk alc260_cfg_tbl[] = { 7151 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER), 7152 SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL), 7153 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER), 7154 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100), 7155 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013), 7156 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_AUTO), /* no quirk */ 7157 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013), 7158 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013), 7159 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600), 7160 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013), 7161 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP), 7162 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP), 7163 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP), 7164 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC), 7165 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC), 7166 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC), 7167 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X), 7168 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC), 7169 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V), 7170 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL), 7171 {} 7172}; 7173 7174static struct alc_config_preset alc260_presets[] = { 7175 [ALC260_BASIC] = { 7176 .mixers = { alc260_base_output_mixer, 7177 alc260_input_mixer }, 7178 .init_verbs = { alc260_init_verbs }, 7179 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 7180 .dac_nids = alc260_dac_nids, 7181 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids), 7182 .adc_nids = alc260_dual_adc_nids, 7183 .num_channel_mode = ARRAY_SIZE(alc260_modes), 7184 .channel_mode = alc260_modes, 7185 .input_mux = &alc260_capture_source, 7186 }, 7187 [ALC260_HP] = { 7188 .mixers = { alc260_hp_output_mixer, 7189 alc260_input_mixer }, 7190 .init_verbs = { alc260_init_verbs, 7191 alc260_hp_unsol_verbs }, 7192 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 7193 .dac_nids = alc260_dac_nids, 7194 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt), 7195 .adc_nids = alc260_adc_nids_alt, 7196 .num_channel_mode = ARRAY_SIZE(alc260_modes), 7197 .channel_mode = alc260_modes, 7198 .input_mux = &alc260_capture_source, 7199 .unsol_event = alc260_hp_unsol_event, 7200 .init_hook = alc260_hp_automute, 7201 }, 7202 [ALC260_HP_DC7600] = { 7203 .mixers = { alc260_hp_dc7600_mixer, 7204 alc260_input_mixer }, 7205 .init_verbs = { alc260_init_verbs, 7206 alc260_hp_dc7600_verbs }, 7207 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 7208 .dac_nids = alc260_dac_nids, 7209 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt), 7210 .adc_nids = alc260_adc_nids_alt, 7211 .num_channel_mode = ARRAY_SIZE(alc260_modes), 7212 .channel_mode = alc260_modes, 7213 .input_mux = &alc260_capture_source, 7214 .unsol_event = alc260_hp_3012_unsol_event, 7215 .init_hook = alc260_hp_3012_automute, 7216 }, 7217 [ALC260_HP_3013] = { 7218 .mixers = { alc260_hp_3013_mixer, 7219 alc260_input_mixer }, 7220 .init_verbs = { alc260_hp_3013_init_verbs, 7221 alc260_hp_3013_unsol_verbs }, 7222 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 7223 .dac_nids = alc260_dac_nids, 7224 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt), 7225 .adc_nids = alc260_adc_nids_alt, 7226 .num_channel_mode = ARRAY_SIZE(alc260_modes), 7227 .channel_mode = alc260_modes, 7228 .input_mux = &alc260_capture_source, 7229 .unsol_event = alc260_hp_3013_unsol_event, 7230 .init_hook = alc260_hp_3013_automute, 7231 }, 7232 [ALC260_FUJITSU_S702X] = { 7233 .mixers = { alc260_fujitsu_mixer }, 7234 .init_verbs = { alc260_fujitsu_init_verbs }, 7235 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 7236 .dac_nids = alc260_dac_nids, 7237 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids), 7238 .adc_nids = alc260_dual_adc_nids, 7239 .num_channel_mode = ARRAY_SIZE(alc260_modes), 7240 .channel_mode = alc260_modes, 7241 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources), 7242 .input_mux = alc260_fujitsu_capture_sources, 7243 }, 7244 [ALC260_ACER] = { 7245 .mixers = { alc260_acer_mixer }, 7246 .init_verbs = { alc260_acer_init_verbs }, 7247 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 7248 .dac_nids = alc260_dac_nids, 7249 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids), 7250 .adc_nids = alc260_dual_adc_nids, 7251 .num_channel_mode = ARRAY_SIZE(alc260_modes), 7252 .channel_mode = alc260_modes, 7253 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources), 7254 .input_mux = alc260_acer_capture_sources, 7255 }, 7256 [ALC260_FAVORIT100] = { 7257 .mixers = { alc260_favorit100_mixer }, 7258 .init_verbs = { alc260_favorit100_init_verbs }, 7259 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 7260 .dac_nids = alc260_dac_nids, 7261 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids), 7262 .adc_nids = alc260_dual_adc_nids, 7263 .num_channel_mode = ARRAY_SIZE(alc260_modes), 7264 .channel_mode = alc260_modes, 7265 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources), 7266 .input_mux = alc260_favorit100_capture_sources, 7267 }, 7268 [ALC260_WILL] = { 7269 .mixers = { alc260_will_mixer }, 7270 .init_verbs = { alc260_init_verbs, alc260_will_verbs }, 7271 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 7272 .dac_nids = alc260_dac_nids, 7273 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids), 7274 .adc_nids = alc260_adc_nids, 7275 .dig_out_nid = ALC260_DIGOUT_NID, 7276 .num_channel_mode = ARRAY_SIZE(alc260_modes), 7277 .channel_mode = alc260_modes, 7278 .input_mux = &alc260_capture_source, 7279 }, 7280 [ALC260_REPLACER_672V] = { 7281 .mixers = { alc260_replacer_672v_mixer }, 7282 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs }, 7283 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 7284 .dac_nids = alc260_dac_nids, 7285 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids), 7286 .adc_nids = alc260_adc_nids, 7287 .dig_out_nid = ALC260_DIGOUT_NID, 7288 .num_channel_mode = ARRAY_SIZE(alc260_modes), 7289 .channel_mode = alc260_modes, 7290 .input_mux = &alc260_capture_source, 7291 .unsol_event = alc260_replacer_672v_unsol_event, 7292 .init_hook = alc260_replacer_672v_automute, 7293 }, 7294#ifdef CONFIG_SND_DEBUG 7295 [ALC260_TEST] = { 7296 .mixers = { alc260_test_mixer }, 7297 .init_verbs = { alc260_test_init_verbs }, 7298 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids), 7299 .dac_nids = alc260_test_dac_nids, 7300 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids), 7301 .adc_nids = alc260_test_adc_nids, 7302 .num_channel_mode = ARRAY_SIZE(alc260_modes), 7303 .channel_mode = alc260_modes, 7304 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources), 7305 .input_mux = alc260_test_capture_sources, 7306 }, 7307#endif 7308}; 7309 7310static int patch_alc260(struct hda_codec *codec) 7311{ 7312 struct alc_spec *spec; 7313 int err, board_config; 7314 7315 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 7316 if (spec == NULL) 7317 return -ENOMEM; 7318 7319 codec->spec = spec; 7320 7321 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST, 7322 alc260_models, 7323 alc260_cfg_tbl); 7324 if (board_config < 0) { 7325 snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 7326 codec->chip_name); 7327 board_config = ALC260_AUTO; 7328 } 7329 7330 if (board_config == ALC260_AUTO) { 7331 alc_pick_fixup(codec, NULL, alc260_fixup_tbl, alc260_fixups); 7332 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); 7333 } 7334 7335 if (board_config == ALC260_AUTO) { 7336 /* automatic parse from the BIOS config */ 7337 err = alc260_parse_auto_config(codec); 7338 if (err < 0) { 7339 alc_free(codec); 7340 return err; 7341 } else if (!err) { 7342 printk(KERN_INFO 7343 "hda_codec: Cannot set up configuration " 7344 "from BIOS. Using base mode...\n"); 7345 board_config = ALC260_BASIC; 7346 } 7347 } 7348 7349 err = snd_hda_attach_beep_device(codec, 0x1); 7350 if (err < 0) { 7351 alc_free(codec); 7352 return err; 7353 } 7354 7355 if (board_config != ALC260_AUTO) 7356 setup_preset(codec, &alc260_presets[board_config]); 7357 7358 spec->stream_analog_playback = &alc260_pcm_analog_playback; 7359 spec->stream_analog_capture = &alc260_pcm_analog_capture; 7360 spec->stream_analog_alt_capture = &alc260_pcm_analog_capture; 7361 7362 spec->stream_digital_playback = &alc260_pcm_digital_playback; 7363 spec->stream_digital_capture = &alc260_pcm_digital_capture; 7364 7365 if (!spec->adc_nids && spec->input_mux) { 7366 /* check whether NID 0x04 is valid */ 7367 unsigned int wcap = get_wcaps(codec, 0x04); 7368 wcap = get_wcaps_type(wcap); 7369 /* get type */ 7370 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) { 7371 spec->adc_nids = alc260_adc_nids_alt; 7372 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt); 7373 } else { 7374 spec->adc_nids = alc260_adc_nids; 7375 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids); 7376 } 7377 } 7378 set_capture_mixer(codec); 7379 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT); 7380 7381 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); 7382 7383 spec->vmaster_nid = 0x08; 7384 7385 codec->patch_ops = alc_patch_ops; 7386 if (board_config == ALC260_AUTO) 7387 spec->init_hook = alc260_auto_init; 7388 spec->shutup = alc_eapd_shutup; 7389#ifdef CONFIG_SND_HDA_POWER_SAVE 7390 if (!spec->loopback.amplist) 7391 spec->loopback.amplist = alc260_loopbacks; 7392#endif 7393 7394 return 0; 7395} 7396 7397 7398/* 7399 * ALC882/883/885/888/889 support 7400 * 7401 * ALC882 is almost identical with ALC880 but has cleaner and more flexible 7402 * configuration. Each pin widget can choose any input DACs and a mixer. 7403 * Each ADC is connected from a mixer of all inputs. This makes possible 7404 * 6-channel independent captures. 7405 * 7406 * In addition, an independent DAC for the multi-playback (not used in this 7407 * driver yet). 7408 */ 7409#define ALC882_DIGOUT_NID 0x06 7410#define ALC882_DIGIN_NID 0x0a 7411#define ALC883_DIGOUT_NID ALC882_DIGOUT_NID 7412#define ALC883_DIGIN_NID ALC882_DIGIN_NID 7413#define ALC1200_DIGOUT_NID 0x10 7414 7415 7416static struct hda_channel_mode alc882_ch_modes[1] = { 7417 { 8, NULL } 7418}; 7419 7420/* DACs */ 7421static hda_nid_t alc882_dac_nids[4] = { 7422 /* front, rear, clfe, rear_surr */ 7423 0x02, 0x03, 0x04, 0x05 7424}; 7425#define alc883_dac_nids alc882_dac_nids 7426 7427/* ADCs */ 7428#define alc882_adc_nids alc880_adc_nids 7429#define alc882_adc_nids_alt alc880_adc_nids_alt 7430#define alc883_adc_nids alc882_adc_nids_alt 7431static hda_nid_t alc883_adc_nids_alt[1] = { 0x08 }; 7432static hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 }; 7433#define alc889_adc_nids alc880_adc_nids 7434 7435static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 }; 7436static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 }; 7437#define alc883_capsrc_nids alc882_capsrc_nids_alt 7438static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 }; 7439#define alc889_capsrc_nids alc882_capsrc_nids 7440 7441/* input MUX */ 7442/* FIXME: should be a matrix-type input source selection */ 7443 7444static struct hda_input_mux alc882_capture_source = { 7445 .num_items = 4, 7446 .items = { 7447 { "Mic", 0x0 }, 7448 { "Front Mic", 0x1 }, 7449 { "Line", 0x2 }, 7450 { "CD", 0x4 }, 7451 }, 7452}; 7453 7454#define alc883_capture_source alc882_capture_source 7455 7456static struct hda_input_mux alc889_capture_source = { 7457 .num_items = 3, 7458 .items = { 7459 { "Front Mic", 0x0 }, 7460 { "Mic", 0x3 }, 7461 { "Line", 0x2 }, 7462 }, 7463}; 7464 7465static struct hda_input_mux mb5_capture_source = { 7466 .num_items = 3, 7467 .items = { 7468 { "Mic", 0x1 }, 7469 { "Line", 0x7 }, 7470 { "CD", 0x4 }, 7471 }, 7472}; 7473 7474static struct hda_input_mux macmini3_capture_source = { 7475 .num_items = 2, 7476 .items = { 7477 { "Line", 0x2 }, 7478 { "CD", 0x4 }, 7479 }, 7480}; 7481 7482static struct hda_input_mux alc883_3stack_6ch_intel = { 7483 .num_items = 4, 7484 .items = { 7485 { "Mic", 0x1 }, 7486 { "Front Mic", 0x0 }, 7487 { "Line", 0x2 }, 7488 { "CD", 0x4 }, 7489 }, 7490}; 7491 7492static struct hda_input_mux alc883_lenovo_101e_capture_source = { 7493 .num_items = 2, 7494 .items = { 7495 { "Mic", 0x1 }, 7496 { "Line", 0x2 }, 7497 }, 7498}; 7499 7500static struct hda_input_mux alc883_lenovo_nb0763_capture_source = { 7501 .num_items = 4, 7502 .items = { 7503 { "Mic", 0x0 }, 7504 { "Internal Mic", 0x1 }, 7505 { "Line", 0x2 }, 7506 { "CD", 0x4 }, 7507 }, 7508}; 7509 7510static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = { 7511 .num_items = 2, 7512 .items = { 7513 { "Mic", 0x0 }, 7514 { "Internal Mic", 0x1 }, 7515 }, 7516}; 7517 7518static struct hda_input_mux alc883_lenovo_sky_capture_source = { 7519 .num_items = 3, 7520 .items = { 7521 { "Mic", 0x0 }, 7522 { "Front Mic", 0x1 }, 7523 { "Line", 0x4 }, 7524 }, 7525}; 7526 7527static struct hda_input_mux alc883_asus_eee1601_capture_source = { 7528 .num_items = 2, 7529 .items = { 7530 { "Mic", 0x0 }, 7531 { "Line", 0x2 }, 7532 }, 7533}; 7534 7535static struct hda_input_mux alc889A_mb31_capture_source = { 7536 .num_items = 2, 7537 .items = { 7538 { "Mic", 0x0 }, 7539 /* Front Mic (0x01) unused */ 7540 { "Line", 0x2 }, 7541 /* Line 2 (0x03) unused */ 7542 /* CD (0x04) unused? */ 7543 }, 7544}; 7545 7546static struct hda_input_mux alc889A_imac91_capture_source = { 7547 .num_items = 2, 7548 .items = { 7549 { "Mic", 0x01 }, 7550 { "Line", 0x2 }, /* Not sure! */ 7551 }, 7552}; 7553 7554/* 7555 * 2ch mode 7556 */ 7557static struct hda_channel_mode alc883_3ST_2ch_modes[1] = { 7558 { 2, NULL } 7559}; 7560 7561/* 7562 * 2ch mode 7563 */ 7564static struct hda_verb alc882_3ST_ch2_init[] = { 7565 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 7566 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7567 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 7568 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7569 { } /* end */ 7570}; 7571 7572/* 7573 * 4ch mode 7574 */ 7575static struct hda_verb alc882_3ST_ch4_init[] = { 7576 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 7577 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7578 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7579 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7580 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7581 { } /* end */ 7582}; 7583 7584/* 7585 * 6ch mode 7586 */ 7587static struct hda_verb alc882_3ST_ch6_init[] = { 7588 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7589 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7590 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, 7591 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7592 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7593 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7594 { } /* end */ 7595}; 7596 7597static struct hda_channel_mode alc882_3ST_6ch_modes[3] = { 7598 { 2, alc882_3ST_ch2_init }, 7599 { 4, alc882_3ST_ch4_init }, 7600 { 6, alc882_3ST_ch6_init }, 7601}; 7602 7603#define alc883_3ST_6ch_modes alc882_3ST_6ch_modes 7604 7605/* 7606 * 2ch mode 7607 */ 7608static struct hda_verb alc883_3ST_ch2_clevo_init[] = { 7609 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, 7610 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 7611 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7612 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 7613 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7614 { } /* end */ 7615}; 7616 7617/* 7618 * 4ch mode 7619 */ 7620static struct hda_verb alc883_3ST_ch4_clevo_init[] = { 7621 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7622 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 7623 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7624 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7625 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7626 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7627 { } /* end */ 7628}; 7629 7630/* 7631 * 6ch mode 7632 */ 7633static struct hda_verb alc883_3ST_ch6_clevo_init[] = { 7634 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7635 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7636 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7637 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, 7638 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7639 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7640 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7641 { } /* end */ 7642}; 7643 7644static struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = { 7645 { 2, alc883_3ST_ch2_clevo_init }, 7646 { 4, alc883_3ST_ch4_clevo_init }, 7647 { 6, alc883_3ST_ch6_clevo_init }, 7648}; 7649 7650 7651/* 7652 * 6ch mode 7653 */ 7654static struct hda_verb alc882_sixstack_ch6_init[] = { 7655 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 7656 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7657 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7658 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7659 { } /* end */ 7660}; 7661 7662/* 7663 * 8ch mode 7664 */ 7665static struct hda_verb alc882_sixstack_ch8_init[] = { 7666 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7667 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7668 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7669 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7670 { } /* end */ 7671}; 7672 7673static struct hda_channel_mode alc882_sixstack_modes[2] = { 7674 { 6, alc882_sixstack_ch6_init }, 7675 { 8, alc882_sixstack_ch8_init }, 7676}; 7677 7678 7679/* Macbook Air 2,1 */ 7680 7681static struct hda_channel_mode alc885_mba21_ch_modes[1] = { 7682 { 2, NULL }, 7683}; 7684 7685/* 7686 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic 7687 */ 7688 7689/* 7690 * 2ch mode 7691 */ 7692static struct hda_verb alc885_mbp_ch2_init[] = { 7693 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 7694 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7695 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7696 { } /* end */ 7697}; 7698 7699/* 7700 * 4ch mode 7701 */ 7702static struct hda_verb alc885_mbp_ch4_init[] = { 7703 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7704 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7705 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7706 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7707 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 7708 { } /* end */ 7709}; 7710 7711static struct hda_channel_mode alc885_mbp_4ch_modes[2] = { 7712 { 2, alc885_mbp_ch2_init }, 7713 { 4, alc885_mbp_ch4_init }, 7714}; 7715 7716/* 7717 * 2ch 7718 * Speakers/Woofer/HP = Front 7719 * LineIn = Input 7720 */ 7721static struct hda_verb alc885_mb5_ch2_init[] = { 7722 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 7723 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 7724 { } /* end */ 7725}; 7726 7727/* 7728 * 6ch mode 7729 * Speakers/HP = Front 7730 * Woofer = LFE 7731 * LineIn = Surround 7732 */ 7733static struct hda_verb alc885_mb5_ch6_init[] = { 7734 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 7735 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7736 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 7737 { } /* end */ 7738}; 7739 7740static struct hda_channel_mode alc885_mb5_6ch_modes[2] = { 7741 { 2, alc885_mb5_ch2_init }, 7742 { 6, alc885_mb5_ch6_init }, 7743}; 7744 7745#define alc885_macmini3_6ch_modes alc885_mb5_6ch_modes 7746 7747/* 7748 * 2ch mode 7749 */ 7750static struct hda_verb alc883_4ST_ch2_init[] = { 7751 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7752 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7753 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 7754 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7755 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 7756 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7757 { } /* end */ 7758}; 7759 7760/* 7761 * 4ch mode 7762 */ 7763static struct hda_verb alc883_4ST_ch4_init[] = { 7764 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7765 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7766 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 7767 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7768 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7769 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7770 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7771 { } /* end */ 7772}; 7773 7774/* 7775 * 6ch mode 7776 */ 7777static struct hda_verb alc883_4ST_ch6_init[] = { 7778 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7779 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7780 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7781 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7782 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, 7783 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7784 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7785 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7786 { } /* end */ 7787}; 7788 7789/* 7790 * 8ch mode 7791 */ 7792static struct hda_verb alc883_4ST_ch8_init[] = { 7793 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7794 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7795 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 }, 7796 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7797 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7798 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, 7799 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7800 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7801 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7802 { } /* end */ 7803}; 7804 7805static struct hda_channel_mode alc883_4ST_8ch_modes[4] = { 7806 { 2, alc883_4ST_ch2_init }, 7807 { 4, alc883_4ST_ch4_init }, 7808 { 6, alc883_4ST_ch6_init }, 7809 { 8, alc883_4ST_ch8_init }, 7810}; 7811 7812 7813/* 7814 * 2ch mode 7815 */ 7816static struct hda_verb alc883_3ST_ch2_intel_init[] = { 7817 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 7818 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7819 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 7820 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7821 { } /* end */ 7822}; 7823 7824/* 7825 * 4ch mode 7826 */ 7827static struct hda_verb alc883_3ST_ch4_intel_init[] = { 7828 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 7829 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7830 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7831 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7832 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7833 { } /* end */ 7834}; 7835 7836/* 7837 * 6ch mode 7838 */ 7839static struct hda_verb alc883_3ST_ch6_intel_init[] = { 7840 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7841 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7842 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 }, 7843 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7844 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7845 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7846 { } /* end */ 7847}; 7848 7849static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = { 7850 { 2, alc883_3ST_ch2_intel_init }, 7851 { 4, alc883_3ST_ch4_intel_init }, 7852 { 6, alc883_3ST_ch6_intel_init }, 7853}; 7854 7855/* 7856 * 2ch mode 7857 */ 7858static struct hda_verb alc889_ch2_intel_init[] = { 7859 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 }, 7860 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 }, 7861 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 }, 7862 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00 }, 7863 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 7864 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7865 { } /* end */ 7866}; 7867 7868/* 7869 * 6ch mode 7870 */ 7871static struct hda_verb alc889_ch6_intel_init[] = { 7872 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 }, 7873 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7874 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 }, 7875 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 }, 7876 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 7877 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7878 { } /* end */ 7879}; 7880 7881/* 7882 * 8ch mode 7883 */ 7884static struct hda_verb alc889_ch8_intel_init[] = { 7885 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 }, 7886 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7887 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 }, 7888 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 }, 7889 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x03 }, 7890 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7891 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7892 { } /* end */ 7893}; 7894 7895static struct hda_channel_mode alc889_8ch_intel_modes[3] = { 7896 { 2, alc889_ch2_intel_init }, 7897 { 6, alc889_ch6_intel_init }, 7898 { 8, alc889_ch8_intel_init }, 7899}; 7900 7901/* 7902 * 6ch mode 7903 */ 7904static struct hda_verb alc883_sixstack_ch6_init[] = { 7905 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 7906 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7907 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7908 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7909 { } /* end */ 7910}; 7911 7912/* 7913 * 8ch mode 7914 */ 7915static struct hda_verb alc883_sixstack_ch8_init[] = { 7916 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7917 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7918 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7919 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7920 { } /* end */ 7921}; 7922 7923static struct hda_channel_mode alc883_sixstack_modes[2] = { 7924 { 6, alc883_sixstack_ch6_init }, 7925 { 8, alc883_sixstack_ch8_init }, 7926}; 7927 7928 7929/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 7930 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b 7931 */ 7932static struct snd_kcontrol_new alc882_base_mixer[] = { 7933 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7934 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 7935 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 7936 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 7937 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 7938 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 7939 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 7940 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 7941 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 7942 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 7943 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 7944 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 7945 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 7946 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 7947 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 7948 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7949 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 7950 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7951 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 7952 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), 7953 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 7954 { } /* end */ 7955}; 7956 7957/* Macbook Air 2,1 same control for HP and internal Speaker */ 7958 7959static struct snd_kcontrol_new alc885_mba21_mixer[] = { 7960 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 7961 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT), 7962 { } 7963}; 7964 7965 7966static struct snd_kcontrol_new alc885_mbp3_mixer[] = { 7967 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 7968 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT), 7969 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT), 7970 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0e, 0x02, HDA_INPUT), 7971 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT), 7972 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 7973 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 7974 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT), 7975 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT), 7976 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT), 7977 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT), 7978 { } /* end */ 7979}; 7980 7981static struct snd_kcontrol_new alc885_mb5_mixer[] = { 7982 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 7983 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT), 7984 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT), 7985 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT), 7986 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT), 7987 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT), 7988 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT), 7989 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT), 7990 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT), 7991 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT), 7992 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 7993 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 7994 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT), 7995 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0x00, HDA_INPUT), 7996 { } /* end */ 7997}; 7998 7999static struct snd_kcontrol_new alc885_macmini3_mixer[] = { 8000 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 8001 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT), 8002 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT), 8003 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT), 8004 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT), 8005 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT), 8006 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT), 8007 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT), 8008 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT), 8009 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT), 8010 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT), 8011 { } /* end */ 8012}; 8013 8014static struct snd_kcontrol_new alc885_imac91_mixer[] = { 8015 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 8016 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT), 8017 { } /* end */ 8018}; 8019 8020 8021static struct snd_kcontrol_new alc882_w2jc_mixer[] = { 8022 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8023 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8024 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 8025 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 8026 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8027 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8028 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8029 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 8030 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8031 { } /* end */ 8032}; 8033 8034static struct snd_kcontrol_new alc882_targa_mixer[] = { 8035 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8036 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8037 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 8038 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 8039 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 8040 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8041 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8042 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8043 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8044 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 8045 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8046 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8047 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), 8048 { } /* end */ 8049}; 8050 8051/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ??? 8052 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c 8053 */ 8054static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = { 8055 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8056 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 8057 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 8058 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT), 8059 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 8060 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 8061 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8062 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8063 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT), 8064 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT), 8065 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8066 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8067 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 8068 { } /* end */ 8069}; 8070 8071static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = { 8072 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8073 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8074 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 8075 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 8076 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 8077 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8078 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8079 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8080 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 8081 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8082 { } /* end */ 8083}; 8084 8085static struct snd_kcontrol_new alc882_chmode_mixer[] = { 8086 { 8087 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 8088 .name = "Channel Mode", 8089 .info = alc_ch_mode_info, 8090 .get = alc_ch_mode_get, 8091 .put = alc_ch_mode_put, 8092 }, 8093 { } /* end */ 8094}; 8095 8096static struct hda_verb alc882_base_init_verbs[] = { 8097 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 8098 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8099 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8100 /* Rear mixer */ 8101 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8102 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8103 /* CLFE mixer */ 8104 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8105 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8106 /* Side mixer */ 8107 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8108 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8109 8110 /* Front Pin: output 0 (0x0c) */ 8111 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8112 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8113 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 8114 /* Rear Pin: output 1 (0x0d) */ 8115 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8116 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8117 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 8118 /* CLFE Pin: output 2 (0x0e) */ 8119 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8120 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8121 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, 8122 /* Side Pin: output 3 (0x0f) */ 8123 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8124 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8125 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, 8126 /* Mic (rear) pin: input vref at 80% */ 8127 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 8128 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8129 /* Front Mic pin: input vref at 80% */ 8130 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 8131 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8132 /* Line In pin: input */ 8133 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 8134 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8135 /* Line-2 In: Headphone output (output 0 - 0x0c) */ 8136 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8137 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8138 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 8139 /* CD pin widget for input */ 8140 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 8141 8142 /* FIXME: use matrix-type input source selection */ 8143 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 8144 /* Input mixer2 */ 8145 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8146 /* Input mixer3 */ 8147 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8148 /* ADC2: mute amp left and right */ 8149 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8150 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 8151 /* ADC3: mute amp left and right */ 8152 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8153 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 8154 8155 { } 8156}; 8157 8158static struct hda_verb alc882_adc1_init_verbs[] = { 8159 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 8160 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8161 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8162 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 8163 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8164 /* ADC1: mute amp left and right */ 8165 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8166 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 8167 { } 8168}; 8169 8170static struct hda_verb alc882_eapd_verbs[] = { 8171 /* change to EAPD mode */ 8172 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 8173 {0x20, AC_VERB_SET_PROC_COEF, 0x3060}, 8174 { } 8175}; 8176 8177static struct hda_verb alc889_eapd_verbs[] = { 8178 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 8179 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, 8180 { } 8181}; 8182 8183static struct hda_verb alc_hp15_unsol_verbs[] = { 8184 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 8185 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8186 {} 8187}; 8188 8189static struct hda_verb alc885_init_verbs[] = { 8190 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 8191 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8192 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8193 /* Rear mixer */ 8194 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8195 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8196 /* CLFE mixer */ 8197 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8198 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8199 /* Side mixer */ 8200 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8201 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8202 8203 /* Front HP Pin: output 0 (0x0c) */ 8204 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8205 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8206 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 8207 /* Front Pin: output 0 (0x0c) */ 8208 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8209 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8210 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 8211 /* Rear Pin: output 1 (0x0d) */ 8212 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8213 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8214 {0x19, AC_VERB_SET_CONNECT_SEL, 0x01}, 8215 /* CLFE Pin: output 2 (0x0e) */ 8216 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8217 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8218 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, 8219 /* Side Pin: output 3 (0x0f) */ 8220 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8221 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8222 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, 8223 /* Mic (rear) pin: input vref at 80% */ 8224 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 8225 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8226 /* Front Mic pin: input vref at 80% */ 8227 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 8228 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8229 /* Line In pin: input */ 8230 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 8231 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8232 8233 /* Mixer elements: 0x18, , 0x1a, 0x1b */ 8234 /* Input mixer1 */ 8235 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8236 /* Input mixer2 */ 8237 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8238 /* Input mixer3 */ 8239 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8240 /* ADC2: mute amp left and right */ 8241 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8242 /* ADC3: mute amp left and right */ 8243 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8244 8245 { } 8246}; 8247 8248static struct hda_verb alc885_init_input_verbs[] = { 8249 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8250 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 8251 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 8252 { } 8253}; 8254 8255 8256/* Unmute Selector 24h and set the default input to front mic */ 8257static struct hda_verb alc889_init_input_verbs[] = { 8258 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00}, 8259 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8260 { } 8261}; 8262 8263 8264#define alc883_init_verbs alc882_base_init_verbs 8265 8266/* Mac Pro test */ 8267static struct snd_kcontrol_new alc882_macpro_mixer[] = { 8268 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8269 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8270 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT), 8271 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT), 8272 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT), 8273 /* FIXME: this looks suspicious... 8274 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x02, HDA_INPUT), 8275 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x02, HDA_INPUT), 8276 */ 8277 { } /* end */ 8278}; 8279 8280static struct hda_verb alc882_macpro_init_verbs[] = { 8281 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 8282 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8283 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8284 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8285 /* Front Pin: output 0 (0x0c) */ 8286 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8287 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8288 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 8289 /* Front Mic pin: input vref at 80% */ 8290 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 8291 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8292 /* Speaker: output */ 8293 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8294 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8295 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04}, 8296 /* Headphone output (output 0 - 0x0c) */ 8297 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8298 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8299 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00}, 8300 8301 /* FIXME: use matrix-type input source selection */ 8302 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 8303 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 8304 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8305 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8306 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 8307 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8308 /* Input mixer2 */ 8309 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8310 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8311 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 8312 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8313 /* Input mixer3 */ 8314 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8315 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8316 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 8317 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8318 /* ADC1: mute amp left and right */ 8319 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8320 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 8321 /* ADC2: mute amp left and right */ 8322 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8323 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 8324 /* ADC3: mute amp left and right */ 8325 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8326 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 8327 8328 { } 8329}; 8330 8331/* Macbook 5,1 */ 8332static struct hda_verb alc885_mb5_init_verbs[] = { 8333 /* DACs */ 8334 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8335 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8336 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8337 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8338 /* Front mixer */ 8339 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8340 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8341 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8342 /* Surround mixer */ 8343 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8344 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8345 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8346 /* LFE mixer */ 8347 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8348 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8349 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8350 /* HP mixer */ 8351 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8352 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8353 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8354 /* Front Pin (0x0c) */ 8355 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01}, 8356 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8357 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00}, 8358 /* LFE Pin (0x0e) */ 8359 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01}, 8360 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8361 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, 8362 /* HP Pin (0x0f) */ 8363 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8364 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8365 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03}, 8366 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 8367 /* Front Mic pin: input vref at 80% */ 8368 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 8369 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8370 /* Line In pin */ 8371 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 8372 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8373 8374 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0x1)}, 8375 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x7)}, 8376 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x4)}, 8377 { } 8378}; 8379 8380/* Macmini 3,1 */ 8381static struct hda_verb alc885_macmini3_init_verbs[] = { 8382 /* DACs */ 8383 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8384 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8385 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8386 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8387 /* Front mixer */ 8388 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8389 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8390 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8391 /* Surround mixer */ 8392 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8393 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8394 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8395 /* LFE mixer */ 8396 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8397 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8398 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8399 /* HP mixer */ 8400 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8401 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8402 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8403 /* Front Pin (0x0c) */ 8404 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01}, 8405 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8406 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00}, 8407 /* LFE Pin (0x0e) */ 8408 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01}, 8409 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8410 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, 8411 /* HP Pin (0x0f) */ 8412 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8413 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8414 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03}, 8415 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 8416 /* Line In pin */ 8417 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 8418 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8419 8420 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8421 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8422 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 8423 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8424 { } 8425}; 8426 8427 8428static struct hda_verb alc885_mba21_init_verbs[] = { 8429 /*Internal and HP Speaker Mixer*/ 8430 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8431 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8432 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8433 /*Internal Speaker Pin (0x0c)*/ 8434 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) }, 8435 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8436 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00}, 8437 /* HP Pin: output 0 (0x0e) */ 8438 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, 8439 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8440 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 8441 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)}, 8442 /* Line in (is hp when jack connected)*/ 8443 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50}, 8444 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8445 8446 { } 8447 }; 8448 8449 8450/* Macbook Pro rev3 */ 8451static struct hda_verb alc885_mbp3_init_verbs[] = { 8452 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 8453 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8454 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8455 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8456 /* Rear mixer */ 8457 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8458 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8459 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8460 /* HP mixer */ 8461 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8462 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8463 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8464 /* Front Pin: output 0 (0x0c) */ 8465 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8466 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8467 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 8468 /* HP Pin: output 0 (0x0e) */ 8469 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, 8470 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8471 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02}, 8472 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 8473 /* Mic (rear) pin: input vref at 80% */ 8474 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 8475 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8476 /* Front Mic pin: input vref at 80% */ 8477 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 8478 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8479 /* Line In pin: use output 1 when in LineOut mode */ 8480 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 8481 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8482 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, 8483 8484 /* FIXME: use matrix-type input source selection */ 8485 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 8486 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 8487 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8488 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8489 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 8490 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8491 /* Input mixer2 */ 8492 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8493 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8494 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 8495 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8496 /* Input mixer3 */ 8497 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8498 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8499 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 8500 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8501 /* ADC1: mute amp left and right */ 8502 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8503 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 8504 /* ADC2: mute amp left and right */ 8505 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8506 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 8507 /* ADC3: mute amp left and right */ 8508 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8509 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 8510 8511 { } 8512}; 8513 8514/* iMac 9,1 */ 8515static struct hda_verb alc885_imac91_init_verbs[] = { 8516 /* Internal Speaker Pin (0x0c) */ 8517 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) }, 8518 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8519 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00}, 8520 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) }, 8521 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8522 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00}, 8523 /* HP Pin: Rear */ 8524 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8525 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8526 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 8527 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)}, 8528 /* Line in Rear */ 8529 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50}, 8530 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8531 /* Front Mic pin: input vref at 80% */ 8532 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 8533 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8534 /* Rear mixer */ 8535 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8536 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8537 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8538 /* Line-Out mixer: unmute input/output amp left and right (volume = 0) */ 8539 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8540 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8541 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8542 /* 0x24 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */ 8543 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8544 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8545 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 8546 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8547 /* 0x23 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */ 8548 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8549 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8550 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 8551 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8552 /* 0x22 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */ 8553 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8554 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8555 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 8556 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8557 /* 0x07 [Audio Input] wcaps 0x10011b: Stereo Amp-In */ 8558 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8559 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 8560 /* 0x08 [Audio Input] wcaps 0x10011b: Stereo Amp-In */ 8561 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8562 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 8563 /* 0x09 [Audio Input] wcaps 0x10011b: Stereo Amp-In */ 8564 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8565 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 8566 { } 8567}; 8568 8569/* iMac 24 mixer. */ 8570static struct snd_kcontrol_new alc885_imac24_mixer[] = { 8571 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 8572 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT), 8573 { } /* end */ 8574}; 8575 8576/* iMac 24 init verbs. */ 8577static struct hda_verb alc885_imac24_init_verbs[] = { 8578 /* Internal speakers: output 0 (0x0c) */ 8579 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8580 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8581 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00}, 8582 /* Internal speakers: output 0 (0x0c) */ 8583 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8584 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8585 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00}, 8586 /* Headphone: output 0 (0x0c) */ 8587 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8588 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8589 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 8590 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 8591 /* Front Mic: input vref at 80% */ 8592 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 8593 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8594 { } 8595}; 8596 8597/* Toggle speaker-output according to the hp-jack state */ 8598static void alc885_imac24_setup(struct hda_codec *codec) 8599{ 8600 struct alc_spec *spec = codec->spec; 8601 8602 spec->autocfg.hp_pins[0] = 0x14; 8603 spec->autocfg.speaker_pins[0] = 0x18; 8604 spec->autocfg.speaker_pins[1] = 0x1a; 8605} 8606 8607#define alc885_mb5_setup alc885_imac24_setup 8608#define alc885_macmini3_setup alc885_imac24_setup 8609 8610/* Macbook Air 2,1 */ 8611static void alc885_mba21_setup(struct hda_codec *codec) 8612{ 8613 struct alc_spec *spec = codec->spec; 8614 8615 spec->autocfg.hp_pins[0] = 0x14; 8616 spec->autocfg.speaker_pins[0] = 0x18; 8617} 8618 8619 8620 8621static void alc885_mbp3_setup(struct hda_codec *codec) 8622{ 8623 struct alc_spec *spec = codec->spec; 8624 8625 spec->autocfg.hp_pins[0] = 0x15; 8626 spec->autocfg.speaker_pins[0] = 0x14; 8627} 8628 8629static void alc885_imac91_setup(struct hda_codec *codec) 8630{ 8631 struct alc_spec *spec = codec->spec; 8632 8633 spec->autocfg.hp_pins[0] = 0x14; 8634 spec->autocfg.speaker_pins[0] = 0x18; 8635 spec->autocfg.speaker_pins[1] = 0x1a; 8636} 8637 8638static struct hda_verb alc882_targa_verbs[] = { 8639 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8640 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8641 8642 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8643 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8644 8645 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ 8646 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */ 8647 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 8648 8649 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 8650 { } /* end */ 8651}; 8652 8653/* toggle speaker-output according to the hp-jack state */ 8654static void alc882_targa_automute(struct hda_codec *codec) 8655{ 8656 struct alc_spec *spec = codec->spec; 8657 alc_automute_amp(codec); 8658 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA, 8659 spec->jack_present ? 1 : 3); 8660} 8661 8662static void alc882_targa_setup(struct hda_codec *codec) 8663{ 8664 struct alc_spec *spec = codec->spec; 8665 8666 spec->autocfg.hp_pins[0] = 0x14; 8667 spec->autocfg.speaker_pins[0] = 0x1b; 8668} 8669 8670static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res) 8671{ 8672 if ((res >> 26) == ALC880_HP_EVENT) 8673 alc882_targa_automute(codec); 8674} 8675 8676static struct hda_verb alc882_asus_a7j_verbs[] = { 8677 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8678 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8679 8680 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8681 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8682 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8683 8684 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */ 8685 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 8686 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */ 8687 8688 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ 8689 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */ 8690 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 8691 { } /* end */ 8692}; 8693 8694static struct hda_verb alc882_asus_a7m_verbs[] = { 8695 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8696 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8697 8698 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8699 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8700 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8701 8702 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */ 8703 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 8704 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */ 8705 8706 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ 8707 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */ 8708 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 8709 { } /* end */ 8710}; 8711 8712static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted) 8713{ 8714 unsigned int gpiostate, gpiomask, gpiodir; 8715 8716 gpiostate = snd_hda_codec_read(codec, codec->afg, 0, 8717 AC_VERB_GET_GPIO_DATA, 0); 8718 8719 if (!muted) 8720 gpiostate |= (1 << pin); 8721 else 8722 gpiostate &= ~(1 << pin); 8723 8724 gpiomask = snd_hda_codec_read(codec, codec->afg, 0, 8725 AC_VERB_GET_GPIO_MASK, 0); 8726 gpiomask |= (1 << pin); 8727 8728 gpiodir = snd_hda_codec_read(codec, codec->afg, 0, 8729 AC_VERB_GET_GPIO_DIRECTION, 0); 8730 gpiodir |= (1 << pin); 8731 8732 8733 snd_hda_codec_write(codec, codec->afg, 0, 8734 AC_VERB_SET_GPIO_MASK, gpiomask); 8735 snd_hda_codec_write(codec, codec->afg, 0, 8736 AC_VERB_SET_GPIO_DIRECTION, gpiodir); 8737 8738 msleep(1); 8739 8740 snd_hda_codec_write(codec, codec->afg, 0, 8741 AC_VERB_SET_GPIO_DATA, gpiostate); 8742} 8743 8744/* set up GPIO at initialization */ 8745static void alc885_macpro_init_hook(struct hda_codec *codec) 8746{ 8747 alc882_gpio_mute(codec, 0, 0); 8748 alc882_gpio_mute(codec, 1, 0); 8749} 8750 8751/* set up GPIO and update auto-muting at initialization */ 8752static void alc885_imac24_init_hook(struct hda_codec *codec) 8753{ 8754 alc885_macpro_init_hook(codec); 8755 alc_automute_amp(codec); 8756} 8757 8758/* 8759 * generic initialization of ADC, input mixers and output mixers 8760 */ 8761static struct hda_verb alc883_auto_init_verbs[] = { 8762 /* 8763 * Unmute ADC0-2 and set the default input to mic-in 8764 */ 8765 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 8766 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8767 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 8768 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8769 8770 /* 8771 * Set up output mixers (0x0c - 0x0f) 8772 */ 8773 /* set vol=0 to output mixers */ 8774 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8775 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8776 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8777 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8778 /* set up input amps for analog loopback */ 8779 /* Amp Indices: DAC = 0, mixer = 1 */ 8780 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8781 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8782 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8783 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8784 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8785 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8786 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8787 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8788 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8789 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8790 8791 /* FIXME: use matrix-type input source selection */ 8792 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 8793 /* Input mixer2 */ 8794 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8795 /* Input mixer3 */ 8796 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8797 { } 8798}; 8799 8800/* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */ 8801static struct hda_verb alc889A_mb31_ch2_init[] = { 8802 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */ 8803 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */ 8804 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */ 8805 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */ 8806 { } /* end */ 8807}; 8808 8809/* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */ 8810static struct hda_verb alc889A_mb31_ch4_init[] = { 8811 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */ 8812 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */ 8813 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */ 8814 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */ 8815 { } /* end */ 8816}; 8817 8818/* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */ 8819static struct hda_verb alc889A_mb31_ch5_init[] = { 8820 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */ 8821 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */ 8822 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */ 8823 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */ 8824 { } /* end */ 8825}; 8826 8827/* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */ 8828static struct hda_verb alc889A_mb31_ch6_init[] = { 8829 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */ 8830 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */ 8831 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */ 8832 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */ 8833 { } /* end */ 8834}; 8835 8836static struct hda_channel_mode alc889A_mb31_6ch_modes[4] = { 8837 { 2, alc889A_mb31_ch2_init }, 8838 { 4, alc889A_mb31_ch4_init }, 8839 { 5, alc889A_mb31_ch5_init }, 8840 { 6, alc889A_mb31_ch6_init }, 8841}; 8842 8843static struct hda_verb alc883_medion_eapd_verbs[] = { 8844 /* eanable EAPD on medion laptop */ 8845 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 8846 {0x20, AC_VERB_SET_PROC_COEF, 0x3070}, 8847 { } 8848}; 8849 8850#define alc883_base_mixer alc882_base_mixer 8851 8852static struct snd_kcontrol_new alc883_mitac_mixer[] = { 8853 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8854 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8855 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 8856 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 8857 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 8858 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 8859 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 8860 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8861 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 8862 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8863 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8864 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), 8865 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8866 { } /* end */ 8867}; 8868 8869static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = { 8870 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8871 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), 8872 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 8873 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 8874 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8875 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 8876 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8877 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8878 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), 8879 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8880 { } /* end */ 8881}; 8882 8883static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = { 8884 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8885 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), 8886 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 8887 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 8888 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8889 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 8890 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8891 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8892 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), 8893 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8894 { } /* end */ 8895}; 8896 8897static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = { 8898 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8899 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8900 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 8901 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 8902 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 8903 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8904 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8905 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8906 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 8907 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8908 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8909 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), 8910 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8911 { } /* end */ 8912}; 8913 8914static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = { 8915 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8916 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8917 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 8918 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 8919 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 8920 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 8921 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 8922 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 8923 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 8924 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 8925 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 8926 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8927 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8928 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8929 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 8930 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8931 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8932 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), 8933 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8934 { } /* end */ 8935}; 8936 8937static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = { 8938 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8939 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8940 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 8941 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 8942 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, 8943 HDA_OUTPUT), 8944 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 8945 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 8946 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 8947 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 8948 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 8949 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 8950 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8951 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8952 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8953 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT), 8954 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8955 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8956 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT), 8957 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8958 { } /* end */ 8959}; 8960 8961static struct snd_kcontrol_new alc885_8ch_intel_mixer[] = { 8962 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8963 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8964 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 8965 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 8966 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, 8967 HDA_OUTPUT), 8968 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 8969 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 8970 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 8971 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 8972 HDA_BIND_MUTE("Speaker Playback Switch", 0x0f, 2, HDA_INPUT), 8973 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 8974 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8975 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8976 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT), 8977 HDA_CODEC_VOLUME("Mic Boost Volume", 0x1b, 0, HDA_INPUT), 8978 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT), 8979 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8980 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT), 8981 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8982 { } /* end */ 8983}; 8984 8985static struct snd_kcontrol_new alc883_fivestack_mixer[] = { 8986 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8987 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8988 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 8989 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 8990 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 8991 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 8992 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 8993 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 8994 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 8995 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 8996 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 8997 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8998 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8999 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9000 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 9001 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9002 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 9003 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), 9004 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 9005 { } /* end */ 9006}; 9007 9008static struct snd_kcontrol_new alc883_targa_mixer[] = { 9009 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9010 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 9011 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 9012 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 9013 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 9014 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 9015 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 9016 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 9017 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 9018 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 9019 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 9020 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 9021 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 9022 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 9023 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9024 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 9025 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9026 { } /* end */ 9027}; 9028 9029static struct snd_kcontrol_new alc883_targa_2ch_mixer[] = { 9030 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9031 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 9032 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 9033 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 9034 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 9035 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 9036 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9037 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 9038 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9039 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 9040 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), 9041 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 9042 { } /* end */ 9043}; 9044 9045static struct snd_kcontrol_new alc883_targa_8ch_mixer[] = { 9046 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 9047 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 9048 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 9049 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), 9050 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 9051 { } /* end */ 9052}; 9053 9054static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = { 9055 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9056 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 9057 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 9058 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 9059 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 9060 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 9061 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 9062 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 9063 { } /* end */ 9064}; 9065 9066static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = { 9067 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9068 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT), 9069 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 9070 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 9071 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 9072 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9073 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9074 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 9075 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 9076 { } /* end */ 9077}; 9078 9079static struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = { 9080 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9081 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 9082 HDA_CODEC_MUTE("Speaker Playback Switch", 0x15, 0x0, HDA_OUTPUT), 9083 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT), 9084 HDA_CODEC_VOLUME("Line Playback Volume", 0x08, 0x0, HDA_INPUT), 9085 HDA_CODEC_MUTE("Line Playback Switch", 0x08, 0x0, HDA_INPUT), 9086 { } /* end */ 9087}; 9088 9089static struct hda_verb alc883_medion_wim2160_verbs[] = { 9090 /* Unmute front mixer */ 9091 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9092 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9093 9094 /* Set speaker pin to front mixer */ 9095 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9096 9097 /* Init headphone pin */ 9098 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9099 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9100 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00}, 9101 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9102 9103 { } /* end */ 9104}; 9105 9106/* toggle speaker-output according to the hp-jack state */ 9107static void alc883_medion_wim2160_setup(struct hda_codec *codec) 9108{ 9109 struct alc_spec *spec = codec->spec; 9110 9111 spec->autocfg.hp_pins[0] = 0x1a; 9112 spec->autocfg.speaker_pins[0] = 0x15; 9113} 9114 9115static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = { 9116 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9117 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 9118 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 9119 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 9120 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 9121 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9122 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 9123 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9124 { } /* end */ 9125}; 9126 9127static struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = { 9128 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9129 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 9130 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 9131 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 9132 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 9133 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 9134 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9135 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 9136 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9137 { } /* end */ 9138}; 9139 9140static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = { 9141 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9142 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 9143 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT), 9144 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT), 9145 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 9146 0x0d, 1, 0x0, HDA_OUTPUT), 9147 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT), 9148 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT), 9149 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT), 9150 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 9151 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 9152 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 9153 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 9154 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 9155 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 9156 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9157 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 9158 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9159 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 9160 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), 9161 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 9162 { } /* end */ 9163}; 9164 9165static struct snd_kcontrol_new alc889A_mb31_mixer[] = { 9166 /* Output mixers */ 9167 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 9168 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT), 9169 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT), 9170 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT), 9171 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00, 9172 HDA_OUTPUT), 9173 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT), 9174 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT), 9175 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT), 9176 /* Output switches */ 9177 HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT), 9178 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT), 9179 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT), 9180 /* Boost mixers */ 9181 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT), 9182 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT), 9183 /* Input mixers */ 9184 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT), 9185 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT), 9186 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 9187 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 9188 { } /* end */ 9189}; 9190 9191static struct snd_kcontrol_new alc883_vaiott_mixer[] = { 9192 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9193 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 9194 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 9195 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 9196 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT), 9197 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 9198 { } /* end */ 9199}; 9200 9201static struct hda_bind_ctls alc883_bind_cap_vol = { 9202 .ops = &snd_hda_bind_vol, 9203 .values = { 9204 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT), 9205 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT), 9206 0 9207 }, 9208}; 9209 9210static struct hda_bind_ctls alc883_bind_cap_switch = { 9211 .ops = &snd_hda_bind_sw, 9212 .values = { 9213 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT), 9214 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT), 9215 0 9216 }, 9217}; 9218 9219static struct snd_kcontrol_new alc883_asus_eee1601_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_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 9223 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 9224 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 9225 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9226 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 9227 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9228 { } /* end */ 9229}; 9230 9231static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = { 9232 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol), 9233 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch), 9234 { 9235 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 9236 /* .name = "Capture Source", */ 9237 .name = "Input Source", 9238 .count = 1, 9239 .info = alc_mux_enum_info, 9240 .get = alc_mux_enum_get, 9241 .put = alc_mux_enum_put, 9242 }, 9243 { } /* end */ 9244}; 9245 9246static struct snd_kcontrol_new alc883_chmode_mixer[] = { 9247 { 9248 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 9249 .name = "Channel Mode", 9250 .info = alc_ch_mode_info, 9251 .get = alc_ch_mode_get, 9252 .put = alc_ch_mode_put, 9253 }, 9254 { } /* end */ 9255}; 9256 9257/* toggle speaker-output according to the hp-jack state */ 9258static void alc883_mitac_setup(struct hda_codec *codec) 9259{ 9260 struct alc_spec *spec = codec->spec; 9261 9262 spec->autocfg.hp_pins[0] = 0x15; 9263 spec->autocfg.speaker_pins[0] = 0x14; 9264 spec->autocfg.speaker_pins[1] = 0x17; 9265} 9266 9267static struct hda_verb alc883_mitac_verbs[] = { 9268 /* HP */ 9269 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9270 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9271 /* Subwoofer */ 9272 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02}, 9273 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9274 9275 /* enable unsolicited event */ 9276 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9277 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */ 9278 9279 { } /* end */ 9280}; 9281 9282static struct hda_verb alc883_clevo_m540r_verbs[] = { 9283 /* HP */ 9284 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9285 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9286 /* Int speaker */ 9287 /*{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},*/ 9288 9289 /* enable unsolicited event */ 9290 /* 9291 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9292 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, 9293 */ 9294 9295 { } /* end */ 9296}; 9297 9298static struct hda_verb alc883_clevo_m720_verbs[] = { 9299 /* HP */ 9300 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9301 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9302 /* Int speaker */ 9303 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01}, 9304 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9305 9306 /* enable unsolicited event */ 9307 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9308 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, 9309 9310 { } /* end */ 9311}; 9312 9313static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = { 9314 /* HP */ 9315 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 9316 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9317 /* Subwoofer */ 9318 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 9319 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9320 9321 /* enable unsolicited event */ 9322 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9323 9324 { } /* end */ 9325}; 9326 9327static struct hda_verb alc883_targa_verbs[] = { 9328 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9329 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9330 9331 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9332 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9333 9334/* Connect Line-Out side jack (SPDIF) to Side */ 9335 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9336 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9337 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, 9338/* Connect Mic jack to CLFE */ 9339 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9340 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9341 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, 9342/* Connect Line-in jack to Surround */ 9343 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9344 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9345 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, 9346/* Connect HP out jack to Front */ 9347 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9348 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9349 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 9350 9351 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9352 9353 { } /* end */ 9354}; 9355 9356static struct hda_verb alc883_lenovo_101e_verbs[] = { 9357 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9358 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN}, 9359 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN}, 9360 { } /* end */ 9361}; 9362 9363static struct hda_verb alc883_lenovo_nb0763_verbs[] = { 9364 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9365 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9366 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9367 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9368 { } /* end */ 9369}; 9370 9371static struct hda_verb alc888_lenovo_ms7195_verbs[] = { 9372 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9373 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9374 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9375 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN}, 9376 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9377 { } /* end */ 9378}; 9379 9380static struct hda_verb alc883_haier_w66_verbs[] = { 9381 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9382 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9383 9384 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9385 9386 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 9387 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9388 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9389 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9390 { } /* end */ 9391}; 9392 9393static struct hda_verb alc888_lenovo_sky_verbs[] = { 9394 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9395 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9396 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9397 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9398 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9399 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9400 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00}, 9401 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9402 { } /* end */ 9403}; 9404 9405static struct hda_verb alc888_6st_dell_verbs[] = { 9406 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9407 { } 9408}; 9409 9410static struct hda_verb alc883_vaiott_verbs[] = { 9411 /* HP */ 9412 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9413 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9414 9415 /* enable unsolicited event */ 9416 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9417 9418 { } /* end */ 9419}; 9420 9421static void alc888_3st_hp_setup(struct hda_codec *codec) 9422{ 9423 struct alc_spec *spec = codec->spec; 9424 9425 spec->autocfg.hp_pins[0] = 0x1b; 9426 spec->autocfg.speaker_pins[0] = 0x14; 9427 spec->autocfg.speaker_pins[1] = 0x16; 9428 spec->autocfg.speaker_pins[2] = 0x18; 9429} 9430 9431static struct hda_verb alc888_3st_hp_verbs[] = { 9432 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */ 9433 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */ 9434 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */ 9435 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9436 { } /* end */ 9437}; 9438 9439/* 9440 * 2ch mode 9441 */ 9442static struct hda_verb alc888_3st_hp_2ch_init[] = { 9443 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 9444 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 9445 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 9446 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 9447 { } /* end */ 9448}; 9449 9450/* 9451 * 4ch mode 9452 */ 9453static struct hda_verb alc888_3st_hp_4ch_init[] = { 9454 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 9455 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 9456 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 9457 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 9458 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 }, 9459 { } /* end */ 9460}; 9461 9462/* 9463 * 6ch mode 9464 */ 9465static struct hda_verb alc888_3st_hp_6ch_init[] = { 9466 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 9467 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 9468 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, 9469 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 9470 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 9471 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 }, 9472 { } /* end */ 9473}; 9474 9475static struct hda_channel_mode alc888_3st_hp_modes[3] = { 9476 { 2, alc888_3st_hp_2ch_init }, 9477 { 4, alc888_3st_hp_4ch_init }, 9478 { 6, alc888_3st_hp_6ch_init }, 9479}; 9480 9481/* toggle front-jack and RCA according to the hp-jack state */ 9482static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec) 9483{ 9484 unsigned int present = snd_hda_jack_detect(codec, 0x1b); 9485 9486 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 9487 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 9488 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 9489 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 9490} 9491 9492/* toggle RCA according to the front-jack state */ 9493static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec) 9494{ 9495 unsigned int present = snd_hda_jack_detect(codec, 0x14); 9496 9497 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 9498 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 9499} 9500 9501static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec, 9502 unsigned int res) 9503{ 9504 if ((res >> 26) == ALC880_HP_EVENT) 9505 alc888_lenovo_ms7195_front_automute(codec); 9506 if ((res >> 26) == ALC880_FRONT_EVENT) 9507 alc888_lenovo_ms7195_rca_automute(codec); 9508} 9509 9510/* toggle speaker-output according to the hp-jack state */ 9511static void alc883_lenovo_nb0763_setup(struct hda_codec *codec) 9512{ 9513 struct alc_spec *spec = codec->spec; 9514 9515 spec->autocfg.hp_pins[0] = 0x14; 9516 spec->autocfg.speaker_pins[0] = 0x15; 9517} 9518 9519/* toggle speaker-output according to the hp-jack state */ 9520#define alc883_targa_init_hook alc882_targa_init_hook 9521#define alc883_targa_unsol_event alc882_targa_unsol_event 9522 9523static void alc883_clevo_m720_setup(struct hda_codec *codec) 9524{ 9525 struct alc_spec *spec = codec->spec; 9526 9527 spec->autocfg.hp_pins[0] = 0x15; 9528 spec->autocfg.speaker_pins[0] = 0x14; 9529} 9530 9531static void alc883_clevo_m720_init_hook(struct hda_codec *codec) 9532{ 9533 alc_automute_amp(codec); 9534 alc88x_simple_mic_automute(codec); 9535} 9536 9537static void alc883_clevo_m720_unsol_event(struct hda_codec *codec, 9538 unsigned int res) 9539{ 9540 switch (res >> 26) { 9541 case ALC880_MIC_EVENT: 9542 alc88x_simple_mic_automute(codec); 9543 break; 9544 default: 9545 alc_automute_amp_unsol_event(codec, res); 9546 break; 9547 } 9548} 9549 9550/* toggle speaker-output according to the hp-jack state */ 9551static void alc883_2ch_fujitsu_pi2515_setup(struct hda_codec *codec) 9552{ 9553 struct alc_spec *spec = codec->spec; 9554 9555 spec->autocfg.hp_pins[0] = 0x14; 9556 spec->autocfg.speaker_pins[0] = 0x15; 9557} 9558 9559static void alc883_haier_w66_setup(struct hda_codec *codec) 9560{ 9561 struct alc_spec *spec = codec->spec; 9562 9563 spec->autocfg.hp_pins[0] = 0x1b; 9564 spec->autocfg.speaker_pins[0] = 0x14; 9565} 9566 9567static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec) 9568{ 9569 int bits = snd_hda_jack_detect(codec, 0x14) ? HDA_AMP_MUTE : 0; 9570 9571 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 9572 HDA_AMP_MUTE, bits); 9573} 9574 9575static void alc883_lenovo_101e_all_automute(struct hda_codec *codec) 9576{ 9577 int bits = snd_hda_jack_detect(codec, 0x1b) ? HDA_AMP_MUTE : 0; 9578 9579 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 9580 HDA_AMP_MUTE, bits); 9581 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 9582 HDA_AMP_MUTE, bits); 9583} 9584 9585static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec, 9586 unsigned int res) 9587{ 9588 if ((res >> 26) == ALC880_HP_EVENT) 9589 alc883_lenovo_101e_all_automute(codec); 9590 if ((res >> 26) == ALC880_FRONT_EVENT) 9591 alc883_lenovo_101e_ispeaker_automute(codec); 9592} 9593 9594/* toggle speaker-output according to the hp-jack state */ 9595static void alc883_acer_aspire_setup(struct hda_codec *codec) 9596{ 9597 struct alc_spec *spec = codec->spec; 9598 9599 spec->autocfg.hp_pins[0] = 0x14; 9600 spec->autocfg.speaker_pins[0] = 0x15; 9601 spec->autocfg.speaker_pins[1] = 0x16; 9602} 9603 9604static struct hda_verb alc883_acer_eapd_verbs[] = { 9605 /* HP Pin: output 0 (0x0c) */ 9606 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9607 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9608 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 9609 /* Front Pin: output 0 (0x0c) */ 9610 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9611 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9612 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9613 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, 9614 /* eanable EAPD on medion laptop */ 9615 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 9616 {0x20, AC_VERB_SET_PROC_COEF, 0x3050}, 9617 /* enable unsolicited event */ 9618 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9619 { } 9620}; 9621 9622static void alc888_6st_dell_setup(struct hda_codec *codec) 9623{ 9624 struct alc_spec *spec = codec->spec; 9625 9626 spec->autocfg.hp_pins[0] = 0x1b; 9627 spec->autocfg.speaker_pins[0] = 0x14; 9628 spec->autocfg.speaker_pins[1] = 0x15; 9629 spec->autocfg.speaker_pins[2] = 0x16; 9630 spec->autocfg.speaker_pins[3] = 0x17; 9631} 9632 9633static void alc888_lenovo_sky_setup(struct hda_codec *codec) 9634{ 9635 struct alc_spec *spec = codec->spec; 9636 9637 spec->autocfg.hp_pins[0] = 0x1b; 9638 spec->autocfg.speaker_pins[0] = 0x14; 9639 spec->autocfg.speaker_pins[1] = 0x15; 9640 spec->autocfg.speaker_pins[2] = 0x16; 9641 spec->autocfg.speaker_pins[3] = 0x17; 9642 spec->autocfg.speaker_pins[4] = 0x1a; 9643} 9644 9645static void alc883_vaiott_setup(struct hda_codec *codec) 9646{ 9647 struct alc_spec *spec = codec->spec; 9648 9649 spec->autocfg.hp_pins[0] = 0x15; 9650 spec->autocfg.speaker_pins[0] = 0x14; 9651 spec->autocfg.speaker_pins[1] = 0x17; 9652} 9653 9654static struct hda_verb alc888_asus_m90v_verbs[] = { 9655 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 9656 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 9657 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9658 /* enable unsolicited event */ 9659 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9660 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, 9661 { } /* end */ 9662}; 9663 9664static void alc883_mode2_setup(struct hda_codec *codec) 9665{ 9666 struct alc_spec *spec = codec->spec; 9667 9668 spec->autocfg.hp_pins[0] = 0x1b; 9669 spec->autocfg.speaker_pins[0] = 0x14; 9670 spec->autocfg.speaker_pins[1] = 0x15; 9671 spec->autocfg.speaker_pins[2] = 0x16; 9672 spec->ext_mic.pin = 0x18; 9673 spec->int_mic.pin = 0x19; 9674 spec->ext_mic.mux_idx = 0; 9675 spec->int_mic.mux_idx = 1; 9676 spec->auto_mic = 1; 9677} 9678 9679static struct hda_verb alc888_asus_eee1601_verbs[] = { 9680 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9681 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9682 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 9683 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9684 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 9685 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b}, 9686 {0x20, AC_VERB_SET_PROC_COEF, 0x0838}, 9687 /* enable unsolicited event */ 9688 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9689 { } /* end */ 9690}; 9691 9692static void alc883_eee1601_inithook(struct hda_codec *codec) 9693{ 9694 struct alc_spec *spec = codec->spec; 9695 9696 spec->autocfg.hp_pins[0] = 0x14; 9697 spec->autocfg.speaker_pins[0] = 0x1b; 9698 alc_automute_pin(codec); 9699} 9700 9701static struct hda_verb alc889A_mb31_verbs[] = { 9702 /* Init rear pin (used as headphone output) */ 9703 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */ 9704 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */ 9705 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9706 /* Init line pin (used as output in 4ch and 6ch mode) */ 9707 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */ 9708 /* Init line 2 pin (used as headphone out by default) */ 9709 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */ 9710 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */ 9711 { } /* end */ 9712}; 9713 9714/* Mute speakers according to the headphone jack state */ 9715static void alc889A_mb31_automute(struct hda_codec *codec) 9716{ 9717 unsigned int present; 9718 9719 /* Mute only in 2ch or 4ch mode */ 9720 if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0) 9721 == 0x00) { 9722 present = snd_hda_jack_detect(codec, 0x15); 9723 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 9724 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 9725 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0, 9726 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 9727 } 9728} 9729 9730static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res) 9731{ 9732 if ((res >> 26) == ALC880_HP_EVENT) 9733 alc889A_mb31_automute(codec); 9734} 9735 9736 9737#ifdef CONFIG_SND_HDA_POWER_SAVE 9738#define alc882_loopbacks alc880_loopbacks 9739#endif 9740 9741/* pcm configuration: identical with ALC880 */ 9742#define alc882_pcm_analog_playback alc880_pcm_analog_playback 9743#define alc882_pcm_analog_capture alc880_pcm_analog_capture 9744#define alc882_pcm_digital_playback alc880_pcm_digital_playback 9745#define alc882_pcm_digital_capture alc880_pcm_digital_capture 9746 9747static hda_nid_t alc883_slave_dig_outs[] = { 9748 ALC1200_DIGOUT_NID, 0, 9749}; 9750 9751static hda_nid_t alc1200_slave_dig_outs[] = { 9752 ALC883_DIGOUT_NID, 0, 9753}; 9754 9755/* 9756 * configuration and preset 9757 */ 9758static const char * const alc882_models[ALC882_MODEL_LAST] = { 9759 [ALC882_3ST_DIG] = "3stack-dig", 9760 [ALC882_6ST_DIG] = "6stack-dig", 9761 [ALC882_ARIMA] = "arima", 9762 [ALC882_W2JC] = "w2jc", 9763 [ALC882_TARGA] = "targa", 9764 [ALC882_ASUS_A7J] = "asus-a7j", 9765 [ALC882_ASUS_A7M] = "asus-a7m", 9766 [ALC885_MACPRO] = "macpro", 9767 [ALC885_MB5] = "mb5", 9768 [ALC885_MACMINI3] = "macmini3", 9769 [ALC885_MBA21] = "mba21", 9770 [ALC885_MBP3] = "mbp3", 9771 [ALC885_IMAC24] = "imac24", 9772 [ALC885_IMAC91] = "imac91", 9773 [ALC883_3ST_2ch_DIG] = "3stack-2ch-dig", 9774 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig", 9775 [ALC883_3ST_6ch] = "3stack-6ch", 9776 [ALC883_6ST_DIG] = "alc883-6stack-dig", 9777 [ALC883_TARGA_DIG] = "targa-dig", 9778 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig", 9779 [ALC883_TARGA_8ch_DIG] = "targa-8ch-dig", 9780 [ALC883_ACER] = "acer", 9781 [ALC883_ACER_ASPIRE] = "acer-aspire", 9782 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g", 9783 [ALC888_ACER_ASPIRE_6530G] = "acer-aspire-6530g", 9784 [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g", 9785 [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g", 9786 [ALC883_MEDION] = "medion", 9787 [ALC883_MEDION_WIM2160] = "medion-wim2160", 9788 [ALC883_LAPTOP_EAPD] = "laptop-eapd", 9789 [ALC883_LENOVO_101E_2ch] = "lenovo-101e", 9790 [ALC883_LENOVO_NB0763] = "lenovo-nb0763", 9791 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig", 9792 [ALC888_LENOVO_SKY] = "lenovo-sky", 9793 [ALC883_HAIER_W66] = "haier-w66", 9794 [ALC888_3ST_HP] = "3stack-hp", 9795 [ALC888_6ST_DELL] = "6stack-dell", 9796 [ALC883_MITAC] = "mitac", 9797 [ALC883_CLEVO_M540R] = "clevo-m540r", 9798 [ALC883_CLEVO_M720] = "clevo-m720", 9799 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515", 9800 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530", 9801 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel", 9802 [ALC889A_INTEL] = "intel-alc889a", 9803 [ALC889_INTEL] = "intel-x58", 9804 [ALC1200_ASUS_P5Q] = "asus-p5q", 9805 [ALC889A_MB31] = "mb31", 9806 [ALC883_SONY_VAIO_TT] = "sony-vaio-tt", 9807 [ALC882_AUTO] = "auto", 9808}; 9809 9810static struct snd_pci_quirk alc882_cfg_tbl[] = { 9811 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG), 9812 9813 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE), 9814 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE), 9815 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE), 9816 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE), 9817 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE), 9818 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE), 9819 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G", 9820 ALC888_ACER_ASPIRE_4930G), 9821 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G", 9822 ALC888_ACER_ASPIRE_4930G), 9823 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G", 9824 ALC888_ACER_ASPIRE_8930G), 9825 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G", 9826 ALC888_ACER_ASPIRE_8930G), 9827 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC882_AUTO), 9828 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC882_AUTO), 9829 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G", 9830 ALC888_ACER_ASPIRE_6530G), 9831 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G", 9832 ALC888_ACER_ASPIRE_6530G), 9833 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G", 9834 ALC888_ACER_ASPIRE_7730G), 9835 /* default Acer -- disabled as it causes more problems. 9836 * model=auto should work fine now 9837 */ 9838 /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */ 9839 9840 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL), 9841 9842 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG), 9843 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP), 9844 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP), 9845 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG), 9846 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP), 9847 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP), 9848 9849 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J), 9850 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J), 9851 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M), 9852 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V), 9853 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC), 9854 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG), 9855 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG), 9856 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG), 9857 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG), 9858 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q), 9859 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601), 9860 9861 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT), 9862 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG), 9863 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG), 9864 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC), 9865 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC), 9866 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD), 9867 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL), 9868 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch), 9869 9870 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG), 9871 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG), 9872 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG), 9873 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */ 9874 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC882_AUTO), 9875 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG), 9876 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG), 9877 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG), 9878 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG), 9879 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG), 9880 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG), 9881 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG), 9882 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG), 9883 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG), 9884 SND_PCI_QUIRK(0x1462, 0x42cd, "MSI", ALC883_TARGA_DIG), 9885 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG), 9886 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG), 9887 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG), 9888 SND_PCI_QUIRK(0x1462, 0x4570, "MSI Wind Top AE2220", ALC883_TARGA_DIG), 9889 SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG), 9890 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG), 9891 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG), 9892 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG), 9893 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG), 9894 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG), 9895 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG), 9896 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG), 9897 SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG), 9898 SND_PCI_QUIRK(0x1462, 0x7437, "MSI NetOn AP1900", ALC883_TARGA_DIG), 9899 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG), 9900 SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG), 9901 9902 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG), 9903 SND_PCI_QUIRK(0x1558, 0x0571, "Clevo laptop M570U", ALC883_3ST_6ch_DIG), 9904 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720), 9905 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720), 9906 SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R), 9907 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD), 9908 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch), 9909 /* SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), */ 9910 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION), 9911 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx", 9912 ALC883_FUJITSU_PI2515), 9913 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx", 9914 ALC888_FUJITSU_XA3530), 9915 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch), 9916 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763), 9917 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763), 9918 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763), 9919 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY), 9920 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG), 9921 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG), 9922 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66), 9923 9924 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL), 9925 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL), 9926 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC), 9927 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL), 9928 SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL), 9929 SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL), 9930 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC882_6ST_DIG), 9931 9932 {} 9933}; 9934 9935/* codec SSID table for Intel Mac */ 9936static struct snd_pci_quirk alc882_ssid_cfg_tbl[] = { 9937 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3), 9938 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3), 9939 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3), 9940 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_MACPRO), 9941 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24), 9942 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24), 9943 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3), 9944 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889A_MB31), 9945 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_ASUS_A7M), 9946 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC885_MBP3), 9947 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC885_MBA21), 9948 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31), 9949 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3), 9950 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24), 9951 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC885_IMAC91), 9952 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5), 9953 SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC885_MB5), 9954 /* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2, 9955 * so apparently no perfect solution yet 9956 */ 9957 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5), 9958 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5), 9959 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC885_MACMINI3), 9960 {} /* terminator */ 9961}; 9962 9963static struct alc_config_preset alc882_presets[] = { 9964 [ALC882_3ST_DIG] = { 9965 .mixers = { alc882_base_mixer }, 9966 .init_verbs = { alc882_base_init_verbs, 9967 alc882_adc1_init_verbs }, 9968 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 9969 .dac_nids = alc882_dac_nids, 9970 .dig_out_nid = ALC882_DIGOUT_NID, 9971 .dig_in_nid = ALC882_DIGIN_NID, 9972 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes), 9973 .channel_mode = alc882_ch_modes, 9974 .need_dac_fix = 1, 9975 .input_mux = &alc882_capture_source, 9976 }, 9977 [ALC882_6ST_DIG] = { 9978 .mixers = { alc882_base_mixer, alc882_chmode_mixer }, 9979 .init_verbs = { alc882_base_init_verbs, 9980 alc882_adc1_init_verbs }, 9981 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 9982 .dac_nids = alc882_dac_nids, 9983 .dig_out_nid = ALC882_DIGOUT_NID, 9984 .dig_in_nid = ALC882_DIGIN_NID, 9985 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes), 9986 .channel_mode = alc882_sixstack_modes, 9987 .input_mux = &alc882_capture_source, 9988 }, 9989 [ALC882_ARIMA] = { 9990 .mixers = { alc882_base_mixer, alc882_chmode_mixer }, 9991 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs, 9992 alc882_eapd_verbs }, 9993 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 9994 .dac_nids = alc882_dac_nids, 9995 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes), 9996 .channel_mode = alc882_sixstack_modes, 9997 .input_mux = &alc882_capture_source, 9998 }, 9999 [ALC882_W2JC] = { 10000 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer }, 10001 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs, 10002 alc882_eapd_verbs, alc880_gpio1_init_verbs }, 10003 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 10004 .dac_nids = alc882_dac_nids, 10005 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), 10006 .channel_mode = alc880_threestack_modes, 10007 .need_dac_fix = 1, 10008 .input_mux = &alc882_capture_source, 10009 .dig_out_nid = ALC882_DIGOUT_NID, 10010 }, 10011 [ALC885_MBA21] = { 10012 .mixers = { alc885_mba21_mixer }, 10013 .init_verbs = { alc885_mba21_init_verbs, alc880_gpio1_init_verbs }, 10014 .num_dacs = 2, 10015 .dac_nids = alc882_dac_nids, 10016 .channel_mode = alc885_mba21_ch_modes, 10017 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes), 10018 .input_mux = &alc882_capture_source, 10019 .unsol_event = alc_automute_amp_unsol_event, 10020 .setup = alc885_mba21_setup, 10021 .init_hook = alc_automute_amp, 10022 }, 10023 [ALC885_MBP3] = { 10024 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer }, 10025 .init_verbs = { alc885_mbp3_init_verbs, 10026 alc880_gpio1_init_verbs }, 10027 .num_dacs = 2, 10028 .dac_nids = alc882_dac_nids, 10029 .hp_nid = 0x04, 10030 .channel_mode = alc885_mbp_4ch_modes, 10031 .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes), 10032 .input_mux = &alc882_capture_source, 10033 .dig_out_nid = ALC882_DIGOUT_NID, 10034 .dig_in_nid = ALC882_DIGIN_NID, 10035 .unsol_event = alc_automute_amp_unsol_event, 10036 .setup = alc885_mbp3_setup, 10037 .init_hook = alc_automute_amp, 10038 }, 10039 [ALC885_MB5] = { 10040 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer }, 10041 .init_verbs = { alc885_mb5_init_verbs, 10042 alc880_gpio1_init_verbs }, 10043 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 10044 .dac_nids = alc882_dac_nids, 10045 .channel_mode = alc885_mb5_6ch_modes, 10046 .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes), 10047 .input_mux = &mb5_capture_source, 10048 .dig_out_nid = ALC882_DIGOUT_NID, 10049 .dig_in_nid = ALC882_DIGIN_NID, 10050 .unsol_event = alc_automute_amp_unsol_event, 10051 .setup = alc885_mb5_setup, 10052 .init_hook = alc_automute_amp, 10053 }, 10054 [ALC885_MACMINI3] = { 10055 .mixers = { alc885_macmini3_mixer, alc882_chmode_mixer }, 10056 .init_verbs = { alc885_macmini3_init_verbs, 10057 alc880_gpio1_init_verbs }, 10058 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 10059 .dac_nids = alc882_dac_nids, 10060 .channel_mode = alc885_macmini3_6ch_modes, 10061 .num_channel_mode = ARRAY_SIZE(alc885_macmini3_6ch_modes), 10062 .input_mux = &macmini3_capture_source, 10063 .dig_out_nid = ALC882_DIGOUT_NID, 10064 .dig_in_nid = ALC882_DIGIN_NID, 10065 .unsol_event = alc_automute_amp_unsol_event, 10066 .setup = alc885_macmini3_setup, 10067 .init_hook = alc_automute_amp, 10068 }, 10069 [ALC885_MACPRO] = { 10070 .mixers = { alc882_macpro_mixer }, 10071 .init_verbs = { alc882_macpro_init_verbs }, 10072 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 10073 .dac_nids = alc882_dac_nids, 10074 .dig_out_nid = ALC882_DIGOUT_NID, 10075 .dig_in_nid = ALC882_DIGIN_NID, 10076 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes), 10077 .channel_mode = alc882_ch_modes, 10078 .input_mux = &alc882_capture_source, 10079 .init_hook = alc885_macpro_init_hook, 10080 }, 10081 [ALC885_IMAC24] = { 10082 .mixers = { alc885_imac24_mixer }, 10083 .init_verbs = { alc885_imac24_init_verbs }, 10084 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 10085 .dac_nids = alc882_dac_nids, 10086 .dig_out_nid = ALC882_DIGOUT_NID, 10087 .dig_in_nid = ALC882_DIGIN_NID, 10088 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes), 10089 .channel_mode = alc882_ch_modes, 10090 .input_mux = &alc882_capture_source, 10091 .unsol_event = alc_automute_amp_unsol_event, 10092 .setup = alc885_imac24_setup, 10093 .init_hook = alc885_imac24_init_hook, 10094 }, 10095 [ALC885_IMAC91] = { 10096 .mixers = {alc885_imac91_mixer}, 10097 .init_verbs = { alc885_imac91_init_verbs, 10098 alc880_gpio1_init_verbs }, 10099 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 10100 .dac_nids = alc882_dac_nids, 10101 .channel_mode = alc885_mba21_ch_modes, 10102 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes), 10103 .input_mux = &alc889A_imac91_capture_source, 10104 .dig_out_nid = ALC882_DIGOUT_NID, 10105 .dig_in_nid = ALC882_DIGIN_NID, 10106 .unsol_event = alc_automute_amp_unsol_event, 10107 .setup = alc885_imac91_setup, 10108 .init_hook = alc_automute_amp, 10109 }, 10110 [ALC882_TARGA] = { 10111 .mixers = { alc882_targa_mixer, alc882_chmode_mixer }, 10112 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs, 10113 alc880_gpio3_init_verbs, alc882_targa_verbs}, 10114 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 10115 .dac_nids = alc882_dac_nids, 10116 .dig_out_nid = ALC882_DIGOUT_NID, 10117 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids), 10118 .adc_nids = alc882_adc_nids, 10119 .capsrc_nids = alc882_capsrc_nids, 10120 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes), 10121 .channel_mode = alc882_3ST_6ch_modes, 10122 .need_dac_fix = 1, 10123 .input_mux = &alc882_capture_source, 10124 .unsol_event = alc882_targa_unsol_event, 10125 .setup = alc882_targa_setup, 10126 .init_hook = alc882_targa_automute, 10127 }, 10128 [ALC882_ASUS_A7J] = { 10129 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer }, 10130 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs, 10131 alc882_asus_a7j_verbs}, 10132 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 10133 .dac_nids = alc882_dac_nids, 10134 .dig_out_nid = ALC882_DIGOUT_NID, 10135 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids), 10136 .adc_nids = alc882_adc_nids, 10137 .capsrc_nids = alc882_capsrc_nids, 10138 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes), 10139 .channel_mode = alc882_3ST_6ch_modes, 10140 .need_dac_fix = 1, 10141 .input_mux = &alc882_capture_source, 10142 }, 10143 [ALC882_ASUS_A7M] = { 10144 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer }, 10145 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs, 10146 alc882_eapd_verbs, alc880_gpio1_init_verbs, 10147 alc882_asus_a7m_verbs }, 10148 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 10149 .dac_nids = alc882_dac_nids, 10150 .dig_out_nid = ALC882_DIGOUT_NID, 10151 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), 10152 .channel_mode = alc880_threestack_modes, 10153 .need_dac_fix = 1, 10154 .input_mux = &alc882_capture_source, 10155 }, 10156 [ALC883_3ST_2ch_DIG] = { 10157 .mixers = { alc883_3ST_2ch_mixer }, 10158 .init_verbs = { alc883_init_verbs }, 10159 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10160 .dac_nids = alc883_dac_nids, 10161 .dig_out_nid = ALC883_DIGOUT_NID, 10162 .dig_in_nid = ALC883_DIGIN_NID, 10163 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10164 .channel_mode = alc883_3ST_2ch_modes, 10165 .input_mux = &alc883_capture_source, 10166 }, 10167 [ALC883_3ST_6ch_DIG] = { 10168 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, 10169 .init_verbs = { alc883_init_verbs }, 10170 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10171 .dac_nids = alc883_dac_nids, 10172 .dig_out_nid = ALC883_DIGOUT_NID, 10173 .dig_in_nid = ALC883_DIGIN_NID, 10174 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 10175 .channel_mode = alc883_3ST_6ch_modes, 10176 .need_dac_fix = 1, 10177 .input_mux = &alc883_capture_source, 10178 }, 10179 [ALC883_3ST_6ch] = { 10180 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, 10181 .init_verbs = { alc883_init_verbs }, 10182 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10183 .dac_nids = alc883_dac_nids, 10184 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 10185 .channel_mode = alc883_3ST_6ch_modes, 10186 .need_dac_fix = 1, 10187 .input_mux = &alc883_capture_source, 10188 }, 10189 [ALC883_3ST_6ch_INTEL] = { 10190 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer }, 10191 .init_verbs = { alc883_init_verbs }, 10192 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10193 .dac_nids = alc883_dac_nids, 10194 .dig_out_nid = ALC883_DIGOUT_NID, 10195 .dig_in_nid = ALC883_DIGIN_NID, 10196 .slave_dig_outs = alc883_slave_dig_outs, 10197 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes), 10198 .channel_mode = alc883_3ST_6ch_intel_modes, 10199 .need_dac_fix = 1, 10200 .input_mux = &alc883_3stack_6ch_intel, 10201 }, 10202 [ALC889A_INTEL] = { 10203 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer }, 10204 .init_verbs = { alc885_init_verbs, alc885_init_input_verbs, 10205 alc_hp15_unsol_verbs }, 10206 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10207 .dac_nids = alc883_dac_nids, 10208 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids), 10209 .adc_nids = alc889_adc_nids, 10210 .dig_out_nid = ALC883_DIGOUT_NID, 10211 .dig_in_nid = ALC883_DIGIN_NID, 10212 .slave_dig_outs = alc883_slave_dig_outs, 10213 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes), 10214 .channel_mode = alc889_8ch_intel_modes, 10215 .capsrc_nids = alc889_capsrc_nids, 10216 .input_mux = &alc889_capture_source, 10217 .setup = alc889_automute_setup, 10218 .init_hook = alc_automute_amp, 10219 .unsol_event = alc_automute_amp_unsol_event, 10220 .need_dac_fix = 1, 10221 }, 10222 [ALC889_INTEL] = { 10223 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer }, 10224 .init_verbs = { alc885_init_verbs, alc889_init_input_verbs, 10225 alc889_eapd_verbs, alc_hp15_unsol_verbs}, 10226 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10227 .dac_nids = alc883_dac_nids, 10228 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids), 10229 .adc_nids = alc889_adc_nids, 10230 .dig_out_nid = ALC883_DIGOUT_NID, 10231 .dig_in_nid = ALC883_DIGIN_NID, 10232 .slave_dig_outs = alc883_slave_dig_outs, 10233 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes), 10234 .channel_mode = alc889_8ch_intel_modes, 10235 .capsrc_nids = alc889_capsrc_nids, 10236 .input_mux = &alc889_capture_source, 10237 .setup = alc889_automute_setup, 10238 .init_hook = alc889_intel_init_hook, 10239 .unsol_event = alc_automute_amp_unsol_event, 10240 .need_dac_fix = 1, 10241 }, 10242 [ALC883_6ST_DIG] = { 10243 .mixers = { alc883_base_mixer, alc883_chmode_mixer }, 10244 .init_verbs = { alc883_init_verbs }, 10245 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10246 .dac_nids = alc883_dac_nids, 10247 .dig_out_nid = ALC883_DIGOUT_NID, 10248 .dig_in_nid = ALC883_DIGIN_NID, 10249 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), 10250 .channel_mode = alc883_sixstack_modes, 10251 .input_mux = &alc883_capture_source, 10252 }, 10253 [ALC883_TARGA_DIG] = { 10254 .mixers = { alc883_targa_mixer, alc883_chmode_mixer }, 10255 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs, 10256 alc883_targa_verbs}, 10257 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10258 .dac_nids = alc883_dac_nids, 10259 .dig_out_nid = ALC883_DIGOUT_NID, 10260 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 10261 .channel_mode = alc883_3ST_6ch_modes, 10262 .need_dac_fix = 1, 10263 .input_mux = &alc883_capture_source, 10264 .unsol_event = alc883_targa_unsol_event, 10265 .setup = alc882_targa_setup, 10266 .init_hook = alc882_targa_automute, 10267 }, 10268 [ALC883_TARGA_2ch_DIG] = { 10269 .mixers = { alc883_targa_2ch_mixer}, 10270 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs, 10271 alc883_targa_verbs}, 10272 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10273 .dac_nids = alc883_dac_nids, 10274 .adc_nids = alc883_adc_nids_alt, 10275 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt), 10276 .capsrc_nids = alc883_capsrc_nids, 10277 .dig_out_nid = ALC883_DIGOUT_NID, 10278 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10279 .channel_mode = alc883_3ST_2ch_modes, 10280 .input_mux = &alc883_capture_source, 10281 .unsol_event = alc883_targa_unsol_event, 10282 .setup = alc882_targa_setup, 10283 .init_hook = alc882_targa_automute, 10284 }, 10285 [ALC883_TARGA_8ch_DIG] = { 10286 .mixers = { alc883_targa_mixer, alc883_targa_8ch_mixer, 10287 alc883_chmode_mixer }, 10288 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs, 10289 alc883_targa_verbs }, 10290 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10291 .dac_nids = alc883_dac_nids, 10292 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev), 10293 .adc_nids = alc883_adc_nids_rev, 10294 .capsrc_nids = alc883_capsrc_nids_rev, 10295 .dig_out_nid = ALC883_DIGOUT_NID, 10296 .dig_in_nid = ALC883_DIGIN_NID, 10297 .num_channel_mode = ARRAY_SIZE(alc883_4ST_8ch_modes), 10298 .channel_mode = alc883_4ST_8ch_modes, 10299 .need_dac_fix = 1, 10300 .input_mux = &alc883_capture_source, 10301 .unsol_event = alc883_targa_unsol_event, 10302 .setup = alc882_targa_setup, 10303 .init_hook = alc882_targa_automute, 10304 }, 10305 [ALC883_ACER] = { 10306 .mixers = { alc883_base_mixer }, 10307 /* On TravelMate laptops, GPIO 0 enables the internal speaker 10308 * and the headphone jack. Turn this on and rely on the 10309 * standard mute methods whenever the user wants to turn 10310 * these outputs off. 10311 */ 10312 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs }, 10313 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10314 .dac_nids = alc883_dac_nids, 10315 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10316 .channel_mode = alc883_3ST_2ch_modes, 10317 .input_mux = &alc883_capture_source, 10318 }, 10319 [ALC883_ACER_ASPIRE] = { 10320 .mixers = { alc883_acer_aspire_mixer }, 10321 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs }, 10322 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10323 .dac_nids = alc883_dac_nids, 10324 .dig_out_nid = ALC883_DIGOUT_NID, 10325 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10326 .channel_mode = alc883_3ST_2ch_modes, 10327 .input_mux = &alc883_capture_source, 10328 .unsol_event = alc_automute_amp_unsol_event, 10329 .setup = alc883_acer_aspire_setup, 10330 .init_hook = alc_automute_amp, 10331 }, 10332 [ALC888_ACER_ASPIRE_4930G] = { 10333 .mixers = { alc888_acer_aspire_4930g_mixer, 10334 alc883_chmode_mixer }, 10335 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs, 10336 alc888_acer_aspire_4930g_verbs }, 10337 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10338 .dac_nids = alc883_dac_nids, 10339 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev), 10340 .adc_nids = alc883_adc_nids_rev, 10341 .capsrc_nids = alc883_capsrc_nids_rev, 10342 .dig_out_nid = ALC883_DIGOUT_NID, 10343 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 10344 .channel_mode = alc883_3ST_6ch_modes, 10345 .need_dac_fix = 1, 10346 .const_channel_count = 6, 10347 .num_mux_defs = 10348 ARRAY_SIZE(alc888_2_capture_sources), 10349 .input_mux = alc888_2_capture_sources, 10350 .unsol_event = alc_automute_amp_unsol_event, 10351 .setup = alc888_acer_aspire_4930g_setup, 10352 .init_hook = alc_automute_amp, 10353 }, 10354 [ALC888_ACER_ASPIRE_6530G] = { 10355 .mixers = { alc888_acer_aspire_6530_mixer }, 10356 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs, 10357 alc888_acer_aspire_6530g_verbs }, 10358 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10359 .dac_nids = alc883_dac_nids, 10360 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev), 10361 .adc_nids = alc883_adc_nids_rev, 10362 .capsrc_nids = alc883_capsrc_nids_rev, 10363 .dig_out_nid = ALC883_DIGOUT_NID, 10364 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10365 .channel_mode = alc883_3ST_2ch_modes, 10366 .num_mux_defs = 10367 ARRAY_SIZE(alc888_2_capture_sources), 10368 .input_mux = alc888_acer_aspire_6530_sources, 10369 .unsol_event = alc_automute_amp_unsol_event, 10370 .setup = alc888_acer_aspire_6530g_setup, 10371 .init_hook = alc_automute_amp, 10372 }, 10373 [ALC888_ACER_ASPIRE_8930G] = { 10374 .mixers = { alc889_acer_aspire_8930g_mixer, 10375 alc883_chmode_mixer }, 10376 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs, 10377 alc889_acer_aspire_8930g_verbs, 10378 alc889_eapd_verbs}, 10379 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10380 .dac_nids = alc883_dac_nids, 10381 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids), 10382 .adc_nids = alc889_adc_nids, 10383 .capsrc_nids = alc889_capsrc_nids, 10384 .dig_out_nid = ALC883_DIGOUT_NID, 10385 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 10386 .channel_mode = alc883_3ST_6ch_modes, 10387 .need_dac_fix = 1, 10388 .const_channel_count = 6, 10389 .num_mux_defs = 10390 ARRAY_SIZE(alc889_capture_sources), 10391 .input_mux = alc889_capture_sources, 10392 .unsol_event = alc_automute_amp_unsol_event, 10393 .setup = alc889_acer_aspire_8930g_setup, 10394 .init_hook = alc_automute_amp, 10395#ifdef CONFIG_SND_HDA_POWER_SAVE 10396 .power_hook = alc_power_eapd, 10397#endif 10398 }, 10399 [ALC888_ACER_ASPIRE_7730G] = { 10400 .mixers = { alc883_3ST_6ch_mixer, 10401 alc883_chmode_mixer }, 10402 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs, 10403 alc888_acer_aspire_7730G_verbs }, 10404 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10405 .dac_nids = alc883_dac_nids, 10406 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev), 10407 .adc_nids = alc883_adc_nids_rev, 10408 .capsrc_nids = alc883_capsrc_nids_rev, 10409 .dig_out_nid = ALC883_DIGOUT_NID, 10410 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 10411 .channel_mode = alc883_3ST_6ch_modes, 10412 .need_dac_fix = 1, 10413 .const_channel_count = 6, 10414 .input_mux = &alc883_capture_source, 10415 .unsol_event = alc_automute_amp_unsol_event, 10416 .setup = alc888_acer_aspire_7730g_setup, 10417 .init_hook = alc_automute_amp, 10418 }, 10419 [ALC883_MEDION] = { 10420 .mixers = { alc883_fivestack_mixer, 10421 alc883_chmode_mixer }, 10422 .init_verbs = { alc883_init_verbs, 10423 alc883_medion_eapd_verbs }, 10424 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10425 .dac_nids = alc883_dac_nids, 10426 .adc_nids = alc883_adc_nids_alt, 10427 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt), 10428 .capsrc_nids = alc883_capsrc_nids, 10429 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), 10430 .channel_mode = alc883_sixstack_modes, 10431 .input_mux = &alc883_capture_source, 10432 }, 10433 [ALC883_MEDION_WIM2160] = { 10434 .mixers = { alc883_medion_wim2160_mixer }, 10435 .init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs }, 10436 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10437 .dac_nids = alc883_dac_nids, 10438 .dig_out_nid = ALC883_DIGOUT_NID, 10439 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 10440 .adc_nids = alc883_adc_nids, 10441 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10442 .channel_mode = alc883_3ST_2ch_modes, 10443 .input_mux = &alc883_capture_source, 10444 .unsol_event = alc_automute_amp_unsol_event, 10445 .setup = alc883_medion_wim2160_setup, 10446 .init_hook = alc_automute_amp, 10447 }, 10448 [ALC883_LAPTOP_EAPD] = { 10449 .mixers = { alc883_base_mixer }, 10450 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs }, 10451 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10452 .dac_nids = alc883_dac_nids, 10453 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10454 .channel_mode = alc883_3ST_2ch_modes, 10455 .input_mux = &alc883_capture_source, 10456 }, 10457 [ALC883_CLEVO_M540R] = { 10458 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, 10459 .init_verbs = { alc883_init_verbs, alc883_clevo_m540r_verbs }, 10460 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10461 .dac_nids = alc883_dac_nids, 10462 .dig_out_nid = ALC883_DIGOUT_NID, 10463 .dig_in_nid = ALC883_DIGIN_NID, 10464 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_clevo_modes), 10465 .channel_mode = alc883_3ST_6ch_clevo_modes, 10466 .need_dac_fix = 1, 10467 .input_mux = &alc883_capture_source, 10468 /* This machine has the hardware HP auto-muting, thus 10469 * we need no software mute via unsol event 10470 */ 10471 }, 10472 [ALC883_CLEVO_M720] = { 10473 .mixers = { alc883_clevo_m720_mixer }, 10474 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs }, 10475 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10476 .dac_nids = alc883_dac_nids, 10477 .dig_out_nid = ALC883_DIGOUT_NID, 10478 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10479 .channel_mode = alc883_3ST_2ch_modes, 10480 .input_mux = &alc883_capture_source, 10481 .unsol_event = alc883_clevo_m720_unsol_event, 10482 .setup = alc883_clevo_m720_setup, 10483 .init_hook = alc883_clevo_m720_init_hook, 10484 }, 10485 [ALC883_LENOVO_101E_2ch] = { 10486 .mixers = { alc883_lenovo_101e_2ch_mixer}, 10487 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs}, 10488 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10489 .dac_nids = alc883_dac_nids, 10490 .adc_nids = alc883_adc_nids_alt, 10491 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt), 10492 .capsrc_nids = alc883_capsrc_nids, 10493 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10494 .channel_mode = alc883_3ST_2ch_modes, 10495 .input_mux = &alc883_lenovo_101e_capture_source, 10496 .unsol_event = alc883_lenovo_101e_unsol_event, 10497 .init_hook = alc883_lenovo_101e_all_automute, 10498 }, 10499 [ALC883_LENOVO_NB0763] = { 10500 .mixers = { alc883_lenovo_nb0763_mixer }, 10501 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs}, 10502 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10503 .dac_nids = alc883_dac_nids, 10504 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10505 .channel_mode = alc883_3ST_2ch_modes, 10506 .need_dac_fix = 1, 10507 .input_mux = &alc883_lenovo_nb0763_capture_source, 10508 .unsol_event = alc_automute_amp_unsol_event, 10509 .setup = alc883_lenovo_nb0763_setup, 10510 .init_hook = alc_automute_amp, 10511 }, 10512 [ALC888_LENOVO_MS7195_DIG] = { 10513 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, 10514 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs}, 10515 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10516 .dac_nids = alc883_dac_nids, 10517 .dig_out_nid = ALC883_DIGOUT_NID, 10518 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 10519 .channel_mode = alc883_3ST_6ch_modes, 10520 .need_dac_fix = 1, 10521 .input_mux = &alc883_capture_source, 10522 .unsol_event = alc883_lenovo_ms7195_unsol_event, 10523 .init_hook = alc888_lenovo_ms7195_front_automute, 10524 }, 10525 [ALC883_HAIER_W66] = { 10526 .mixers = { alc883_targa_2ch_mixer}, 10527 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs}, 10528 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10529 .dac_nids = alc883_dac_nids, 10530 .dig_out_nid = ALC883_DIGOUT_NID, 10531 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10532 .channel_mode = alc883_3ST_2ch_modes, 10533 .input_mux = &alc883_capture_source, 10534 .unsol_event = alc_automute_amp_unsol_event, 10535 .setup = alc883_haier_w66_setup, 10536 .init_hook = alc_automute_amp, 10537 }, 10538 [ALC888_3ST_HP] = { 10539 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, 10540 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs }, 10541 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10542 .dac_nids = alc883_dac_nids, 10543 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes), 10544 .channel_mode = alc888_3st_hp_modes, 10545 .need_dac_fix = 1, 10546 .input_mux = &alc883_capture_source, 10547 .unsol_event = alc_automute_amp_unsol_event, 10548 .setup = alc888_3st_hp_setup, 10549 .init_hook = alc_automute_amp, 10550 }, 10551 [ALC888_6ST_DELL] = { 10552 .mixers = { alc883_base_mixer, alc883_chmode_mixer }, 10553 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs }, 10554 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10555 .dac_nids = alc883_dac_nids, 10556 .dig_out_nid = ALC883_DIGOUT_NID, 10557 .dig_in_nid = ALC883_DIGIN_NID, 10558 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), 10559 .channel_mode = alc883_sixstack_modes, 10560 .input_mux = &alc883_capture_source, 10561 .unsol_event = alc_automute_amp_unsol_event, 10562 .setup = alc888_6st_dell_setup, 10563 .init_hook = alc_automute_amp, 10564 }, 10565 [ALC883_MITAC] = { 10566 .mixers = { alc883_mitac_mixer }, 10567 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs }, 10568 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10569 .dac_nids = alc883_dac_nids, 10570 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10571 .channel_mode = alc883_3ST_2ch_modes, 10572 .input_mux = &alc883_capture_source, 10573 .unsol_event = alc_automute_amp_unsol_event, 10574 .setup = alc883_mitac_setup, 10575 .init_hook = alc_automute_amp, 10576 }, 10577 [ALC883_FUJITSU_PI2515] = { 10578 .mixers = { alc883_2ch_fujitsu_pi2515_mixer }, 10579 .init_verbs = { alc883_init_verbs, 10580 alc883_2ch_fujitsu_pi2515_verbs}, 10581 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10582 .dac_nids = alc883_dac_nids, 10583 .dig_out_nid = ALC883_DIGOUT_NID, 10584 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10585 .channel_mode = alc883_3ST_2ch_modes, 10586 .input_mux = &alc883_fujitsu_pi2515_capture_source, 10587 .unsol_event = alc_automute_amp_unsol_event, 10588 .setup = alc883_2ch_fujitsu_pi2515_setup, 10589 .init_hook = alc_automute_amp, 10590 }, 10591 [ALC888_FUJITSU_XA3530] = { 10592 .mixers = { alc888_base_mixer, alc883_chmode_mixer }, 10593 .init_verbs = { alc883_init_verbs, 10594 alc888_fujitsu_xa3530_verbs }, 10595 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10596 .dac_nids = alc883_dac_nids, 10597 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev), 10598 .adc_nids = alc883_adc_nids_rev, 10599 .capsrc_nids = alc883_capsrc_nids_rev, 10600 .dig_out_nid = ALC883_DIGOUT_NID, 10601 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes), 10602 .channel_mode = alc888_4ST_8ch_intel_modes, 10603 .num_mux_defs = 10604 ARRAY_SIZE(alc888_2_capture_sources), 10605 .input_mux = alc888_2_capture_sources, 10606 .unsol_event = alc_automute_amp_unsol_event, 10607 .setup = alc888_fujitsu_xa3530_setup, 10608 .init_hook = alc_automute_amp, 10609 }, 10610 [ALC888_LENOVO_SKY] = { 10611 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer }, 10612 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs}, 10613 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10614 .dac_nids = alc883_dac_nids, 10615 .dig_out_nid = ALC883_DIGOUT_NID, 10616 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), 10617 .channel_mode = alc883_sixstack_modes, 10618 .need_dac_fix = 1, 10619 .input_mux = &alc883_lenovo_sky_capture_source, 10620 .unsol_event = alc_automute_amp_unsol_event, 10621 .setup = alc888_lenovo_sky_setup, 10622 .init_hook = alc_automute_amp, 10623 }, 10624 [ALC888_ASUS_M90V] = { 10625 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, 10626 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs }, 10627 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10628 .dac_nids = alc883_dac_nids, 10629 .dig_out_nid = ALC883_DIGOUT_NID, 10630 .dig_in_nid = ALC883_DIGIN_NID, 10631 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 10632 .channel_mode = alc883_3ST_6ch_modes, 10633 .need_dac_fix = 1, 10634 .input_mux = &alc883_fujitsu_pi2515_capture_source, 10635 .unsol_event = alc_sku_unsol_event, 10636 .setup = alc883_mode2_setup, 10637 .init_hook = alc_inithook, 10638 }, 10639 [ALC888_ASUS_EEE1601] = { 10640 .mixers = { alc883_asus_eee1601_mixer }, 10641 .cap_mixer = alc883_asus_eee1601_cap_mixer, 10642 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs }, 10643 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10644 .dac_nids = alc883_dac_nids, 10645 .dig_out_nid = ALC883_DIGOUT_NID, 10646 .dig_in_nid = ALC883_DIGIN_NID, 10647 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10648 .channel_mode = alc883_3ST_2ch_modes, 10649 .need_dac_fix = 1, 10650 .input_mux = &alc883_asus_eee1601_capture_source, 10651 .unsol_event = alc_sku_unsol_event, 10652 .init_hook = alc883_eee1601_inithook, 10653 }, 10654 [ALC1200_ASUS_P5Q] = { 10655 .mixers = { alc883_base_mixer, alc883_chmode_mixer }, 10656 .init_verbs = { alc883_init_verbs }, 10657 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10658 .dac_nids = alc883_dac_nids, 10659 .dig_out_nid = ALC1200_DIGOUT_NID, 10660 .dig_in_nid = ALC883_DIGIN_NID, 10661 .slave_dig_outs = alc1200_slave_dig_outs, 10662 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), 10663 .channel_mode = alc883_sixstack_modes, 10664 .input_mux = &alc883_capture_source, 10665 }, 10666 [ALC889A_MB31] = { 10667 .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer}, 10668 .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs, 10669 alc880_gpio1_init_verbs }, 10670 .adc_nids = alc883_adc_nids, 10671 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 10672 .capsrc_nids = alc883_capsrc_nids, 10673 .dac_nids = alc883_dac_nids, 10674 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10675 .channel_mode = alc889A_mb31_6ch_modes, 10676 .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes), 10677 .input_mux = &alc889A_mb31_capture_source, 10678 .dig_out_nid = ALC883_DIGOUT_NID, 10679 .unsol_event = alc889A_mb31_unsol_event, 10680 .init_hook = alc889A_mb31_automute, 10681 }, 10682 [ALC883_SONY_VAIO_TT] = { 10683 .mixers = { alc883_vaiott_mixer }, 10684 .init_verbs = { alc883_init_verbs, alc883_vaiott_verbs }, 10685 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10686 .dac_nids = alc883_dac_nids, 10687 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10688 .channel_mode = alc883_3ST_2ch_modes, 10689 .input_mux = &alc883_capture_source, 10690 .unsol_event = alc_automute_amp_unsol_event, 10691 .setup = alc883_vaiott_setup, 10692 .init_hook = alc_automute_amp, 10693 }, 10694}; 10695 10696 10697/* 10698 * Pin config fixes 10699 */ 10700enum { 10701 PINFIX_ABIT_AW9D_MAX, 10702 PINFIX_LENOVO_Y530, 10703 PINFIX_PB_M5210, 10704 PINFIX_ACER_ASPIRE_7736, 10705 PINFIX_GIGABYTE_880GM, 10706}; 10707 10708static const struct alc_fixup alc882_fixups[] = { 10709 [PINFIX_ABIT_AW9D_MAX] = { 10710 .type = ALC_FIXUP_PINS, 10711 .v.pins = (const struct alc_pincfg[]) { 10712 { 0x15, 0x01080104 }, /* side */ 10713 { 0x16, 0x01011012 }, /* rear */ 10714 { 0x17, 0x01016011 }, /* clfe */ 10715 { } 10716 } 10717 }, 10718 [PINFIX_LENOVO_Y530] = { 10719 .type = ALC_FIXUP_PINS, 10720 .v.pins = (const struct alc_pincfg[]) { 10721 { 0x15, 0x99130112 }, /* rear int speakers */ 10722 { 0x16, 0x99130111 }, /* subwoofer */ 10723 { } 10724 } 10725 }, 10726 [PINFIX_PB_M5210] = { 10727 .type = ALC_FIXUP_VERBS, 10728 .v.verbs = (const struct hda_verb[]) { 10729 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 }, 10730 {} 10731 } 10732 }, 10733 [PINFIX_ACER_ASPIRE_7736] = { 10734 .type = ALC_FIXUP_SKU, 10735 .v.sku = ALC_FIXUP_SKU_IGNORE, 10736 }, 10737 [PINFIX_GIGABYTE_880GM] = { 10738 .type = ALC_FIXUP_PINS, 10739 .v.pins = (const struct alc_pincfg[]) { 10740 { 0x14, 0x1114410 }, /* set as speaker */ 10741 { } 10742 } 10743 }, 10744}; 10745 10746static struct snd_pci_quirk alc882_fixup_tbl[] = { 10747 SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", PINFIX_PB_M5210), 10748 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", PINFIX_LENOVO_Y530), 10749 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX), 10750 SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", PINFIX_ACER_ASPIRE_7736), 10751 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte", PINFIX_GIGABYTE_880GM), 10752 {} 10753}; 10754 10755/* 10756 * BIOS auto configuration 10757 */ 10758static int alc882_auto_create_input_ctls(struct hda_codec *codec, 10759 const struct auto_pin_cfg *cfg) 10760{ 10761 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x23, 0x22); 10762} 10763 10764static void alc882_auto_set_output_and_unmute(struct hda_codec *codec, 10765 hda_nid_t nid, int pin_type, 10766 hda_nid_t dac) 10767{ 10768 int idx; 10769 10770 /* set as output */ 10771 alc_set_pin_output(codec, nid, pin_type); 10772 10773 if (dac == 0x25) 10774 idx = 4; 10775 else if (dac >= 0x02 && dac <= 0x05) 10776 idx = dac - 2; 10777 else 10778 return; 10779 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx); 10780} 10781 10782static void alc882_auto_init_multi_out(struct hda_codec *codec) 10783{ 10784 struct alc_spec *spec = codec->spec; 10785 int i; 10786 10787 for (i = 0; i <= HDA_SIDE; i++) { 10788 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 10789 int pin_type = get_pin_type(spec->autocfg.line_out_type); 10790 if (nid) 10791 alc882_auto_set_output_and_unmute(codec, nid, pin_type, 10792 spec->multiout.dac_nids[i]); 10793 } 10794} 10795 10796static void alc882_auto_init_hp_out(struct hda_codec *codec) 10797{ 10798 struct alc_spec *spec = codec->spec; 10799 hda_nid_t pin, dac; 10800 int i; 10801 10802 if (spec->autocfg.line_out_type != AUTO_PIN_HP_OUT) { 10803 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) { 10804 pin = spec->autocfg.hp_pins[i]; 10805 if (!pin) 10806 break; 10807 dac = spec->multiout.hp_nid; 10808 if (!dac) 10809 dac = spec->multiout.dac_nids[0]; /* to front */ 10810 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, dac); 10811 } 10812 } 10813 10814 if (spec->autocfg.line_out_type != AUTO_PIN_SPEAKER_OUT) { 10815 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) { 10816 pin = spec->autocfg.speaker_pins[i]; 10817 if (!pin) 10818 break; 10819 dac = spec->multiout.extra_out_nid[0]; 10820 if (!dac) 10821 dac = spec->multiout.dac_nids[0]; /* to front */ 10822 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac); 10823 } 10824 } 10825} 10826 10827static void alc882_auto_init_analog_input(struct hda_codec *codec) 10828{ 10829 struct alc_spec *spec = codec->spec; 10830 struct auto_pin_cfg *cfg = &spec->autocfg; 10831 int i; 10832 10833 for (i = 0; i < cfg->num_inputs; i++) { 10834 hda_nid_t nid = cfg->inputs[i].pin; 10835 alc_set_input_pin(codec, nid, cfg->inputs[i].type); 10836 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP) 10837 snd_hda_codec_write(codec, nid, 0, 10838 AC_VERB_SET_AMP_GAIN_MUTE, 10839 AMP_OUT_MUTE); 10840 } 10841} 10842 10843static void alc882_auto_init_input_src(struct hda_codec *codec) 10844{ 10845 struct alc_spec *spec = codec->spec; 10846 int c; 10847 10848 for (c = 0; c < spec->num_adc_nids; c++) { 10849 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS]; 10850 hda_nid_t nid = spec->capsrc_nids[c]; 10851 unsigned int mux_idx; 10852 const struct hda_input_mux *imux; 10853 int conns, mute, idx, item; 10854 10855 /* mute ADC */ 10856 snd_hda_codec_write(codec, spec->adc_nids[c], 0, 10857 AC_VERB_SET_AMP_GAIN_MUTE, 10858 AMP_IN_MUTE(0)); 10859 10860 conns = snd_hda_get_connections(codec, nid, conn_list, 10861 ARRAY_SIZE(conn_list)); 10862 if (conns < 0) 10863 continue; 10864 mux_idx = c >= spec->num_mux_defs ? 0 : c; 10865 imux = &spec->input_mux[mux_idx]; 10866 if (!imux->num_items && mux_idx > 0) 10867 imux = &spec->input_mux[0]; 10868 for (idx = 0; idx < conns; idx++) { 10869 /* if the current connection is the selected one, 10870 * unmute it as default - otherwise mute it 10871 */ 10872 mute = AMP_IN_MUTE(idx); 10873 for (item = 0; item < imux->num_items; item++) { 10874 if (imux->items[item].index == idx) { 10875 if (spec->cur_mux[c] == item) 10876 mute = AMP_IN_UNMUTE(idx); 10877 break; 10878 } 10879 } 10880 /* check if we have a selector or mixer 10881 * we could check for the widget type instead, but 10882 * just check for Amp-In presence (in case of mixer 10883 * without amp-in there is something wrong, this 10884 * function shouldn't be used or capsrc nid is wrong) 10885 */ 10886 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) 10887 snd_hda_codec_write(codec, nid, 0, 10888 AC_VERB_SET_AMP_GAIN_MUTE, 10889 mute); 10890 else if (mute != AMP_IN_MUTE(idx)) 10891 snd_hda_codec_write(codec, nid, 0, 10892 AC_VERB_SET_CONNECT_SEL, 10893 idx); 10894 } 10895 } 10896} 10897 10898/* add mic boosts if needed */ 10899static int alc_auto_add_mic_boost(struct hda_codec *codec) 10900{ 10901 struct alc_spec *spec = codec->spec; 10902 struct auto_pin_cfg *cfg = &spec->autocfg; 10903 int i, err; 10904 int type_idx = 0; 10905 hda_nid_t nid; 10906 const char *prev_label = NULL; 10907 10908 for (i = 0; i < cfg->num_inputs; i++) { 10909 if (cfg->inputs[i].type > AUTO_PIN_MIC) 10910 break; 10911 nid = cfg->inputs[i].pin; 10912 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) { 10913 const char *label; 10914 char boost_label[32]; 10915 10916 label = hda_get_autocfg_input_label(codec, cfg, i); 10917 if (prev_label && !strcmp(label, prev_label)) 10918 type_idx++; 10919 else 10920 type_idx = 0; 10921 prev_label = label; 10922 10923 snprintf(boost_label, sizeof(boost_label), 10924 "%s Boost Volume", label); 10925 err = add_control(spec, ALC_CTL_WIDGET_VOL, 10926 boost_label, type_idx, 10927 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT)); 10928 if (err < 0) 10929 return err; 10930 } 10931 } 10932 return 0; 10933} 10934 10935/* almost identical with ALC880 parser... */ 10936static int alc882_parse_auto_config(struct hda_codec *codec) 10937{ 10938 struct alc_spec *spec = codec->spec; 10939 static hda_nid_t alc882_ignore[] = { 0x1d, 0 }; 10940 int err; 10941 10942 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 10943 alc882_ignore); 10944 if (err < 0) 10945 return err; 10946 if (!spec->autocfg.line_outs) 10947 return 0; /* can't find valid BIOS pin config */ 10948 10949 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); 10950 if (err < 0) 10951 return err; 10952 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg); 10953 if (err < 0) 10954 return err; 10955 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0], 10956 "Headphone"); 10957 if (err < 0) 10958 return err; 10959 err = alc880_auto_create_extra_out(spec, 10960 spec->autocfg.speaker_pins[0], 10961 "Speaker"); 10962 if (err < 0) 10963 return err; 10964 err = alc882_auto_create_input_ctls(codec, &spec->autocfg); 10965 if (err < 0) 10966 return err; 10967 10968 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 10969 10970 alc_auto_parse_digital(codec); 10971 10972 if (spec->kctls.list) 10973 add_mixer(spec, spec->kctls.list); 10974 10975 add_verb(spec, alc883_auto_init_verbs); 10976 /* if ADC 0x07 is available, initialize it, too */ 10977 if (get_wcaps_type(get_wcaps(codec, 0x07)) == AC_WID_AUD_IN) 10978 add_verb(spec, alc882_adc1_init_verbs); 10979 10980 spec->num_mux_defs = 1; 10981 spec->input_mux = &spec->private_imux[0]; 10982 10983 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); 10984 10985 err = alc_auto_add_mic_boost(codec); 10986 if (err < 0) 10987 return err; 10988 10989 return 1; /* config found */ 10990} 10991 10992/* additional initialization for auto-configuration model */ 10993static void alc882_auto_init(struct hda_codec *codec) 10994{ 10995 struct alc_spec *spec = codec->spec; 10996 alc882_auto_init_multi_out(codec); 10997 alc882_auto_init_hp_out(codec); 10998 alc882_auto_init_analog_input(codec); 10999 alc882_auto_init_input_src(codec); 11000 alc_auto_init_digital(codec); 11001 if (spec->unsol_event) 11002 alc_inithook(codec); 11003} 11004 11005static int patch_alc882(struct hda_codec *codec) 11006{ 11007 struct alc_spec *spec; 11008 int err, board_config; 11009 11010 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 11011 if (spec == NULL) 11012 return -ENOMEM; 11013 11014 codec->spec = spec; 11015 11016 switch (codec->vendor_id) { 11017 case 0x10ec0882: 11018 case 0x10ec0885: 11019 break; 11020 default: 11021 /* ALC883 and variants */ 11022 alc_fix_pll_init(codec, 0x20, 0x0a, 10); 11023 break; 11024 } 11025 11026 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST, 11027 alc882_models, 11028 alc882_cfg_tbl); 11029 11030 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) 11031 board_config = snd_hda_check_board_codec_sid_config(codec, 11032 ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl); 11033 11034 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) { 11035 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 11036 codec->chip_name); 11037 board_config = ALC882_AUTO; 11038 } 11039 11040 if (board_config == ALC882_AUTO) { 11041 alc_pick_fixup(codec, NULL, alc882_fixup_tbl, alc882_fixups); 11042 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); 11043 } 11044 11045 alc_auto_parse_customize_define(codec); 11046 11047 if (board_config == ALC882_AUTO) { 11048 /* automatic parse from the BIOS config */ 11049 err = alc882_parse_auto_config(codec); 11050 if (err < 0) { 11051 alc_free(codec); 11052 return err; 11053 } else if (!err) { 11054 printk(KERN_INFO 11055 "hda_codec: Cannot set up configuration " 11056 "from BIOS. Using base mode...\n"); 11057 board_config = ALC882_3ST_DIG; 11058 } 11059 } 11060 11061 if (has_cdefine_beep(codec)) { 11062 err = snd_hda_attach_beep_device(codec, 0x1); 11063 if (err < 0) { 11064 alc_free(codec); 11065 return err; 11066 } 11067 } 11068 11069 if (board_config != ALC882_AUTO) 11070 setup_preset(codec, &alc882_presets[board_config]); 11071 11072 spec->stream_analog_playback = &alc882_pcm_analog_playback; 11073 spec->stream_analog_capture = &alc882_pcm_analog_capture; 11074 /* FIXME: setup DAC5 */ 11075 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/ 11076 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture; 11077 11078 spec->stream_digital_playback = &alc882_pcm_digital_playback; 11079 spec->stream_digital_capture = &alc882_pcm_digital_capture; 11080 11081 if (!spec->adc_nids && spec->input_mux) { 11082 int i, j; 11083 spec->num_adc_nids = 0; 11084 for (i = 0; i < ARRAY_SIZE(alc882_adc_nids); i++) { 11085 const struct hda_input_mux *imux = spec->input_mux; 11086 hda_nid_t cap; 11087 hda_nid_t items[16]; 11088 hda_nid_t nid = alc882_adc_nids[i]; 11089 unsigned int wcap = get_wcaps(codec, nid); 11090 /* get type */ 11091 wcap = get_wcaps_type(wcap); 11092 if (wcap != AC_WID_AUD_IN) 11093 continue; 11094 spec->private_adc_nids[spec->num_adc_nids] = nid; 11095 err = snd_hda_get_connections(codec, nid, &cap, 1); 11096 if (err < 0) 11097 continue; 11098 err = snd_hda_get_connections(codec, cap, items, 11099 ARRAY_SIZE(items)); 11100 if (err < 0) 11101 continue; 11102 for (j = 0; j < imux->num_items; j++) 11103 if (imux->items[j].index >= err) 11104 break; 11105 if (j < imux->num_items) 11106 continue; 11107 spec->private_capsrc_nids[spec->num_adc_nids] = cap; 11108 spec->num_adc_nids++; 11109 } 11110 spec->adc_nids = spec->private_adc_nids; 11111 spec->capsrc_nids = spec->private_capsrc_nids; 11112 } 11113 11114 set_capture_mixer(codec); 11115 11116 if (has_cdefine_beep(codec)) 11117 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 11118 11119 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); 11120 11121 spec->vmaster_nid = 0x0c; 11122 11123 codec->patch_ops = alc_patch_ops; 11124 if (board_config == ALC882_AUTO) 11125 spec->init_hook = alc882_auto_init; 11126 11127 alc_init_jacks(codec); 11128#ifdef CONFIG_SND_HDA_POWER_SAVE 11129 if (!spec->loopback.amplist) 11130 spec->loopback.amplist = alc882_loopbacks; 11131#endif 11132 11133 return 0; 11134} 11135 11136 11137/* 11138 * ALC262 support 11139 */ 11140 11141#define ALC262_DIGOUT_NID ALC880_DIGOUT_NID 11142#define ALC262_DIGIN_NID ALC880_DIGIN_NID 11143 11144#define alc262_dac_nids alc260_dac_nids 11145#define alc262_adc_nids alc882_adc_nids 11146#define alc262_adc_nids_alt alc882_adc_nids_alt 11147#define alc262_capsrc_nids alc882_capsrc_nids 11148#define alc262_capsrc_nids_alt alc882_capsrc_nids_alt 11149 11150#define alc262_modes alc260_modes 11151#define alc262_capture_source alc882_capture_source 11152 11153static hda_nid_t alc262_dmic_adc_nids[1] = { 11154 /* ADC0 */ 11155 0x09 11156}; 11157 11158static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 }; 11159 11160static struct snd_kcontrol_new alc262_base_mixer[] = { 11161 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11162 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 11163 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 11164 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 11165 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 11166 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 11167 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11168 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11169 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 11170 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 11171 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 11172 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), 11173 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT), 11174 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 11175 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 11176 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT), 11177 { } /* end */ 11178}; 11179 11180/* update HP, line and mono-out pins according to the master switch */ 11181static void alc262_hp_master_update(struct hda_codec *codec) 11182{ 11183 struct alc_spec *spec = codec->spec; 11184 int val = spec->master_sw; 11185 11186 /* HP & line-out */ 11187 snd_hda_codec_write_cache(codec, 0x1b, 0, 11188 AC_VERB_SET_PIN_WIDGET_CONTROL, 11189 val ? PIN_HP : 0); 11190 snd_hda_codec_write_cache(codec, 0x15, 0, 11191 AC_VERB_SET_PIN_WIDGET_CONTROL, 11192 val ? PIN_HP : 0); 11193 /* mono (speaker) depending on the HP jack sense */ 11194 val = val && !spec->jack_present; 11195 snd_hda_codec_write_cache(codec, 0x16, 0, 11196 AC_VERB_SET_PIN_WIDGET_CONTROL, 11197 val ? PIN_OUT : 0); 11198} 11199 11200static void alc262_hp_bpc_automute(struct hda_codec *codec) 11201{ 11202 struct alc_spec *spec = codec->spec; 11203 11204 spec->jack_present = snd_hda_jack_detect(codec, 0x1b); 11205 alc262_hp_master_update(codec); 11206} 11207 11208static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res) 11209{ 11210 if ((res >> 26) != ALC880_HP_EVENT) 11211 return; 11212 alc262_hp_bpc_automute(codec); 11213} 11214 11215static void alc262_hp_wildwest_automute(struct hda_codec *codec) 11216{ 11217 struct alc_spec *spec = codec->spec; 11218 11219 spec->jack_present = snd_hda_jack_detect(codec, 0x15); 11220 alc262_hp_master_update(codec); 11221} 11222 11223static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec, 11224 unsigned int res) 11225{ 11226 if ((res >> 26) != ALC880_HP_EVENT) 11227 return; 11228 alc262_hp_wildwest_automute(codec); 11229} 11230 11231#define alc262_hp_master_sw_get alc260_hp_master_sw_get 11232 11233static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol, 11234 struct snd_ctl_elem_value *ucontrol) 11235{ 11236 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 11237 struct alc_spec *spec = codec->spec; 11238 int val = !!*ucontrol->value.integer.value; 11239 11240 if (val == spec->master_sw) 11241 return 0; 11242 spec->master_sw = val; 11243 alc262_hp_master_update(codec); 11244 return 1; 11245} 11246 11247#define ALC262_HP_MASTER_SWITCH \ 11248 { \ 11249 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 11250 .name = "Master Playback Switch", \ 11251 .info = snd_ctl_boolean_mono_info, \ 11252 .get = alc262_hp_master_sw_get, \ 11253 .put = alc262_hp_master_sw_put, \ 11254 }, \ 11255 { \ 11256 .iface = NID_MAPPING, \ 11257 .name = "Master Playback Switch", \ 11258 .private_value = 0x15 | (0x16 << 8) | (0x1b << 16), \ 11259 } 11260 11261 11262static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = { 11263 ALC262_HP_MASTER_SWITCH, 11264 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11265 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT), 11266 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 11267 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0, 11268 HDA_OUTPUT), 11269 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0, 11270 HDA_OUTPUT), 11271 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11272 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11273 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 11274 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 11275 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 11276 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), 11277 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 11278 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 11279 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 11280 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 11281 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT), 11282 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT), 11283 { } /* end */ 11284}; 11285 11286static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = { 11287 ALC262_HP_MASTER_SWITCH, 11288 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11289 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 11290 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 11291 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 11292 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0, 11293 HDA_OUTPUT), 11294 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0, 11295 HDA_OUTPUT), 11296 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT), 11297 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT), 11298 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x1a, 0, HDA_INPUT), 11299 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT), 11300 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT), 11301 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 11302 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 11303 { } /* end */ 11304}; 11305 11306static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = { 11307 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11308 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11309 HDA_CODEC_VOLUME("Rear Mic Boost Volume", 0x18, 0, HDA_INPUT), 11310 { } /* end */ 11311}; 11312 11313/* mute/unmute internal speaker according to the hp jack and mute state */ 11314static void alc262_hp_t5735_setup(struct hda_codec *codec) 11315{ 11316 struct alc_spec *spec = codec->spec; 11317 11318 spec->autocfg.hp_pins[0] = 0x15; 11319 spec->autocfg.speaker_pins[0] = 0x14; 11320} 11321 11322static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = { 11323 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11324 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 11325 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 11326 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 11327 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11328 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11329 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 11330 { } /* end */ 11331}; 11332 11333static struct hda_verb alc262_hp_t5735_verbs[] = { 11334 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 11335 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11336 11337 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 11338 { } 11339}; 11340 11341static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = { 11342 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11343 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 11344 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT), 11345 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT), 11346 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT), 11347 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT), 11348 { } /* end */ 11349}; 11350 11351static struct hda_verb alc262_hp_rp5700_verbs[] = { 11352 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 11353 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 11354 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 11355 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 11356 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 11357 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 11358 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 11359 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 11360 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))}, 11361 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))}, 11362 {} 11363}; 11364 11365static struct hda_input_mux alc262_hp_rp5700_capture_source = { 11366 .num_items = 1, 11367 .items = { 11368 { "Line", 0x1 }, 11369 }, 11370}; 11371 11372/* bind hp and internal speaker mute (with plug check) as master switch */ 11373static void alc262_hippo_master_update(struct hda_codec *codec) 11374{ 11375 struct alc_spec *spec = codec->spec; 11376 hda_nid_t hp_nid = spec->autocfg.hp_pins[0]; 11377 hda_nid_t line_nid = spec->autocfg.line_out_pins[0]; 11378 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0]; 11379 unsigned int mute; 11380 11381 /* HP */ 11382 mute = spec->master_sw ? 0 : HDA_AMP_MUTE; 11383 snd_hda_codec_amp_stereo(codec, hp_nid, HDA_OUTPUT, 0, 11384 HDA_AMP_MUTE, mute); 11385 /* mute internal speaker per jack sense */ 11386 if (spec->jack_present) 11387 mute = HDA_AMP_MUTE; 11388 if (line_nid) 11389 snd_hda_codec_amp_stereo(codec, line_nid, HDA_OUTPUT, 0, 11390 HDA_AMP_MUTE, mute); 11391 if (speaker_nid && speaker_nid != line_nid) 11392 snd_hda_codec_amp_stereo(codec, speaker_nid, HDA_OUTPUT, 0, 11393 HDA_AMP_MUTE, mute); 11394} 11395 11396#define alc262_hippo_master_sw_get alc262_hp_master_sw_get 11397 11398static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol, 11399 struct snd_ctl_elem_value *ucontrol) 11400{ 11401 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 11402 struct alc_spec *spec = codec->spec; 11403 int val = !!*ucontrol->value.integer.value; 11404 11405 if (val == spec->master_sw) 11406 return 0; 11407 spec->master_sw = val; 11408 alc262_hippo_master_update(codec); 11409 return 1; 11410} 11411 11412#define ALC262_HIPPO_MASTER_SWITCH \ 11413 { \ 11414 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 11415 .name = "Master Playback Switch", \ 11416 .info = snd_ctl_boolean_mono_info, \ 11417 .get = alc262_hippo_master_sw_get, \ 11418 .put = alc262_hippo_master_sw_put, \ 11419 }, \ 11420 { \ 11421 .iface = NID_MAPPING, \ 11422 .name = "Master Playback Switch", \ 11423 .subdevice = SUBDEV_HP(0) | (SUBDEV_LINE(0) << 8) | \ 11424 (SUBDEV_SPEAKER(0) << 16), \ 11425 } 11426 11427static struct snd_kcontrol_new alc262_hippo_mixer[] = { 11428 ALC262_HIPPO_MASTER_SWITCH, 11429 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11430 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 11431 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 11432 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 11433 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 11434 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11435 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11436 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 11437 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 11438 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 11439 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), 11440 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 11441 { } /* end */ 11442}; 11443 11444static struct snd_kcontrol_new alc262_hippo1_mixer[] = { 11445 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11446 ALC262_HIPPO_MASTER_SWITCH, 11447 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 11448 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 11449 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 11450 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 11451 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11452 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11453 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 11454 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 11455 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 11456 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), 11457 { } /* end */ 11458}; 11459 11460/* mute/unmute internal speaker according to the hp jack and mute state */ 11461static void alc262_hippo_automute(struct hda_codec *codec) 11462{ 11463 struct alc_spec *spec = codec->spec; 11464 hda_nid_t hp_nid = spec->autocfg.hp_pins[0]; 11465 11466 spec->jack_present = snd_hda_jack_detect(codec, hp_nid); 11467 alc262_hippo_master_update(codec); 11468} 11469 11470static void alc262_hippo_unsol_event(struct hda_codec *codec, unsigned int res) 11471{ 11472 if ((res >> 26) != ALC880_HP_EVENT) 11473 return; 11474 alc262_hippo_automute(codec); 11475} 11476 11477static void alc262_hippo_setup(struct hda_codec *codec) 11478{ 11479 struct alc_spec *spec = codec->spec; 11480 11481 spec->autocfg.hp_pins[0] = 0x15; 11482 spec->autocfg.speaker_pins[0] = 0x14; 11483} 11484 11485static void alc262_hippo1_setup(struct hda_codec *codec) 11486{ 11487 struct alc_spec *spec = codec->spec; 11488 11489 spec->autocfg.hp_pins[0] = 0x1b; 11490 spec->autocfg.speaker_pins[0] = 0x14; 11491} 11492 11493 11494static struct snd_kcontrol_new alc262_sony_mixer[] = { 11495 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11496 ALC262_HIPPO_MASTER_SWITCH, 11497 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11498 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11499 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 11500 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 11501 { } /* end */ 11502}; 11503 11504static struct snd_kcontrol_new alc262_benq_t31_mixer[] = { 11505 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11506 ALC262_HIPPO_MASTER_SWITCH, 11507 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 11508 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11509 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11510 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 11511 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 11512 { } /* end */ 11513}; 11514 11515static struct snd_kcontrol_new alc262_tyan_mixer[] = { 11516 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11517 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT), 11518 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT), 11519 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT), 11520 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 11521 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 11522 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11523 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11524 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 11525 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 11526 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 11527 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), 11528 { } /* end */ 11529}; 11530 11531static struct hda_verb alc262_tyan_verbs[] = { 11532 /* Headphone automute */ 11533 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 11534 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11535 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 11536 11537 /* P11 AUX_IN, white 4-pin connector */ 11538 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 11539 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1}, 11540 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93}, 11541 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19}, 11542 11543 {} 11544}; 11545 11546/* unsolicited event for HP jack sensing */ 11547static void alc262_tyan_setup(struct hda_codec *codec) 11548{ 11549 struct alc_spec *spec = codec->spec; 11550 11551 spec->autocfg.hp_pins[0] = 0x1b; 11552 spec->autocfg.speaker_pins[0] = 0x15; 11553} 11554 11555 11556#define alc262_capture_mixer alc882_capture_mixer 11557#define alc262_capture_alt_mixer alc882_capture_alt_mixer 11558 11559/* 11560 * generic initialization of ADC, input mixers and output mixers 11561 */ 11562static struct hda_verb alc262_init_verbs[] = { 11563 /* 11564 * Unmute ADC0-2 and set the default input to mic-in 11565 */ 11566 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 11567 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11568 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 11569 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11570 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 11571 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11572 11573 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 11574 * mixer widget 11575 * Note: PASD motherboards uses the Line In 2 as the input for 11576 * front panel mic (mic 2) 11577 */ 11578 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 11579 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 11580 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 11581 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 11582 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 11583 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 11584 11585 /* 11586 * Set up output mixers (0x0c - 0x0e) 11587 */ 11588 /* set vol=0 to output mixers */ 11589 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 11590 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 11591 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 11592 /* set up input amps for analog loopback */ 11593 /* Amp Indices: DAC = 0, mixer = 1 */ 11594 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11595 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11596 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11597 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11598 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11599 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11600 11601 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 11602 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 11603 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 11604 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 11605 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 11606 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 11607 11608 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 11609 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 11610 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 11611 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 11612 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 11613 11614 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 11615 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 11616 11617 /* FIXME: use matrix-type input source selection */ 11618 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 11619 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 11620 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 11621 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 11622 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 11623 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 11624 /* Input mixer2 */ 11625 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 11626 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 11627 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 11628 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 11629 /* Input mixer3 */ 11630 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 11631 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 11632 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 11633 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 11634 11635 { } 11636}; 11637 11638static struct hda_verb alc262_eapd_verbs[] = { 11639 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 11640 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, 11641 { } 11642}; 11643 11644static struct hda_verb alc262_hippo1_unsol_verbs[] = { 11645 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 11646 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 11647 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 11648 11649 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 11650 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11651 {} 11652}; 11653 11654static struct hda_verb alc262_sony_unsol_verbs[] = { 11655 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 11656 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 11657 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic 11658 11659 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 11660 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11661 {} 11662}; 11663 11664static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = { 11665 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11666 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 11667 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 11668 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11669 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11670 { } /* end */ 11671}; 11672 11673static struct hda_verb alc262_toshiba_s06_verbs[] = { 11674 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 11675 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 11676 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11677 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 11678 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09}, 11679 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 11680 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 11681 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 11682 {} 11683}; 11684 11685static void alc262_toshiba_s06_setup(struct hda_codec *codec) 11686{ 11687 struct alc_spec *spec = codec->spec; 11688 11689 spec->autocfg.hp_pins[0] = 0x15; 11690 spec->autocfg.speaker_pins[0] = 0x14; 11691 spec->ext_mic.pin = 0x18; 11692 spec->ext_mic.mux_idx = 0; 11693 spec->int_mic.pin = 0x12; 11694 spec->int_mic.mux_idx = 9; 11695 spec->auto_mic = 1; 11696} 11697 11698/* 11699 * nec model 11700 * 0x15 = headphone 11701 * 0x16 = internal speaker 11702 * 0x18 = external mic 11703 */ 11704 11705static struct snd_kcontrol_new alc262_nec_mixer[] = { 11706 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 11707 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT), 11708 11709 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11710 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11711 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 11712 11713 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 11714 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 11715 { } /* end */ 11716}; 11717 11718static struct hda_verb alc262_nec_verbs[] = { 11719 /* Unmute Speaker */ 11720 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 11721 11722 /* Headphone */ 11723 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 11724 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 11725 11726 /* External mic to headphone */ 11727 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11728 /* External mic to speaker */ 11729 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11730 {} 11731}; 11732 11733/* 11734 * fujitsu model 11735 * 0x14 = headphone/spdif-out, 0x15 = internal speaker, 11736 * 0x1b = port replicator headphone out 11737 */ 11738 11739#define ALC_HP_EVENT 0x37 11740 11741static struct hda_verb alc262_fujitsu_unsol_verbs[] = { 11742 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, 11743 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11744 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, 11745 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11746 {} 11747}; 11748 11749static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = { 11750 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, 11751 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11752 {} 11753}; 11754 11755static struct hda_verb alc262_lenovo_3000_init_verbs[] = { 11756 /* Front Mic pin: input vref at 50% */ 11757 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, 11758 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 11759 {} 11760}; 11761 11762static struct hda_input_mux alc262_fujitsu_capture_source = { 11763 .num_items = 3, 11764 .items = { 11765 { "Mic", 0x0 }, 11766 { "Internal Mic", 0x1 }, 11767 { "CD", 0x4 }, 11768 }, 11769}; 11770 11771static struct hda_input_mux alc262_HP_capture_source = { 11772 .num_items = 5, 11773 .items = { 11774 { "Mic", 0x0 }, 11775 { "Front Mic", 0x1 }, 11776 { "Line", 0x2 }, 11777 { "CD", 0x4 }, 11778 { "AUX IN", 0x6 }, 11779 }, 11780}; 11781 11782static struct hda_input_mux alc262_HP_D7000_capture_source = { 11783 .num_items = 4, 11784 .items = { 11785 { "Mic", 0x0 }, 11786 { "Front Mic", 0x2 }, 11787 { "Line", 0x1 }, 11788 { "CD", 0x4 }, 11789 }, 11790}; 11791 11792/* mute/unmute internal speaker according to the hp jacks and mute state */ 11793static void alc262_fujitsu_automute(struct hda_codec *codec, int force) 11794{ 11795 struct alc_spec *spec = codec->spec; 11796 unsigned int mute; 11797 11798 if (force || !spec->sense_updated) { 11799 spec->jack_present = snd_hda_jack_detect(codec, 0x14) || 11800 snd_hda_jack_detect(codec, 0x1b); 11801 spec->sense_updated = 1; 11802 } 11803 /* unmute internal speaker only if both HPs are unplugged and 11804 * master switch is on 11805 */ 11806 if (spec->jack_present) 11807 mute = HDA_AMP_MUTE; 11808 else 11809 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0); 11810 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 11811 HDA_AMP_MUTE, mute); 11812} 11813 11814/* unsolicited event for HP jack sensing */ 11815static void alc262_fujitsu_unsol_event(struct hda_codec *codec, 11816 unsigned int res) 11817{ 11818 if ((res >> 26) != ALC_HP_EVENT) 11819 return; 11820 alc262_fujitsu_automute(codec, 1); 11821} 11822 11823static void alc262_fujitsu_init_hook(struct hda_codec *codec) 11824{ 11825 alc262_fujitsu_automute(codec, 1); 11826} 11827 11828/* bind volumes of both NID 0x0c and 0x0d */ 11829static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = { 11830 .ops = &snd_hda_bind_vol, 11831 .values = { 11832 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT), 11833 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT), 11834 0 11835 }, 11836}; 11837 11838/* mute/unmute internal speaker according to the hp jack and mute state */ 11839static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force) 11840{ 11841 struct alc_spec *spec = codec->spec; 11842 unsigned int mute; 11843 11844 if (force || !spec->sense_updated) { 11845 spec->jack_present = snd_hda_jack_detect(codec, 0x1b); 11846 spec->sense_updated = 1; 11847 } 11848 if (spec->jack_present) { 11849 /* mute internal speaker */ 11850 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 11851 HDA_AMP_MUTE, HDA_AMP_MUTE); 11852 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0, 11853 HDA_AMP_MUTE, HDA_AMP_MUTE); 11854 } else { 11855 /* unmute internal speaker if necessary */ 11856 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0); 11857 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 11858 HDA_AMP_MUTE, mute); 11859 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0, 11860 HDA_AMP_MUTE, mute); 11861 } 11862} 11863 11864/* unsolicited event for HP jack sensing */ 11865static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec, 11866 unsigned int res) 11867{ 11868 if ((res >> 26) != ALC_HP_EVENT) 11869 return; 11870 alc262_lenovo_3000_automute(codec, 1); 11871} 11872 11873static int amp_stereo_mute_update(struct hda_codec *codec, hda_nid_t nid, 11874 int dir, int idx, long *valp) 11875{ 11876 int i, change = 0; 11877 11878 for (i = 0; i < 2; i++, valp++) 11879 change |= snd_hda_codec_amp_update(codec, nid, i, dir, idx, 11880 HDA_AMP_MUTE, 11881 *valp ? 0 : HDA_AMP_MUTE); 11882 return change; 11883} 11884 11885/* bind hp and internal speaker mute (with plug check) */ 11886static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol, 11887 struct snd_ctl_elem_value *ucontrol) 11888{ 11889 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 11890 long *valp = ucontrol->value.integer.value; 11891 int change; 11892 11893 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp); 11894 change |= amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp); 11895 if (change) 11896 alc262_fujitsu_automute(codec, 0); 11897 return change; 11898} 11899 11900static struct snd_kcontrol_new alc262_fujitsu_mixer[] = { 11901 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol), 11902 { 11903 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 11904 .name = "Master Playback Switch", 11905 .subdevice = HDA_SUBDEV_AMP_FLAG, 11906 .info = snd_hda_mixer_amp_switch_info, 11907 .get = snd_hda_mixer_amp_switch_get, 11908 .put = alc262_fujitsu_master_sw_put, 11909 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 11910 }, 11911 { 11912 .iface = NID_MAPPING, 11913 .name = "Master Playback Switch", 11914 .private_value = 0x1b, 11915 }, 11916 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 11917 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 11918 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 11919 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11920 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11921 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), 11922 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 11923 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 11924 { } /* end */ 11925}; 11926 11927/* bind hp and internal speaker mute (with plug check) */ 11928static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol, 11929 struct snd_ctl_elem_value *ucontrol) 11930{ 11931 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 11932 long *valp = ucontrol->value.integer.value; 11933 int change; 11934 11935 change = amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp); 11936 if (change) 11937 alc262_lenovo_3000_automute(codec, 0); 11938 return change; 11939} 11940 11941static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = { 11942 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol), 11943 { 11944 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 11945 .name = "Master Playback Switch", 11946 .subdevice = HDA_SUBDEV_AMP_FLAG, 11947 .info = snd_hda_mixer_amp_switch_info, 11948 .get = snd_hda_mixer_amp_switch_get, 11949 .put = alc262_lenovo_3000_master_sw_put, 11950 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT), 11951 }, 11952 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 11953 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 11954 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 11955 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11956 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11957 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), 11958 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 11959 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 11960 { } /* end */ 11961}; 11962 11963static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = { 11964 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol), 11965 ALC262_HIPPO_MASTER_SWITCH, 11966 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11967 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11968 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 11969 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 11970 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 11971 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), 11972 { } /* end */ 11973}; 11974 11975/* additional init verbs for Benq laptops */ 11976static struct hda_verb alc262_EAPD_verbs[] = { 11977 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 11978 {0x20, AC_VERB_SET_PROC_COEF, 0x3070}, 11979 {} 11980}; 11981 11982static struct hda_verb alc262_benq_t31_EAPD_verbs[] = { 11983 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 11984 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 11985 11986 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 11987 {0x20, AC_VERB_SET_PROC_COEF, 0x3050}, 11988 {} 11989}; 11990 11991/* Samsung Q1 Ultra Vista model setup */ 11992static struct snd_kcontrol_new alc262_ultra_mixer[] = { 11993 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11994 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT), 11995 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 11996 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 11997 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT), 11998 HDA_CODEC_VOLUME("Headphone Mic Boost Volume", 0x15, 0, HDA_INPUT), 11999 { } /* end */ 12000}; 12001 12002static struct hda_verb alc262_ultra_verbs[] = { 12003 /* output mixer */ 12004 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 12005 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 12006 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 12007 /* speaker */ 12008 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 12009 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 12010 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12011 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 12012 /* HP */ 12013 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 12014 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 12015 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12016 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 12017 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 12018 /* internal mic */ 12019 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 12020 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 12021 /* ADC, choose mic */ 12022 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 12023 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 12024 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12025 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 12026 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 12027 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 12028 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, 12029 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, 12030 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, 12031 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)}, 12032 {} 12033}; 12034 12035/* mute/unmute internal speaker according to the hp jack and mute state */ 12036static void alc262_ultra_automute(struct hda_codec *codec) 12037{ 12038 struct alc_spec *spec = codec->spec; 12039 unsigned int mute; 12040 12041 mute = 0; 12042 /* auto-mute only when HP is used as HP */ 12043 if (!spec->cur_mux[0]) { 12044 spec->jack_present = snd_hda_jack_detect(codec, 0x15); 12045 if (spec->jack_present) 12046 mute = HDA_AMP_MUTE; 12047 } 12048 /* mute/unmute internal speaker */ 12049 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 12050 HDA_AMP_MUTE, mute); 12051 /* mute/unmute HP */ 12052 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 12053 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE); 12054} 12055 12056/* unsolicited event for HP jack sensing */ 12057static void alc262_ultra_unsol_event(struct hda_codec *codec, 12058 unsigned int res) 12059{ 12060 if ((res >> 26) != ALC880_HP_EVENT) 12061 return; 12062 alc262_ultra_automute(codec); 12063} 12064 12065static struct hda_input_mux alc262_ultra_capture_source = { 12066 .num_items = 2, 12067 .items = { 12068 { "Mic", 0x1 }, 12069 { "Headphone", 0x7 }, 12070 }, 12071}; 12072 12073static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol, 12074 struct snd_ctl_elem_value *ucontrol) 12075{ 12076 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 12077 struct alc_spec *spec = codec->spec; 12078 int ret; 12079 12080 ret = alc_mux_enum_put(kcontrol, ucontrol); 12081 if (!ret) 12082 return 0; 12083 /* reprogram the HP pin as mic or HP according to the input source */ 12084 snd_hda_codec_write_cache(codec, 0x15, 0, 12085 AC_VERB_SET_PIN_WIDGET_CONTROL, 12086 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP); 12087 alc262_ultra_automute(codec); /* mute/unmute HP */ 12088 return ret; 12089} 12090 12091static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = { 12092 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT), 12093 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT), 12094 { 12095 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 12096 .name = "Capture Source", 12097 .info = alc_mux_enum_info, 12098 .get = alc_mux_enum_get, 12099 .put = alc262_ultra_mux_enum_put, 12100 }, 12101 { 12102 .iface = NID_MAPPING, 12103 .name = "Capture Source", 12104 .private_value = 0x15, 12105 }, 12106 { } /* end */ 12107}; 12108 12109/* We use two mixers depending on the output pin; 0x16 is a mono output 12110 * and thus it's bound with a different mixer. 12111 * This function returns which mixer amp should be used. 12112 */ 12113static int alc262_check_volbit(hda_nid_t nid) 12114{ 12115 if (!nid) 12116 return 0; 12117 else if (nid == 0x16) 12118 return 2; 12119 else 12120 return 1; 12121} 12122 12123static int alc262_add_out_vol_ctl(struct alc_spec *spec, hda_nid_t nid, 12124 const char *pfx, int *vbits, int idx) 12125{ 12126 unsigned long val; 12127 int vbit; 12128 12129 vbit = alc262_check_volbit(nid); 12130 if (!vbit) 12131 return 0; 12132 if (*vbits & vbit) /* a volume control for this mixer already there */ 12133 return 0; 12134 *vbits |= vbit; 12135 if (vbit == 2) 12136 val = HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT); 12137 else 12138 val = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT); 12139 return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx, val); 12140} 12141 12142static int alc262_add_out_sw_ctl(struct alc_spec *spec, hda_nid_t nid, 12143 const char *pfx, int idx) 12144{ 12145 unsigned long val; 12146 12147 if (!nid) 12148 return 0; 12149 if (nid == 0x16) 12150 val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT); 12151 else 12152 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT); 12153 return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx, val); 12154} 12155 12156/* add playback controls from the parsed DAC table */ 12157static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, 12158 const struct auto_pin_cfg *cfg) 12159{ 12160 const char *pfx; 12161 int vbits; 12162 int i, err; 12163 12164 spec->multiout.num_dacs = 1; /* only use one dac */ 12165 spec->multiout.dac_nids = spec->private_dac_nids; 12166 spec->multiout.dac_nids[0] = 2; 12167 12168 pfx = alc_get_line_out_pfx(cfg, true); 12169 if (!pfx) 12170 pfx = "Front"; 12171 for (i = 0; i < 2; i++) { 12172 err = alc262_add_out_sw_ctl(spec, cfg->line_out_pins[i], pfx, i); 12173 if (err < 0) 12174 return err; 12175 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { 12176 err = alc262_add_out_sw_ctl(spec, cfg->speaker_pins[i], 12177 "Speaker", i); 12178 if (err < 0) 12179 return err; 12180 } 12181 if (cfg->line_out_type != AUTO_PIN_HP_OUT) { 12182 err = alc262_add_out_sw_ctl(spec, cfg->hp_pins[i], 12183 "Headphone", i); 12184 if (err < 0) 12185 return err; 12186 } 12187 } 12188 12189 vbits = alc262_check_volbit(cfg->line_out_pins[0]) | 12190 alc262_check_volbit(cfg->speaker_pins[0]) | 12191 alc262_check_volbit(cfg->hp_pins[0]); 12192 if (vbits == 1 || vbits == 2) 12193 pfx = "Master"; /* only one mixer is used */ 12194 vbits = 0; 12195 for (i = 0; i < 2; i++) { 12196 err = alc262_add_out_vol_ctl(spec, cfg->line_out_pins[i], pfx, 12197 &vbits, i); 12198 if (err < 0) 12199 return err; 12200 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { 12201 err = alc262_add_out_vol_ctl(spec, cfg->speaker_pins[i], 12202 "Speaker", &vbits, i); 12203 if (err < 0) 12204 return err; 12205 } 12206 if (cfg->line_out_type != AUTO_PIN_HP_OUT) { 12207 err = alc262_add_out_vol_ctl(spec, cfg->hp_pins[i], 12208 "Headphone", &vbits, i); 12209 if (err < 0) 12210 return err; 12211 } 12212 } 12213 return 0; 12214} 12215 12216#define alc262_auto_create_input_ctls \ 12217 alc882_auto_create_input_ctls 12218 12219/* 12220 * generic initialization of ADC, input mixers and output mixers 12221 */ 12222static struct hda_verb alc262_volume_init_verbs[] = { 12223 /* 12224 * Unmute ADC0-2 and set the default input to mic-in 12225 */ 12226 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 12227 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12228 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 12229 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12230 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 12231 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12232 12233 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 12234 * mixer widget 12235 * Note: PASD motherboards uses the Line In 2 as the input for 12236 * front panel mic (mic 2) 12237 */ 12238 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 12239 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 12240 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 12241 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 12242 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 12243 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 12244 12245 /* 12246 * Set up output mixers (0x0c - 0x0f) 12247 */ 12248 /* set vol=0 to output mixers */ 12249 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 12250 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 12251 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 12252 12253 /* set up input amps for analog loopback */ 12254 /* Amp Indices: DAC = 0, mixer = 1 */ 12255 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12256 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12257 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12258 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12259 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12260 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12261 12262 /* FIXME: use matrix-type input source selection */ 12263 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 12264 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 12265 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 12266 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 12267 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 12268 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 12269 /* Input mixer2 */ 12270 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 12271 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 12272 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 12273 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 12274 /* Input mixer3 */ 12275 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 12276 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 12277 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 12278 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 12279 12280 { } 12281}; 12282 12283static struct hda_verb alc262_HP_BPC_init_verbs[] = { 12284 /* 12285 * Unmute ADC0-2 and set the default input to mic-in 12286 */ 12287 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 12288 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12289 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 12290 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12291 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 12292 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12293 12294 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 12295 * mixer widget 12296 * Note: PASD motherboards uses the Line In 2 as the input for 12297 * front panel mic (mic 2) 12298 */ 12299 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 12300 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 12301 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 12302 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 12303 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 12304 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 12305 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, 12306 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, 12307 12308 /* 12309 * Set up output mixers (0x0c - 0x0e) 12310 */ 12311 /* set vol=0 to output mixers */ 12312 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 12313 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 12314 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 12315 12316 /* set up input amps for analog loopback */ 12317 /* Amp Indices: DAC = 0, mixer = 1 */ 12318 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12319 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12320 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12321 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12322 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12323 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12324 12325 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 12326 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 12327 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 12328 12329 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 12330 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 12331 12332 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 12333 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 12334 12335 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 12336 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 12337 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 12338 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 12339 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 12340 12341 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 12342 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 12343 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 12344 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 12345 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 12346 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 12347 12348 12349 /* FIXME: use matrix-type input source selection */ 12350 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */ 12351 /* Input mixer1: only unmute Mic */ 12352 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 12353 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))}, 12354 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 12355 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 12356 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 12357 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))}, 12358 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))}, 12359 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))}, 12360 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))}, 12361 /* Input mixer2 */ 12362 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 12363 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))}, 12364 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 12365 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 12366 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 12367 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))}, 12368 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))}, 12369 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))}, 12370 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))}, 12371 /* Input mixer3 */ 12372 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 12373 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))}, 12374 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 12375 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 12376 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 12377 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))}, 12378 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))}, 12379 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))}, 12380 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))}, 12381 12382 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 12383 12384 { } 12385}; 12386 12387static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = { 12388 /* 12389 * Unmute ADC0-2 and set the default input to mic-in 12390 */ 12391 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 12392 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12393 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 12394 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12395 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 12396 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12397 12398 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 12399 * mixer widget 12400 * Note: PASD motherboards uses the Line In 2 as the input for front 12401 * panel mic (mic 2) 12402 */ 12403 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 12404 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 12405 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 12406 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 12407 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 12408 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 12409 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, 12410 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, 12411 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, 12412 /* 12413 * Set up output mixers (0x0c - 0x0e) 12414 */ 12415 /* set vol=0 to output mixers */ 12416 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 12417 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 12418 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 12419 12420 /* set up input amps for analog loopback */ 12421 /* Amp Indices: DAC = 0, mixer = 1 */ 12422 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12423 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12424 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12425 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12426 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12427 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12428 12429 12430 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */ 12431 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */ 12432 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */ 12433 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */ 12434 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */ 12435 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */ 12436 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */ 12437 12438 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 12439 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 12440 12441 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 12442 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 12443 12444 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */ 12445 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 12446 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 12447 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, 12448 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 12449 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 12450 12451 /* FIXME: use matrix-type input source selection */ 12452 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 12453 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 12454 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/ 12455 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/ 12456 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/ 12457 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/ 12458 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/ 12459 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */ 12460 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/ 12461 /* Input mixer2 */ 12462 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 12463 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 12464 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, 12465 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, 12466 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, 12467 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */ 12468 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, 12469 /* Input mixer3 */ 12470 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 12471 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 12472 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, 12473 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, 12474 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, 12475 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */ 12476 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, 12477 12478 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 12479 12480 { } 12481}; 12482 12483static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = { 12484 12485 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */ 12486 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 12487 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01}, 12488 12489 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */ 12490 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */ 12491 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) }, 12492 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) }, 12493 12494 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */ 12495 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 12496 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 12497 {} 12498}; 12499 12500/* 12501 * Pin config fixes 12502 */ 12503enum { 12504 PINFIX_FSC_H270, 12505}; 12506 12507static const struct alc_fixup alc262_fixups[] = { 12508 [PINFIX_FSC_H270] = { 12509 .type = ALC_FIXUP_PINS, 12510 .v.pins = (const struct alc_pincfg[]) { 12511 { 0x14, 0x99130110 }, /* speaker */ 12512 { 0x15, 0x0221142f }, /* front HP */ 12513 { 0x1b, 0x0121141f }, /* rear HP */ 12514 { } 12515 } 12516 }, 12517}; 12518 12519static struct snd_pci_quirk alc262_fixup_tbl[] = { 12520 SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", PINFIX_FSC_H270), 12521 {} 12522}; 12523 12524 12525#ifdef CONFIG_SND_HDA_POWER_SAVE 12526#define alc262_loopbacks alc880_loopbacks 12527#endif 12528 12529/* pcm configuration: identical with ALC880 */ 12530#define alc262_pcm_analog_playback alc880_pcm_analog_playback 12531#define alc262_pcm_analog_capture alc880_pcm_analog_capture 12532#define alc262_pcm_digital_playback alc880_pcm_digital_playback 12533#define alc262_pcm_digital_capture alc880_pcm_digital_capture 12534 12535/* 12536 * BIOS auto configuration 12537 */ 12538static int alc262_parse_auto_config(struct hda_codec *codec) 12539{ 12540 struct alc_spec *spec = codec->spec; 12541 int err; 12542 static hda_nid_t alc262_ignore[] = { 0x1d, 0 }; 12543 12544 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 12545 alc262_ignore); 12546 if (err < 0) 12547 return err; 12548 if (!spec->autocfg.line_outs) { 12549 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) { 12550 spec->multiout.max_channels = 2; 12551 spec->no_analog = 1; 12552 goto dig_only; 12553 } 12554 return 0; /* can't find valid BIOS pin config */ 12555 } 12556 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg); 12557 if (err < 0) 12558 return err; 12559 err = alc262_auto_create_input_ctls(codec, &spec->autocfg); 12560 if (err < 0) 12561 return err; 12562 12563 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 12564 12565 dig_only: 12566 alc_auto_parse_digital(codec); 12567 12568 if (spec->kctls.list) 12569 add_mixer(spec, spec->kctls.list); 12570 12571 add_verb(spec, alc262_volume_init_verbs); 12572 spec->num_mux_defs = 1; 12573 spec->input_mux = &spec->private_imux[0]; 12574 12575 err = alc_auto_add_mic_boost(codec); 12576 if (err < 0) 12577 return err; 12578 12579 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); 12580 12581 return 1; 12582} 12583 12584#define alc262_auto_init_multi_out alc882_auto_init_multi_out 12585#define alc262_auto_init_hp_out alc882_auto_init_hp_out 12586#define alc262_auto_init_analog_input alc882_auto_init_analog_input 12587#define alc262_auto_init_input_src alc882_auto_init_input_src 12588 12589 12590/* init callback for auto-configuration model -- overriding the default init */ 12591static void alc262_auto_init(struct hda_codec *codec) 12592{ 12593 struct alc_spec *spec = codec->spec; 12594 alc262_auto_init_multi_out(codec); 12595 alc262_auto_init_hp_out(codec); 12596 alc262_auto_init_analog_input(codec); 12597 alc262_auto_init_input_src(codec); 12598 alc_auto_init_digital(codec); 12599 if (spec->unsol_event) 12600 alc_inithook(codec); 12601} 12602 12603/* 12604 * configuration and preset 12605 */ 12606static const char * const alc262_models[ALC262_MODEL_LAST] = { 12607 [ALC262_BASIC] = "basic", 12608 [ALC262_HIPPO] = "hippo", 12609 [ALC262_HIPPO_1] = "hippo_1", 12610 [ALC262_FUJITSU] = "fujitsu", 12611 [ALC262_HP_BPC] = "hp-bpc", 12612 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000", 12613 [ALC262_HP_TC_T5735] = "hp-tc-t5735", 12614 [ALC262_HP_RP5700] = "hp-rp5700", 12615 [ALC262_BENQ_ED8] = "benq", 12616 [ALC262_BENQ_T31] = "benq-t31", 12617 [ALC262_SONY_ASSAMD] = "sony-assamd", 12618 [ALC262_TOSHIBA_S06] = "toshiba-s06", 12619 [ALC262_TOSHIBA_RX1] = "toshiba-rx1", 12620 [ALC262_ULTRA] = "ultra", 12621 [ALC262_LENOVO_3000] = "lenovo-3000", 12622 [ALC262_NEC] = "nec", 12623 [ALC262_TYAN] = "tyan", 12624 [ALC262_AUTO] = "auto", 12625}; 12626 12627static struct snd_pci_quirk alc262_cfg_tbl[] = { 12628 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO), 12629 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC), 12630 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series", 12631 ALC262_HP_BPC), 12632 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series", 12633 ALC262_HP_BPC), 12634 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1500, "HP z series", 12635 ALC262_HP_BPC), 12636 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series", 12637 ALC262_HP_BPC), 12638 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL), 12639 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF), 12640 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL), 12641 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF), 12642 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL), 12643 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF), 12644 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL), 12645 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF), 12646 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC), 12647 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC), 12648 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC), 12649 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735", 12650 ALC262_HP_TC_T5735), 12651 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700), 12652 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD), 12653 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO), 12654 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD), 12655 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */ 12656 SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06), 12657 SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO), 12658 SND_PCI_QUIRK(0x104d, 0x9047, "Sony VAIO Type G", ALC262_AUTO), 12659#if 0 /* disable the quirk since model=auto works better in recent versions */ 12660 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO", 12661 ALC262_SONY_ASSAMD), 12662#endif 12663 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1", 12664 ALC262_TOSHIBA_RX1), 12665 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06), 12666 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU), 12667 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU), 12668 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN), 12669 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1", 12670 ALC262_ULTRA), 12671 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO), 12672 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000), 12673 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8), 12674 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31), 12675 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1), 12676 {} 12677}; 12678 12679static struct alc_config_preset alc262_presets[] = { 12680 [ALC262_BASIC] = { 12681 .mixers = { alc262_base_mixer }, 12682 .init_verbs = { alc262_init_verbs }, 12683 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12684 .dac_nids = alc262_dac_nids, 12685 .hp_nid = 0x03, 12686 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12687 .channel_mode = alc262_modes, 12688 .input_mux = &alc262_capture_source, 12689 }, 12690 [ALC262_HIPPO] = { 12691 .mixers = { alc262_hippo_mixer }, 12692 .init_verbs = { alc262_init_verbs, alc_hp15_unsol_verbs}, 12693 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12694 .dac_nids = alc262_dac_nids, 12695 .hp_nid = 0x03, 12696 .dig_out_nid = ALC262_DIGOUT_NID, 12697 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12698 .channel_mode = alc262_modes, 12699 .input_mux = &alc262_capture_source, 12700 .unsol_event = alc262_hippo_unsol_event, 12701 .setup = alc262_hippo_setup, 12702 .init_hook = alc262_hippo_automute, 12703 }, 12704 [ALC262_HIPPO_1] = { 12705 .mixers = { alc262_hippo1_mixer }, 12706 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs}, 12707 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12708 .dac_nids = alc262_dac_nids, 12709 .hp_nid = 0x02, 12710 .dig_out_nid = ALC262_DIGOUT_NID, 12711 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12712 .channel_mode = alc262_modes, 12713 .input_mux = &alc262_capture_source, 12714 .unsol_event = alc262_hippo_unsol_event, 12715 .setup = alc262_hippo1_setup, 12716 .init_hook = alc262_hippo_automute, 12717 }, 12718 [ALC262_FUJITSU] = { 12719 .mixers = { alc262_fujitsu_mixer }, 12720 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs, 12721 alc262_fujitsu_unsol_verbs }, 12722 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12723 .dac_nids = alc262_dac_nids, 12724 .hp_nid = 0x03, 12725 .dig_out_nid = ALC262_DIGOUT_NID, 12726 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12727 .channel_mode = alc262_modes, 12728 .input_mux = &alc262_fujitsu_capture_source, 12729 .unsol_event = alc262_fujitsu_unsol_event, 12730 .init_hook = alc262_fujitsu_init_hook, 12731 }, 12732 [ALC262_HP_BPC] = { 12733 .mixers = { alc262_HP_BPC_mixer }, 12734 .init_verbs = { alc262_HP_BPC_init_verbs }, 12735 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12736 .dac_nids = alc262_dac_nids, 12737 .hp_nid = 0x03, 12738 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12739 .channel_mode = alc262_modes, 12740 .input_mux = &alc262_HP_capture_source, 12741 .unsol_event = alc262_hp_bpc_unsol_event, 12742 .init_hook = alc262_hp_bpc_automute, 12743 }, 12744 [ALC262_HP_BPC_D7000_WF] = { 12745 .mixers = { alc262_HP_BPC_WildWest_mixer }, 12746 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs }, 12747 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12748 .dac_nids = alc262_dac_nids, 12749 .hp_nid = 0x03, 12750 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12751 .channel_mode = alc262_modes, 12752 .input_mux = &alc262_HP_D7000_capture_source, 12753 .unsol_event = alc262_hp_wildwest_unsol_event, 12754 .init_hook = alc262_hp_wildwest_automute, 12755 }, 12756 [ALC262_HP_BPC_D7000_WL] = { 12757 .mixers = { alc262_HP_BPC_WildWest_mixer, 12758 alc262_HP_BPC_WildWest_option_mixer }, 12759 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs }, 12760 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12761 .dac_nids = alc262_dac_nids, 12762 .hp_nid = 0x03, 12763 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12764 .channel_mode = alc262_modes, 12765 .input_mux = &alc262_HP_D7000_capture_source, 12766 .unsol_event = alc262_hp_wildwest_unsol_event, 12767 .init_hook = alc262_hp_wildwest_automute, 12768 }, 12769 [ALC262_HP_TC_T5735] = { 12770 .mixers = { alc262_hp_t5735_mixer }, 12771 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs }, 12772 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12773 .dac_nids = alc262_dac_nids, 12774 .hp_nid = 0x03, 12775 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12776 .channel_mode = alc262_modes, 12777 .input_mux = &alc262_capture_source, 12778 .unsol_event = alc_sku_unsol_event, 12779 .setup = alc262_hp_t5735_setup, 12780 .init_hook = alc_inithook, 12781 }, 12782 [ALC262_HP_RP5700] = { 12783 .mixers = { alc262_hp_rp5700_mixer }, 12784 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs }, 12785 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12786 .dac_nids = alc262_dac_nids, 12787 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12788 .channel_mode = alc262_modes, 12789 .input_mux = &alc262_hp_rp5700_capture_source, 12790 }, 12791 [ALC262_BENQ_ED8] = { 12792 .mixers = { alc262_base_mixer }, 12793 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs }, 12794 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12795 .dac_nids = alc262_dac_nids, 12796 .hp_nid = 0x03, 12797 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12798 .channel_mode = alc262_modes, 12799 .input_mux = &alc262_capture_source, 12800 }, 12801 [ALC262_SONY_ASSAMD] = { 12802 .mixers = { alc262_sony_mixer }, 12803 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs}, 12804 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12805 .dac_nids = alc262_dac_nids, 12806 .hp_nid = 0x02, 12807 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12808 .channel_mode = alc262_modes, 12809 .input_mux = &alc262_capture_source, 12810 .unsol_event = alc262_hippo_unsol_event, 12811 .setup = alc262_hippo_setup, 12812 .init_hook = alc262_hippo_automute, 12813 }, 12814 [ALC262_BENQ_T31] = { 12815 .mixers = { alc262_benq_t31_mixer }, 12816 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, 12817 alc_hp15_unsol_verbs }, 12818 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12819 .dac_nids = alc262_dac_nids, 12820 .hp_nid = 0x03, 12821 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12822 .channel_mode = alc262_modes, 12823 .input_mux = &alc262_capture_source, 12824 .unsol_event = alc262_hippo_unsol_event, 12825 .setup = alc262_hippo_setup, 12826 .init_hook = alc262_hippo_automute, 12827 }, 12828 [ALC262_ULTRA] = { 12829 .mixers = { alc262_ultra_mixer }, 12830 .cap_mixer = alc262_ultra_capture_mixer, 12831 .init_verbs = { alc262_ultra_verbs }, 12832 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12833 .dac_nids = alc262_dac_nids, 12834 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12835 .channel_mode = alc262_modes, 12836 .input_mux = &alc262_ultra_capture_source, 12837 .adc_nids = alc262_adc_nids, /* ADC0 */ 12838 .capsrc_nids = alc262_capsrc_nids, 12839 .num_adc_nids = 1, /* single ADC */ 12840 .unsol_event = alc262_ultra_unsol_event, 12841 .init_hook = alc262_ultra_automute, 12842 }, 12843 [ALC262_LENOVO_3000] = { 12844 .mixers = { alc262_lenovo_3000_mixer }, 12845 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs, 12846 alc262_lenovo_3000_unsol_verbs, 12847 alc262_lenovo_3000_init_verbs }, 12848 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12849 .dac_nids = alc262_dac_nids, 12850 .hp_nid = 0x03, 12851 .dig_out_nid = ALC262_DIGOUT_NID, 12852 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12853 .channel_mode = alc262_modes, 12854 .input_mux = &alc262_fujitsu_capture_source, 12855 .unsol_event = alc262_lenovo_3000_unsol_event, 12856 }, 12857 [ALC262_NEC] = { 12858 .mixers = { alc262_nec_mixer }, 12859 .init_verbs = { alc262_nec_verbs }, 12860 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12861 .dac_nids = alc262_dac_nids, 12862 .hp_nid = 0x03, 12863 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12864 .channel_mode = alc262_modes, 12865 .input_mux = &alc262_capture_source, 12866 }, 12867 [ALC262_TOSHIBA_S06] = { 12868 .mixers = { alc262_toshiba_s06_mixer }, 12869 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs, 12870 alc262_eapd_verbs }, 12871 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12872 .capsrc_nids = alc262_dmic_capsrc_nids, 12873 .dac_nids = alc262_dac_nids, 12874 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */ 12875 .num_adc_nids = 1, /* single ADC */ 12876 .dig_out_nid = ALC262_DIGOUT_NID, 12877 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12878 .channel_mode = alc262_modes, 12879 .unsol_event = alc_sku_unsol_event, 12880 .setup = alc262_toshiba_s06_setup, 12881 .init_hook = alc_inithook, 12882 }, 12883 [ALC262_TOSHIBA_RX1] = { 12884 .mixers = { alc262_toshiba_rx1_mixer }, 12885 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs }, 12886 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12887 .dac_nids = alc262_dac_nids, 12888 .hp_nid = 0x03, 12889 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12890 .channel_mode = alc262_modes, 12891 .input_mux = &alc262_capture_source, 12892 .unsol_event = alc262_hippo_unsol_event, 12893 .setup = alc262_hippo_setup, 12894 .init_hook = alc262_hippo_automute, 12895 }, 12896 [ALC262_TYAN] = { 12897 .mixers = { alc262_tyan_mixer }, 12898 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs}, 12899 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12900 .dac_nids = alc262_dac_nids, 12901 .hp_nid = 0x02, 12902 .dig_out_nid = ALC262_DIGOUT_NID, 12903 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12904 .channel_mode = alc262_modes, 12905 .input_mux = &alc262_capture_source, 12906 .unsol_event = alc_automute_amp_unsol_event, 12907 .setup = alc262_tyan_setup, 12908 .init_hook = alc_automute_amp, 12909 }, 12910}; 12911 12912static int patch_alc262(struct hda_codec *codec) 12913{ 12914 struct alc_spec *spec; 12915 int board_config; 12916 int err; 12917 12918 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 12919 if (spec == NULL) 12920 return -ENOMEM; 12921 12922 codec->spec = spec; 12923#if 0 12924 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is 12925 * under-run 12926 */ 12927 { 12928 int tmp; 12929 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7); 12930 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0); 12931 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7); 12932 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80); 12933 } 12934#endif 12935 alc_auto_parse_customize_define(codec); 12936 12937 alc_fix_pll_init(codec, 0x20, 0x0a, 10); 12938 12939 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST, 12940 alc262_models, 12941 alc262_cfg_tbl); 12942 12943 if (board_config < 0) { 12944 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 12945 codec->chip_name); 12946 board_config = ALC262_AUTO; 12947 } 12948 12949 if (board_config == ALC262_AUTO) { 12950 alc_pick_fixup(codec, NULL, alc262_fixup_tbl, alc262_fixups); 12951 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); 12952 } 12953 12954 if (board_config == ALC262_AUTO) { 12955 /* automatic parse from the BIOS config */ 12956 err = alc262_parse_auto_config(codec); 12957 if (err < 0) { 12958 alc_free(codec); 12959 return err; 12960 } else if (!err) { 12961 printk(KERN_INFO 12962 "hda_codec: Cannot set up configuration " 12963 "from BIOS. Using base mode...\n"); 12964 board_config = ALC262_BASIC; 12965 } 12966 } 12967 12968 if (!spec->no_analog && has_cdefine_beep(codec)) { 12969 err = snd_hda_attach_beep_device(codec, 0x1); 12970 if (err < 0) { 12971 alc_free(codec); 12972 return err; 12973 } 12974 } 12975 12976 if (board_config != ALC262_AUTO) 12977 setup_preset(codec, &alc262_presets[board_config]); 12978 12979 spec->stream_analog_playback = &alc262_pcm_analog_playback; 12980 spec->stream_analog_capture = &alc262_pcm_analog_capture; 12981 12982 spec->stream_digital_playback = &alc262_pcm_digital_playback; 12983 spec->stream_digital_capture = &alc262_pcm_digital_capture; 12984 12985 if (!spec->adc_nids && spec->input_mux) { 12986 int i; 12987 /* check whether the digital-mic has to be supported */ 12988 for (i = 0; i < spec->input_mux->num_items; i++) { 12989 if (spec->input_mux->items[i].index >= 9) 12990 break; 12991 } 12992 if (i < spec->input_mux->num_items) { 12993 /* use only ADC0 */ 12994 spec->adc_nids = alc262_dmic_adc_nids; 12995 spec->num_adc_nids = 1; 12996 spec->capsrc_nids = alc262_dmic_capsrc_nids; 12997 } else { 12998 /* all analog inputs */ 12999 /* check whether NID 0x07 is valid */ 13000 unsigned int wcap = get_wcaps(codec, 0x07); 13001 13002 /* get type */ 13003 wcap = get_wcaps_type(wcap); 13004 if (wcap != AC_WID_AUD_IN) { 13005 spec->adc_nids = alc262_adc_nids_alt; 13006 spec->num_adc_nids = 13007 ARRAY_SIZE(alc262_adc_nids_alt); 13008 spec->capsrc_nids = alc262_capsrc_nids_alt; 13009 } else { 13010 spec->adc_nids = alc262_adc_nids; 13011 spec->num_adc_nids = 13012 ARRAY_SIZE(alc262_adc_nids); 13013 spec->capsrc_nids = alc262_capsrc_nids; 13014 } 13015 } 13016 } 13017 if (!spec->cap_mixer && !spec->no_analog) 13018 set_capture_mixer(codec); 13019 if (!spec->no_analog && has_cdefine_beep(codec)) 13020 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 13021 13022 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); 13023 13024 spec->vmaster_nid = 0x0c; 13025 13026 codec->patch_ops = alc_patch_ops; 13027 if (board_config == ALC262_AUTO) 13028 spec->init_hook = alc262_auto_init; 13029 spec->shutup = alc_eapd_shutup; 13030 13031 alc_init_jacks(codec); 13032#ifdef CONFIG_SND_HDA_POWER_SAVE 13033 if (!spec->loopback.amplist) 13034 spec->loopback.amplist = alc262_loopbacks; 13035#endif 13036 13037 return 0; 13038} 13039 13040/* 13041 * ALC268 channel source setting (2 channel) 13042 */ 13043#define ALC268_DIGOUT_NID ALC880_DIGOUT_NID 13044#define alc268_modes alc260_modes 13045 13046static hda_nid_t alc268_dac_nids[2] = { 13047 /* front, hp */ 13048 0x02, 0x03 13049}; 13050 13051static hda_nid_t alc268_adc_nids[2] = { 13052 /* ADC0-1 */ 13053 0x08, 0x07 13054}; 13055 13056static hda_nid_t alc268_adc_nids_alt[1] = { 13057 /* ADC0 */ 13058 0x08 13059}; 13060 13061static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 }; 13062 13063static struct snd_kcontrol_new alc268_base_mixer[] = { 13064 /* output mixer control */ 13065 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), 13066 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 13067 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT), 13068 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 13069 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 13070 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), 13071 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT), 13072 { } 13073}; 13074 13075static struct snd_kcontrol_new alc268_toshiba_mixer[] = { 13076 /* output mixer control */ 13077 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), 13078 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT), 13079 ALC262_HIPPO_MASTER_SWITCH, 13080 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 13081 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), 13082 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT), 13083 { } 13084}; 13085 13086/* bind Beep switches of both NID 0x0f and 0x10 */ 13087static struct hda_bind_ctls alc268_bind_beep_sw = { 13088 .ops = &snd_hda_bind_sw, 13089 .values = { 13090 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT), 13091 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT), 13092 0 13093 }, 13094}; 13095 13096static struct snd_kcontrol_new alc268_beep_mixer[] = { 13097 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT), 13098 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw), 13099 { } 13100}; 13101 13102static struct hda_verb alc268_eapd_verbs[] = { 13103 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 13104 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, 13105 { } 13106}; 13107 13108/* Toshiba specific */ 13109static struct hda_verb alc268_toshiba_verbs[] = { 13110 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 13111 { } /* end */ 13112}; 13113 13114/* Acer specific */ 13115/* bind volumes of both NID 0x02 and 0x03 */ 13116static struct hda_bind_ctls alc268_acer_bind_master_vol = { 13117 .ops = &snd_hda_bind_vol, 13118 .values = { 13119 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), 13120 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT), 13121 0 13122 }, 13123}; 13124 13125/* mute/unmute internal speaker according to the hp jack and mute state */ 13126static void alc268_acer_automute(struct hda_codec *codec, int force) 13127{ 13128 struct alc_spec *spec = codec->spec; 13129 unsigned int mute; 13130 13131 if (force || !spec->sense_updated) { 13132 spec->jack_present = snd_hda_jack_detect(codec, 0x14); 13133 spec->sense_updated = 1; 13134 } 13135 if (spec->jack_present) 13136 mute = HDA_AMP_MUTE; /* mute internal speaker */ 13137 else /* unmute internal speaker if necessary */ 13138 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0); 13139 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 13140 HDA_AMP_MUTE, mute); 13141} 13142 13143 13144/* bind hp and internal speaker mute (with plug check) */ 13145static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol, 13146 struct snd_ctl_elem_value *ucontrol) 13147{ 13148 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 13149 long *valp = ucontrol->value.integer.value; 13150 int change; 13151 13152 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp); 13153 if (change) 13154 alc268_acer_automute(codec, 0); 13155 return change; 13156} 13157 13158static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = { 13159 /* output mixer control */ 13160 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), 13161 { 13162 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 13163 .name = "Master Playback Switch", 13164 .subdevice = HDA_SUBDEV_AMP_FLAG, 13165 .info = snd_hda_mixer_amp_switch_info, 13166 .get = snd_hda_mixer_amp_switch_get, 13167 .put = alc268_acer_master_sw_put, 13168 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 13169 }, 13170 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT), 13171 { } 13172}; 13173 13174static struct snd_kcontrol_new alc268_acer_mixer[] = { 13175 /* output mixer control */ 13176 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), 13177 { 13178 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 13179 .name = "Master Playback Switch", 13180 .subdevice = HDA_SUBDEV_AMP_FLAG, 13181 .info = snd_hda_mixer_amp_switch_info, 13182 .get = snd_hda_mixer_amp_switch_get, 13183 .put = alc268_acer_master_sw_put, 13184 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 13185 }, 13186 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 13187 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), 13188 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT), 13189 { } 13190}; 13191 13192static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = { 13193 /* output mixer control */ 13194 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), 13195 { 13196 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 13197 .name = "Master Playback Switch", 13198 .subdevice = HDA_SUBDEV_AMP_FLAG, 13199 .info = snd_hda_mixer_amp_switch_info, 13200 .get = snd_hda_mixer_amp_switch_get, 13201 .put = alc268_acer_master_sw_put, 13202 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 13203 }, 13204 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 13205 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT), 13206 { } 13207}; 13208 13209static struct hda_verb alc268_acer_aspire_one_verbs[] = { 13210 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 13211 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 13212 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 13213 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 13214 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06}, 13215 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017}, 13216 { } 13217}; 13218 13219static struct hda_verb alc268_acer_verbs[] = { 13220 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */ 13221 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 13222 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 13223 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 13224 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 13225 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 13226 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 13227 { } 13228}; 13229 13230/* unsolicited event for HP jack sensing */ 13231#define alc268_toshiba_unsol_event alc262_hippo_unsol_event 13232#define alc268_toshiba_setup alc262_hippo_setup 13233#define alc268_toshiba_automute alc262_hippo_automute 13234 13235static void alc268_acer_unsol_event(struct hda_codec *codec, 13236 unsigned int res) 13237{ 13238 if ((res >> 26) != ALC880_HP_EVENT) 13239 return; 13240 alc268_acer_automute(codec, 1); 13241} 13242 13243static void alc268_acer_init_hook(struct hda_codec *codec) 13244{ 13245 alc268_acer_automute(codec, 1); 13246} 13247 13248/* toggle speaker-output according to the hp-jack state */ 13249static void alc268_aspire_one_speaker_automute(struct hda_codec *codec) 13250{ 13251 unsigned int present; 13252 unsigned char bits; 13253 13254 present = snd_hda_jack_detect(codec, 0x15); 13255 bits = present ? HDA_AMP_MUTE : 0; 13256 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0, 13257 HDA_AMP_MUTE, bits); 13258 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1, 13259 HDA_AMP_MUTE, bits); 13260} 13261 13262static void alc268_acer_lc_unsol_event(struct hda_codec *codec, 13263 unsigned int res) 13264{ 13265 switch (res >> 26) { 13266 case ALC880_HP_EVENT: 13267 alc268_aspire_one_speaker_automute(codec); 13268 break; 13269 case ALC880_MIC_EVENT: 13270 alc_mic_automute(codec); 13271 break; 13272 } 13273} 13274 13275static void alc268_acer_lc_setup(struct hda_codec *codec) 13276{ 13277 struct alc_spec *spec = codec->spec; 13278 spec->ext_mic.pin = 0x18; 13279 spec->ext_mic.mux_idx = 0; 13280 spec->int_mic.pin = 0x12; 13281 spec->int_mic.mux_idx = 6; 13282 spec->auto_mic = 1; 13283} 13284 13285static void alc268_acer_lc_init_hook(struct hda_codec *codec) 13286{ 13287 alc268_aspire_one_speaker_automute(codec); 13288 alc_mic_automute(codec); 13289} 13290 13291static struct snd_kcontrol_new alc268_dell_mixer[] = { 13292 /* output mixer control */ 13293 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 13294 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 13295 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 13296 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 13297 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 13298 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), 13299 { } 13300}; 13301 13302static struct hda_verb alc268_dell_verbs[] = { 13303 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 13304 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 13305 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 13306 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, 13307 { } 13308}; 13309 13310/* mute/unmute internal speaker according to the hp jack and mute state */ 13311static void alc268_dell_setup(struct hda_codec *codec) 13312{ 13313 struct alc_spec *spec = codec->spec; 13314 13315 spec->autocfg.hp_pins[0] = 0x15; 13316 spec->autocfg.speaker_pins[0] = 0x14; 13317 spec->ext_mic.pin = 0x18; 13318 spec->ext_mic.mux_idx = 0; 13319 spec->int_mic.pin = 0x19; 13320 spec->int_mic.mux_idx = 1; 13321 spec->auto_mic = 1; 13322} 13323 13324static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = { 13325 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT), 13326 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 13327 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT), 13328 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 13329 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT), 13330 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT), 13331 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 13332 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), 13333 { } 13334}; 13335 13336static struct hda_verb alc267_quanta_il1_verbs[] = { 13337 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 13338 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, 13339 { } 13340}; 13341 13342static void alc267_quanta_il1_setup(struct hda_codec *codec) 13343{ 13344 struct alc_spec *spec = codec->spec; 13345 spec->autocfg.hp_pins[0] = 0x15; 13346 spec->autocfg.speaker_pins[0] = 0x14; 13347 spec->ext_mic.pin = 0x18; 13348 spec->ext_mic.mux_idx = 0; 13349 spec->int_mic.pin = 0x19; 13350 spec->int_mic.mux_idx = 1; 13351 spec->auto_mic = 1; 13352} 13353 13354/* 13355 * generic initialization of ADC, input mixers and output mixers 13356 */ 13357static struct hda_verb alc268_base_init_verbs[] = { 13358 /* Unmute DAC0-1 and set vol = 0 */ 13359 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 13360 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 13361 13362 /* 13363 * Set up output mixers (0x0c - 0x0e) 13364 */ 13365 /* set vol=0 to output mixers */ 13366 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13367 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00}, 13368 13369 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13370 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13371 13372 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 13373 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 13374 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 13375 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 13376 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 13377 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 13378 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 13379 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 13380 13381 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 13382 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 13383 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 13384 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 13385 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 13386 13387 /* set PCBEEP vol = 0, mute connections */ 13388 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13389 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 13390 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 13391 13392 /* Unmute Selector 23h,24h and set the default input to mic-in */ 13393 13394 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00}, 13395 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 13396 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00}, 13397 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 13398 13399 { } 13400}; 13401 13402/* 13403 * generic initialization of ADC, input mixers and output mixers 13404 */ 13405static struct hda_verb alc268_volume_init_verbs[] = { 13406 /* set output DAC */ 13407 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 13408 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 13409 13410 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 13411 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 13412 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 13413 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 13414 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 13415 13416 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13417 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13418 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13419 13420 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 13421 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 13422 13423 /* set PCBEEP vol = 0, mute connections */ 13424 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13425 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 13426 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 13427 13428 { } 13429}; 13430 13431static struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = { 13432 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT), 13433 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT), 13434 { } /* end */ 13435}; 13436 13437static struct snd_kcontrol_new alc268_capture_alt_mixer[] = { 13438 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT), 13439 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT), 13440 _DEFINE_CAPSRC(1), 13441 { } /* end */ 13442}; 13443 13444static struct snd_kcontrol_new alc268_capture_mixer[] = { 13445 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT), 13446 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT), 13447 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT), 13448 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT), 13449 _DEFINE_CAPSRC(2), 13450 { } /* end */ 13451}; 13452 13453static struct hda_input_mux alc268_capture_source = { 13454 .num_items = 4, 13455 .items = { 13456 { "Mic", 0x0 }, 13457 { "Front Mic", 0x1 }, 13458 { "Line", 0x2 }, 13459 { "CD", 0x3 }, 13460 }, 13461}; 13462 13463static struct hda_input_mux alc268_acer_capture_source = { 13464 .num_items = 3, 13465 .items = { 13466 { "Mic", 0x0 }, 13467 { "Internal Mic", 0x1 }, 13468 { "Line", 0x2 }, 13469 }, 13470}; 13471 13472static struct hda_input_mux alc268_acer_dmic_capture_source = { 13473 .num_items = 3, 13474 .items = { 13475 { "Mic", 0x0 }, 13476 { "Internal Mic", 0x6 }, 13477 { "Line", 0x2 }, 13478 }, 13479}; 13480 13481#ifdef CONFIG_SND_DEBUG 13482static struct snd_kcontrol_new alc268_test_mixer[] = { 13483 /* Volume widgets */ 13484 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT), 13485 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT), 13486 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT), 13487 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT), 13488 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT), 13489 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT), 13490 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT), 13491 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT), 13492 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT), 13493 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT), 13494 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT), 13495 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT), 13496 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT), 13497 /* The below appears problematic on some hardwares */ 13498 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/ 13499 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT), 13500 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT), 13501 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT), 13502 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT), 13503 13504 /* Modes for retasking pin widgets */ 13505 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT), 13506 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT), 13507 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT), 13508 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT), 13509 13510 /* Controls for GPIO pins, assuming they are configured as outputs */ 13511 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01), 13512 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02), 13513 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04), 13514 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08), 13515 13516 /* Switches to allow the digital SPDIF output pin to be enabled. 13517 * The ALC268 does not have an SPDIF input. 13518 */ 13519 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01), 13520 13521 /* A switch allowing EAPD to be enabled. Some laptops seem to use 13522 * this output to turn on an external amplifier. 13523 */ 13524 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02), 13525 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02), 13526 13527 { } /* end */ 13528}; 13529#endif 13530 13531/* create input playback/capture controls for the given pin */ 13532static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid, 13533 const char *ctlname, int idx) 13534{ 13535 hda_nid_t dac; 13536 int err; 13537 13538 switch (nid) { 13539 case 0x14: 13540 case 0x16: 13541 dac = 0x02; 13542 break; 13543 case 0x15: 13544 case 0x1a: /* ALC259/269 only */ 13545 case 0x1b: /* ALC259/269 only */ 13546 case 0x21: /* ALC269vb has this pin, too */ 13547 dac = 0x03; 13548 break; 13549 default: 13550 snd_printd(KERN_WARNING "hda_codec: " 13551 "ignoring pin 0x%x as unknown\n", nid); 13552 return 0; 13553 } 13554 if (spec->multiout.dac_nids[0] != dac && 13555 spec->multiout.dac_nids[1] != dac) { 13556 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname, 13557 HDA_COMPOSE_AMP_VAL(dac, 3, idx, 13558 HDA_OUTPUT)); 13559 if (err < 0) 13560 return err; 13561 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac; 13562 } 13563 13564 if (nid != 0x16) 13565 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname, 13566 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT)); 13567 else /* mono */ 13568 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname, 13569 HDA_COMPOSE_AMP_VAL(nid, 2, idx, HDA_OUTPUT)); 13570 if (err < 0) 13571 return err; 13572 return 0; 13573} 13574 13575/* add playback controls from the parsed DAC table */ 13576static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec, 13577 const struct auto_pin_cfg *cfg) 13578{ 13579 hda_nid_t nid; 13580 int err; 13581 13582 spec->multiout.dac_nids = spec->private_dac_nids; 13583 13584 nid = cfg->line_out_pins[0]; 13585 if (nid) { 13586 const char *name; 13587 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) 13588 name = "Speaker"; 13589 else 13590 name = "Front"; 13591 err = alc268_new_analog_output(spec, nid, name, 0); 13592 if (err < 0) 13593 return err; 13594 } 13595 13596 nid = cfg->speaker_pins[0]; 13597 if (nid == 0x1d) { 13598 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, "Speaker", 13599 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT)); 13600 if (err < 0) 13601 return err; 13602 } else if (nid) { 13603 err = alc268_new_analog_output(spec, nid, "Speaker", 0); 13604 if (err < 0) 13605 return err; 13606 } 13607 nid = cfg->hp_pins[0]; 13608 if (nid) { 13609 err = alc268_new_analog_output(spec, nid, "Headphone", 0); 13610 if (err < 0) 13611 return err; 13612 } 13613 13614 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2]; 13615 if (nid == 0x16) { 13616 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, "Mono", 13617 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT)); 13618 if (err < 0) 13619 return err; 13620 } 13621 return 0; 13622} 13623 13624/* create playback/capture controls for input pins */ 13625static int alc268_auto_create_input_ctls(struct hda_codec *codec, 13626 const struct auto_pin_cfg *cfg) 13627{ 13628 return alc_auto_create_input_ctls(codec, cfg, 0, 0x23, 0x24); 13629} 13630 13631static void alc268_auto_set_output_and_unmute(struct hda_codec *codec, 13632 hda_nid_t nid, int pin_type) 13633{ 13634 int idx; 13635 13636 alc_set_pin_output(codec, nid, pin_type); 13637 if (nid == 0x14 || nid == 0x16) 13638 idx = 0; 13639 else 13640 idx = 1; 13641 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx); 13642} 13643 13644static void alc268_auto_init_multi_out(struct hda_codec *codec) 13645{ 13646 struct alc_spec *spec = codec->spec; 13647 int i; 13648 13649 for (i = 0; i < spec->autocfg.line_outs; i++) { 13650 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 13651 int pin_type = get_pin_type(spec->autocfg.line_out_type); 13652 alc268_auto_set_output_and_unmute(codec, nid, pin_type); 13653 } 13654} 13655 13656static void alc268_auto_init_hp_out(struct hda_codec *codec) 13657{ 13658 struct alc_spec *spec = codec->spec; 13659 hda_nid_t pin; 13660 int i; 13661 13662 for (i = 0; i < spec->autocfg.hp_outs; i++) { 13663 pin = spec->autocfg.hp_pins[i]; 13664 alc268_auto_set_output_and_unmute(codec, pin, PIN_HP); 13665 } 13666 for (i = 0; i < spec->autocfg.speaker_outs; i++) { 13667 pin = spec->autocfg.speaker_pins[i]; 13668 alc268_auto_set_output_and_unmute(codec, pin, PIN_OUT); 13669 } 13670 if (spec->autocfg.mono_out_pin) 13671 snd_hda_codec_write(codec, spec->autocfg.mono_out_pin, 0, 13672 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); 13673} 13674 13675static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec) 13676{ 13677 struct alc_spec *spec = codec->spec; 13678 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0]; 13679 hda_nid_t hp_nid = spec->autocfg.hp_pins[0]; 13680 hda_nid_t line_nid = spec->autocfg.line_out_pins[0]; 13681 unsigned int dac_vol1, dac_vol2; 13682 13683 if (line_nid == 0x1d || speaker_nid == 0x1d) { 13684 snd_hda_codec_write(codec, speaker_nid, 0, 13685 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); 13686 /* mute mixer inputs from 0x1d */ 13687 snd_hda_codec_write(codec, 0x0f, 0, 13688 AC_VERB_SET_AMP_GAIN_MUTE, 13689 AMP_IN_UNMUTE(1)); 13690 snd_hda_codec_write(codec, 0x10, 0, 13691 AC_VERB_SET_AMP_GAIN_MUTE, 13692 AMP_IN_UNMUTE(1)); 13693 } else { 13694 /* unmute mixer inputs from 0x1d */ 13695 snd_hda_codec_write(codec, 0x0f, 0, 13696 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)); 13697 snd_hda_codec_write(codec, 0x10, 0, 13698 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)); 13699 } 13700 13701 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */ 13702 if (line_nid == 0x14) 13703 dac_vol2 = AMP_OUT_ZERO; 13704 else if (line_nid == 0x15) 13705 dac_vol1 = AMP_OUT_ZERO; 13706 if (hp_nid == 0x14) 13707 dac_vol2 = AMP_OUT_ZERO; 13708 else if (hp_nid == 0x15) 13709 dac_vol1 = AMP_OUT_ZERO; 13710 if (line_nid != 0x16 || hp_nid != 0x16 || 13711 spec->autocfg.line_out_pins[1] != 0x16 || 13712 spec->autocfg.line_out_pins[2] != 0x16) 13713 dac_vol1 = dac_vol2 = AMP_OUT_ZERO; 13714 13715 snd_hda_codec_write(codec, 0x02, 0, 13716 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1); 13717 snd_hda_codec_write(codec, 0x03, 0, 13718 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2); 13719} 13720 13721/* pcm configuration: identical with ALC880 */ 13722#define alc268_pcm_analog_playback alc880_pcm_analog_playback 13723#define alc268_pcm_analog_capture alc880_pcm_analog_capture 13724#define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture 13725#define alc268_pcm_digital_playback alc880_pcm_digital_playback 13726 13727/* 13728 * BIOS auto configuration 13729 */ 13730static int alc268_parse_auto_config(struct hda_codec *codec) 13731{ 13732 struct alc_spec *spec = codec->spec; 13733 int err; 13734 static hda_nid_t alc268_ignore[] = { 0 }; 13735 13736 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 13737 alc268_ignore); 13738 if (err < 0) 13739 return err; 13740 if (!spec->autocfg.line_outs) { 13741 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) { 13742 spec->multiout.max_channels = 2; 13743 spec->no_analog = 1; 13744 goto dig_only; 13745 } 13746 return 0; /* can't find valid BIOS pin config */ 13747 } 13748 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg); 13749 if (err < 0) 13750 return err; 13751 err = alc268_auto_create_input_ctls(codec, &spec->autocfg); 13752 if (err < 0) 13753 return err; 13754 13755 spec->multiout.max_channels = 2; 13756 13757 dig_only: 13758 /* digital only support output */ 13759 alc_auto_parse_digital(codec); 13760 if (spec->kctls.list) 13761 add_mixer(spec, spec->kctls.list); 13762 13763 if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d) 13764 add_mixer(spec, alc268_beep_mixer); 13765 13766 add_verb(spec, alc268_volume_init_verbs); 13767 spec->num_mux_defs = 2; 13768 spec->input_mux = &spec->private_imux[0]; 13769 13770 err = alc_auto_add_mic_boost(codec); 13771 if (err < 0) 13772 return err; 13773 13774 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); 13775 13776 return 1; 13777} 13778 13779#define alc268_auto_init_analog_input alc882_auto_init_analog_input 13780#define alc268_auto_init_input_src alc882_auto_init_input_src 13781 13782/* init callback for auto-configuration model -- overriding the default init */ 13783static void alc268_auto_init(struct hda_codec *codec) 13784{ 13785 struct alc_spec *spec = codec->spec; 13786 alc268_auto_init_multi_out(codec); 13787 alc268_auto_init_hp_out(codec); 13788 alc268_auto_init_mono_speaker_out(codec); 13789 alc268_auto_init_analog_input(codec); 13790 alc268_auto_init_input_src(codec); 13791 alc_auto_init_digital(codec); 13792 if (spec->unsol_event) 13793 alc_inithook(codec); 13794} 13795 13796/* 13797 * configuration and preset 13798 */ 13799static const char * const alc268_models[ALC268_MODEL_LAST] = { 13800 [ALC267_QUANTA_IL1] = "quanta-il1", 13801 [ALC268_3ST] = "3stack", 13802 [ALC268_TOSHIBA] = "toshiba", 13803 [ALC268_ACER] = "acer", 13804 [ALC268_ACER_DMIC] = "acer-dmic", 13805 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire", 13806 [ALC268_DELL] = "dell", 13807 [ALC268_ZEPTO] = "zepto", 13808#ifdef CONFIG_SND_DEBUG 13809 [ALC268_TEST] = "test", 13810#endif 13811 [ALC268_AUTO] = "auto", 13812}; 13813 13814static struct snd_pci_quirk alc268_cfg_tbl[] = { 13815 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER), 13816 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER), 13817 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER), 13818 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER), 13819 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER), 13820 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One", 13821 ALC268_ACER_ASPIRE_ONE), 13822 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL), 13823 SND_PCI_QUIRK_MASK(0x1028, 0xfff0, 0x02b0, 13824 "Dell Inspiron Mini9/Vostro A90", ALC268_DELL), 13825 /* almost compatible with toshiba but with optional digital outs; 13826 * auto-probing seems working fine 13827 */ 13828 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series", 13829 ALC268_AUTO), 13830 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST), 13831 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO), 13832 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA), 13833 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER), 13834 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1), 13835 {} 13836}; 13837 13838/* Toshiba laptops have no unique PCI SSID but only codec SSID */ 13839static struct snd_pci_quirk alc268_ssid_cfg_tbl[] = { 13840 SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO), 13841 SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO), 13842 SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05", 13843 ALC268_TOSHIBA), 13844 {} 13845}; 13846 13847static struct alc_config_preset alc268_presets[] = { 13848 [ALC267_QUANTA_IL1] = { 13849 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer, 13850 alc268_capture_nosrc_mixer }, 13851 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 13852 alc267_quanta_il1_verbs }, 13853 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 13854 .dac_nids = alc268_dac_nids, 13855 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 13856 .adc_nids = alc268_adc_nids_alt, 13857 .hp_nid = 0x03, 13858 .num_channel_mode = ARRAY_SIZE(alc268_modes), 13859 .channel_mode = alc268_modes, 13860 .unsol_event = alc_sku_unsol_event, 13861 .setup = alc267_quanta_il1_setup, 13862 .init_hook = alc_inithook, 13863 }, 13864 [ALC268_3ST] = { 13865 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer, 13866 alc268_beep_mixer }, 13867 .init_verbs = { alc268_base_init_verbs }, 13868 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 13869 .dac_nids = alc268_dac_nids, 13870 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 13871 .adc_nids = alc268_adc_nids_alt, 13872 .capsrc_nids = alc268_capsrc_nids, 13873 .hp_nid = 0x03, 13874 .dig_out_nid = ALC268_DIGOUT_NID, 13875 .num_channel_mode = ARRAY_SIZE(alc268_modes), 13876 .channel_mode = alc268_modes, 13877 .input_mux = &alc268_capture_source, 13878 }, 13879 [ALC268_TOSHIBA] = { 13880 .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer, 13881 alc268_beep_mixer }, 13882 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 13883 alc268_toshiba_verbs }, 13884 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 13885 .dac_nids = alc268_dac_nids, 13886 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 13887 .adc_nids = alc268_adc_nids_alt, 13888 .capsrc_nids = alc268_capsrc_nids, 13889 .hp_nid = 0x03, 13890 .num_channel_mode = ARRAY_SIZE(alc268_modes), 13891 .channel_mode = alc268_modes, 13892 .input_mux = &alc268_capture_source, 13893 .unsol_event = alc268_toshiba_unsol_event, 13894 .setup = alc268_toshiba_setup, 13895 .init_hook = alc268_toshiba_automute, 13896 }, 13897 [ALC268_ACER] = { 13898 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer, 13899 alc268_beep_mixer }, 13900 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 13901 alc268_acer_verbs }, 13902 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 13903 .dac_nids = alc268_dac_nids, 13904 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 13905 .adc_nids = alc268_adc_nids_alt, 13906 .capsrc_nids = alc268_capsrc_nids, 13907 .hp_nid = 0x02, 13908 .num_channel_mode = ARRAY_SIZE(alc268_modes), 13909 .channel_mode = alc268_modes, 13910 .input_mux = &alc268_acer_capture_source, 13911 .unsol_event = alc268_acer_unsol_event, 13912 .init_hook = alc268_acer_init_hook, 13913 }, 13914 [ALC268_ACER_DMIC] = { 13915 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer, 13916 alc268_beep_mixer }, 13917 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 13918 alc268_acer_verbs }, 13919 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 13920 .dac_nids = alc268_dac_nids, 13921 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 13922 .adc_nids = alc268_adc_nids_alt, 13923 .capsrc_nids = alc268_capsrc_nids, 13924 .hp_nid = 0x02, 13925 .num_channel_mode = ARRAY_SIZE(alc268_modes), 13926 .channel_mode = alc268_modes, 13927 .input_mux = &alc268_acer_dmic_capture_source, 13928 .unsol_event = alc268_acer_unsol_event, 13929 .init_hook = alc268_acer_init_hook, 13930 }, 13931 [ALC268_ACER_ASPIRE_ONE] = { 13932 .mixers = { alc268_acer_aspire_one_mixer, 13933 alc268_beep_mixer, 13934 alc268_capture_nosrc_mixer }, 13935 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 13936 alc268_acer_aspire_one_verbs }, 13937 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 13938 .dac_nids = alc268_dac_nids, 13939 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 13940 .adc_nids = alc268_adc_nids_alt, 13941 .capsrc_nids = alc268_capsrc_nids, 13942 .hp_nid = 0x03, 13943 .num_channel_mode = ARRAY_SIZE(alc268_modes), 13944 .channel_mode = alc268_modes, 13945 .unsol_event = alc268_acer_lc_unsol_event, 13946 .setup = alc268_acer_lc_setup, 13947 .init_hook = alc268_acer_lc_init_hook, 13948 }, 13949 [ALC268_DELL] = { 13950 .mixers = { alc268_dell_mixer, alc268_beep_mixer, 13951 alc268_capture_nosrc_mixer }, 13952 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 13953 alc268_dell_verbs }, 13954 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 13955 .dac_nids = alc268_dac_nids, 13956 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 13957 .adc_nids = alc268_adc_nids_alt, 13958 .capsrc_nids = alc268_capsrc_nids, 13959 .hp_nid = 0x02, 13960 .num_channel_mode = ARRAY_SIZE(alc268_modes), 13961 .channel_mode = alc268_modes, 13962 .unsol_event = alc_sku_unsol_event, 13963 .setup = alc268_dell_setup, 13964 .init_hook = alc_inithook, 13965 }, 13966 [ALC268_ZEPTO] = { 13967 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer, 13968 alc268_beep_mixer }, 13969 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 13970 alc268_toshiba_verbs }, 13971 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 13972 .dac_nids = alc268_dac_nids, 13973 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 13974 .adc_nids = alc268_adc_nids_alt, 13975 .capsrc_nids = alc268_capsrc_nids, 13976 .hp_nid = 0x03, 13977 .dig_out_nid = ALC268_DIGOUT_NID, 13978 .num_channel_mode = ARRAY_SIZE(alc268_modes), 13979 .channel_mode = alc268_modes, 13980 .input_mux = &alc268_capture_source, 13981 .setup = alc268_toshiba_setup, 13982 .init_hook = alc268_toshiba_automute, 13983 }, 13984#ifdef CONFIG_SND_DEBUG 13985 [ALC268_TEST] = { 13986 .mixers = { alc268_test_mixer, alc268_capture_mixer }, 13987 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 13988 alc268_volume_init_verbs }, 13989 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 13990 .dac_nids = alc268_dac_nids, 13991 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 13992 .adc_nids = alc268_adc_nids_alt, 13993 .capsrc_nids = alc268_capsrc_nids, 13994 .hp_nid = 0x03, 13995 .dig_out_nid = ALC268_DIGOUT_NID, 13996 .num_channel_mode = ARRAY_SIZE(alc268_modes), 13997 .channel_mode = alc268_modes, 13998 .input_mux = &alc268_capture_source, 13999 }, 14000#endif 14001}; 14002 14003static int patch_alc268(struct hda_codec *codec) 14004{ 14005 struct alc_spec *spec; 14006 int board_config; 14007 int i, has_beep, err; 14008 14009 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 14010 if (spec == NULL) 14011 return -ENOMEM; 14012 14013 codec->spec = spec; 14014 14015 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST, 14016 alc268_models, 14017 alc268_cfg_tbl); 14018 14019 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) 14020 board_config = snd_hda_check_board_codec_sid_config(codec, 14021 ALC268_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl); 14022 14023 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) { 14024 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 14025 codec->chip_name); 14026 board_config = ALC268_AUTO; 14027 } 14028 14029 if (board_config == ALC268_AUTO) { 14030 /* automatic parse from the BIOS config */ 14031 err = alc268_parse_auto_config(codec); 14032 if (err < 0) { 14033 alc_free(codec); 14034 return err; 14035 } else if (!err) { 14036 printk(KERN_INFO 14037 "hda_codec: Cannot set up configuration " 14038 "from BIOS. Using base mode...\n"); 14039 board_config = ALC268_3ST; 14040 } 14041 } 14042 14043 if (board_config != ALC268_AUTO) 14044 setup_preset(codec, &alc268_presets[board_config]); 14045 14046 spec->stream_analog_playback = &alc268_pcm_analog_playback; 14047 spec->stream_analog_capture = &alc268_pcm_analog_capture; 14048 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture; 14049 14050 spec->stream_digital_playback = &alc268_pcm_digital_playback; 14051 14052 has_beep = 0; 14053 for (i = 0; i < spec->num_mixers; i++) { 14054 if (spec->mixers[i] == alc268_beep_mixer) { 14055 has_beep = 1; 14056 break; 14057 } 14058 } 14059 14060 if (has_beep) { 14061 err = snd_hda_attach_beep_device(codec, 0x1); 14062 if (err < 0) { 14063 alc_free(codec); 14064 return err; 14065 } 14066 if (!query_amp_caps(codec, 0x1d, HDA_INPUT)) 14067 /* override the amp caps for beep generator */ 14068 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT, 14069 (0x0c << AC_AMPCAP_OFFSET_SHIFT) | 14070 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) | 14071 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) | 14072 (0 << AC_AMPCAP_MUTE_SHIFT)); 14073 } 14074 14075 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) { 14076 /* check whether NID 0x07 is valid */ 14077 unsigned int wcap = get_wcaps(codec, 0x07); 14078 14079 spec->capsrc_nids = alc268_capsrc_nids; 14080 /* get type */ 14081 wcap = get_wcaps_type(wcap); 14082 if (spec->auto_mic || 14083 wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) { 14084 spec->adc_nids = alc268_adc_nids_alt; 14085 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt); 14086 if (spec->auto_mic) 14087 fixup_automic_adc(codec); 14088 if (spec->auto_mic || spec->input_mux->num_items == 1) 14089 add_mixer(spec, alc268_capture_nosrc_mixer); 14090 else 14091 add_mixer(spec, alc268_capture_alt_mixer); 14092 } else { 14093 spec->adc_nids = alc268_adc_nids; 14094 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids); 14095 add_mixer(spec, alc268_capture_mixer); 14096 } 14097 } 14098 14099 spec->vmaster_nid = 0x02; 14100 14101 codec->patch_ops = alc_patch_ops; 14102 if (board_config == ALC268_AUTO) 14103 spec->init_hook = alc268_auto_init; 14104 spec->shutup = alc_eapd_shutup; 14105 14106 alc_init_jacks(codec); 14107 14108 return 0; 14109} 14110 14111/* 14112 * ALC269 channel source setting (2 channel) 14113 */ 14114#define ALC269_DIGOUT_NID ALC880_DIGOUT_NID 14115 14116#define alc269_dac_nids alc260_dac_nids 14117 14118static hda_nid_t alc269_adc_nids[1] = { 14119 /* ADC1 */ 14120 0x08, 14121}; 14122 14123static hda_nid_t alc269_capsrc_nids[1] = { 14124 0x23, 14125}; 14126 14127static hda_nid_t alc269vb_adc_nids[1] = { 14128 /* ADC1 */ 14129 0x09, 14130}; 14131 14132static hda_nid_t alc269vb_capsrc_nids[1] = { 14133 0x22, 14134}; 14135 14136static hda_nid_t alc269_adc_candidates[] = { 14137 0x08, 0x09, 0x07, 14138}; 14139 14140#define alc269_modes alc260_modes 14141#define alc269_capture_source alc880_lg_lw_capture_source 14142 14143static struct snd_kcontrol_new alc269_base_mixer[] = { 14144 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 14145 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 14146 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 14147 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 14148 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 14149 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 14150 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 14151 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 14152 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 14153 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), 14154 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 14155 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT), 14156 { } /* end */ 14157}; 14158 14159static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = { 14160 /* output mixer control */ 14161 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), 14162 { 14163 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 14164 .name = "Master Playback Switch", 14165 .subdevice = HDA_SUBDEV_AMP_FLAG, 14166 .info = snd_hda_mixer_amp_switch_info, 14167 .get = snd_hda_mixer_amp_switch_get, 14168 .put = alc268_acer_master_sw_put, 14169 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 14170 }, 14171 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 14172 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 14173 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 14174 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 14175 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 14176 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), 14177 { } 14178}; 14179 14180static struct snd_kcontrol_new alc269_lifebook_mixer[] = { 14181 /* output mixer control */ 14182 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), 14183 { 14184 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 14185 .name = "Master Playback Switch", 14186 .subdevice = HDA_SUBDEV_AMP_FLAG, 14187 .info = snd_hda_mixer_amp_switch_info, 14188 .get = snd_hda_mixer_amp_switch_get, 14189 .put = alc268_acer_master_sw_put, 14190 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 14191 }, 14192 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 14193 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 14194 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 14195 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 14196 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 14197 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), 14198 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT), 14199 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT), 14200 HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x1b, 0, HDA_INPUT), 14201 { } 14202}; 14203 14204static struct snd_kcontrol_new alc269_laptop_mixer[] = { 14205 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 14206 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 14207 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 14208 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 14209 { } /* end */ 14210}; 14211 14212static struct snd_kcontrol_new alc269vb_laptop_mixer[] = { 14213 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 14214 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 14215 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT), 14216 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 14217 { } /* end */ 14218}; 14219 14220static struct snd_kcontrol_new alc269_asus_mixer[] = { 14221 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT), 14222 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x0, HDA_INPUT), 14223 { } /* end */ 14224}; 14225 14226/* capture mixer elements */ 14227static struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = { 14228 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 14229 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 14230 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 14231 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), 14232 { } /* end */ 14233}; 14234 14235static struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = { 14236 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 14237 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 14238 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 14239 { } /* end */ 14240}; 14241 14242static struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = { 14243 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), 14244 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), 14245 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 14246 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), 14247 { } /* end */ 14248}; 14249 14250static struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = { 14251 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), 14252 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), 14253 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 14254 { } /* end */ 14255}; 14256 14257/* FSC amilo */ 14258#define alc269_fujitsu_mixer alc269_laptop_mixer 14259 14260static struct hda_verb alc269_quanta_fl1_verbs[] = { 14261 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 14262 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14263 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 14264 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 14265 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 14266 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14267 { } 14268}; 14269 14270static struct hda_verb alc269_lifebook_verbs[] = { 14271 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 14272 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, 14273 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14274 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 14275 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 14276 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 14277 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 14278 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 14279 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 14280 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14281 { } 14282}; 14283 14284/* toggle speaker-output according to the hp-jack state */ 14285static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec) 14286{ 14287 unsigned int present; 14288 unsigned char bits; 14289 14290 present = snd_hda_jack_detect(codec, 0x15); 14291 bits = present ? HDA_AMP_MUTE : 0; 14292 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 14293 HDA_AMP_MUTE, bits); 14294 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 14295 HDA_AMP_MUTE, bits); 14296 14297 snd_hda_codec_write(codec, 0x20, 0, 14298 AC_VERB_SET_COEF_INDEX, 0x0c); 14299 snd_hda_codec_write(codec, 0x20, 0, 14300 AC_VERB_SET_PROC_COEF, 0x680); 14301 14302 snd_hda_codec_write(codec, 0x20, 0, 14303 AC_VERB_SET_COEF_INDEX, 0x0c); 14304 snd_hda_codec_write(codec, 0x20, 0, 14305 AC_VERB_SET_PROC_COEF, 0x480); 14306} 14307 14308/* toggle speaker-output according to the hp-jacks state */ 14309static void alc269_lifebook_speaker_automute(struct hda_codec *codec) 14310{ 14311 unsigned int present; 14312 unsigned char bits; 14313 14314 /* Check laptop headphone socket */ 14315 present = snd_hda_jack_detect(codec, 0x15); 14316 14317 /* Check port replicator headphone socket */ 14318 present |= snd_hda_jack_detect(codec, 0x1a); 14319 14320 bits = present ? HDA_AMP_MUTE : 0; 14321 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 14322 HDA_AMP_MUTE, bits); 14323 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 14324 HDA_AMP_MUTE, bits); 14325 14326 snd_hda_codec_write(codec, 0x20, 0, 14327 AC_VERB_SET_COEF_INDEX, 0x0c); 14328 snd_hda_codec_write(codec, 0x20, 0, 14329 AC_VERB_SET_PROC_COEF, 0x680); 14330 14331 snd_hda_codec_write(codec, 0x20, 0, 14332 AC_VERB_SET_COEF_INDEX, 0x0c); 14333 snd_hda_codec_write(codec, 0x20, 0, 14334 AC_VERB_SET_PROC_COEF, 0x480); 14335} 14336 14337static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec) 14338{ 14339 unsigned int present_laptop; 14340 unsigned int present_dock; 14341 14342 present_laptop = snd_hda_jack_detect(codec, 0x18); 14343 present_dock = snd_hda_jack_detect(codec, 0x1b); 14344 14345 /* Laptop mic port overrides dock mic port, design decision */ 14346 if (present_dock) 14347 snd_hda_codec_write(codec, 0x23, 0, 14348 AC_VERB_SET_CONNECT_SEL, 0x3); 14349 if (present_laptop) 14350 snd_hda_codec_write(codec, 0x23, 0, 14351 AC_VERB_SET_CONNECT_SEL, 0x0); 14352 if (!present_dock && !present_laptop) 14353 snd_hda_codec_write(codec, 0x23, 0, 14354 AC_VERB_SET_CONNECT_SEL, 0x1); 14355} 14356 14357static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec, 14358 unsigned int res) 14359{ 14360 switch (res >> 26) { 14361 case ALC880_HP_EVENT: 14362 alc269_quanta_fl1_speaker_automute(codec); 14363 break; 14364 case ALC880_MIC_EVENT: 14365 alc_mic_automute(codec); 14366 break; 14367 } 14368} 14369 14370static void alc269_lifebook_unsol_event(struct hda_codec *codec, 14371 unsigned int res) 14372{ 14373 if ((res >> 26) == ALC880_HP_EVENT) 14374 alc269_lifebook_speaker_automute(codec); 14375 if ((res >> 26) == ALC880_MIC_EVENT) 14376 alc269_lifebook_mic_autoswitch(codec); 14377} 14378 14379static void alc269_quanta_fl1_setup(struct hda_codec *codec) 14380{ 14381 struct alc_spec *spec = codec->spec; 14382 spec->autocfg.hp_pins[0] = 0x15; 14383 spec->autocfg.speaker_pins[0] = 0x14; 14384 spec->ext_mic.pin = 0x18; 14385 spec->ext_mic.mux_idx = 0; 14386 spec->int_mic.pin = 0x19; 14387 spec->int_mic.mux_idx = 1; 14388 spec->auto_mic = 1; 14389} 14390 14391static void alc269_quanta_fl1_init_hook(struct hda_codec *codec) 14392{ 14393 alc269_quanta_fl1_speaker_automute(codec); 14394 alc_mic_automute(codec); 14395} 14396 14397static void alc269_lifebook_init_hook(struct hda_codec *codec) 14398{ 14399 alc269_lifebook_speaker_automute(codec); 14400 alc269_lifebook_mic_autoswitch(codec); 14401} 14402 14403static struct hda_verb alc269_laptop_dmic_init_verbs[] = { 14404 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 14405 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05}, 14406 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 }, 14407 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))}, 14408 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14409 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 14410 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 14411 {} 14412}; 14413 14414static struct hda_verb alc269_laptop_amic_init_verbs[] = { 14415 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 14416 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01}, 14417 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 }, 14418 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))}, 14419 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 14420 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 14421 {} 14422}; 14423 14424static struct hda_verb alc269vb_laptop_dmic_init_verbs[] = { 14425 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, 14426 {0x22, AC_VERB_SET_CONNECT_SEL, 0x06}, 14427 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 }, 14428 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))}, 14429 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14430 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 14431 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 14432 {} 14433}; 14434 14435static struct hda_verb alc269vb_laptop_amic_init_verbs[] = { 14436 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, 14437 {0x22, AC_VERB_SET_CONNECT_SEL, 0x01}, 14438 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 }, 14439 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))}, 14440 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14441 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 14442 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 14443 {} 14444}; 14445 14446static struct hda_verb alc271_acer_dmic_verbs[] = { 14447 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d}, 14448 {0x20, AC_VERB_SET_PROC_COEF, 0x4000}, 14449 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14450 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 14451 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 14452 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 14453 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, 14454 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 14455 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 14456 {0x22, AC_VERB_SET_CONNECT_SEL, 6}, 14457 { } 14458}; 14459 14460/* toggle speaker-output according to the hp-jack state */ 14461static void alc269_speaker_automute(struct hda_codec *codec) 14462{ 14463 struct alc_spec *spec = codec->spec; 14464 unsigned int nid = spec->autocfg.hp_pins[0]; 14465 unsigned int present; 14466 unsigned char bits; 14467 14468 present = snd_hda_jack_detect(codec, nid); 14469 bits = present ? HDA_AMP_MUTE : 0; 14470 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 14471 HDA_AMP_MUTE, bits); 14472 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 14473 HDA_AMP_MUTE, bits); 14474 snd_hda_input_jack_report(codec, nid); 14475} 14476 14477/* unsolicited event for HP jack sensing */ 14478static void alc269_laptop_unsol_event(struct hda_codec *codec, 14479 unsigned int res) 14480{ 14481 switch (res >> 26) { 14482 case ALC880_HP_EVENT: 14483 alc269_speaker_automute(codec); 14484 break; 14485 case ALC880_MIC_EVENT: 14486 alc_mic_automute(codec); 14487 break; 14488 } 14489} 14490 14491static void alc269_laptop_amic_setup(struct hda_codec *codec) 14492{ 14493 struct alc_spec *spec = codec->spec; 14494 spec->autocfg.hp_pins[0] = 0x15; 14495 spec->autocfg.speaker_pins[0] = 0x14; 14496 spec->ext_mic.pin = 0x18; 14497 spec->ext_mic.mux_idx = 0; 14498 spec->int_mic.pin = 0x19; 14499 spec->int_mic.mux_idx = 1; 14500 spec->auto_mic = 1; 14501} 14502 14503static void alc269_laptop_dmic_setup(struct hda_codec *codec) 14504{ 14505 struct alc_spec *spec = codec->spec; 14506 spec->autocfg.hp_pins[0] = 0x15; 14507 spec->autocfg.speaker_pins[0] = 0x14; 14508 spec->ext_mic.pin = 0x18; 14509 spec->ext_mic.mux_idx = 0; 14510 spec->int_mic.pin = 0x12; 14511 spec->int_mic.mux_idx = 5; 14512 spec->auto_mic = 1; 14513} 14514 14515static void alc269vb_laptop_amic_setup(struct hda_codec *codec) 14516{ 14517 struct alc_spec *spec = codec->spec; 14518 spec->autocfg.hp_pins[0] = 0x21; 14519 spec->autocfg.speaker_pins[0] = 0x14; 14520 spec->ext_mic.pin = 0x18; 14521 spec->ext_mic.mux_idx = 0; 14522 spec->int_mic.pin = 0x19; 14523 spec->int_mic.mux_idx = 1; 14524 spec->auto_mic = 1; 14525} 14526 14527static void alc269vb_laptop_dmic_setup(struct hda_codec *codec) 14528{ 14529 struct alc_spec *spec = codec->spec; 14530 spec->autocfg.hp_pins[0] = 0x21; 14531 spec->autocfg.speaker_pins[0] = 0x14; 14532 spec->ext_mic.pin = 0x18; 14533 spec->ext_mic.mux_idx = 0; 14534 spec->int_mic.pin = 0x12; 14535 spec->int_mic.mux_idx = 6; 14536 spec->auto_mic = 1; 14537} 14538 14539static void alc269_laptop_inithook(struct hda_codec *codec) 14540{ 14541 alc269_speaker_automute(codec); 14542 alc_mic_automute(codec); 14543} 14544 14545/* 14546 * generic initialization of ADC, input mixers and output mixers 14547 */ 14548static struct hda_verb alc269_init_verbs[] = { 14549 /* 14550 * Unmute ADC0 and set the default input to mic-in 14551 */ 14552 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14553 14554 /* 14555 * Set up output mixers (0x02 - 0x03) 14556 */ 14557 /* set vol=0 to output mixers */ 14558 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 14559 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 14560 14561 /* set up input amps for analog loopback */ 14562 /* Amp Indices: DAC = 0, mixer = 1 */ 14563 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14564 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 14565 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14566 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 14567 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14568 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 14569 14570 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 14571 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 14572 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 14573 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 14574 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 14575 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14576 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14577 14578 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 14579 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 14580 14581 /* FIXME: use Mux-type input source selection */ 14582 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */ 14583 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 14584 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00}, 14585 14586 /* set EAPD */ 14587 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 14588 { } 14589}; 14590 14591static struct hda_verb alc269vb_init_verbs[] = { 14592 /* 14593 * Unmute ADC0 and set the default input to mic-in 14594 */ 14595 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14596 14597 /* 14598 * Set up output mixers (0x02 - 0x03) 14599 */ 14600 /* set vol=0 to output mixers */ 14601 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 14602 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 14603 14604 /* set up input amps for analog loopback */ 14605 /* Amp Indices: DAC = 0, mixer = 1 */ 14606 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14607 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 14608 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14609 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 14610 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14611 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 14612 14613 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 14614 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 14615 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 14616 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 14617 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 14618 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14619 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14620 14621 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 14622 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 14623 14624 /* FIXME: use Mux-type input source selection */ 14625 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */ 14626 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 14627 {0x22, AC_VERB_SET_CONNECT_SEL, 0x00}, 14628 14629 /* set EAPD */ 14630 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 14631 { } 14632}; 14633 14634#define alc269_auto_create_multi_out_ctls \ 14635 alc268_auto_create_multi_out_ctls 14636#define alc269_auto_create_input_ctls \ 14637 alc268_auto_create_input_ctls 14638 14639#ifdef CONFIG_SND_HDA_POWER_SAVE 14640#define alc269_loopbacks alc880_loopbacks 14641#endif 14642 14643/* pcm configuration: identical with ALC880 */ 14644#define alc269_pcm_analog_playback alc880_pcm_analog_playback 14645#define alc269_pcm_analog_capture alc880_pcm_analog_capture 14646#define alc269_pcm_digital_playback alc880_pcm_digital_playback 14647#define alc269_pcm_digital_capture alc880_pcm_digital_capture 14648 14649static struct hda_pcm_stream alc269_44k_pcm_analog_playback = { 14650 .substreams = 1, 14651 .channels_min = 2, 14652 .channels_max = 8, 14653 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */ 14654 /* NID is set in alc_build_pcms */ 14655 .ops = { 14656 .open = alc880_playback_pcm_open, 14657 .prepare = alc880_playback_pcm_prepare, 14658 .cleanup = alc880_playback_pcm_cleanup 14659 }, 14660}; 14661 14662static struct hda_pcm_stream alc269_44k_pcm_analog_capture = { 14663 .substreams = 1, 14664 .channels_min = 2, 14665 .channels_max = 2, 14666 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */ 14667 /* NID is set in alc_build_pcms */ 14668}; 14669 14670#ifdef CONFIG_SND_HDA_POWER_SAVE 14671static int alc269_mic2_for_mute_led(struct hda_codec *codec) 14672{ 14673 switch (codec->subsystem_id) { 14674 case 0x103c1586: 14675 return 1; 14676 } 14677 return 0; 14678} 14679 14680static int alc269_mic2_mute_check_ps(struct hda_codec *codec, hda_nid_t nid) 14681{ 14682 /* update mute-LED according to the speaker mute state */ 14683 if (nid == 0x01 || nid == 0x14) { 14684 int pinval; 14685 if (snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0) & 14686 HDA_AMP_MUTE) 14687 pinval = 0x24; 14688 else 14689 pinval = 0x20; 14690 /* mic2 vref pin is used for mute LED control */ 14691 snd_hda_codec_update_cache(codec, 0x19, 0, 14692 AC_VERB_SET_PIN_WIDGET_CONTROL, 14693 pinval); 14694 } 14695 return alc_check_power_status(codec, nid); 14696} 14697#endif /* CONFIG_SND_HDA_POWER_SAVE */ 14698 14699static int alc275_setup_dual_adc(struct hda_codec *codec) 14700{ 14701 struct alc_spec *spec = codec->spec; 14702 14703 if (codec->vendor_id != 0x10ec0275 || !spec->auto_mic) 14704 return 0; 14705 if ((spec->ext_mic.pin >= 0x18 && spec->int_mic.pin <= 0x13) || 14706 (spec->ext_mic.pin <= 0x12 && spec->int_mic.pin >= 0x18)) { 14707 if (spec->ext_mic.pin <= 0x12) { 14708 spec->private_adc_nids[0] = 0x08; 14709 spec->private_adc_nids[1] = 0x11; 14710 spec->private_capsrc_nids[0] = 0x23; 14711 spec->private_capsrc_nids[1] = 0x22; 14712 } else { 14713 spec->private_adc_nids[0] = 0x11; 14714 spec->private_adc_nids[1] = 0x08; 14715 spec->private_capsrc_nids[0] = 0x22; 14716 spec->private_capsrc_nids[1] = 0x23; 14717 } 14718 spec->adc_nids = spec->private_adc_nids; 14719 spec->capsrc_nids = spec->private_capsrc_nids; 14720 spec->num_adc_nids = 2; 14721 spec->dual_adc_switch = 1; 14722 snd_printdd("realtek: enabling dual ADC switchg (%02x:%02x)\n", 14723 spec->adc_nids[0], spec->adc_nids[1]); 14724 return 1; 14725 } 14726 return 0; 14727} 14728 14729/* different alc269-variants */ 14730enum { 14731 ALC269_TYPE_NORMAL, 14732 ALC269_TYPE_ALC258, 14733 ALC269_TYPE_ALC259, 14734 ALC269_TYPE_ALC269VB, 14735 ALC269_TYPE_ALC270, 14736 ALC269_TYPE_ALC271X, 14737}; 14738 14739/* 14740 * BIOS auto configuration 14741 */ 14742static int alc269_parse_auto_config(struct hda_codec *codec) 14743{ 14744 struct alc_spec *spec = codec->spec; 14745 int err; 14746 static hda_nid_t alc269_ignore[] = { 0x1d, 0 }; 14747 14748 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 14749 alc269_ignore); 14750 if (err < 0) 14751 return err; 14752 14753 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg); 14754 if (err < 0) 14755 return err; 14756 if (spec->codec_variant == ALC269_TYPE_NORMAL) 14757 err = alc269_auto_create_input_ctls(codec, &spec->autocfg); 14758 else 14759 err = alc_auto_create_input_ctls(codec, &spec->autocfg, 0, 14760 0x22, 0); 14761 if (err < 0) 14762 return err; 14763 14764 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 14765 14766 alc_auto_parse_digital(codec); 14767 14768 if (spec->kctls.list) 14769 add_mixer(spec, spec->kctls.list); 14770 14771 if (spec->codec_variant != ALC269_TYPE_NORMAL) { 14772 add_verb(spec, alc269vb_init_verbs); 14773 alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21); 14774 } else { 14775 add_verb(spec, alc269_init_verbs); 14776 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); 14777 } 14778 14779 spec->num_mux_defs = 1; 14780 spec->input_mux = &spec->private_imux[0]; 14781 14782 if (!alc275_setup_dual_adc(codec)) 14783 fillup_priv_adc_nids(codec, alc269_adc_candidates, 14784 sizeof(alc269_adc_candidates)); 14785 14786 err = alc_auto_add_mic_boost(codec); 14787 if (err < 0) 14788 return err; 14789 14790 if (!spec->cap_mixer && !spec->no_analog) 14791 set_capture_mixer(codec); 14792 14793 return 1; 14794} 14795 14796#define alc269_auto_init_multi_out alc268_auto_init_multi_out 14797#define alc269_auto_init_hp_out alc268_auto_init_hp_out 14798#define alc269_auto_init_analog_input alc882_auto_init_analog_input 14799#define alc269_auto_init_input_src alc882_auto_init_input_src 14800 14801 14802/* init callback for auto-configuration model -- overriding the default init */ 14803static void alc269_auto_init(struct hda_codec *codec) 14804{ 14805 struct alc_spec *spec = codec->spec; 14806 alc269_auto_init_multi_out(codec); 14807 alc269_auto_init_hp_out(codec); 14808 alc269_auto_init_analog_input(codec); 14809 if (!spec->dual_adc_switch) 14810 alc269_auto_init_input_src(codec); 14811 alc_auto_init_digital(codec); 14812 if (spec->unsol_event) 14813 alc_inithook(codec); 14814} 14815 14816static void alc269_toggle_power_output(struct hda_codec *codec, int power_up) 14817{ 14818 int val = alc_read_coef_idx(codec, 0x04); 14819 if (power_up) 14820 val |= 1 << 11; 14821 else 14822 val &= ~(1 << 11); 14823 alc_write_coef_idx(codec, 0x04, val); 14824} 14825 14826static void alc269_shutup(struct hda_codec *codec) 14827{ 14828 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) 14829 alc269_toggle_power_output(codec, 0); 14830 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) { 14831 alc269_toggle_power_output(codec, 0); 14832 msleep(150); 14833 } 14834} 14835 14836#ifdef SND_HDA_NEEDS_RESUME 14837static int alc269_resume(struct hda_codec *codec) 14838{ 14839 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) { 14840 alc269_toggle_power_output(codec, 0); 14841 msleep(150); 14842 } 14843 14844 codec->patch_ops.init(codec); 14845 14846 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) { 14847 alc269_toggle_power_output(codec, 1); 14848 msleep(200); 14849 } 14850 14851 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) 14852 alc269_toggle_power_output(codec, 1); 14853 14854 snd_hda_codec_resume_amp(codec); 14855 snd_hda_codec_resume_cache(codec); 14856 hda_call_check_power_status(codec, 0x01); 14857 return 0; 14858} 14859#endif /* SND_HDA_NEEDS_RESUME */ 14860 14861static void alc269_fixup_hweq(struct hda_codec *codec, 14862 const struct alc_fixup *fix, int action) 14863{ 14864 int coef; 14865 14866 if (action != ALC_FIXUP_ACT_INIT) 14867 return; 14868 coef = alc_read_coef_idx(codec, 0x1e); 14869 alc_write_coef_idx(codec, 0x1e, coef | 0x80); 14870} 14871 14872enum { 14873 ALC269_FIXUP_SONY_VAIO, 14874 ALC275_FIXUP_SONY_VAIO_GPIO2, 14875 ALC269_FIXUP_DELL_M101Z, 14876 ALC269_FIXUP_SKU_IGNORE, 14877 ALC269_FIXUP_ASUS_G73JW, 14878 ALC269_FIXUP_LENOVO_EAPD, 14879 ALC275_FIXUP_SONY_HWEQ, 14880}; 14881 14882static const struct alc_fixup alc269_fixups[] = { 14883 [ALC269_FIXUP_SONY_VAIO] = { 14884 .type = ALC_FIXUP_VERBS, 14885 .v.verbs = (const struct hda_verb[]) { 14886 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD}, 14887 {} 14888 } 14889 }, 14890 [ALC275_FIXUP_SONY_VAIO_GPIO2] = { 14891 .type = ALC_FIXUP_VERBS, 14892 .v.verbs = (const struct hda_verb[]) { 14893 {0x01, AC_VERB_SET_GPIO_MASK, 0x04}, 14894 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04}, 14895 {0x01, AC_VERB_SET_GPIO_DATA, 0x00}, 14896 { } 14897 }, 14898 .chained = true, 14899 .chain_id = ALC269_FIXUP_SONY_VAIO 14900 }, 14901 [ALC269_FIXUP_DELL_M101Z] = { 14902 .type = ALC_FIXUP_VERBS, 14903 .v.verbs = (const struct hda_verb[]) { 14904 /* Enables internal speaker */ 14905 {0x20, AC_VERB_SET_COEF_INDEX, 13}, 14906 {0x20, AC_VERB_SET_PROC_COEF, 0x4040}, 14907 {} 14908 } 14909 }, 14910 [ALC269_FIXUP_SKU_IGNORE] = { 14911 .type = ALC_FIXUP_SKU, 14912 .v.sku = ALC_FIXUP_SKU_IGNORE, 14913 }, 14914 [ALC269_FIXUP_ASUS_G73JW] = { 14915 .type = ALC_FIXUP_PINS, 14916 .v.pins = (const struct alc_pincfg[]) { 14917 { 0x17, 0x99130111 }, /* subwoofer */ 14918 { } 14919 } 14920 }, 14921 [ALC269_FIXUP_LENOVO_EAPD] = { 14922 .type = ALC_FIXUP_VERBS, 14923 .v.verbs = (const struct hda_verb[]) { 14924 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0}, 14925 {} 14926 } 14927 }, 14928 [ALC275_FIXUP_SONY_HWEQ] = { 14929 .type = ALC_FIXUP_FUNC, 14930 .v.func = alc269_fixup_hweq, 14931 .chained = true, 14932 .chain_id = ALC275_FIXUP_SONY_VAIO_GPIO2 14933 } 14934}; 14935 14936static struct snd_pci_quirk alc269_fixup_tbl[] = { 14937 SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2), 14938 SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ), 14939 SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ), 14940 SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO), 14941 SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z), 14942 SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE), 14943 SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE), 14944 SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE), 14945 SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE), 14946 SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE), 14947 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW), 14948 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD), 14949 {} 14950}; 14951 14952 14953/* 14954 * configuration and preset 14955 */ 14956static const char * const alc269_models[ALC269_MODEL_LAST] = { 14957 [ALC269_BASIC] = "basic", 14958 [ALC269_QUANTA_FL1] = "quanta", 14959 [ALC269_AMIC] = "laptop-amic", 14960 [ALC269_DMIC] = "laptop-dmic", 14961 [ALC269_FUJITSU] = "fujitsu", 14962 [ALC269_LIFEBOOK] = "lifebook", 14963 [ALC269_AUTO] = "auto", 14964}; 14965 14966static struct snd_pci_quirk alc269_cfg_tbl[] = { 14967 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1), 14968 SND_PCI_QUIRK(0x1025, 0x047c, "ACER ZGA", ALC271_ACER), 14969 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A", 14970 ALC269_AMIC), 14971 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269VB_AMIC), 14972 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269VB_AMIC), 14973 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269VB_AMIC), 14974 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_AMIC), 14975 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269VB_AMIC), 14976 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269VB_AMIC), 14977 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269VB_AMIC), 14978 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269VB_AMIC), 14979 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_AMIC), 14980 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269VB_AMIC), 14981 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_AMIC), 14982 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_AMIC), 14983 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_AMIC), 14984 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_AMIC), 14985 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_AMIC), 14986 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_AMIC), 14987 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_AMIC), 14988 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_AMIC), 14989 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_AMIC), 14990 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_AMIC), 14991 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_AMIC), 14992 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_AMIC), 14993 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_AMIC), 14994 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_AMIC), 14995 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_AMIC), 14996 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_AMIC), 14997 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_AMIC), 14998 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_AMIC), 14999 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_AMIC), 15000 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_AMIC), 15001 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_AMIC), 15002 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_DMIC), 15003 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_AMIC), 15004 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_AMIC), 15005 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_AMIC), 15006 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_AMIC), 15007 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901", 15008 ALC269_DMIC), 15009 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101", 15010 ALC269_DMIC), 15011 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC), 15012 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC), 15013 SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_AUTO), 15014 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK), 15015 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC), 15016 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU), 15017 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_AMIC), 15018 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_AMIC), 15019 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_DMIC), 15020 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_DMIC), 15021 {} 15022}; 15023 15024static struct alc_config_preset alc269_presets[] = { 15025 [ALC269_BASIC] = { 15026 .mixers = { alc269_base_mixer }, 15027 .init_verbs = { alc269_init_verbs }, 15028 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 15029 .dac_nids = alc269_dac_nids, 15030 .hp_nid = 0x03, 15031 .num_channel_mode = ARRAY_SIZE(alc269_modes), 15032 .channel_mode = alc269_modes, 15033 .input_mux = &alc269_capture_source, 15034 }, 15035 [ALC269_QUANTA_FL1] = { 15036 .mixers = { alc269_quanta_fl1_mixer }, 15037 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs }, 15038 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 15039 .dac_nids = alc269_dac_nids, 15040 .hp_nid = 0x03, 15041 .num_channel_mode = ARRAY_SIZE(alc269_modes), 15042 .channel_mode = alc269_modes, 15043 .input_mux = &alc269_capture_source, 15044 .unsol_event = alc269_quanta_fl1_unsol_event, 15045 .setup = alc269_quanta_fl1_setup, 15046 .init_hook = alc269_quanta_fl1_init_hook, 15047 }, 15048 [ALC269_AMIC] = { 15049 .mixers = { alc269_laptop_mixer }, 15050 .cap_mixer = alc269_laptop_analog_capture_mixer, 15051 .init_verbs = { alc269_init_verbs, 15052 alc269_laptop_amic_init_verbs }, 15053 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 15054 .dac_nids = alc269_dac_nids, 15055 .hp_nid = 0x03, 15056 .num_channel_mode = ARRAY_SIZE(alc269_modes), 15057 .channel_mode = alc269_modes, 15058 .unsol_event = alc269_laptop_unsol_event, 15059 .setup = alc269_laptop_amic_setup, 15060 .init_hook = alc269_laptop_inithook, 15061 }, 15062 [ALC269_DMIC] = { 15063 .mixers = { alc269_laptop_mixer }, 15064 .cap_mixer = alc269_laptop_digital_capture_mixer, 15065 .init_verbs = { alc269_init_verbs, 15066 alc269_laptop_dmic_init_verbs }, 15067 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 15068 .dac_nids = alc269_dac_nids, 15069 .hp_nid = 0x03, 15070 .num_channel_mode = ARRAY_SIZE(alc269_modes), 15071 .channel_mode = alc269_modes, 15072 .unsol_event = alc269_laptop_unsol_event, 15073 .setup = alc269_laptop_dmic_setup, 15074 .init_hook = alc269_laptop_inithook, 15075 }, 15076 [ALC269VB_AMIC] = { 15077 .mixers = { alc269vb_laptop_mixer }, 15078 .cap_mixer = alc269vb_laptop_analog_capture_mixer, 15079 .init_verbs = { alc269vb_init_verbs, 15080 alc269vb_laptop_amic_init_verbs }, 15081 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 15082 .dac_nids = alc269_dac_nids, 15083 .hp_nid = 0x03, 15084 .num_channel_mode = ARRAY_SIZE(alc269_modes), 15085 .channel_mode = alc269_modes, 15086 .unsol_event = alc269_laptop_unsol_event, 15087 .setup = alc269vb_laptop_amic_setup, 15088 .init_hook = alc269_laptop_inithook, 15089 }, 15090 [ALC269VB_DMIC] = { 15091 .mixers = { alc269vb_laptop_mixer }, 15092 .cap_mixer = alc269vb_laptop_digital_capture_mixer, 15093 .init_verbs = { alc269vb_init_verbs, 15094 alc269vb_laptop_dmic_init_verbs }, 15095 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 15096 .dac_nids = alc269_dac_nids, 15097 .hp_nid = 0x03, 15098 .num_channel_mode = ARRAY_SIZE(alc269_modes), 15099 .channel_mode = alc269_modes, 15100 .unsol_event = alc269_laptop_unsol_event, 15101 .setup = alc269vb_laptop_dmic_setup, 15102 .init_hook = alc269_laptop_inithook, 15103 }, 15104 [ALC269_FUJITSU] = { 15105 .mixers = { alc269_fujitsu_mixer }, 15106 .cap_mixer = alc269_laptop_digital_capture_mixer, 15107 .init_verbs = { alc269_init_verbs, 15108 alc269_laptop_dmic_init_verbs }, 15109 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 15110 .dac_nids = alc269_dac_nids, 15111 .hp_nid = 0x03, 15112 .num_channel_mode = ARRAY_SIZE(alc269_modes), 15113 .channel_mode = alc269_modes, 15114 .unsol_event = alc269_laptop_unsol_event, 15115 .setup = alc269_laptop_dmic_setup, 15116 .init_hook = alc269_laptop_inithook, 15117 }, 15118 [ALC269_LIFEBOOK] = { 15119 .mixers = { alc269_lifebook_mixer }, 15120 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs }, 15121 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 15122 .dac_nids = alc269_dac_nids, 15123 .hp_nid = 0x03, 15124 .num_channel_mode = ARRAY_SIZE(alc269_modes), 15125 .channel_mode = alc269_modes, 15126 .input_mux = &alc269_capture_source, 15127 .unsol_event = alc269_lifebook_unsol_event, 15128 .init_hook = alc269_lifebook_init_hook, 15129 }, 15130 [ALC271_ACER] = { 15131 .mixers = { alc269_asus_mixer }, 15132 .cap_mixer = alc269vb_laptop_digital_capture_mixer, 15133 .init_verbs = { alc269_init_verbs, alc271_acer_dmic_verbs }, 15134 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 15135 .dac_nids = alc269_dac_nids, 15136 .adc_nids = alc262_dmic_adc_nids, 15137 .num_adc_nids = ARRAY_SIZE(alc262_dmic_adc_nids), 15138 .capsrc_nids = alc262_dmic_capsrc_nids, 15139 .num_channel_mode = ARRAY_SIZE(alc269_modes), 15140 .channel_mode = alc269_modes, 15141 .input_mux = &alc269_capture_source, 15142 .dig_out_nid = ALC880_DIGOUT_NID, 15143 .unsol_event = alc_sku_unsol_event, 15144 .setup = alc269vb_laptop_dmic_setup, 15145 .init_hook = alc_inithook, 15146 }, 15147}; 15148 15149static int alc269_fill_coef(struct hda_codec *codec) 15150{ 15151 int val; 15152 15153 if ((alc_read_coef_idx(codec, 0) & 0x00ff) < 0x015) { 15154 alc_write_coef_idx(codec, 0xf, 0x960b); 15155 alc_write_coef_idx(codec, 0xe, 0x8817); 15156 } 15157 15158 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x016) { 15159 alc_write_coef_idx(codec, 0xf, 0x960b); 15160 alc_write_coef_idx(codec, 0xe, 0x8814); 15161 } 15162 15163 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) { 15164 val = alc_read_coef_idx(codec, 0x04); 15165 /* Power up output pin */ 15166 alc_write_coef_idx(codec, 0x04, val | (1<<11)); 15167 } 15168 15169 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) { 15170 val = alc_read_coef_idx(codec, 0xd); 15171 if ((val & 0x0c00) >> 10 != 0x1) { 15172 /* Capless ramp up clock control */ 15173 alc_write_coef_idx(codec, 0xd, val | 1<<10); 15174 } 15175 val = alc_read_coef_idx(codec, 0x17); 15176 if ((val & 0x01c0) >> 6 != 0x4) { 15177 /* Class D power on reset */ 15178 alc_write_coef_idx(codec, 0x17, val | 1<<7); 15179 } 15180 } 15181 return 0; 15182} 15183 15184static int patch_alc269(struct hda_codec *codec) 15185{ 15186 struct alc_spec *spec; 15187 int board_config, coef; 15188 int err; 15189 15190 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 15191 if (spec == NULL) 15192 return -ENOMEM; 15193 15194 codec->spec = spec; 15195 15196 alc_auto_parse_customize_define(codec); 15197 15198 if (codec->vendor_id == 0x10ec0269) { 15199 coef = alc_read_coef_idx(codec, 0); 15200 if ((coef & 0x00f0) == 0x0010) { 15201 if (codec->bus->pci->subsystem_vendor == 0x1025 && 15202 spec->cdefine.platform_type == 1) { 15203 alc_codec_rename(codec, "ALC271X"); 15204 spec->codec_variant = ALC269_TYPE_ALC271X; 15205 } else if ((coef & 0xf000) == 0x1000) { 15206 spec->codec_variant = ALC269_TYPE_ALC270; 15207 } else if ((coef & 0xf000) == 0x2000) { 15208 alc_codec_rename(codec, "ALC259"); 15209 spec->codec_variant = ALC269_TYPE_ALC259; 15210 } else if ((coef & 0xf000) == 0x3000) { 15211 alc_codec_rename(codec, "ALC258"); 15212 spec->codec_variant = ALC269_TYPE_ALC258; 15213 } else { 15214 alc_codec_rename(codec, "ALC269VB"); 15215 spec->codec_variant = ALC269_TYPE_ALC269VB; 15216 } 15217 } else 15218 alc_fix_pll_init(codec, 0x20, 0x04, 15); 15219 alc269_fill_coef(codec); 15220 } 15221 15222 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST, 15223 alc269_models, 15224 alc269_cfg_tbl); 15225 15226 if (board_config < 0) { 15227 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 15228 codec->chip_name); 15229 board_config = ALC269_AUTO; 15230 } 15231 15232 if (board_config == ALC269_AUTO) { 15233 alc_pick_fixup(codec, NULL, alc269_fixup_tbl, alc269_fixups); 15234 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); 15235 } 15236 15237 if (board_config == ALC269_AUTO) { 15238 /* automatic parse from the BIOS config */ 15239 err = alc269_parse_auto_config(codec); 15240 if (err < 0) { 15241 alc_free(codec); 15242 return err; 15243 } else if (!err) { 15244 printk(KERN_INFO 15245 "hda_codec: Cannot set up configuration " 15246 "from BIOS. Using base mode...\n"); 15247 board_config = ALC269_BASIC; 15248 } 15249 } 15250 15251 if (has_cdefine_beep(codec)) { 15252 err = snd_hda_attach_beep_device(codec, 0x1); 15253 if (err < 0) { 15254 alc_free(codec); 15255 return err; 15256 } 15257 } 15258 15259 if (board_config != ALC269_AUTO) 15260 setup_preset(codec, &alc269_presets[board_config]); 15261 15262 if (board_config == ALC269_QUANTA_FL1) { 15263 /* Due to a hardware problem on Lenovo Ideadpad, we need to 15264 * fix the sample rate of analog I/O to 44.1kHz 15265 */ 15266 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback; 15267 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture; 15268 } else if (spec->dual_adc_switch) { 15269 spec->stream_analog_playback = &alc269_pcm_analog_playback; 15270 /* switch ADC dynamically */ 15271 spec->stream_analog_capture = &dualmic_pcm_analog_capture; 15272 } else { 15273 spec->stream_analog_playback = &alc269_pcm_analog_playback; 15274 spec->stream_analog_capture = &alc269_pcm_analog_capture; 15275 } 15276 spec->stream_digital_playback = &alc269_pcm_digital_playback; 15277 spec->stream_digital_capture = &alc269_pcm_digital_capture; 15278 15279 if (!spec->adc_nids) { /* wasn't filled automatically? use default */ 15280 if (spec->codec_variant == ALC269_TYPE_NORMAL) { 15281 spec->adc_nids = alc269_adc_nids; 15282 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids); 15283 spec->capsrc_nids = alc269_capsrc_nids; 15284 } else { 15285 spec->adc_nids = alc269vb_adc_nids; 15286 spec->num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids); 15287 spec->capsrc_nids = alc269vb_capsrc_nids; 15288 } 15289 } 15290 15291 if (!spec->cap_mixer) 15292 set_capture_mixer(codec); 15293 if (has_cdefine_beep(codec)) 15294 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); 15295 15296 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); 15297 15298 spec->vmaster_nid = 0x02; 15299 15300 codec->patch_ops = alc_patch_ops; 15301#ifdef SND_HDA_NEEDS_RESUME 15302 codec->patch_ops.resume = alc269_resume; 15303#endif 15304 if (board_config == ALC269_AUTO) 15305 spec->init_hook = alc269_auto_init; 15306 spec->shutup = alc269_shutup; 15307 15308 alc_init_jacks(codec); 15309#ifdef CONFIG_SND_HDA_POWER_SAVE 15310 if (!spec->loopback.amplist) 15311 spec->loopback.amplist = alc269_loopbacks; 15312 if (alc269_mic2_for_mute_led(codec)) 15313 codec->patch_ops.check_power_status = alc269_mic2_mute_check_ps; 15314#endif 15315 15316 return 0; 15317} 15318 15319/* 15320 * ALC861 channel source setting (2/6 channel selection for 3-stack) 15321 */ 15322 15323/* 15324 * set the path ways for 2 channel output 15325 * need to set the codec line out and mic 1 pin widgets to inputs 15326 */ 15327static struct hda_verb alc861_threestack_ch2_init[] = { 15328 /* set pin widget 1Ah (line in) for input */ 15329 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 15330 /* set pin widget 18h (mic1/2) for input, for mic also enable 15331 * the vref 15332 */ 15333 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15334 15335 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, 15336#if 0 15337 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/ 15338 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/ 15339#endif 15340 { } /* end */ 15341}; 15342/* 15343 * 6ch mode 15344 * need to set the codec line out and mic 1 pin widgets to outputs 15345 */ 15346static struct hda_verb alc861_threestack_ch6_init[] = { 15347 /* set pin widget 1Ah (line in) for output (Back Surround)*/ 15348 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15349 /* set pin widget 18h (mic1) for output (CLFE)*/ 15350 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15351 15352 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15353 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15354 15355 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 }, 15356#if 0 15357 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/ 15358 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/ 15359#endif 15360 { } /* end */ 15361}; 15362 15363static struct hda_channel_mode alc861_threestack_modes[2] = { 15364 { 2, alc861_threestack_ch2_init }, 15365 { 6, alc861_threestack_ch6_init }, 15366}; 15367/* Set mic1 as input and unmute the mixer */ 15368static struct hda_verb alc861_uniwill_m31_ch2_init[] = { 15369 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15370 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/ 15371 { } /* end */ 15372}; 15373/* Set mic1 as output and mute mixer */ 15374static struct hda_verb alc861_uniwill_m31_ch4_init[] = { 15375 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15376 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/ 15377 { } /* end */ 15378}; 15379 15380static struct hda_channel_mode alc861_uniwill_m31_modes[2] = { 15381 { 2, alc861_uniwill_m31_ch2_init }, 15382 { 4, alc861_uniwill_m31_ch4_init }, 15383}; 15384 15385/* Set mic1 and line-in as input and unmute the mixer */ 15386static struct hda_verb alc861_asus_ch2_init[] = { 15387 /* set pin widget 1Ah (line in) for input */ 15388 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 15389 /* set pin widget 18h (mic1/2) for input, for mic also enable 15390 * the vref 15391 */ 15392 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15393 15394 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, 15395#if 0 15396 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/ 15397 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/ 15398#endif 15399 { } /* end */ 15400}; 15401/* Set mic1 nad line-in as output and mute mixer */ 15402static struct hda_verb alc861_asus_ch6_init[] = { 15403 /* set pin widget 1Ah (line in) for output (Back Surround)*/ 15404 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15405 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */ 15406 /* set pin widget 18h (mic1) for output (CLFE)*/ 15407 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15408 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */ 15409 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15410 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15411 15412 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 }, 15413#if 0 15414 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/ 15415 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/ 15416#endif 15417 { } /* end */ 15418}; 15419 15420static struct hda_channel_mode alc861_asus_modes[2] = { 15421 { 2, alc861_asus_ch2_init }, 15422 { 6, alc861_asus_ch6_init }, 15423}; 15424 15425/* patch-ALC861 */ 15426 15427static struct snd_kcontrol_new alc861_base_mixer[] = { 15428 /* output mixer control */ 15429 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), 15430 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), 15431 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT), 15432 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT), 15433 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), 15434 15435 /*Input mixer control */ 15436 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT), 15437 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */ 15438 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), 15439 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), 15440 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT), 15441 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT), 15442 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), 15443 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), 15444 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), 15445 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT), 15446 15447 { } /* end */ 15448}; 15449 15450static struct snd_kcontrol_new alc861_3ST_mixer[] = { 15451 /* output mixer control */ 15452 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), 15453 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), 15454 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT), 15455 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT), 15456 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */ 15457 15458 /* Input mixer control */ 15459 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT), 15460 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */ 15461 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), 15462 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), 15463 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT), 15464 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT), 15465 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), 15466 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), 15467 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), 15468 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT), 15469 15470 { 15471 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 15472 .name = "Channel Mode", 15473 .info = alc_ch_mode_info, 15474 .get = alc_ch_mode_get, 15475 .put = alc_ch_mode_put, 15476 .private_value = ARRAY_SIZE(alc861_threestack_modes), 15477 }, 15478 { } /* end */ 15479}; 15480 15481static struct snd_kcontrol_new alc861_toshiba_mixer[] = { 15482 /* output mixer control */ 15483 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT), 15484 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), 15485 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), 15486 15487 { } /* end */ 15488}; 15489 15490static struct snd_kcontrol_new alc861_uniwill_m31_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 { 15511 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 15512 .name = "Channel Mode", 15513 .info = alc_ch_mode_info, 15514 .get = alc_ch_mode_get, 15515 .put = alc_ch_mode_put, 15516 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes), 15517 }, 15518 { } /* end */ 15519}; 15520 15521static struct snd_kcontrol_new alc861_asus_mixer[] = { 15522 /* output mixer control */ 15523 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), 15524 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), 15525 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT), 15526 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT), 15527 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), 15528 15529 /* Input mixer control */ 15530 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT), 15531 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), 15532 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), 15533 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), 15534 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT), 15535 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT), 15536 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), 15537 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), 15538 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), 15539 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT), 15540 15541 { 15542 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 15543 .name = "Channel Mode", 15544 .info = alc_ch_mode_info, 15545 .get = alc_ch_mode_get, 15546 .put = alc_ch_mode_put, 15547 .private_value = ARRAY_SIZE(alc861_asus_modes), 15548 }, 15549 { } 15550}; 15551 15552/* additional mixer */ 15553static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = { 15554 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), 15555 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), 15556 { } 15557}; 15558 15559/* 15560 * generic initialization of ADC, input mixers and output mixers 15561 */ 15562static struct hda_verb alc861_base_init_verbs[] = { 15563 /* 15564 * Unmute ADC0 and set the default input to mic-in 15565 */ 15566 /* port-A for surround (rear panel) */ 15567 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15568 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15569 /* port-B for mic-in (rear panel) with vref */ 15570 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15571 /* port-C for line-in (rear panel) */ 15572 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 15573 /* port-D for Front */ 15574 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15575 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15576 /* port-E for HP out (front panel) */ 15577 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, 15578 /* route front PCM to HP */ 15579 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15580 /* port-F for mic-in (front panel) with vref */ 15581 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15582 /* port-G for CLFE (rear panel) */ 15583 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15584 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15585 /* port-H for side (rear panel) */ 15586 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15587 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15588 /* CD-in */ 15589 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 15590 /* route front mic to ADC1*/ 15591 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 15592 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15593 15594 /* Unmute DAC0~3 & spdif out*/ 15595 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15596 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15597 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15598 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15599 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15600 15601 /* Unmute Mixer 14 (mic) 1c (Line in)*/ 15602 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15603 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15604 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15605 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15606 15607 /* Unmute Stereo Mixer 15 */ 15608 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15609 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15610 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 15611 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */ 15612 15613 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15614 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15615 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15616 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15617 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15618 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15619 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15620 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15621 /* hp used DAC 3 (Front) */ 15622 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 15623 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 15624 15625 { } 15626}; 15627 15628static struct hda_verb alc861_threestack_init_verbs[] = { 15629 /* 15630 * Unmute ADC0 and set the default input to mic-in 15631 */ 15632 /* port-A for surround (rear panel) */ 15633 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 15634 /* port-B for mic-in (rear panel) with vref */ 15635 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15636 /* port-C for line-in (rear panel) */ 15637 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 15638 /* port-D for Front */ 15639 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15640 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15641 /* port-E for HP out (front panel) */ 15642 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, 15643 /* route front PCM to HP */ 15644 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15645 /* port-F for mic-in (front panel) with vref */ 15646 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15647 /* port-G for CLFE (rear panel) */ 15648 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 15649 /* port-H for side (rear panel) */ 15650 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 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 /* Unmute DAC0~3 & spdif out*/ 15657 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15658 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15659 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15660 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15661 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15662 15663 /* Unmute Mixer 14 (mic) 1c (Line in)*/ 15664 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15665 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15666 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15667 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15668 15669 /* Unmute Stereo Mixer 15 */ 15670 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15671 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15672 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 15673 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */ 15674 15675 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15676 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15677 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15678 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15679 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15680 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15681 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15682 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15683 /* hp used DAC 3 (Front) */ 15684 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 15685 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 15686 { } 15687}; 15688 15689static struct hda_verb alc861_uniwill_m31_init_verbs[] = { 15690 /* 15691 * Unmute ADC0 and set the default input to mic-in 15692 */ 15693 /* port-A for surround (rear panel) */ 15694 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 15695 /* port-B for mic-in (rear panel) with vref */ 15696 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15697 /* port-C for line-in (rear panel) */ 15698 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 15699 /* port-D for Front */ 15700 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15701 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15702 /* port-E for HP out (front panel) */ 15703 /* this has to be set to VREF80 */ 15704 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15705 /* route front PCM to HP */ 15706 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15707 /* port-F for mic-in (front panel) with vref */ 15708 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15709 /* port-G for CLFE (rear panel) */ 15710 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 15711 /* port-H for side (rear panel) */ 15712 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 15713 /* CD-in */ 15714 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 15715 /* route front mic to ADC1*/ 15716 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 15717 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15718 /* Unmute DAC0~3 & spdif out*/ 15719 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15720 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15721 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15722 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15723 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15724 15725 /* Unmute Mixer 14 (mic) 1c (Line in)*/ 15726 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15727 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15728 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15729 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15730 15731 /* Unmute Stereo Mixer 15 */ 15732 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15733 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15734 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 15735 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */ 15736 15737 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15738 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15739 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15740 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15741 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15742 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15743 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15744 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15745 /* hp used DAC 3 (Front) */ 15746 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 15747 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 15748 { } 15749}; 15750 15751static struct hda_verb alc861_asus_init_verbs[] = { 15752 /* 15753 * Unmute ADC0 and set the default input to mic-in 15754 */ 15755 /* port-A for surround (rear panel) 15756 * according to codec#0 this is the HP jack 15757 */ 15758 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */ 15759 /* route front PCM to HP */ 15760 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 }, 15761 /* port-B for mic-in (rear panel) with vref */ 15762 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15763 /* port-C for line-in (rear panel) */ 15764 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 15765 /* port-D for Front */ 15766 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15767 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15768 /* port-E for HP out (front panel) */ 15769 /* this has to be set to VREF80 */ 15770 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15771 /* route front PCM to HP */ 15772 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15773 /* port-F for mic-in (front panel) with vref */ 15774 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15775 /* port-G for CLFE (rear panel) */ 15776 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15777 /* port-H for side (rear panel) */ 15778 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15779 /* CD-in */ 15780 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 15781 /* route front mic to ADC1*/ 15782 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 15783 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15784 /* Unmute DAC0~3 & spdif out*/ 15785 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15786 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15787 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15788 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15789 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15790 /* Unmute Mixer 14 (mic) 1c (Line in)*/ 15791 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15792 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15793 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15794 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15795 15796 /* Unmute Stereo Mixer 15 */ 15797 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15798 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15799 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 15800 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */ 15801 15802 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15803 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15804 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15805 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15806 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15807 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15808 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15809 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15810 /* hp used DAC 3 (Front) */ 15811 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 15812 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 15813 { } 15814}; 15815 15816/* additional init verbs for ASUS laptops */ 15817static struct hda_verb alc861_asus_laptop_init_verbs[] = { 15818 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */ 15819 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */ 15820 { } 15821}; 15822 15823/* 15824 * generic initialization of ADC, input mixers and output mixers 15825 */ 15826static struct hda_verb alc861_auto_init_verbs[] = { 15827 /* 15828 * Unmute ADC0 and set the default input to mic-in 15829 */ 15830 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */ 15831 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15832 15833 /* Unmute DAC0~3 & spdif out*/ 15834 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 15835 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 15836 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 15837 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 15838 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15839 15840 /* Unmute Mixer 14 (mic) 1c (Line in)*/ 15841 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15842 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15843 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15844 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15845 15846 /* Unmute Stereo Mixer 15 */ 15847 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15848 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15849 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 15850 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, 15851 15852 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 15853 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 15854 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 15855 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 15856 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 15857 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 15858 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 15859 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 15860 15861 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 15862 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 15863 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 15864 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 15865 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 15866 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 15867 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 15868 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 15869 15870 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */ 15871 15872 { } 15873}; 15874 15875static struct hda_verb alc861_toshiba_init_verbs[] = { 15876 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 15877 15878 { } 15879}; 15880 15881/* toggle speaker-output according to the hp-jack state */ 15882static void alc861_toshiba_automute(struct hda_codec *codec) 15883{ 15884 unsigned int present = snd_hda_jack_detect(codec, 0x0f); 15885 15886 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0, 15887 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 15888 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3, 15889 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE); 15890} 15891 15892static void alc861_toshiba_unsol_event(struct hda_codec *codec, 15893 unsigned int res) 15894{ 15895 if ((res >> 26) == ALC880_HP_EVENT) 15896 alc861_toshiba_automute(codec); 15897} 15898 15899/* pcm configuration: identical with ALC880 */ 15900#define alc861_pcm_analog_playback alc880_pcm_analog_playback 15901#define alc861_pcm_analog_capture alc880_pcm_analog_capture 15902#define alc861_pcm_digital_playback alc880_pcm_digital_playback 15903#define alc861_pcm_digital_capture alc880_pcm_digital_capture 15904 15905 15906#define ALC861_DIGOUT_NID 0x07 15907 15908static struct hda_channel_mode alc861_8ch_modes[1] = { 15909 { 8, NULL } 15910}; 15911 15912static hda_nid_t alc861_dac_nids[4] = { 15913 /* front, surround, clfe, side */ 15914 0x03, 0x06, 0x05, 0x04 15915}; 15916 15917static hda_nid_t alc660_dac_nids[3] = { 15918 /* front, clfe, surround */ 15919 0x03, 0x05, 0x06 15920}; 15921 15922static hda_nid_t alc861_adc_nids[1] = { 15923 /* ADC0-2 */ 15924 0x08, 15925}; 15926 15927static struct hda_input_mux alc861_capture_source = { 15928 .num_items = 5, 15929 .items = { 15930 { "Mic", 0x0 }, 15931 { "Front Mic", 0x3 }, 15932 { "Line", 0x1 }, 15933 { "CD", 0x4 }, 15934 { "Mixer", 0x5 }, 15935 }, 15936}; 15937 15938static hda_nid_t alc861_look_for_dac(struct hda_codec *codec, hda_nid_t pin) 15939{ 15940 struct alc_spec *spec = codec->spec; 15941 hda_nid_t mix, srcs[5]; 15942 int i, j, num; 15943 15944 if (snd_hda_get_connections(codec, pin, &mix, 1) != 1) 15945 return 0; 15946 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs)); 15947 if (num < 0) 15948 return 0; 15949 for (i = 0; i < num; i++) { 15950 unsigned int type; 15951 type = get_wcaps_type(get_wcaps(codec, srcs[i])); 15952 if (type != AC_WID_AUD_OUT) 15953 continue; 15954 for (j = 0; j < spec->multiout.num_dacs; j++) 15955 if (spec->multiout.dac_nids[j] == srcs[i]) 15956 break; 15957 if (j >= spec->multiout.num_dacs) 15958 return srcs[i]; 15959 } 15960 return 0; 15961} 15962 15963/* fill in the dac_nids table from the parsed pin configuration */ 15964static int alc861_auto_fill_dac_nids(struct hda_codec *codec, 15965 const struct auto_pin_cfg *cfg) 15966{ 15967 struct alc_spec *spec = codec->spec; 15968 int i; 15969 hda_nid_t nid, dac; 15970 15971 spec->multiout.dac_nids = spec->private_dac_nids; 15972 for (i = 0; i < cfg->line_outs; i++) { 15973 nid = cfg->line_out_pins[i]; 15974 dac = alc861_look_for_dac(codec, nid); 15975 if (!dac) 15976 continue; 15977 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac; 15978 } 15979 return 0; 15980} 15981 15982static int __alc861_create_out_sw(struct hda_codec *codec, const char *pfx, 15983 hda_nid_t nid, int idx, unsigned int chs) 15984{ 15985 return __add_pb_sw_ctrl(codec->spec, ALC_CTL_WIDGET_MUTE, pfx, idx, 15986 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT)); 15987} 15988 15989#define alc861_create_out_sw(codec, pfx, nid, chs) \ 15990 __alc861_create_out_sw(codec, pfx, nid, 0, chs) 15991 15992/* add playback controls from the parsed DAC table */ 15993static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec, 15994 const struct auto_pin_cfg *cfg) 15995{ 15996 struct alc_spec *spec = codec->spec; 15997 static const char * const chname[4] = { 15998 "Front", "Surround", NULL /*CLFE*/, "Side" 15999 }; 16000 const char *pfx = alc_get_line_out_pfx(cfg, true); 16001 hda_nid_t nid; 16002 int i, err; 16003 16004 for (i = 0; i < cfg->line_outs; i++) { 16005 nid = spec->multiout.dac_nids[i]; 16006 if (!nid) 16007 continue; 16008 if (!pfx && i == 2) { 16009 /* Center/LFE */ 16010 err = alc861_create_out_sw(codec, "Center", nid, 1); 16011 if (err < 0) 16012 return err; 16013 err = alc861_create_out_sw(codec, "LFE", nid, 2); 16014 if (err < 0) 16015 return err; 16016 } else { 16017 const char *name = pfx; 16018 int index = i; 16019 if (!name) { 16020 name = chname[i]; 16021 index = 0; 16022 } 16023 err = __alc861_create_out_sw(codec, name, nid, index, 3); 16024 if (err < 0) 16025 return err; 16026 } 16027 } 16028 return 0; 16029} 16030 16031static int alc861_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin) 16032{ 16033 struct alc_spec *spec = codec->spec; 16034 int err; 16035 hda_nid_t nid; 16036 16037 if (!pin) 16038 return 0; 16039 16040 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) { 16041 nid = alc861_look_for_dac(codec, pin); 16042 if (nid) { 16043 err = alc861_create_out_sw(codec, "Headphone", nid, 3); 16044 if (err < 0) 16045 return err; 16046 spec->multiout.hp_nid = nid; 16047 } 16048 } 16049 return 0; 16050} 16051 16052/* create playback/capture controls for input pins */ 16053static int alc861_auto_create_input_ctls(struct hda_codec *codec, 16054 const struct auto_pin_cfg *cfg) 16055{ 16056 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x08, 0); 16057} 16058 16059static void alc861_auto_set_output_and_unmute(struct hda_codec *codec, 16060 hda_nid_t nid, 16061 int pin_type, hda_nid_t dac) 16062{ 16063 hda_nid_t mix, srcs[5]; 16064 int i, num; 16065 16066 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 16067 pin_type); 16068 snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE, 16069 AMP_OUT_UNMUTE); 16070 if (snd_hda_get_connections(codec, nid, &mix, 1) != 1) 16071 return; 16072 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs)); 16073 if (num < 0) 16074 return; 16075 for (i = 0; i < num; i++) { 16076 unsigned int mute; 16077 if (srcs[i] == dac || srcs[i] == 0x15) 16078 mute = AMP_IN_UNMUTE(i); 16079 else 16080 mute = AMP_IN_MUTE(i); 16081 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE, 16082 mute); 16083 } 16084} 16085 16086static void alc861_auto_init_multi_out(struct hda_codec *codec) 16087{ 16088 struct alc_spec *spec = codec->spec; 16089 int i; 16090 16091 for (i = 0; i < spec->autocfg.line_outs; i++) { 16092 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 16093 int pin_type = get_pin_type(spec->autocfg.line_out_type); 16094 if (nid) 16095 alc861_auto_set_output_and_unmute(codec, nid, pin_type, 16096 spec->multiout.dac_nids[i]); 16097 } 16098} 16099 16100static void alc861_auto_init_hp_out(struct hda_codec *codec) 16101{ 16102 struct alc_spec *spec = codec->spec; 16103 16104 if (spec->autocfg.hp_outs) 16105 alc861_auto_set_output_and_unmute(codec, 16106 spec->autocfg.hp_pins[0], 16107 PIN_HP, 16108 spec->multiout.hp_nid); 16109 if (spec->autocfg.speaker_outs) 16110 alc861_auto_set_output_and_unmute(codec, 16111 spec->autocfg.speaker_pins[0], 16112 PIN_OUT, 16113 spec->multiout.dac_nids[0]); 16114} 16115 16116static void alc861_auto_init_analog_input(struct hda_codec *codec) 16117{ 16118 struct alc_spec *spec = codec->spec; 16119 struct auto_pin_cfg *cfg = &spec->autocfg; 16120 int i; 16121 16122 for (i = 0; i < cfg->num_inputs; i++) { 16123 hda_nid_t nid = cfg->inputs[i].pin; 16124 if (nid >= 0x0c && nid <= 0x11) 16125 alc_set_input_pin(codec, nid, cfg->inputs[i].type); 16126 } 16127} 16128 16129/* parse the BIOS configuration and set up the alc_spec */ 16130/* return 1 if successful, 0 if the proper config is not found, 16131 * or a negative error code 16132 */ 16133static int alc861_parse_auto_config(struct hda_codec *codec) 16134{ 16135 struct alc_spec *spec = codec->spec; 16136 int err; 16137 static hda_nid_t alc861_ignore[] = { 0x1d, 0 }; 16138 16139 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 16140 alc861_ignore); 16141 if (err < 0) 16142 return err; 16143 if (!spec->autocfg.line_outs) 16144 return 0; /* can't find valid BIOS pin config */ 16145 16146 err = alc861_auto_fill_dac_nids(codec, &spec->autocfg); 16147 if (err < 0) 16148 return err; 16149 err = alc861_auto_create_multi_out_ctls(codec, &spec->autocfg); 16150 if (err < 0) 16151 return err; 16152 err = alc861_auto_create_hp_ctls(codec, spec->autocfg.hp_pins[0]); 16153 if (err < 0) 16154 return err; 16155 err = alc861_auto_create_input_ctls(codec, &spec->autocfg); 16156 if (err < 0) 16157 return err; 16158 16159 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 16160 16161 alc_auto_parse_digital(codec); 16162 16163 if (spec->kctls.list) 16164 add_mixer(spec, spec->kctls.list); 16165 16166 add_verb(spec, alc861_auto_init_verbs); 16167 16168 spec->num_mux_defs = 1; 16169 spec->input_mux = &spec->private_imux[0]; 16170 16171 spec->adc_nids = alc861_adc_nids; 16172 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids); 16173 set_capture_mixer(codec); 16174 16175 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b, 0); 16176 16177 return 1; 16178} 16179 16180/* additional initialization for auto-configuration model */ 16181static void alc861_auto_init(struct hda_codec *codec) 16182{ 16183 struct alc_spec *spec = codec->spec; 16184 alc861_auto_init_multi_out(codec); 16185 alc861_auto_init_hp_out(codec); 16186 alc861_auto_init_analog_input(codec); 16187 alc_auto_init_digital(codec); 16188 if (spec->unsol_event) 16189 alc_inithook(codec); 16190} 16191 16192#ifdef CONFIG_SND_HDA_POWER_SAVE 16193static struct hda_amp_list alc861_loopbacks[] = { 16194 { 0x15, HDA_INPUT, 0 }, 16195 { 0x15, HDA_INPUT, 1 }, 16196 { 0x15, HDA_INPUT, 2 }, 16197 { 0x15, HDA_INPUT, 3 }, 16198 { } /* end */ 16199}; 16200#endif 16201 16202 16203/* 16204 * configuration and preset 16205 */ 16206static const char * const alc861_models[ALC861_MODEL_LAST] = { 16207 [ALC861_3ST] = "3stack", 16208 [ALC660_3ST] = "3stack-660", 16209 [ALC861_3ST_DIG] = "3stack-dig", 16210 [ALC861_6ST_DIG] = "6stack-dig", 16211 [ALC861_UNIWILL_M31] = "uniwill-m31", 16212 [ALC861_TOSHIBA] = "toshiba", 16213 [ALC861_ASUS] = "asus", 16214 [ALC861_ASUS_LAPTOP] = "asus-laptop", 16215 [ALC861_AUTO] = "auto", 16216}; 16217 16218static struct snd_pci_quirk alc861_cfg_tbl[] = { 16219 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST), 16220 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP), 16221 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP), 16222 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS), 16223 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP), 16224 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG), 16225 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA), 16226 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!) 16227 * Any other models that need this preset? 16228 */ 16229 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */ 16230 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST), 16231 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST), 16232 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31), 16233 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31), 16234 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP), 16235 /* FIXME: the below seems conflict */ 16236 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */ 16237 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST), 16238 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST), 16239 {} 16240}; 16241 16242static struct alc_config_preset alc861_presets[] = { 16243 [ALC861_3ST] = { 16244 .mixers = { alc861_3ST_mixer }, 16245 .init_verbs = { alc861_threestack_init_verbs }, 16246 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 16247 .dac_nids = alc861_dac_nids, 16248 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes), 16249 .channel_mode = alc861_threestack_modes, 16250 .need_dac_fix = 1, 16251 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 16252 .adc_nids = alc861_adc_nids, 16253 .input_mux = &alc861_capture_source, 16254 }, 16255 [ALC861_3ST_DIG] = { 16256 .mixers = { alc861_base_mixer }, 16257 .init_verbs = { alc861_threestack_init_verbs }, 16258 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 16259 .dac_nids = alc861_dac_nids, 16260 .dig_out_nid = ALC861_DIGOUT_NID, 16261 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes), 16262 .channel_mode = alc861_threestack_modes, 16263 .need_dac_fix = 1, 16264 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 16265 .adc_nids = alc861_adc_nids, 16266 .input_mux = &alc861_capture_source, 16267 }, 16268 [ALC861_6ST_DIG] = { 16269 .mixers = { alc861_base_mixer }, 16270 .init_verbs = { alc861_base_init_verbs }, 16271 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 16272 .dac_nids = alc861_dac_nids, 16273 .dig_out_nid = ALC861_DIGOUT_NID, 16274 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes), 16275 .channel_mode = alc861_8ch_modes, 16276 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 16277 .adc_nids = alc861_adc_nids, 16278 .input_mux = &alc861_capture_source, 16279 }, 16280 [ALC660_3ST] = { 16281 .mixers = { alc861_3ST_mixer }, 16282 .init_verbs = { alc861_threestack_init_verbs }, 16283 .num_dacs = ARRAY_SIZE(alc660_dac_nids), 16284 .dac_nids = alc660_dac_nids, 16285 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes), 16286 .channel_mode = alc861_threestack_modes, 16287 .need_dac_fix = 1, 16288 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 16289 .adc_nids = alc861_adc_nids, 16290 .input_mux = &alc861_capture_source, 16291 }, 16292 [ALC861_UNIWILL_M31] = { 16293 .mixers = { alc861_uniwill_m31_mixer }, 16294 .init_verbs = { alc861_uniwill_m31_init_verbs }, 16295 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 16296 .dac_nids = alc861_dac_nids, 16297 .dig_out_nid = ALC861_DIGOUT_NID, 16298 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes), 16299 .channel_mode = alc861_uniwill_m31_modes, 16300 .need_dac_fix = 1, 16301 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 16302 .adc_nids = alc861_adc_nids, 16303 .input_mux = &alc861_capture_source, 16304 }, 16305 [ALC861_TOSHIBA] = { 16306 .mixers = { alc861_toshiba_mixer }, 16307 .init_verbs = { alc861_base_init_verbs, 16308 alc861_toshiba_init_verbs }, 16309 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 16310 .dac_nids = alc861_dac_nids, 16311 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 16312 .channel_mode = alc883_3ST_2ch_modes, 16313 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 16314 .adc_nids = alc861_adc_nids, 16315 .input_mux = &alc861_capture_source, 16316 .unsol_event = alc861_toshiba_unsol_event, 16317 .init_hook = alc861_toshiba_automute, 16318 }, 16319 [ALC861_ASUS] = { 16320 .mixers = { alc861_asus_mixer }, 16321 .init_verbs = { alc861_asus_init_verbs }, 16322 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 16323 .dac_nids = alc861_dac_nids, 16324 .dig_out_nid = ALC861_DIGOUT_NID, 16325 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes), 16326 .channel_mode = alc861_asus_modes, 16327 .need_dac_fix = 1, 16328 .hp_nid = 0x06, 16329 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 16330 .adc_nids = alc861_adc_nids, 16331 .input_mux = &alc861_capture_source, 16332 }, 16333 [ALC861_ASUS_LAPTOP] = { 16334 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer }, 16335 .init_verbs = { alc861_asus_init_verbs, 16336 alc861_asus_laptop_init_verbs }, 16337 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 16338 .dac_nids = alc861_dac_nids, 16339 .dig_out_nid = ALC861_DIGOUT_NID, 16340 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 16341 .channel_mode = alc883_3ST_2ch_modes, 16342 .need_dac_fix = 1, 16343 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 16344 .adc_nids = alc861_adc_nids, 16345 .input_mux = &alc861_capture_source, 16346 }, 16347}; 16348 16349/* Pin config fixes */ 16350enum { 16351 PINFIX_FSC_AMILO_PI1505, 16352}; 16353 16354static const struct alc_fixup alc861_fixups[] = { 16355 [PINFIX_FSC_AMILO_PI1505] = { 16356 .type = ALC_FIXUP_PINS, 16357 .v.pins = (const struct alc_pincfg[]) { 16358 { 0x0b, 0x0221101f }, /* HP */ 16359 { 0x0f, 0x90170310 }, /* speaker */ 16360 { } 16361 } 16362 }, 16363}; 16364 16365static struct snd_pci_quirk alc861_fixup_tbl[] = { 16366 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505), 16367 {} 16368}; 16369 16370static int patch_alc861(struct hda_codec *codec) 16371{ 16372 struct alc_spec *spec; 16373 int board_config; 16374 int err; 16375 16376 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 16377 if (spec == NULL) 16378 return -ENOMEM; 16379 16380 codec->spec = spec; 16381 16382 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST, 16383 alc861_models, 16384 alc861_cfg_tbl); 16385 16386 if (board_config < 0) { 16387 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 16388 codec->chip_name); 16389 board_config = ALC861_AUTO; 16390 } 16391 16392 if (board_config == ALC861_AUTO) { 16393 alc_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups); 16394 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); 16395 } 16396 16397 if (board_config == ALC861_AUTO) { 16398 /* automatic parse from the BIOS config */ 16399 err = alc861_parse_auto_config(codec); 16400 if (err < 0) { 16401 alc_free(codec); 16402 return err; 16403 } else if (!err) { 16404 printk(KERN_INFO 16405 "hda_codec: Cannot set up configuration " 16406 "from BIOS. Using base mode...\n"); 16407 board_config = ALC861_3ST_DIG; 16408 } 16409 } 16410 16411 err = snd_hda_attach_beep_device(codec, 0x23); 16412 if (err < 0) { 16413 alc_free(codec); 16414 return err; 16415 } 16416 16417 if (board_config != ALC861_AUTO) 16418 setup_preset(codec, &alc861_presets[board_config]); 16419 16420 spec->stream_analog_playback = &alc861_pcm_analog_playback; 16421 spec->stream_analog_capture = &alc861_pcm_analog_capture; 16422 16423 spec->stream_digital_playback = &alc861_pcm_digital_playback; 16424 spec->stream_digital_capture = &alc861_pcm_digital_capture; 16425 16426 if (!spec->cap_mixer) 16427 set_capture_mixer(codec); 16428 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT); 16429 16430 spec->vmaster_nid = 0x03; 16431 16432 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); 16433 16434 codec->patch_ops = alc_patch_ops; 16435 if (board_config == ALC861_AUTO) { 16436 spec->init_hook = alc861_auto_init; 16437#ifdef CONFIG_SND_HDA_POWER_SAVE 16438 spec->power_hook = alc_power_eapd; 16439#endif 16440 } 16441#ifdef CONFIG_SND_HDA_POWER_SAVE 16442 if (!spec->loopback.amplist) 16443 spec->loopback.amplist = alc861_loopbacks; 16444#endif 16445 16446 return 0; 16447} 16448 16449/* 16450 * ALC861-VD support 16451 * 16452 * Based on ALC882 16453 * 16454 * In addition, an independent DAC 16455 */ 16456#define ALC861VD_DIGOUT_NID 0x06 16457 16458static hda_nid_t alc861vd_dac_nids[4] = { 16459 /* front, surr, clfe, side surr */ 16460 0x02, 0x03, 0x04, 0x05 16461}; 16462 16463/* dac_nids for ALC660vd are in a different order - according to 16464 * Realtek's driver. 16465 * This should probably result in a different mixer for 6stack models 16466 * of ALC660vd codecs, but for now there is only 3stack mixer 16467 * - and it is the same as in 861vd. 16468 * adc_nids in ALC660vd are (is) the same as in 861vd 16469 */ 16470static hda_nid_t alc660vd_dac_nids[3] = { 16471 /* front, rear, clfe, rear_surr */ 16472 0x02, 0x04, 0x03 16473}; 16474 16475static hda_nid_t alc861vd_adc_nids[1] = { 16476 /* ADC0 */ 16477 0x09, 16478}; 16479 16480static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 }; 16481 16482/* input MUX */ 16483/* FIXME: should be a matrix-type input source selection */ 16484static struct hda_input_mux alc861vd_capture_source = { 16485 .num_items = 4, 16486 .items = { 16487 { "Mic", 0x0 }, 16488 { "Front Mic", 0x1 }, 16489 { "Line", 0x2 }, 16490 { "CD", 0x4 }, 16491 }, 16492}; 16493 16494static struct hda_input_mux alc861vd_dallas_capture_source = { 16495 .num_items = 2, 16496 .items = { 16497 { "Mic", 0x0 }, 16498 { "Internal Mic", 0x1 }, 16499 }, 16500}; 16501 16502static struct hda_input_mux alc861vd_hp_capture_source = { 16503 .num_items = 2, 16504 .items = { 16505 { "Front Mic", 0x0 }, 16506 { "ATAPI Mic", 0x1 }, 16507 }, 16508}; 16509 16510/* 16511 * 2ch mode 16512 */ 16513static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = { 16514 { 2, NULL } 16515}; 16516 16517/* 16518 * 6ch mode 16519 */ 16520static struct hda_verb alc861vd_6stack_ch6_init[] = { 16521 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 16522 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 16523 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 16524 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 16525 { } /* end */ 16526}; 16527 16528/* 16529 * 8ch mode 16530 */ 16531static struct hda_verb alc861vd_6stack_ch8_init[] = { 16532 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 16533 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 16534 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 16535 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 16536 { } /* end */ 16537}; 16538 16539static struct hda_channel_mode alc861vd_6stack_modes[2] = { 16540 { 6, alc861vd_6stack_ch6_init }, 16541 { 8, alc861vd_6stack_ch8_init }, 16542}; 16543 16544static struct snd_kcontrol_new alc861vd_chmode_mixer[] = { 16545 { 16546 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 16547 .name = "Channel Mode", 16548 .info = alc_ch_mode_info, 16549 .get = alc_ch_mode_get, 16550 .put = alc_ch_mode_put, 16551 }, 16552 { } /* end */ 16553}; 16554 16555/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 16556 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b 16557 */ 16558static struct snd_kcontrol_new alc861vd_6st_mixer[] = { 16559 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 16560 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 16561 16562 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT), 16563 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 16564 16565 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, 16566 HDA_OUTPUT), 16567 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, 16568 HDA_OUTPUT), 16569 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 16570 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 16571 16572 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT), 16573 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 16574 16575 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 16576 16577 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 16578 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 16579 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 16580 16581 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), 16582 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 16583 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 16584 16585 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 16586 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 16587 16588 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 16589 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 16590 16591 { } /* end */ 16592}; 16593 16594static struct snd_kcontrol_new alc861vd_3st_mixer[] = { 16595 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 16596 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 16597 16598 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 16599 16600 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 16601 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 16602 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 16603 16604 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), 16605 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 16606 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 16607 16608 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 16609 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 16610 16611 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 16612 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 16613 16614 { } /* end */ 16615}; 16616 16617static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = { 16618 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 16619 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/ 16620 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 16621 16622 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 16623 16624 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 16625 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 16626 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 16627 16628 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), 16629 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 16630 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 16631 16632 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 16633 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 16634 16635 { } /* end */ 16636}; 16637 16638/* Pin assignment: Speaker=0x14, HP = 0x15, 16639 * Mic=0x18, Internal Mic = 0x19, CD = 0x1c, PC Beep = 0x1d 16640 */ 16641static struct snd_kcontrol_new alc861vd_dallas_mixer[] = { 16642 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 16643 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT), 16644 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 16645 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT), 16646 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 16647 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 16648 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 16649 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), 16650 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 16651 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 16652 { } /* end */ 16653}; 16654 16655/* Pin assignment: Speaker=0x14, Line-out = 0x15, 16656 * Front Mic=0x18, ATAPI Mic = 0x19, 16657 */ 16658static struct snd_kcontrol_new alc861vd_hp_mixer[] = { 16659 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 16660 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 16661 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 16662 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT), 16663 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 16664 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 16665 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 16666 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 16667 16668 { } /* end */ 16669}; 16670 16671/* 16672 * generic initialization of ADC, input mixers and output mixers 16673 */ 16674static struct hda_verb alc861vd_volume_init_verbs[] = { 16675 /* 16676 * Unmute ADC0 and set the default input to mic-in 16677 */ 16678 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 16679 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 16680 16681 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of 16682 * the analog-loopback mixer widget 16683 */ 16684 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 16685 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 16686 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 16687 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 16688 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 16689 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 16690 16691 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */ 16692 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 16693 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 16694 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 16695 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, 16696 16697 /* 16698 * Set up output mixers (0x02 - 0x05) 16699 */ 16700 /* set vol=0 to output mixers */ 16701 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 16702 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 16703 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 16704 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 16705 16706 /* set up input amps for analog loopback */ 16707 /* Amp Indices: DAC = 0, mixer = 1 */ 16708 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 16709 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 16710 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 16711 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 16712 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 16713 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 16714 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 16715 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 16716 16717 { } 16718}; 16719 16720/* 16721 * 3-stack pin configuration: 16722 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b 16723 */ 16724static struct hda_verb alc861vd_3stack_init_verbs[] = { 16725 /* 16726 * Set pin mode and muting 16727 */ 16728 /* set front pin widgets 0x14 for output */ 16729 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 16730 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 16731 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 16732 16733 /* Mic (rear) pin: input vref at 80% */ 16734 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 16735 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 16736 /* Front Mic pin: input vref at 80% */ 16737 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 16738 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 16739 /* Line In pin: input */ 16740 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 16741 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 16742 /* Line-2 In: Headphone output (output 0 - 0x0c) */ 16743 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 16744 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 16745 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 16746 /* CD pin widget for input */ 16747 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 16748 16749 { } 16750}; 16751 16752/* 16753 * 6-stack pin configuration: 16754 */ 16755static struct hda_verb alc861vd_6stack_init_verbs[] = { 16756 /* 16757 * Set pin mode and muting 16758 */ 16759 /* set front pin widgets 0x14 for output */ 16760 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 16761 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 16762 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 16763 16764 /* Rear Pin: output 1 (0x0d) */ 16765 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 16766 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 16767 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 16768 /* CLFE Pin: output 2 (0x0e) */ 16769 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 16770 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 16771 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, 16772 /* Side Pin: output 3 (0x0f) */ 16773 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 16774 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 16775 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, 16776 16777 /* Mic (rear) pin: input vref at 80% */ 16778 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 16779 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 16780 /* Front Mic pin: input vref at 80% */ 16781 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 16782 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 16783 /* Line In pin: input */ 16784 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 16785 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 16786 /* Line-2 In: Headphone output (output 0 - 0x0c) */ 16787 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 16788 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 16789 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 16790 /* CD pin widget for input */ 16791 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 16792 16793 { } 16794}; 16795 16796static struct hda_verb alc861vd_eapd_verbs[] = { 16797 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 16798 { } 16799}; 16800 16801static struct hda_verb alc660vd_eapd_verbs[] = { 16802 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 16803 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, 16804 { } 16805}; 16806 16807static struct hda_verb alc861vd_lenovo_unsol_verbs[] = { 16808 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 16809 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 16810 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, 16811 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 16812 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 16813 {} 16814}; 16815 16816static void alc861vd_lenovo_setup(struct hda_codec *codec) 16817{ 16818 struct alc_spec *spec = codec->spec; 16819 spec->autocfg.hp_pins[0] = 0x1b; 16820 spec->autocfg.speaker_pins[0] = 0x14; 16821} 16822 16823static void alc861vd_lenovo_init_hook(struct hda_codec *codec) 16824{ 16825 alc_automute_amp(codec); 16826 alc88x_simple_mic_automute(codec); 16827} 16828 16829static void alc861vd_lenovo_unsol_event(struct hda_codec *codec, 16830 unsigned int res) 16831{ 16832 switch (res >> 26) { 16833 case ALC880_MIC_EVENT: 16834 alc88x_simple_mic_automute(codec); 16835 break; 16836 default: 16837 alc_automute_amp_unsol_event(codec, res); 16838 break; 16839 } 16840} 16841 16842static struct hda_verb alc861vd_dallas_verbs[] = { 16843 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 16844 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 16845 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 16846 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 16847 16848 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 16849 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 16850 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 16851 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 16852 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 16853 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 16854 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 16855 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 16856 16857 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 16858 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 16859 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 16860 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 16861 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 16862 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 16863 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 16864 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 16865 16866 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, 16867 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 16868 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, 16869 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 16870 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 16871 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 16872 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 16873 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 16874 16875 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 16876 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 16877 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 16878 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 16879 16880 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 16881 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 16882 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 16883 16884 { } /* end */ 16885}; 16886 16887/* toggle speaker-output according to the hp-jack state */ 16888static void alc861vd_dallas_setup(struct hda_codec *codec) 16889{ 16890 struct alc_spec *spec = codec->spec; 16891 16892 spec->autocfg.hp_pins[0] = 0x15; 16893 spec->autocfg.speaker_pins[0] = 0x14; 16894} 16895 16896#ifdef CONFIG_SND_HDA_POWER_SAVE 16897#define alc861vd_loopbacks alc880_loopbacks 16898#endif 16899 16900/* pcm configuration: identical with ALC880 */ 16901#define alc861vd_pcm_analog_playback alc880_pcm_analog_playback 16902#define alc861vd_pcm_analog_capture alc880_pcm_analog_capture 16903#define alc861vd_pcm_digital_playback alc880_pcm_digital_playback 16904#define alc861vd_pcm_digital_capture alc880_pcm_digital_capture 16905 16906/* 16907 * configuration and preset 16908 */ 16909static const char * const alc861vd_models[ALC861VD_MODEL_LAST] = { 16910 [ALC660VD_3ST] = "3stack-660", 16911 [ALC660VD_3ST_DIG] = "3stack-660-digout", 16912 [ALC660VD_ASUS_V1S] = "asus-v1s", 16913 [ALC861VD_3ST] = "3stack", 16914 [ALC861VD_3ST_DIG] = "3stack-digout", 16915 [ALC861VD_6ST_DIG] = "6stack-digout", 16916 [ALC861VD_LENOVO] = "lenovo", 16917 [ALC861VD_DALLAS] = "dallas", 16918 [ALC861VD_HP] = "hp", 16919 [ALC861VD_AUTO] = "auto", 16920}; 16921 16922static struct snd_pci_quirk alc861vd_cfg_tbl[] = { 16923 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST), 16924 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP), 16925 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST), 16926 /*SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),*/ /* auto */ 16927 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S), 16928 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG), 16929 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST), 16930 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO), 16931 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/ 16932 SND_PCI_QUIRK(0x1179, 0xff01, "Toshiba A135", ALC861VD_LENOVO), 16933 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO), 16934 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS), 16935 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG), 16936 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO), 16937 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG), 16938 {} 16939}; 16940 16941static struct alc_config_preset alc861vd_presets[] = { 16942 [ALC660VD_3ST] = { 16943 .mixers = { alc861vd_3st_mixer }, 16944 .init_verbs = { alc861vd_volume_init_verbs, 16945 alc861vd_3stack_init_verbs }, 16946 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids), 16947 .dac_nids = alc660vd_dac_nids, 16948 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 16949 .channel_mode = alc861vd_3stack_2ch_modes, 16950 .input_mux = &alc861vd_capture_source, 16951 }, 16952 [ALC660VD_3ST_DIG] = { 16953 .mixers = { alc861vd_3st_mixer }, 16954 .init_verbs = { alc861vd_volume_init_verbs, 16955 alc861vd_3stack_init_verbs }, 16956 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids), 16957 .dac_nids = alc660vd_dac_nids, 16958 .dig_out_nid = ALC861VD_DIGOUT_NID, 16959 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 16960 .channel_mode = alc861vd_3stack_2ch_modes, 16961 .input_mux = &alc861vd_capture_source, 16962 }, 16963 [ALC861VD_3ST] = { 16964 .mixers = { alc861vd_3st_mixer }, 16965 .init_verbs = { alc861vd_volume_init_verbs, 16966 alc861vd_3stack_init_verbs }, 16967 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids), 16968 .dac_nids = alc861vd_dac_nids, 16969 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 16970 .channel_mode = alc861vd_3stack_2ch_modes, 16971 .input_mux = &alc861vd_capture_source, 16972 }, 16973 [ALC861VD_3ST_DIG] = { 16974 .mixers = { alc861vd_3st_mixer }, 16975 .init_verbs = { alc861vd_volume_init_verbs, 16976 alc861vd_3stack_init_verbs }, 16977 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids), 16978 .dac_nids = alc861vd_dac_nids, 16979 .dig_out_nid = ALC861VD_DIGOUT_NID, 16980 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 16981 .channel_mode = alc861vd_3stack_2ch_modes, 16982 .input_mux = &alc861vd_capture_source, 16983 }, 16984 [ALC861VD_6ST_DIG] = { 16985 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer }, 16986 .init_verbs = { alc861vd_volume_init_verbs, 16987 alc861vd_6stack_init_verbs }, 16988 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids), 16989 .dac_nids = alc861vd_dac_nids, 16990 .dig_out_nid = ALC861VD_DIGOUT_NID, 16991 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes), 16992 .channel_mode = alc861vd_6stack_modes, 16993 .input_mux = &alc861vd_capture_source, 16994 }, 16995 [ALC861VD_LENOVO] = { 16996 .mixers = { alc861vd_lenovo_mixer }, 16997 .init_verbs = { alc861vd_volume_init_verbs, 16998 alc861vd_3stack_init_verbs, 16999 alc861vd_eapd_verbs, 17000 alc861vd_lenovo_unsol_verbs }, 17001 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids), 17002 .dac_nids = alc660vd_dac_nids, 17003 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 17004 .channel_mode = alc861vd_3stack_2ch_modes, 17005 .input_mux = &alc861vd_capture_source, 17006 .unsol_event = alc861vd_lenovo_unsol_event, 17007 .setup = alc861vd_lenovo_setup, 17008 .init_hook = alc861vd_lenovo_init_hook, 17009 }, 17010 [ALC861VD_DALLAS] = { 17011 .mixers = { alc861vd_dallas_mixer }, 17012 .init_verbs = { alc861vd_dallas_verbs }, 17013 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids), 17014 .dac_nids = alc861vd_dac_nids, 17015 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 17016 .channel_mode = alc861vd_3stack_2ch_modes, 17017 .input_mux = &alc861vd_dallas_capture_source, 17018 .unsol_event = alc_automute_amp_unsol_event, 17019 .setup = alc861vd_dallas_setup, 17020 .init_hook = alc_automute_amp, 17021 }, 17022 [ALC861VD_HP] = { 17023 .mixers = { alc861vd_hp_mixer }, 17024 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs }, 17025 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids), 17026 .dac_nids = alc861vd_dac_nids, 17027 .dig_out_nid = ALC861VD_DIGOUT_NID, 17028 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 17029 .channel_mode = alc861vd_3stack_2ch_modes, 17030 .input_mux = &alc861vd_hp_capture_source, 17031 .unsol_event = alc_automute_amp_unsol_event, 17032 .setup = alc861vd_dallas_setup, 17033 .init_hook = alc_automute_amp, 17034 }, 17035 [ALC660VD_ASUS_V1S] = { 17036 .mixers = { alc861vd_lenovo_mixer }, 17037 .init_verbs = { alc861vd_volume_init_verbs, 17038 alc861vd_3stack_init_verbs, 17039 alc861vd_eapd_verbs, 17040 alc861vd_lenovo_unsol_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 .unsol_event = alc861vd_lenovo_unsol_event, 17048 .setup = alc861vd_lenovo_setup, 17049 .init_hook = alc861vd_lenovo_init_hook, 17050 }, 17051}; 17052 17053/* 17054 * BIOS auto configuration 17055 */ 17056static int alc861vd_auto_create_input_ctls(struct hda_codec *codec, 17057 const struct auto_pin_cfg *cfg) 17058{ 17059 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x22, 0); 17060} 17061 17062 17063static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec, 17064 hda_nid_t nid, int pin_type, int dac_idx) 17065{ 17066 alc_set_pin_output(codec, nid, pin_type); 17067} 17068 17069static void alc861vd_auto_init_multi_out(struct hda_codec *codec) 17070{ 17071 struct alc_spec *spec = codec->spec; 17072 int i; 17073 17074 for (i = 0; i <= HDA_SIDE; i++) { 17075 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 17076 int pin_type = get_pin_type(spec->autocfg.line_out_type); 17077 if (nid) 17078 alc861vd_auto_set_output_and_unmute(codec, nid, 17079 pin_type, i); 17080 } 17081} 17082 17083 17084static void alc861vd_auto_init_hp_out(struct hda_codec *codec) 17085{ 17086 struct alc_spec *spec = codec->spec; 17087 hda_nid_t pin; 17088 17089 pin = spec->autocfg.hp_pins[0]; 17090 if (pin) /* connect to front and use dac 0 */ 17091 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); 17092 pin = spec->autocfg.speaker_pins[0]; 17093 if (pin) 17094 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0); 17095} 17096 17097#define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID 17098 17099static void alc861vd_auto_init_analog_input(struct hda_codec *codec) 17100{ 17101 struct alc_spec *spec = codec->spec; 17102 struct auto_pin_cfg *cfg = &spec->autocfg; 17103 int i; 17104 17105 for (i = 0; i < cfg->num_inputs; i++) { 17106 hda_nid_t nid = cfg->inputs[i].pin; 17107 if (alc_is_input_pin(codec, nid)) { 17108 alc_set_input_pin(codec, nid, cfg->inputs[i].type); 17109 if (nid != ALC861VD_PIN_CD_NID && 17110 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)) 17111 snd_hda_codec_write(codec, nid, 0, 17112 AC_VERB_SET_AMP_GAIN_MUTE, 17113 AMP_OUT_MUTE); 17114 } 17115 } 17116} 17117 17118#define alc861vd_auto_init_input_src alc882_auto_init_input_src 17119 17120#define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02) 17121#define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c) 17122 17123/* add playback controls from the parsed DAC table */ 17124/* Based on ALC880 version. But ALC861VD has separate, 17125 * different NIDs for mute/unmute switch and volume control */ 17126static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec, 17127 const struct auto_pin_cfg *cfg) 17128{ 17129 static const char * const chname[4] = { 17130 "Front", "Surround", "CLFE", "Side" 17131 }; 17132 const char *pfx = alc_get_line_out_pfx(cfg, true); 17133 hda_nid_t nid_v, nid_s; 17134 int i, err; 17135 17136 for (i = 0; i < cfg->line_outs; i++) { 17137 if (!spec->multiout.dac_nids[i]) 17138 continue; 17139 nid_v = alc861vd_idx_to_mixer_vol( 17140 alc880_dac_to_idx( 17141 spec->multiout.dac_nids[i])); 17142 nid_s = alc861vd_idx_to_mixer_switch( 17143 alc880_dac_to_idx( 17144 spec->multiout.dac_nids[i])); 17145 17146 if (!pfx && i == 2) { 17147 /* Center/LFE */ 17148 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, 17149 "Center", 17150 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0, 17151 HDA_OUTPUT)); 17152 if (err < 0) 17153 return err; 17154 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, 17155 "LFE", 17156 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0, 17157 HDA_OUTPUT)); 17158 if (err < 0) 17159 return err; 17160 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, 17161 "Center", 17162 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2, 17163 HDA_INPUT)); 17164 if (err < 0) 17165 return err; 17166 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, 17167 "LFE", 17168 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2, 17169 HDA_INPUT)); 17170 if (err < 0) 17171 return err; 17172 } else { 17173 const char *name = pfx; 17174 int index = i; 17175 if (!name) { 17176 name = chname[i]; 17177 index = 0; 17178 } 17179 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, 17180 name, index, 17181 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, 17182 HDA_OUTPUT)); 17183 if (err < 0) 17184 return err; 17185 err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, 17186 name, index, 17187 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, 17188 HDA_INPUT)); 17189 if (err < 0) 17190 return err; 17191 } 17192 } 17193 return 0; 17194} 17195 17196/* add playback controls for speaker and HP outputs */ 17197/* Based on ALC880 version. But ALC861VD has separate, 17198 * different NIDs for mute/unmute switch and volume control */ 17199static int alc861vd_auto_create_extra_out(struct alc_spec *spec, 17200 hda_nid_t pin, const char *pfx) 17201{ 17202 hda_nid_t nid_v, nid_s; 17203 int err; 17204 17205 if (!pin) 17206 return 0; 17207 17208 if (alc880_is_fixed_pin(pin)) { 17209 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); 17210 /* specify the DAC as the extra output */ 17211 if (!spec->multiout.hp_nid) 17212 spec->multiout.hp_nid = nid_v; 17213 else 17214 spec->multiout.extra_out_nid[0] = nid_v; 17215 /* control HP volume/switch on the output mixer amp */ 17216 nid_v = alc861vd_idx_to_mixer_vol( 17217 alc880_fixed_pin_idx(pin)); 17218 nid_s = alc861vd_idx_to_mixer_switch( 17219 alc880_fixed_pin_idx(pin)); 17220 17221 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, 17222 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT)); 17223 if (err < 0) 17224 return err; 17225 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx, 17226 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT)); 17227 if (err < 0) 17228 return err; 17229 } else if (alc880_is_multi_pin(pin)) { 17230 /* set manual connection */ 17231 /* we have only a switch on HP-out PIN */ 17232 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, 17233 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); 17234 if (err < 0) 17235 return err; 17236 } 17237 return 0; 17238} 17239 17240/* parse the BIOS configuration and set up the alc_spec 17241 * return 1 if successful, 0 if the proper config is not found, 17242 * or a negative error code 17243 * Based on ALC880 version - had to change it to override 17244 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */ 17245static int alc861vd_parse_auto_config(struct hda_codec *codec) 17246{ 17247 struct alc_spec *spec = codec->spec; 17248 int err; 17249 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 }; 17250 17251 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 17252 alc861vd_ignore); 17253 if (err < 0) 17254 return err; 17255 if (!spec->autocfg.line_outs) 17256 return 0; /* can't find valid BIOS pin config */ 17257 17258 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); 17259 if (err < 0) 17260 return err; 17261 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg); 17262 if (err < 0) 17263 return err; 17264 err = alc861vd_auto_create_extra_out(spec, 17265 spec->autocfg.speaker_pins[0], 17266 "Speaker"); 17267 if (err < 0) 17268 return err; 17269 err = alc861vd_auto_create_extra_out(spec, 17270 spec->autocfg.hp_pins[0], 17271 "Headphone"); 17272 if (err < 0) 17273 return err; 17274 err = alc861vd_auto_create_input_ctls(codec, &spec->autocfg); 17275 if (err < 0) 17276 return err; 17277 17278 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 17279 17280 alc_auto_parse_digital(codec); 17281 17282 if (spec->kctls.list) 17283 add_mixer(spec, spec->kctls.list); 17284 17285 add_verb(spec, alc861vd_volume_init_verbs); 17286 17287 spec->num_mux_defs = 1; 17288 spec->input_mux = &spec->private_imux[0]; 17289 17290 err = alc_auto_add_mic_boost(codec); 17291 if (err < 0) 17292 return err; 17293 17294 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); 17295 17296 return 1; 17297} 17298 17299/* additional initialization for auto-configuration model */ 17300static void alc861vd_auto_init(struct hda_codec *codec) 17301{ 17302 struct alc_spec *spec = codec->spec; 17303 alc861vd_auto_init_multi_out(codec); 17304 alc861vd_auto_init_hp_out(codec); 17305 alc861vd_auto_init_analog_input(codec); 17306 alc861vd_auto_init_input_src(codec); 17307 alc_auto_init_digital(codec); 17308 if (spec->unsol_event) 17309 alc_inithook(codec); 17310} 17311 17312enum { 17313 ALC660VD_FIX_ASUS_GPIO1 17314}; 17315 17316/* reset GPIO1 */ 17317static const struct alc_fixup alc861vd_fixups[] = { 17318 [ALC660VD_FIX_ASUS_GPIO1] = { 17319 .type = ALC_FIXUP_VERBS, 17320 .v.verbs = (const struct hda_verb[]) { 17321 {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, 17322 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, 17323 {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, 17324 { } 17325 } 17326 }, 17327}; 17328 17329static struct snd_pci_quirk alc861vd_fixup_tbl[] = { 17330 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1), 17331 {} 17332}; 17333 17334static int patch_alc861vd(struct hda_codec *codec) 17335{ 17336 struct alc_spec *spec; 17337 int err, board_config; 17338 17339 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 17340 if (spec == NULL) 17341 return -ENOMEM; 17342 17343 codec->spec = spec; 17344 17345 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST, 17346 alc861vd_models, 17347 alc861vd_cfg_tbl); 17348 17349 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) { 17350 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 17351 codec->chip_name); 17352 board_config = ALC861VD_AUTO; 17353 } 17354 17355 if (board_config == ALC861VD_AUTO) { 17356 alc_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups); 17357 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); 17358 } 17359 17360 if (board_config == ALC861VD_AUTO) { 17361 /* automatic parse from the BIOS config */ 17362 err = alc861vd_parse_auto_config(codec); 17363 if (err < 0) { 17364 alc_free(codec); 17365 return err; 17366 } else if (!err) { 17367 printk(KERN_INFO 17368 "hda_codec: Cannot set up configuration " 17369 "from BIOS. Using base mode...\n"); 17370 board_config = ALC861VD_3ST; 17371 } 17372 } 17373 17374 err = snd_hda_attach_beep_device(codec, 0x23); 17375 if (err < 0) { 17376 alc_free(codec); 17377 return err; 17378 } 17379 17380 if (board_config != ALC861VD_AUTO) 17381 setup_preset(codec, &alc861vd_presets[board_config]); 17382 17383 if (codec->vendor_id == 0x10ec0660) { 17384 /* always turn on EAPD */ 17385 add_verb(spec, alc660vd_eapd_verbs); 17386 } 17387 17388 spec->stream_analog_playback = &alc861vd_pcm_analog_playback; 17389 spec->stream_analog_capture = &alc861vd_pcm_analog_capture; 17390 17391 spec->stream_digital_playback = &alc861vd_pcm_digital_playback; 17392 spec->stream_digital_capture = &alc861vd_pcm_digital_capture; 17393 17394 if (!spec->adc_nids) { 17395 spec->adc_nids = alc861vd_adc_nids; 17396 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids); 17397 } 17398 if (!spec->capsrc_nids) 17399 spec->capsrc_nids = alc861vd_capsrc_nids; 17400 17401 set_capture_mixer(codec); 17402 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 17403 17404 spec->vmaster_nid = 0x02; 17405 17406 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); 17407 17408 codec->patch_ops = alc_patch_ops; 17409 17410 if (board_config == ALC861VD_AUTO) 17411 spec->init_hook = alc861vd_auto_init; 17412 spec->shutup = alc_eapd_shutup; 17413#ifdef CONFIG_SND_HDA_POWER_SAVE 17414 if (!spec->loopback.amplist) 17415 spec->loopback.amplist = alc861vd_loopbacks; 17416#endif 17417 17418 return 0; 17419} 17420 17421/* 17422 * ALC662 support 17423 * 17424 * ALC662 is almost identical with ALC880 but has cleaner and more flexible 17425 * configuration. Each pin widget can choose any input DACs and a mixer. 17426 * Each ADC is connected from a mixer of all inputs. This makes possible 17427 * 6-channel independent captures. 17428 * 17429 * In addition, an independent DAC for the multi-playback (not used in this 17430 * driver yet). 17431 */ 17432#define ALC662_DIGOUT_NID 0x06 17433#define ALC662_DIGIN_NID 0x0a 17434 17435static hda_nid_t alc662_dac_nids[3] = { 17436 /* front, rear, clfe */ 17437 0x02, 0x03, 0x04 17438}; 17439 17440static hda_nid_t alc272_dac_nids[2] = { 17441 0x02, 0x03 17442}; 17443 17444static hda_nid_t alc662_adc_nids[2] = { 17445 /* ADC1-2 */ 17446 0x09, 0x08 17447}; 17448 17449static hda_nid_t alc272_adc_nids[1] = { 17450 /* ADC1-2 */ 17451 0x08, 17452}; 17453 17454static hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 }; 17455static hda_nid_t alc272_capsrc_nids[1] = { 0x23 }; 17456 17457 17458/* input MUX */ 17459/* FIXME: should be a matrix-type input source selection */ 17460static struct hda_input_mux alc662_capture_source = { 17461 .num_items = 4, 17462 .items = { 17463 { "Mic", 0x0 }, 17464 { "Front Mic", 0x1 }, 17465 { "Line", 0x2 }, 17466 { "CD", 0x4 }, 17467 }, 17468}; 17469 17470static struct hda_input_mux alc662_lenovo_101e_capture_source = { 17471 .num_items = 2, 17472 .items = { 17473 { "Mic", 0x1 }, 17474 { "Line", 0x2 }, 17475 }, 17476}; 17477 17478static struct hda_input_mux alc663_capture_source = { 17479 .num_items = 3, 17480 .items = { 17481 { "Mic", 0x0 }, 17482 { "Front Mic", 0x1 }, 17483 { "Line", 0x2 }, 17484 }, 17485}; 17486 17487#if 0 /* set to 1 for testing other input sources below */ 17488static struct hda_input_mux alc272_nc10_capture_source = { 17489 .num_items = 16, 17490 .items = { 17491 { "Autoselect Mic", 0x0 }, 17492 { "Internal Mic", 0x1 }, 17493 { "In-0x02", 0x2 }, 17494 { "In-0x03", 0x3 }, 17495 { "In-0x04", 0x4 }, 17496 { "In-0x05", 0x5 }, 17497 { "In-0x06", 0x6 }, 17498 { "In-0x07", 0x7 }, 17499 { "In-0x08", 0x8 }, 17500 { "In-0x09", 0x9 }, 17501 { "In-0x0a", 0x0a }, 17502 { "In-0x0b", 0x0b }, 17503 { "In-0x0c", 0x0c }, 17504 { "In-0x0d", 0x0d }, 17505 { "In-0x0e", 0x0e }, 17506 { "In-0x0f", 0x0f }, 17507 }, 17508}; 17509#endif 17510 17511/* 17512 * 2ch mode 17513 */ 17514static struct hda_channel_mode alc662_3ST_2ch_modes[1] = { 17515 { 2, NULL } 17516}; 17517 17518/* 17519 * 2ch mode 17520 */ 17521static struct hda_verb alc662_3ST_ch2_init[] = { 17522 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 17523 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 17524 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 17525 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 17526 { } /* end */ 17527}; 17528 17529/* 17530 * 6ch mode 17531 */ 17532static struct hda_verb alc662_3ST_ch6_init[] = { 17533 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 17534 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 17535 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, 17536 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 17537 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 17538 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 17539 { } /* end */ 17540}; 17541 17542static struct hda_channel_mode alc662_3ST_6ch_modes[2] = { 17543 { 2, alc662_3ST_ch2_init }, 17544 { 6, alc662_3ST_ch6_init }, 17545}; 17546 17547/* 17548 * 2ch mode 17549 */ 17550static struct hda_verb alc662_sixstack_ch6_init[] = { 17551 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 17552 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 17553 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 17554 { } /* end */ 17555}; 17556 17557/* 17558 * 6ch mode 17559 */ 17560static struct hda_verb alc662_sixstack_ch8_init[] = { 17561 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 17562 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 17563 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 17564 { } /* end */ 17565}; 17566 17567static struct hda_channel_mode alc662_5stack_modes[2] = { 17568 { 2, alc662_sixstack_ch6_init }, 17569 { 6, alc662_sixstack_ch8_init }, 17570}; 17571 17572/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 17573 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b 17574 */ 17575 17576static struct snd_kcontrol_new alc662_base_mixer[] = { 17577 /* output mixer control */ 17578 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), 17579 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT), 17580 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT), 17581 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT), 17582 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT), 17583 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT), 17584 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT), 17585 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT), 17586 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 17587 17588 /*Input mixer control */ 17589 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT), 17590 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT), 17591 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT), 17592 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT), 17593 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT), 17594 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT), 17595 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT), 17596 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT), 17597 { } /* end */ 17598}; 17599 17600static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = { 17601 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 17602 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT), 17603 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 17604 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 17605 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 17606 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 17607 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 17608 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17609 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17610 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 17611 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 17612 { } /* end */ 17613}; 17614 17615static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = { 17616 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 17617 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT), 17618 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT), 17619 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT), 17620 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT), 17621 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT), 17622 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT), 17623 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT), 17624 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 17625 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 17626 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 17627 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 17628 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 17629 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17630 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17631 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 17632 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 17633 { } /* end */ 17634}; 17635 17636static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = { 17637 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 17638 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT), 17639 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT), 17640 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT), 17641 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 17642 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 17643 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 17644 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 17645 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 17646 { } /* end */ 17647}; 17648 17649static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = { 17650 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT), 17651 ALC262_HIPPO_MASTER_SWITCH, 17652 17653 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 17654 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17655 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17656 17657 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), 17658 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 17659 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 17660 { } /* end */ 17661}; 17662 17663static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = { 17664 ALC262_HIPPO_MASTER_SWITCH, 17665 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 17666 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT), 17667 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT), 17668 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT), 17669 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT), 17670 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 17671 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 17672 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17673 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17674 { } /* end */ 17675}; 17676 17677static struct hda_bind_ctls alc663_asus_bind_master_vol = { 17678 .ops = &snd_hda_bind_vol, 17679 .values = { 17680 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), 17681 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT), 17682 0 17683 }, 17684}; 17685 17686static struct hda_bind_ctls alc663_asus_one_bind_switch = { 17687 .ops = &snd_hda_bind_sw, 17688 .values = { 17689 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 17690 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT), 17691 0 17692 }, 17693}; 17694 17695static struct snd_kcontrol_new alc663_m51va_mixer[] = { 17696 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol), 17697 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch), 17698 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17699 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17700 { } /* end */ 17701}; 17702 17703static struct hda_bind_ctls alc663_asus_tree_bind_switch = { 17704 .ops = &snd_hda_bind_sw, 17705 .values = { 17706 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 17707 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT), 17708 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT), 17709 0 17710 }, 17711}; 17712 17713static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = { 17714 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol), 17715 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch), 17716 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17717 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17718 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 17719 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 17720 17721 { } /* end */ 17722}; 17723 17724static struct hda_bind_ctls alc663_asus_four_bind_switch = { 17725 .ops = &snd_hda_bind_sw, 17726 .values = { 17727 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 17728 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT), 17729 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT), 17730 0 17731 }, 17732}; 17733 17734static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = { 17735 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol), 17736 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch), 17737 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17738 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17739 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 17740 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 17741 { } /* end */ 17742}; 17743 17744static struct snd_kcontrol_new alc662_1bjd_mixer[] = { 17745 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 17746 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 17747 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 17748 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17749 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17750 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 17751 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 17752 { } /* end */ 17753}; 17754 17755static struct hda_bind_ctls alc663_asus_two_bind_master_vol = { 17756 .ops = &snd_hda_bind_vol, 17757 .values = { 17758 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), 17759 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT), 17760 0 17761 }, 17762}; 17763 17764static struct hda_bind_ctls alc663_asus_two_bind_switch = { 17765 .ops = &snd_hda_bind_sw, 17766 .values = { 17767 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 17768 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT), 17769 0 17770 }, 17771}; 17772 17773static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = { 17774 HDA_BIND_VOL("Master Playback Volume", 17775 &alc663_asus_two_bind_master_vol), 17776 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch), 17777 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 17778 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT), 17779 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17780 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17781 { } /* end */ 17782}; 17783 17784static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = { 17785 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol), 17786 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch), 17787 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 17788 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 17789 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17790 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17791 { } /* end */ 17792}; 17793 17794static struct snd_kcontrol_new alc663_g71v_mixer[] = { 17795 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 17796 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 17797 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT), 17798 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT), 17799 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT), 17800 17801 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17802 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17803 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 17804 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 17805 { } /* end */ 17806}; 17807 17808static struct snd_kcontrol_new alc663_g50v_mixer[] = { 17809 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 17810 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 17811 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT), 17812 17813 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17814 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17815 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 17816 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 17817 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 17818 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 17819 { } /* end */ 17820}; 17821 17822static struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = { 17823 .ops = &snd_hda_bind_sw, 17824 .values = { 17825 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 17826 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT), 17827 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT), 17828 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT), 17829 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT), 17830 0 17831 }, 17832}; 17833 17834static struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = { 17835 .ops = &snd_hda_bind_sw, 17836 .values = { 17837 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 17838 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT), 17839 0 17840 }, 17841}; 17842 17843static struct snd_kcontrol_new alc663_mode7_mixer[] = { 17844 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch), 17845 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol), 17846 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch), 17847 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 17848 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT), 17849 HDA_CODEC_VOLUME("IntMic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17850 HDA_CODEC_MUTE("IntMic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17851 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 17852 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 17853 { } /* end */ 17854}; 17855 17856static struct snd_kcontrol_new alc663_mode8_mixer[] = { 17857 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch), 17858 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol), 17859 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch), 17860 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x15, 0x0, HDA_OUTPUT), 17861 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT), 17862 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17863 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17864 { } /* end */ 17865}; 17866 17867 17868static struct snd_kcontrol_new alc662_chmode_mixer[] = { 17869 { 17870 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 17871 .name = "Channel Mode", 17872 .info = alc_ch_mode_info, 17873 .get = alc_ch_mode_get, 17874 .put = alc_ch_mode_put, 17875 }, 17876 { } /* end */ 17877}; 17878 17879static struct hda_verb alc662_init_verbs[] = { 17880 /* ADC: mute amp left and right */ 17881 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 17882 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 17883 17884 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 17885 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 17886 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 17887 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 17888 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 17889 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 17890 17891 /* Front Pin: output 0 (0x0c) */ 17892 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 17893 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17894 17895 /* Rear Pin: output 1 (0x0d) */ 17896 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 17897 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17898 17899 /* CLFE Pin: output 2 (0x0e) */ 17900 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 17901 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17902 17903 /* Mic (rear) pin: input vref at 80% */ 17904 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 17905 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 17906 /* Front Mic pin: input vref at 80% */ 17907 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 17908 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 17909 /* Line In pin: input */ 17910 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17911 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 17912 /* Line-2 In: Headphone output (output 0 - 0x0c) */ 17913 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17914 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17915 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 17916 /* CD pin widget for input */ 17917 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17918 17919 /* FIXME: use matrix-type input source selection */ 17920 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 17921 /* Input mixer */ 17922 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 17923 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 17924 17925 { } 17926}; 17927 17928static struct hda_verb alc662_eapd_init_verbs[] = { 17929 /* always trun on EAPD */ 17930 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 17931 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, 17932 { } 17933}; 17934 17935static struct hda_verb alc662_sue_init_verbs[] = { 17936 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT}, 17937 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT}, 17938 {} 17939}; 17940 17941static struct hda_verb alc662_eeepc_sue_init_verbs[] = { 17942 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 17943 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17944 {} 17945}; 17946 17947/* Set Unsolicited Event*/ 17948static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = { 17949 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 17950 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17951 {} 17952}; 17953 17954static struct hda_verb alc663_m51va_init_verbs[] = { 17955 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17956 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17957 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17958 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17959 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ 17960 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 17961 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)}, 17962 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 17963 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17964 {} 17965}; 17966 17967static struct hda_verb alc663_21jd_amic_init_verbs[] = { 17968 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17969 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17970 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ 17971 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 17972 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 17973 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 17974 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17975 {} 17976}; 17977 17978static struct hda_verb alc662_1bjd_amic_init_verbs[] = { 17979 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17980 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17981 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17982 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */ 17983 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 17984 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 17985 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 17986 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17987 {} 17988}; 17989 17990static struct hda_verb alc663_15jd_amic_init_verbs[] = { 17991 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17992 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17993 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ 17994 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 17995 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 17996 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 17997 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17998 {} 17999}; 18000 18001static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = { 18002 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 18003 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 18004 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 18005 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */ 18006 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 18007 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 18008 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */ 18009 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 18010 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 18011 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 18012 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 18013 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 18014 {} 18015}; 18016 18017static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = { 18018 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 18019 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 18020 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 18021 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ 18022 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 18023 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 18024 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ 18025 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 18026 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 18027 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 18028 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 18029 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 18030 {} 18031}; 18032 18033static struct hda_verb alc663_g71v_init_verbs[] = { 18034 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 18035 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */ 18036 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */ 18037 18038 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 18039 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 18040 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */ 18041 18042 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT}, 18043 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT}, 18044 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT}, 18045 {} 18046}; 18047 18048static struct hda_verb alc663_g50v_init_verbs[] = { 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, 0x00}, /* Headphone */ 18052 18053 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 18054 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 18055 {} 18056}; 18057 18058static struct hda_verb alc662_ecs_init_verbs[] = { 18059 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f}, 18060 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 18061 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 18062 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 18063 {} 18064}; 18065 18066static struct hda_verb alc272_dell_zm1_init_verbs[] = { 18067 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 18068 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 18069 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 18070 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 18071 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 18072 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 18073 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ 18074 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 18075 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)}, 18076 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 18077 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 18078 {} 18079}; 18080 18081static struct hda_verb alc272_dell_init_verbs[] = { 18082 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 18083 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 18084 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 18085 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 18086 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 18087 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 18088 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ 18089 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 18090 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)}, 18091 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 18092 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 18093 {} 18094}; 18095 18096static struct hda_verb alc663_mode7_init_verbs[] = { 18097 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 18098 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 18099 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 18100 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 18101 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 18102 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 18103 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, 18104 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 18105 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 18106 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ 18107 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 18108 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)}, 18109 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 18110 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 18111 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 18112 {} 18113}; 18114 18115static struct hda_verb alc663_mode8_init_verbs[] = { 18116 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 18117 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 18118 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 18119 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 18120 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 18121 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 18122 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 18123 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 18124 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 18125 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 18126 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ 18127 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 18128 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)}, 18129 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 18130 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 18131 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 18132 {} 18133}; 18134 18135static struct snd_kcontrol_new alc662_auto_capture_mixer[] = { 18136 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), 18137 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), 18138 { } /* end */ 18139}; 18140 18141static struct snd_kcontrol_new alc272_auto_capture_mixer[] = { 18142 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 18143 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 18144 { } /* end */ 18145}; 18146 18147static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec) 18148{ 18149 unsigned int present; 18150 unsigned char bits; 18151 18152 present = snd_hda_jack_detect(codec, 0x14); 18153 bits = present ? HDA_AMP_MUTE : 0; 18154 18155 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 18156 HDA_AMP_MUTE, bits); 18157} 18158 18159static void alc662_lenovo_101e_all_automute(struct hda_codec *codec) 18160{ 18161 unsigned int present; 18162 unsigned char bits; 18163 18164 present = snd_hda_jack_detect(codec, 0x1b); 18165 bits = present ? HDA_AMP_MUTE : 0; 18166 18167 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 18168 HDA_AMP_MUTE, bits); 18169 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 18170 HDA_AMP_MUTE, bits); 18171} 18172 18173static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec, 18174 unsigned int res) 18175{ 18176 if ((res >> 26) == ALC880_HP_EVENT) 18177 alc662_lenovo_101e_all_automute(codec); 18178 if ((res >> 26) == ALC880_FRONT_EVENT) 18179 alc662_lenovo_101e_ispeaker_automute(codec); 18180} 18181 18182/* unsolicited event for HP jack sensing */ 18183static void alc662_eeepc_unsol_event(struct hda_codec *codec, 18184 unsigned int res) 18185{ 18186 if ((res >> 26) == ALC880_MIC_EVENT) 18187 alc_mic_automute(codec); 18188 else 18189 alc262_hippo_unsol_event(codec, res); 18190} 18191 18192static void alc662_eeepc_setup(struct hda_codec *codec) 18193{ 18194 struct alc_spec *spec = codec->spec; 18195 18196 alc262_hippo1_setup(codec); 18197 spec->ext_mic.pin = 0x18; 18198 spec->ext_mic.mux_idx = 0; 18199 spec->int_mic.pin = 0x19; 18200 spec->int_mic.mux_idx = 1; 18201 spec->auto_mic = 1; 18202} 18203 18204static void alc662_eeepc_inithook(struct hda_codec *codec) 18205{ 18206 alc262_hippo_automute(codec); 18207 alc_mic_automute(codec); 18208} 18209 18210static void alc662_eeepc_ep20_setup(struct hda_codec *codec) 18211{ 18212 struct alc_spec *spec = codec->spec; 18213 18214 spec->autocfg.hp_pins[0] = 0x14; 18215 spec->autocfg.speaker_pins[0] = 0x1b; 18216} 18217 18218#define alc662_eeepc_ep20_inithook alc262_hippo_master_update 18219 18220static void alc663_m51va_speaker_automute(struct hda_codec *codec) 18221{ 18222 unsigned int present; 18223 unsigned char bits; 18224 18225 present = snd_hda_jack_detect(codec, 0x21); 18226 bits = present ? HDA_AMP_MUTE : 0; 18227 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 18228 HDA_AMP_MUTE, bits); 18229 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 18230 HDA_AMP_MUTE, bits); 18231} 18232 18233static void alc663_21jd_two_speaker_automute(struct hda_codec *codec) 18234{ 18235 unsigned int present; 18236 unsigned char bits; 18237 18238 present = snd_hda_jack_detect(codec, 0x21); 18239 bits = present ? HDA_AMP_MUTE : 0; 18240 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 18241 HDA_AMP_MUTE, bits); 18242 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 18243 HDA_AMP_MUTE, bits); 18244 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0, 18245 HDA_AMP_MUTE, bits); 18246 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1, 18247 HDA_AMP_MUTE, bits); 18248} 18249 18250static void alc663_15jd_two_speaker_automute(struct hda_codec *codec) 18251{ 18252 unsigned int present; 18253 unsigned char bits; 18254 18255 present = snd_hda_jack_detect(codec, 0x15); 18256 bits = present ? HDA_AMP_MUTE : 0; 18257 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 18258 HDA_AMP_MUTE, bits); 18259 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 18260 HDA_AMP_MUTE, bits); 18261 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0, 18262 HDA_AMP_MUTE, bits); 18263 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1, 18264 HDA_AMP_MUTE, bits); 18265} 18266 18267static void alc662_f5z_speaker_automute(struct hda_codec *codec) 18268{ 18269 unsigned int present; 18270 unsigned char bits; 18271 18272 present = snd_hda_jack_detect(codec, 0x1b); 18273 bits = present ? 0 : PIN_OUT; 18274 snd_hda_codec_write(codec, 0x14, 0, 18275 AC_VERB_SET_PIN_WIDGET_CONTROL, bits); 18276} 18277 18278static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec) 18279{ 18280 unsigned int present1, present2; 18281 18282 present1 = snd_hda_jack_detect(codec, 0x21); 18283 present2 = snd_hda_jack_detect(codec, 0x15); 18284 18285 if (present1 || present2) { 18286 snd_hda_codec_write_cache(codec, 0x14, 0, 18287 AC_VERB_SET_PIN_WIDGET_CONTROL, 0); 18288 } else { 18289 snd_hda_codec_write_cache(codec, 0x14, 0, 18290 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); 18291 } 18292} 18293 18294static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec) 18295{ 18296 unsigned int present1, present2; 18297 18298 present1 = snd_hda_jack_detect(codec, 0x1b); 18299 present2 = snd_hda_jack_detect(codec, 0x15); 18300 18301 if (present1 || present2) { 18302 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 18303 HDA_AMP_MUTE, HDA_AMP_MUTE); 18304 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 18305 HDA_AMP_MUTE, HDA_AMP_MUTE); 18306 } else { 18307 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 18308 HDA_AMP_MUTE, 0); 18309 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 18310 HDA_AMP_MUTE, 0); 18311 } 18312} 18313 18314static void alc663_two_hp_m7_speaker_automute(struct hda_codec *codec) 18315{ 18316 unsigned int present1, present2; 18317 18318 present1 = snd_hda_codec_read(codec, 0x1b, 0, 18319 AC_VERB_GET_PIN_SENSE, 0) 18320 & AC_PINSENSE_PRESENCE; 18321 present2 = snd_hda_codec_read(codec, 0x21, 0, 18322 AC_VERB_GET_PIN_SENSE, 0) 18323 & AC_PINSENSE_PRESENCE; 18324 18325 if (present1 || present2) { 18326 snd_hda_codec_write_cache(codec, 0x14, 0, 18327 AC_VERB_SET_PIN_WIDGET_CONTROL, 0); 18328 snd_hda_codec_write_cache(codec, 0x17, 0, 18329 AC_VERB_SET_PIN_WIDGET_CONTROL, 0); 18330 } else { 18331 snd_hda_codec_write_cache(codec, 0x14, 0, 18332 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); 18333 snd_hda_codec_write_cache(codec, 0x17, 0, 18334 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); 18335 } 18336} 18337 18338static void alc663_two_hp_m8_speaker_automute(struct hda_codec *codec) 18339{ 18340 unsigned int present1, present2; 18341 18342 present1 = snd_hda_codec_read(codec, 0x21, 0, 18343 AC_VERB_GET_PIN_SENSE, 0) 18344 & AC_PINSENSE_PRESENCE; 18345 present2 = snd_hda_codec_read(codec, 0x15, 0, 18346 AC_VERB_GET_PIN_SENSE, 0) 18347 & AC_PINSENSE_PRESENCE; 18348 18349 if (present1 || present2) { 18350 snd_hda_codec_write_cache(codec, 0x14, 0, 18351 AC_VERB_SET_PIN_WIDGET_CONTROL, 0); 18352 snd_hda_codec_write_cache(codec, 0x17, 0, 18353 AC_VERB_SET_PIN_WIDGET_CONTROL, 0); 18354 } else { 18355 snd_hda_codec_write_cache(codec, 0x14, 0, 18356 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); 18357 snd_hda_codec_write_cache(codec, 0x17, 0, 18358 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); 18359 } 18360} 18361 18362static void alc663_m51va_unsol_event(struct hda_codec *codec, 18363 unsigned int res) 18364{ 18365 switch (res >> 26) { 18366 case ALC880_HP_EVENT: 18367 alc663_m51va_speaker_automute(codec); 18368 break; 18369 case ALC880_MIC_EVENT: 18370 alc_mic_automute(codec); 18371 break; 18372 } 18373} 18374 18375static void alc663_m51va_setup(struct hda_codec *codec) 18376{ 18377 struct alc_spec *spec = codec->spec; 18378 spec->ext_mic.pin = 0x18; 18379 spec->ext_mic.mux_idx = 0; 18380 spec->int_mic.pin = 0x12; 18381 spec->int_mic.mux_idx = 9; 18382 spec->auto_mic = 1; 18383} 18384 18385static void alc663_m51va_inithook(struct hda_codec *codec) 18386{ 18387 alc663_m51va_speaker_automute(codec); 18388 alc_mic_automute(codec); 18389} 18390 18391/* ***************** Mode1 ******************************/ 18392#define alc663_mode1_unsol_event alc663_m51va_unsol_event 18393 18394static void alc663_mode1_setup(struct hda_codec *codec) 18395{ 18396 struct alc_spec *spec = codec->spec; 18397 spec->ext_mic.pin = 0x18; 18398 spec->ext_mic.mux_idx = 0; 18399 spec->int_mic.pin = 0x19; 18400 spec->int_mic.mux_idx = 1; 18401 spec->auto_mic = 1; 18402} 18403 18404#define alc663_mode1_inithook alc663_m51va_inithook 18405 18406/* ***************** Mode2 ******************************/ 18407static void alc662_mode2_unsol_event(struct hda_codec *codec, 18408 unsigned int res) 18409{ 18410 switch (res >> 26) { 18411 case ALC880_HP_EVENT: 18412 alc662_f5z_speaker_automute(codec); 18413 break; 18414 case ALC880_MIC_EVENT: 18415 alc_mic_automute(codec); 18416 break; 18417 } 18418} 18419 18420#define alc662_mode2_setup alc663_mode1_setup 18421 18422static void alc662_mode2_inithook(struct hda_codec *codec) 18423{ 18424 alc662_f5z_speaker_automute(codec); 18425 alc_mic_automute(codec); 18426} 18427/* ***************** Mode3 ******************************/ 18428static void alc663_mode3_unsol_event(struct hda_codec *codec, 18429 unsigned int res) 18430{ 18431 switch (res >> 26) { 18432 case ALC880_HP_EVENT: 18433 alc663_two_hp_m1_speaker_automute(codec); 18434 break; 18435 case ALC880_MIC_EVENT: 18436 alc_mic_automute(codec); 18437 break; 18438 } 18439} 18440 18441#define alc663_mode3_setup alc663_mode1_setup 18442 18443static void alc663_mode3_inithook(struct hda_codec *codec) 18444{ 18445 alc663_two_hp_m1_speaker_automute(codec); 18446 alc_mic_automute(codec); 18447} 18448/* ***************** Mode4 ******************************/ 18449static void alc663_mode4_unsol_event(struct hda_codec *codec, 18450 unsigned int res) 18451{ 18452 switch (res >> 26) { 18453 case ALC880_HP_EVENT: 18454 alc663_21jd_two_speaker_automute(codec); 18455 break; 18456 case ALC880_MIC_EVENT: 18457 alc_mic_automute(codec); 18458 break; 18459 } 18460} 18461 18462#define alc663_mode4_setup alc663_mode1_setup 18463 18464static void alc663_mode4_inithook(struct hda_codec *codec) 18465{ 18466 alc663_21jd_two_speaker_automute(codec); 18467 alc_mic_automute(codec); 18468} 18469/* ***************** Mode5 ******************************/ 18470static void alc663_mode5_unsol_event(struct hda_codec *codec, 18471 unsigned int res) 18472{ 18473 switch (res >> 26) { 18474 case ALC880_HP_EVENT: 18475 alc663_15jd_two_speaker_automute(codec); 18476 break; 18477 case ALC880_MIC_EVENT: 18478 alc_mic_automute(codec); 18479 break; 18480 } 18481} 18482 18483#define alc663_mode5_setup alc663_mode1_setup 18484 18485static void alc663_mode5_inithook(struct hda_codec *codec) 18486{ 18487 alc663_15jd_two_speaker_automute(codec); 18488 alc_mic_automute(codec); 18489} 18490/* ***************** Mode6 ******************************/ 18491static void alc663_mode6_unsol_event(struct hda_codec *codec, 18492 unsigned int res) 18493{ 18494 switch (res >> 26) { 18495 case ALC880_HP_EVENT: 18496 alc663_two_hp_m2_speaker_automute(codec); 18497 break; 18498 case ALC880_MIC_EVENT: 18499 alc_mic_automute(codec); 18500 break; 18501 } 18502} 18503 18504#define alc663_mode6_setup alc663_mode1_setup 18505 18506static void alc663_mode6_inithook(struct hda_codec *codec) 18507{ 18508 alc663_two_hp_m2_speaker_automute(codec); 18509 alc_mic_automute(codec); 18510} 18511 18512/* ***************** Mode7 ******************************/ 18513static void alc663_mode7_unsol_event(struct hda_codec *codec, 18514 unsigned int res) 18515{ 18516 switch (res >> 26) { 18517 case ALC880_HP_EVENT: 18518 alc663_two_hp_m7_speaker_automute(codec); 18519 break; 18520 case ALC880_MIC_EVENT: 18521 alc_mic_automute(codec); 18522 break; 18523 } 18524} 18525 18526#define alc663_mode7_setup alc663_mode1_setup 18527 18528static void alc663_mode7_inithook(struct hda_codec *codec) 18529{ 18530 alc663_two_hp_m7_speaker_automute(codec); 18531 alc_mic_automute(codec); 18532} 18533 18534/* ***************** Mode8 ******************************/ 18535static void alc663_mode8_unsol_event(struct hda_codec *codec, 18536 unsigned int res) 18537{ 18538 switch (res >> 26) { 18539 case ALC880_HP_EVENT: 18540 alc663_two_hp_m8_speaker_automute(codec); 18541 break; 18542 case ALC880_MIC_EVENT: 18543 alc_mic_automute(codec); 18544 break; 18545 } 18546} 18547 18548#define alc663_mode8_setup alc663_m51va_setup 18549 18550static void alc663_mode8_inithook(struct hda_codec *codec) 18551{ 18552 alc663_two_hp_m8_speaker_automute(codec); 18553 alc_mic_automute(codec); 18554} 18555 18556static void alc663_g71v_hp_automute(struct hda_codec *codec) 18557{ 18558 unsigned int present; 18559 unsigned char bits; 18560 18561 present = snd_hda_jack_detect(codec, 0x21); 18562 bits = present ? HDA_AMP_MUTE : 0; 18563 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 18564 HDA_AMP_MUTE, bits); 18565 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 18566 HDA_AMP_MUTE, bits); 18567} 18568 18569static void alc663_g71v_front_automute(struct hda_codec *codec) 18570{ 18571 unsigned int present; 18572 unsigned char bits; 18573 18574 present = snd_hda_jack_detect(codec, 0x15); 18575 bits = present ? HDA_AMP_MUTE : 0; 18576 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 18577 HDA_AMP_MUTE, bits); 18578} 18579 18580static void alc663_g71v_unsol_event(struct hda_codec *codec, 18581 unsigned int res) 18582{ 18583 switch (res >> 26) { 18584 case ALC880_HP_EVENT: 18585 alc663_g71v_hp_automute(codec); 18586 break; 18587 case ALC880_FRONT_EVENT: 18588 alc663_g71v_front_automute(codec); 18589 break; 18590 case ALC880_MIC_EVENT: 18591 alc_mic_automute(codec); 18592 break; 18593 } 18594} 18595 18596#define alc663_g71v_setup alc663_m51va_setup 18597 18598static void alc663_g71v_inithook(struct hda_codec *codec) 18599{ 18600 alc663_g71v_front_automute(codec); 18601 alc663_g71v_hp_automute(codec); 18602 alc_mic_automute(codec); 18603} 18604 18605static void alc663_g50v_unsol_event(struct hda_codec *codec, 18606 unsigned int res) 18607{ 18608 switch (res >> 26) { 18609 case ALC880_HP_EVENT: 18610 alc663_m51va_speaker_automute(codec); 18611 break; 18612 case ALC880_MIC_EVENT: 18613 alc_mic_automute(codec); 18614 break; 18615 } 18616} 18617 18618#define alc663_g50v_setup alc663_m51va_setup 18619 18620static void alc663_g50v_inithook(struct hda_codec *codec) 18621{ 18622 alc663_m51va_speaker_automute(codec); 18623 alc_mic_automute(codec); 18624} 18625 18626static struct snd_kcontrol_new alc662_ecs_mixer[] = { 18627 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT), 18628 ALC262_HIPPO_MASTER_SWITCH, 18629 18630 HDA_CODEC_VOLUME("Mic/LineIn Boost Volume", 0x18, 0, HDA_INPUT), 18631 HDA_CODEC_VOLUME("Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT), 18632 HDA_CODEC_MUTE("Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT), 18633 18634 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), 18635 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 18636 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 18637 { } /* end */ 18638}; 18639 18640static struct snd_kcontrol_new alc272_nc10_mixer[] = { 18641 /* Master Playback automatically created from Speaker and Headphone */ 18642 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 18643 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 18644 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 18645 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT), 18646 18647 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 18648 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 18649 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 18650 18651 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 18652 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 18653 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), 18654 { } /* end */ 18655}; 18656 18657#ifdef CONFIG_SND_HDA_POWER_SAVE 18658#define alc662_loopbacks alc880_loopbacks 18659#endif 18660 18661 18662/* pcm configuration: identical with ALC880 */ 18663#define alc662_pcm_analog_playback alc880_pcm_analog_playback 18664#define alc662_pcm_analog_capture alc880_pcm_analog_capture 18665#define alc662_pcm_digital_playback alc880_pcm_digital_playback 18666#define alc662_pcm_digital_capture alc880_pcm_digital_capture 18667 18668/* 18669 * configuration and preset 18670 */ 18671static const char * const alc662_models[ALC662_MODEL_LAST] = { 18672 [ALC662_3ST_2ch_DIG] = "3stack-dig", 18673 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig", 18674 [ALC662_3ST_6ch] = "3stack-6ch", 18675 [ALC662_5ST_DIG] = "5stack-dig", 18676 [ALC662_LENOVO_101E] = "lenovo-101e", 18677 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701", 18678 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20", 18679 [ALC662_ECS] = "ecs", 18680 [ALC663_ASUS_M51VA] = "m51va", 18681 [ALC663_ASUS_G71V] = "g71v", 18682 [ALC663_ASUS_H13] = "h13", 18683 [ALC663_ASUS_G50V] = "g50v", 18684 [ALC663_ASUS_MODE1] = "asus-mode1", 18685 [ALC662_ASUS_MODE2] = "asus-mode2", 18686 [ALC663_ASUS_MODE3] = "asus-mode3", 18687 [ALC663_ASUS_MODE4] = "asus-mode4", 18688 [ALC663_ASUS_MODE5] = "asus-mode5", 18689 [ALC663_ASUS_MODE6] = "asus-mode6", 18690 [ALC663_ASUS_MODE7] = "asus-mode7", 18691 [ALC663_ASUS_MODE8] = "asus-mode8", 18692 [ALC272_DELL] = "dell", 18693 [ALC272_DELL_ZM1] = "dell-zm1", 18694 [ALC272_SAMSUNG_NC10] = "samsung-nc10", 18695 [ALC662_AUTO] = "auto", 18696}; 18697 18698static struct snd_pci_quirk alc662_cfg_tbl[] = { 18699 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS), 18700 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL), 18701 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1), 18702 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1), 18703 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3), 18704 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC663_ASUS_MODE1), 18705 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3), 18706 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1), 18707 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2), 18708 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1), 18709 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC663_ASUS_MODE1), 18710 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC663_ASUS_MODE1), 18711 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2), 18712 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC663_ASUS_MODE7), 18713 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC663_ASUS_MODE7), 18714 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC663_ASUS_MODE8), 18715 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC663_ASUS_MODE3), 18716 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC663_ASUS_MODE1), 18717 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2), 18718 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_ASUS_MODE2), 18719 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC663_ASUS_MODE1), 18720 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2), 18721 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6), 18722 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6), 18723 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2), 18724 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC663_ASUS_MODE1), 18725 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3), 18726 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA), 18727 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2), 18728 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2), 18729 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5), 18730 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6), 18731 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2), 18732 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1), 18733 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2), 18734 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2), 18735 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA), 18736 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/ 18737 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3), 18738 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3), 18739 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1), 18740 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC663_ASUS_MODE1), 18741 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1), 18742 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1), 18743 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1), 18744 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2), 18745 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2), 18746 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1), 18747 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1), 18748 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3), 18749 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1), 18750 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1), 18751 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V), 18752 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/ 18753 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1), 18754 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2), 18755 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA), 18756 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1), 18757 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4), 18758 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG), 18759 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701), 18760 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20), 18761 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS), 18762 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K", 18763 ALC662_3ST_6ch_DIG), 18764 SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO), 18765 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10), 18766 SND_PCI_QUIRK(0x152d, 0x2304, "Quanta WH1", ALC663_ASUS_H13), 18767 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG), 18768 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA), 18769 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E), 18770 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0", 18771 ALC662_3ST_6ch_DIG), 18772 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x", 18773 ALC663_ASUS_H13), 18774 SND_PCI_QUIRK(0x1991, 0x5628, "Ordissimo EVE", ALC662_LENOVO_101E), 18775 {} 18776}; 18777 18778static struct alc_config_preset alc662_presets[] = { 18779 [ALC662_3ST_2ch_DIG] = { 18780 .mixers = { alc662_3ST_2ch_mixer }, 18781 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs }, 18782 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18783 .dac_nids = alc662_dac_nids, 18784 .dig_out_nid = ALC662_DIGOUT_NID, 18785 .dig_in_nid = ALC662_DIGIN_NID, 18786 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18787 .channel_mode = alc662_3ST_2ch_modes, 18788 .input_mux = &alc662_capture_source, 18789 }, 18790 [ALC662_3ST_6ch_DIG] = { 18791 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer }, 18792 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs }, 18793 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18794 .dac_nids = alc662_dac_nids, 18795 .dig_out_nid = ALC662_DIGOUT_NID, 18796 .dig_in_nid = ALC662_DIGIN_NID, 18797 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), 18798 .channel_mode = alc662_3ST_6ch_modes, 18799 .need_dac_fix = 1, 18800 .input_mux = &alc662_capture_source, 18801 }, 18802 [ALC662_3ST_6ch] = { 18803 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer }, 18804 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs }, 18805 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18806 .dac_nids = alc662_dac_nids, 18807 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), 18808 .channel_mode = alc662_3ST_6ch_modes, 18809 .need_dac_fix = 1, 18810 .input_mux = &alc662_capture_source, 18811 }, 18812 [ALC662_5ST_DIG] = { 18813 .mixers = { alc662_base_mixer, alc662_chmode_mixer }, 18814 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs }, 18815 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18816 .dac_nids = alc662_dac_nids, 18817 .dig_out_nid = ALC662_DIGOUT_NID, 18818 .dig_in_nid = ALC662_DIGIN_NID, 18819 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes), 18820 .channel_mode = alc662_5stack_modes, 18821 .input_mux = &alc662_capture_source, 18822 }, 18823 [ALC662_LENOVO_101E] = { 18824 .mixers = { alc662_lenovo_101e_mixer }, 18825 .init_verbs = { alc662_init_verbs, 18826 alc662_eapd_init_verbs, 18827 alc662_sue_init_verbs }, 18828 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18829 .dac_nids = alc662_dac_nids, 18830 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18831 .channel_mode = alc662_3ST_2ch_modes, 18832 .input_mux = &alc662_lenovo_101e_capture_source, 18833 .unsol_event = alc662_lenovo_101e_unsol_event, 18834 .init_hook = alc662_lenovo_101e_all_automute, 18835 }, 18836 [ALC662_ASUS_EEEPC_P701] = { 18837 .mixers = { alc662_eeepc_p701_mixer }, 18838 .init_verbs = { alc662_init_verbs, 18839 alc662_eapd_init_verbs, 18840 alc662_eeepc_sue_init_verbs }, 18841 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18842 .dac_nids = alc662_dac_nids, 18843 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18844 .channel_mode = alc662_3ST_2ch_modes, 18845 .unsol_event = alc662_eeepc_unsol_event, 18846 .setup = alc662_eeepc_setup, 18847 .init_hook = alc662_eeepc_inithook, 18848 }, 18849 [ALC662_ASUS_EEEPC_EP20] = { 18850 .mixers = { alc662_eeepc_ep20_mixer, 18851 alc662_chmode_mixer }, 18852 .init_verbs = { alc662_init_verbs, 18853 alc662_eapd_init_verbs, 18854 alc662_eeepc_ep20_sue_init_verbs }, 18855 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18856 .dac_nids = alc662_dac_nids, 18857 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), 18858 .channel_mode = alc662_3ST_6ch_modes, 18859 .input_mux = &alc662_lenovo_101e_capture_source, 18860 .unsol_event = alc662_eeepc_unsol_event, 18861 .setup = alc662_eeepc_ep20_setup, 18862 .init_hook = alc662_eeepc_ep20_inithook, 18863 }, 18864 [ALC662_ECS] = { 18865 .mixers = { alc662_ecs_mixer }, 18866 .init_verbs = { alc662_init_verbs, 18867 alc662_eapd_init_verbs, 18868 alc662_ecs_init_verbs }, 18869 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18870 .dac_nids = alc662_dac_nids, 18871 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18872 .channel_mode = alc662_3ST_2ch_modes, 18873 .unsol_event = alc662_eeepc_unsol_event, 18874 .setup = alc662_eeepc_setup, 18875 .init_hook = alc662_eeepc_inithook, 18876 }, 18877 [ALC663_ASUS_M51VA] = { 18878 .mixers = { alc663_m51va_mixer }, 18879 .init_verbs = { alc662_init_verbs, 18880 alc662_eapd_init_verbs, 18881 alc663_m51va_init_verbs }, 18882 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18883 .dac_nids = alc662_dac_nids, 18884 .dig_out_nid = ALC662_DIGOUT_NID, 18885 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18886 .channel_mode = alc662_3ST_2ch_modes, 18887 .unsol_event = alc663_m51va_unsol_event, 18888 .setup = alc663_m51va_setup, 18889 .init_hook = alc663_m51va_inithook, 18890 }, 18891 [ALC663_ASUS_G71V] = { 18892 .mixers = { alc663_g71v_mixer }, 18893 .init_verbs = { alc662_init_verbs, 18894 alc662_eapd_init_verbs, 18895 alc663_g71v_init_verbs }, 18896 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18897 .dac_nids = alc662_dac_nids, 18898 .dig_out_nid = ALC662_DIGOUT_NID, 18899 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18900 .channel_mode = alc662_3ST_2ch_modes, 18901 .unsol_event = alc663_g71v_unsol_event, 18902 .setup = alc663_g71v_setup, 18903 .init_hook = alc663_g71v_inithook, 18904 }, 18905 [ALC663_ASUS_H13] = { 18906 .mixers = { alc663_m51va_mixer }, 18907 .init_verbs = { alc662_init_verbs, 18908 alc662_eapd_init_verbs, 18909 alc663_m51va_init_verbs }, 18910 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18911 .dac_nids = alc662_dac_nids, 18912 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18913 .channel_mode = alc662_3ST_2ch_modes, 18914 .unsol_event = alc663_m51va_unsol_event, 18915 .init_hook = alc663_m51va_inithook, 18916 }, 18917 [ALC663_ASUS_G50V] = { 18918 .mixers = { alc663_g50v_mixer }, 18919 .init_verbs = { alc662_init_verbs, 18920 alc662_eapd_init_verbs, 18921 alc663_g50v_init_verbs }, 18922 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18923 .dac_nids = alc662_dac_nids, 18924 .dig_out_nid = ALC662_DIGOUT_NID, 18925 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), 18926 .channel_mode = alc662_3ST_6ch_modes, 18927 .input_mux = &alc663_capture_source, 18928 .unsol_event = alc663_g50v_unsol_event, 18929 .setup = alc663_g50v_setup, 18930 .init_hook = alc663_g50v_inithook, 18931 }, 18932 [ALC663_ASUS_MODE1] = { 18933 .mixers = { alc663_m51va_mixer }, 18934 .cap_mixer = alc662_auto_capture_mixer, 18935 .init_verbs = { alc662_init_verbs, 18936 alc662_eapd_init_verbs, 18937 alc663_21jd_amic_init_verbs }, 18938 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18939 .hp_nid = 0x03, 18940 .dac_nids = alc662_dac_nids, 18941 .dig_out_nid = ALC662_DIGOUT_NID, 18942 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18943 .channel_mode = alc662_3ST_2ch_modes, 18944 .unsol_event = alc663_mode1_unsol_event, 18945 .setup = alc663_mode1_setup, 18946 .init_hook = alc663_mode1_inithook, 18947 }, 18948 [ALC662_ASUS_MODE2] = { 18949 .mixers = { alc662_1bjd_mixer }, 18950 .cap_mixer = alc662_auto_capture_mixer, 18951 .init_verbs = { alc662_init_verbs, 18952 alc662_eapd_init_verbs, 18953 alc662_1bjd_amic_init_verbs }, 18954 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18955 .dac_nids = alc662_dac_nids, 18956 .dig_out_nid = ALC662_DIGOUT_NID, 18957 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18958 .channel_mode = alc662_3ST_2ch_modes, 18959 .unsol_event = alc662_mode2_unsol_event, 18960 .setup = alc662_mode2_setup, 18961 .init_hook = alc662_mode2_inithook, 18962 }, 18963 [ALC663_ASUS_MODE3] = { 18964 .mixers = { alc663_two_hp_m1_mixer }, 18965 .cap_mixer = alc662_auto_capture_mixer, 18966 .init_verbs = { alc662_init_verbs, 18967 alc662_eapd_init_verbs, 18968 alc663_two_hp_amic_m1_init_verbs }, 18969 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18970 .hp_nid = 0x03, 18971 .dac_nids = alc662_dac_nids, 18972 .dig_out_nid = ALC662_DIGOUT_NID, 18973 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18974 .channel_mode = alc662_3ST_2ch_modes, 18975 .unsol_event = alc663_mode3_unsol_event, 18976 .setup = alc663_mode3_setup, 18977 .init_hook = alc663_mode3_inithook, 18978 }, 18979 [ALC663_ASUS_MODE4] = { 18980 .mixers = { alc663_asus_21jd_clfe_mixer }, 18981 .cap_mixer = alc662_auto_capture_mixer, 18982 .init_verbs = { alc662_init_verbs, 18983 alc662_eapd_init_verbs, 18984 alc663_21jd_amic_init_verbs}, 18985 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18986 .hp_nid = 0x03, 18987 .dac_nids = alc662_dac_nids, 18988 .dig_out_nid = ALC662_DIGOUT_NID, 18989 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18990 .channel_mode = alc662_3ST_2ch_modes, 18991 .unsol_event = alc663_mode4_unsol_event, 18992 .setup = alc663_mode4_setup, 18993 .init_hook = alc663_mode4_inithook, 18994 }, 18995 [ALC663_ASUS_MODE5] = { 18996 .mixers = { alc663_asus_15jd_clfe_mixer }, 18997 .cap_mixer = alc662_auto_capture_mixer, 18998 .init_verbs = { alc662_init_verbs, 18999 alc662_eapd_init_verbs, 19000 alc663_15jd_amic_init_verbs }, 19001 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 19002 .hp_nid = 0x03, 19003 .dac_nids = alc662_dac_nids, 19004 .dig_out_nid = ALC662_DIGOUT_NID, 19005 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 19006 .channel_mode = alc662_3ST_2ch_modes, 19007 .unsol_event = alc663_mode5_unsol_event, 19008 .setup = alc663_mode5_setup, 19009 .init_hook = alc663_mode5_inithook, 19010 }, 19011 [ALC663_ASUS_MODE6] = { 19012 .mixers = { alc663_two_hp_m2_mixer }, 19013 .cap_mixer = alc662_auto_capture_mixer, 19014 .init_verbs = { alc662_init_verbs, 19015 alc662_eapd_init_verbs, 19016 alc663_two_hp_amic_m2_init_verbs }, 19017 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 19018 .hp_nid = 0x03, 19019 .dac_nids = alc662_dac_nids, 19020 .dig_out_nid = ALC662_DIGOUT_NID, 19021 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 19022 .channel_mode = alc662_3ST_2ch_modes, 19023 .unsol_event = alc663_mode6_unsol_event, 19024 .setup = alc663_mode6_setup, 19025 .init_hook = alc663_mode6_inithook, 19026 }, 19027 [ALC663_ASUS_MODE7] = { 19028 .mixers = { alc663_mode7_mixer }, 19029 .cap_mixer = alc662_auto_capture_mixer, 19030 .init_verbs = { alc662_init_verbs, 19031 alc662_eapd_init_verbs, 19032 alc663_mode7_init_verbs }, 19033 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 19034 .hp_nid = 0x03, 19035 .dac_nids = alc662_dac_nids, 19036 .dig_out_nid = ALC662_DIGOUT_NID, 19037 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 19038 .channel_mode = alc662_3ST_2ch_modes, 19039 .unsol_event = alc663_mode7_unsol_event, 19040 .setup = alc663_mode7_setup, 19041 .init_hook = alc663_mode7_inithook, 19042 }, 19043 [ALC663_ASUS_MODE8] = { 19044 .mixers = { alc663_mode8_mixer }, 19045 .cap_mixer = alc662_auto_capture_mixer, 19046 .init_verbs = { alc662_init_verbs, 19047 alc662_eapd_init_verbs, 19048 alc663_mode8_init_verbs }, 19049 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 19050 .hp_nid = 0x03, 19051 .dac_nids = alc662_dac_nids, 19052 .dig_out_nid = ALC662_DIGOUT_NID, 19053 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 19054 .channel_mode = alc662_3ST_2ch_modes, 19055 .unsol_event = alc663_mode8_unsol_event, 19056 .setup = alc663_mode8_setup, 19057 .init_hook = alc663_mode8_inithook, 19058 }, 19059 [ALC272_DELL] = { 19060 .mixers = { alc663_m51va_mixer }, 19061 .cap_mixer = alc272_auto_capture_mixer, 19062 .init_verbs = { alc662_init_verbs, 19063 alc662_eapd_init_verbs, 19064 alc272_dell_init_verbs }, 19065 .num_dacs = ARRAY_SIZE(alc272_dac_nids), 19066 .dac_nids = alc272_dac_nids, 19067 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 19068 .adc_nids = alc272_adc_nids, 19069 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids), 19070 .capsrc_nids = alc272_capsrc_nids, 19071 .channel_mode = alc662_3ST_2ch_modes, 19072 .unsol_event = alc663_m51va_unsol_event, 19073 .setup = alc663_m51va_setup, 19074 .init_hook = alc663_m51va_inithook, 19075 }, 19076 [ALC272_DELL_ZM1] = { 19077 .mixers = { alc663_m51va_mixer }, 19078 .cap_mixer = alc662_auto_capture_mixer, 19079 .init_verbs = { alc662_init_verbs, 19080 alc662_eapd_init_verbs, 19081 alc272_dell_zm1_init_verbs }, 19082 .num_dacs = ARRAY_SIZE(alc272_dac_nids), 19083 .dac_nids = alc272_dac_nids, 19084 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 19085 .adc_nids = alc662_adc_nids, 19086 .num_adc_nids = 1, 19087 .capsrc_nids = alc662_capsrc_nids, 19088 .channel_mode = alc662_3ST_2ch_modes, 19089 .unsol_event = alc663_m51va_unsol_event, 19090 .setup = alc663_m51va_setup, 19091 .init_hook = alc663_m51va_inithook, 19092 }, 19093 [ALC272_SAMSUNG_NC10] = { 19094 .mixers = { alc272_nc10_mixer }, 19095 .init_verbs = { alc662_init_verbs, 19096 alc662_eapd_init_verbs, 19097 alc663_21jd_amic_init_verbs }, 19098 .num_dacs = ARRAY_SIZE(alc272_dac_nids), 19099 .dac_nids = alc272_dac_nids, 19100 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 19101 .channel_mode = alc662_3ST_2ch_modes, 19102 /*.input_mux = &alc272_nc10_capture_source,*/ 19103 .unsol_event = alc663_mode4_unsol_event, 19104 .setup = alc663_mode4_setup, 19105 .init_hook = alc663_mode4_inithook, 19106 }, 19107}; 19108 19109 19110/* 19111 * BIOS auto configuration 19112 */ 19113 19114/* convert from MIX nid to DAC */ 19115static hda_nid_t alc662_mix_to_dac(struct hda_codec *codec, hda_nid_t nid) 19116{ 19117 hda_nid_t list[4]; 19118 int i, num; 19119 19120 num = snd_hda_get_connections(codec, nid, list, ARRAY_SIZE(list)); 19121 for (i = 0; i < num; i++) { 19122 if (get_wcaps_type(get_wcaps(codec, list[i])) == AC_WID_AUD_OUT) 19123 return list[i]; 19124 } 19125 return 0; 19126} 19127 19128/* get MIX nid connected to the given pin targeted to DAC */ 19129static hda_nid_t alc662_dac_to_mix(struct hda_codec *codec, hda_nid_t pin, 19130 hda_nid_t dac) 19131{ 19132 hda_nid_t mix[5]; 19133 int i, num; 19134 19135 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix)); 19136 for (i = 0; i < num; i++) { 19137 if (alc662_mix_to_dac(codec, mix[i]) == dac) 19138 return mix[i]; 19139 } 19140 return 0; 19141} 19142 19143/* look for an empty DAC slot */ 19144static hda_nid_t alc662_look_for_dac(struct hda_codec *codec, hda_nid_t pin) 19145{ 19146 struct alc_spec *spec = codec->spec; 19147 hda_nid_t srcs[5]; 19148 int i, j, num; 19149 19150 num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs)); 19151 if (num < 0) 19152 return 0; 19153 for (i = 0; i < num; i++) { 19154 hda_nid_t nid = alc662_mix_to_dac(codec, srcs[i]); 19155 if (!nid) 19156 continue; 19157 for (j = 0; j < spec->multiout.num_dacs; j++) 19158 if (spec->multiout.dac_nids[j] == nid) 19159 break; 19160 if (j >= spec->multiout.num_dacs) 19161 return nid; 19162 } 19163 return 0; 19164} 19165 19166/* fill in the dac_nids table from the parsed pin configuration */ 19167static int alc662_auto_fill_dac_nids(struct hda_codec *codec, 19168 const struct auto_pin_cfg *cfg) 19169{ 19170 struct alc_spec *spec = codec->spec; 19171 int i; 19172 hda_nid_t dac; 19173 19174 spec->multiout.dac_nids = spec->private_dac_nids; 19175 for (i = 0; i < cfg->line_outs; i++) { 19176 dac = alc662_look_for_dac(codec, cfg->line_out_pins[i]); 19177 if (!dac) 19178 continue; 19179 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac; 19180 } 19181 return 0; 19182} 19183 19184static inline int __alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx, 19185 hda_nid_t nid, int idx, unsigned int chs) 19186{ 19187 return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx, 19188 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT)); 19189} 19190 19191static inline int __alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx, 19192 hda_nid_t nid, int idx, unsigned int chs) 19193{ 19194 return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx, 19195 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT)); 19196} 19197 19198#define alc662_add_vol_ctl(spec, pfx, nid, chs) \ 19199 __alc662_add_vol_ctl(spec, pfx, nid, 0, chs) 19200#define alc662_add_sw_ctl(spec, pfx, nid, chs) \ 19201 __alc662_add_sw_ctl(spec, pfx, nid, 0, chs) 19202#define alc662_add_stereo_vol(spec, pfx, nid) \ 19203 alc662_add_vol_ctl(spec, pfx, nid, 3) 19204#define alc662_add_stereo_sw(spec, pfx, nid) \ 19205 alc662_add_sw_ctl(spec, pfx, nid, 3) 19206 19207/* add playback controls from the parsed DAC table */ 19208static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec, 19209 const struct auto_pin_cfg *cfg) 19210{ 19211 struct alc_spec *spec = codec->spec; 19212 static const char * const chname[4] = { 19213 "Front", "Surround", NULL /*CLFE*/, "Side" 19214 }; 19215 const char *pfx = alc_get_line_out_pfx(cfg, true); 19216 hda_nid_t nid, mix; 19217 int i, err; 19218 19219 for (i = 0; i < cfg->line_outs; i++) { 19220 nid = spec->multiout.dac_nids[i]; 19221 if (!nid) 19222 continue; 19223 mix = alc662_dac_to_mix(codec, cfg->line_out_pins[i], nid); 19224 if (!mix) 19225 continue; 19226 if (!pfx && i == 2) { 19227 /* Center/LFE */ 19228 err = alc662_add_vol_ctl(spec, "Center", nid, 1); 19229 if (err < 0) 19230 return err; 19231 err = alc662_add_vol_ctl(spec, "LFE", nid, 2); 19232 if (err < 0) 19233 return err; 19234 err = alc662_add_sw_ctl(spec, "Center", mix, 1); 19235 if (err < 0) 19236 return err; 19237 err = alc662_add_sw_ctl(spec, "LFE", mix, 2); 19238 if (err < 0) 19239 return err; 19240 } else { 19241 const char *name = pfx; 19242 int index = i; 19243 if (!name) { 19244 name = chname[i]; 19245 index = 0; 19246 } 19247 err = __alc662_add_vol_ctl(spec, name, nid, index, 3); 19248 if (err < 0) 19249 return err; 19250 err = __alc662_add_sw_ctl(spec, name, mix, index, 3); 19251 if (err < 0) 19252 return err; 19253 } 19254 } 19255 return 0; 19256} 19257 19258/* add playback controls for speaker and HP outputs */ 19259/* return DAC nid if any new DAC is assigned */ 19260static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin, 19261 const char *pfx) 19262{ 19263 struct alc_spec *spec = codec->spec; 19264 hda_nid_t nid, mix; 19265 int err; 19266 19267 if (!pin) 19268 return 0; 19269 nid = alc662_look_for_dac(codec, pin); 19270 if (!nid) { 19271 /* the corresponding DAC is already occupied */ 19272 if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP)) 19273 return 0; /* no way */ 19274 /* create a switch only */ 19275 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, 19276 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); 19277 } 19278 19279 mix = alc662_dac_to_mix(codec, pin, nid); 19280 if (!mix) 19281 return 0; 19282 err = alc662_add_vol_ctl(spec, pfx, nid, 3); 19283 if (err < 0) 19284 return err; 19285 err = alc662_add_sw_ctl(spec, pfx, mix, 3); 19286 if (err < 0) 19287 return err; 19288 return nid; 19289} 19290 19291/* create playback/capture controls for input pins */ 19292#define alc662_auto_create_input_ctls \ 19293 alc882_auto_create_input_ctls 19294 19295static void alc662_auto_set_output_and_unmute(struct hda_codec *codec, 19296 hda_nid_t nid, int pin_type, 19297 hda_nid_t dac) 19298{ 19299 int i, num; 19300 hda_nid_t srcs[HDA_MAX_CONNECTIONS]; 19301 19302 alc_set_pin_output(codec, nid, pin_type); 19303 num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs)); 19304 for (i = 0; i < num; i++) { 19305 if (alc662_mix_to_dac(codec, srcs[i]) != dac) 19306 continue; 19307 /* need the manual connection? */ 19308 if (num > 1) 19309 snd_hda_codec_write(codec, nid, 0, 19310 AC_VERB_SET_CONNECT_SEL, i); 19311 /* unmute mixer widget inputs */ 19312 snd_hda_codec_write(codec, srcs[i], 0, 19313 AC_VERB_SET_AMP_GAIN_MUTE, 19314 AMP_IN_UNMUTE(0)); 19315 snd_hda_codec_write(codec, srcs[i], 0, 19316 AC_VERB_SET_AMP_GAIN_MUTE, 19317 AMP_IN_UNMUTE(1)); 19318 return; 19319 } 19320} 19321 19322static void alc662_auto_init_multi_out(struct hda_codec *codec) 19323{ 19324 struct alc_spec *spec = codec->spec; 19325 int pin_type = get_pin_type(spec->autocfg.line_out_type); 19326 int i; 19327 19328 for (i = 0; i <= HDA_SIDE; i++) { 19329 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 19330 if (nid) 19331 alc662_auto_set_output_and_unmute(codec, nid, pin_type, 19332 spec->multiout.dac_nids[i]); 19333 } 19334} 19335 19336static void alc662_auto_init_hp_out(struct hda_codec *codec) 19337{ 19338 struct alc_spec *spec = codec->spec; 19339 hda_nid_t pin; 19340 19341 pin = spec->autocfg.hp_pins[0]; 19342 if (pin) 19343 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 19344 spec->multiout.hp_nid); 19345 pin = spec->autocfg.speaker_pins[0]; 19346 if (pin) 19347 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT, 19348 spec->multiout.extra_out_nid[0]); 19349} 19350 19351#define ALC662_PIN_CD_NID ALC880_PIN_CD_NID 19352 19353static void alc662_auto_init_analog_input(struct hda_codec *codec) 19354{ 19355 struct alc_spec *spec = codec->spec; 19356 struct auto_pin_cfg *cfg = &spec->autocfg; 19357 int i; 19358 19359 for (i = 0; i < cfg->num_inputs; i++) { 19360 hda_nid_t nid = cfg->inputs[i].pin; 19361 if (alc_is_input_pin(codec, nid)) { 19362 alc_set_input_pin(codec, nid, cfg->inputs[i].type); 19363 if (nid != ALC662_PIN_CD_NID && 19364 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)) 19365 snd_hda_codec_write(codec, nid, 0, 19366 AC_VERB_SET_AMP_GAIN_MUTE, 19367 AMP_OUT_MUTE); 19368 } 19369 } 19370} 19371 19372#define alc662_auto_init_input_src alc882_auto_init_input_src 19373 19374static int alc662_parse_auto_config(struct hda_codec *codec) 19375{ 19376 struct alc_spec *spec = codec->spec; 19377 int err; 19378 static hda_nid_t alc662_ignore[] = { 0x1d, 0 }; 19379 19380 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 19381 alc662_ignore); 19382 if (err < 0) 19383 return err; 19384 if (!spec->autocfg.line_outs) 19385 return 0; /* can't find valid BIOS pin config */ 19386 19387 err = alc662_auto_fill_dac_nids(codec, &spec->autocfg); 19388 if (err < 0) 19389 return err; 19390 err = alc662_auto_create_multi_out_ctls(codec, &spec->autocfg); 19391 if (err < 0) 19392 return err; 19393 err = alc662_auto_create_extra_out(codec, 19394 spec->autocfg.speaker_pins[0], 19395 "Speaker"); 19396 if (err < 0) 19397 return err; 19398 if (err) 19399 spec->multiout.extra_out_nid[0] = err; 19400 err = alc662_auto_create_extra_out(codec, spec->autocfg.hp_pins[0], 19401 "Headphone"); 19402 if (err < 0) 19403 return err; 19404 if (err) 19405 spec->multiout.hp_nid = err; 19406 err = alc662_auto_create_input_ctls(codec, &spec->autocfg); 19407 if (err < 0) 19408 return err; 19409 19410 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 19411 19412 alc_auto_parse_digital(codec); 19413 19414 if (spec->kctls.list) 19415 add_mixer(spec, spec->kctls.list); 19416 19417 spec->num_mux_defs = 1; 19418 spec->input_mux = &spec->private_imux[0]; 19419 19420 err = alc_auto_add_mic_boost(codec); 19421 if (err < 0) 19422 return err; 19423 19424 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 || 19425 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670) 19426 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0x21); 19427 else 19428 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); 19429 19430 return 1; 19431} 19432 19433/* additional initialization for auto-configuration model */ 19434static void alc662_auto_init(struct hda_codec *codec) 19435{ 19436 struct alc_spec *spec = codec->spec; 19437 alc662_auto_init_multi_out(codec); 19438 alc662_auto_init_hp_out(codec); 19439 alc662_auto_init_analog_input(codec); 19440 alc662_auto_init_input_src(codec); 19441 alc_auto_init_digital(codec); 19442 if (spec->unsol_event) 19443 alc_inithook(codec); 19444} 19445 19446static void alc272_fixup_mario(struct hda_codec *codec, 19447 const struct alc_fixup *fix, int action) 19448{ 19449 if (action != ALC_FIXUP_ACT_PROBE) 19450 return; 19451 if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT, 19452 (0x3b << AC_AMPCAP_OFFSET_SHIFT) | 19453 (0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) | 19454 (0x03 << AC_AMPCAP_STEP_SIZE_SHIFT) | 19455 (0 << AC_AMPCAP_MUTE_SHIFT))) 19456 printk(KERN_WARNING 19457 "hda_codec: failed to override amp caps for NID 0x2\n"); 19458} 19459 19460enum { 19461 ALC662_FIXUP_ASPIRE, 19462 ALC662_FIXUP_IDEAPAD, 19463 ALC272_FIXUP_MARIO, 19464 ALC662_FIXUP_CZC_P10T, 19465 ALC662_FIXUP_GIGABYTE, 19466}; 19467 19468static const struct alc_fixup alc662_fixups[] = { 19469 [ALC662_FIXUP_ASPIRE] = { 19470 .type = ALC_FIXUP_PINS, 19471 .v.pins = (const struct alc_pincfg[]) { 19472 { 0x15, 0x99130112 }, /* subwoofer */ 19473 { } 19474 } 19475 }, 19476 [ALC662_FIXUP_IDEAPAD] = { 19477 .type = ALC_FIXUP_PINS, 19478 .v.pins = (const struct alc_pincfg[]) { 19479 { 0x17, 0x99130112 }, /* subwoofer */ 19480 { } 19481 } 19482 }, 19483 [ALC272_FIXUP_MARIO] = { 19484 .type = ALC_FIXUP_FUNC, 19485 .v.func = alc272_fixup_mario, 19486 }, 19487 [ALC662_FIXUP_CZC_P10T] = { 19488 .type = ALC_FIXUP_VERBS, 19489 .v.verbs = (const struct hda_verb[]) { 19490 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0}, 19491 {} 19492 } 19493 }, 19494 [ALC662_FIXUP_GIGABYTE] = { 19495 .type = ALC_FIXUP_PINS, 19496 .v.pins = (const struct alc_pincfg[]) { 19497 { 0x14, 0x1114410 }, /* set as speaker */ 19498 { } 19499 } 19500 }, 19501}; 19502 19503static struct snd_pci_quirk alc662_fixup_tbl[] = { 19504 SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE), 19505 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE), 19506 SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD), 19507 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte", ALC662_FIXUP_GIGABYTE), 19508 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD), 19509 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD), 19510 SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T), 19511 {} 19512}; 19513 19514static const struct alc_model_fixup alc662_fixup_models[] = { 19515 {.id = ALC272_FIXUP_MARIO, .name = "mario"}, 19516 {} 19517}; 19518 19519 19520static int patch_alc662(struct hda_codec *codec) 19521{ 19522 struct alc_spec *spec; 19523 int err, board_config; 19524 int coef; 19525 19526 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 19527 if (!spec) 19528 return -ENOMEM; 19529 19530 codec->spec = spec; 19531 19532 alc_auto_parse_customize_define(codec); 19533 19534 alc_fix_pll_init(codec, 0x20, 0x04, 15); 19535 19536 coef = alc_read_coef_idx(codec, 0); 19537 if (coef == 0x8020 || coef == 0x8011) 19538 alc_codec_rename(codec, "ALC661"); 19539 else if (coef & (1 << 14) && 19540 codec->bus->pci->subsystem_vendor == 0x1025 && 19541 spec->cdefine.platform_type == 1) 19542 alc_codec_rename(codec, "ALC272X"); 19543 else if (coef == 0x4011) 19544 alc_codec_rename(codec, "ALC656"); 19545 19546 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST, 19547 alc662_models, 19548 alc662_cfg_tbl); 19549 if (board_config < 0) { 19550 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 19551 codec->chip_name); 19552 board_config = ALC662_AUTO; 19553 } 19554 19555 if (board_config == ALC662_AUTO) { 19556 alc_pick_fixup(codec, alc662_fixup_models, 19557 alc662_fixup_tbl, alc662_fixups); 19558 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); 19559 /* automatic parse from the BIOS config */ 19560 err = alc662_parse_auto_config(codec); 19561 if (err < 0) { 19562 alc_free(codec); 19563 return err; 19564 } else if (!err) { 19565 printk(KERN_INFO 19566 "hda_codec: Cannot set up configuration " 19567 "from BIOS. Using base mode...\n"); 19568 board_config = ALC662_3ST_2ch_DIG; 19569 } 19570 } 19571 19572 if (has_cdefine_beep(codec)) { 19573 err = snd_hda_attach_beep_device(codec, 0x1); 19574 if (err < 0) { 19575 alc_free(codec); 19576 return err; 19577 } 19578 } 19579 19580 if (board_config != ALC662_AUTO) 19581 setup_preset(codec, &alc662_presets[board_config]); 19582 19583 spec->stream_analog_playback = &alc662_pcm_analog_playback; 19584 spec->stream_analog_capture = &alc662_pcm_analog_capture; 19585 19586 spec->stream_digital_playback = &alc662_pcm_digital_playback; 19587 spec->stream_digital_capture = &alc662_pcm_digital_capture; 19588 19589 if (!spec->adc_nids) { 19590 spec->adc_nids = alc662_adc_nids; 19591 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids); 19592 } 19593 if (!spec->capsrc_nids) 19594 spec->capsrc_nids = alc662_capsrc_nids; 19595 19596 if (!spec->cap_mixer) 19597 set_capture_mixer(codec); 19598 19599 if (has_cdefine_beep(codec)) { 19600 switch (codec->vendor_id) { 19601 case 0x10ec0662: 19602 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 19603 break; 19604 case 0x10ec0272: 19605 case 0x10ec0663: 19606 case 0x10ec0665: 19607 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); 19608 break; 19609 case 0x10ec0273: 19610 set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT); 19611 break; 19612 } 19613 } 19614 spec->vmaster_nid = 0x02; 19615 19616 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); 19617 19618 codec->patch_ops = alc_patch_ops; 19619 if (board_config == ALC662_AUTO) 19620 spec->init_hook = alc662_auto_init; 19621 spec->shutup = alc_eapd_shutup; 19622 19623 alc_init_jacks(codec); 19624 19625#ifdef CONFIG_SND_HDA_POWER_SAVE 19626 if (!spec->loopback.amplist) 19627 spec->loopback.amplist = alc662_loopbacks; 19628#endif 19629 19630 return 0; 19631} 19632 19633static int patch_alc888(struct hda_codec *codec) 19634{ 19635 if ((alc_read_coef_idx(codec, 0) & 0x00f0)==0x0030){ 19636 kfree(codec->chip_name); 19637 if (codec->vendor_id == 0x10ec0887) 19638 codec->chip_name = kstrdup("ALC887-VD", GFP_KERNEL); 19639 else 19640 codec->chip_name = kstrdup("ALC888-VD", GFP_KERNEL); 19641 if (!codec->chip_name) { 19642 alc_free(codec); 19643 return -ENOMEM; 19644 } 19645 return patch_alc662(codec); 19646 } 19647 return patch_alc882(codec); 19648} 19649 19650/* 19651 * ALC680 support 19652 */ 19653#define ALC680_DIGIN_NID ALC880_DIGIN_NID 19654#define ALC680_DIGOUT_NID ALC880_DIGOUT_NID 19655#define alc680_modes alc260_modes 19656 19657static hda_nid_t alc680_dac_nids[3] = { 19658 /* Lout1, Lout2, hp */ 19659 0x02, 0x03, 0x04 19660}; 19661 19662static hda_nid_t alc680_adc_nids[3] = { 19663 /* ADC0-2 */ 19664 /* DMIC, MIC, Line-in*/ 19665 0x07, 0x08, 0x09 19666}; 19667 19668/* 19669 * Analog capture ADC cgange 19670 */ 19671static void alc680_rec_autoswitch(struct hda_codec *codec) 19672{ 19673 struct alc_spec *spec = codec->spec; 19674 struct auto_pin_cfg *cfg = &spec->autocfg; 19675 int pin_found = 0; 19676 int type_found = AUTO_PIN_LAST; 19677 hda_nid_t nid; 19678 int i; 19679 19680 for (i = 0; i < cfg->num_inputs; i++) { 19681 nid = cfg->inputs[i].pin; 19682 if (!(snd_hda_query_pin_caps(codec, nid) & 19683 AC_PINCAP_PRES_DETECT)) 19684 continue; 19685 if (snd_hda_jack_detect(codec, nid)) { 19686 if (cfg->inputs[i].type < type_found) { 19687 type_found = cfg->inputs[i].type; 19688 pin_found = nid; 19689 } 19690 } 19691 } 19692 19693 nid = 0x07; 19694 if (pin_found) 19695 snd_hda_get_connections(codec, pin_found, &nid, 1); 19696 19697 if (nid != spec->cur_adc) 19698 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1); 19699 spec->cur_adc = nid; 19700 snd_hda_codec_setup_stream(codec, nid, spec->cur_adc_stream_tag, 0, 19701 spec->cur_adc_format); 19702} 19703 19704static int alc680_capture_pcm_prepare(struct hda_pcm_stream *hinfo, 19705 struct hda_codec *codec, 19706 unsigned int stream_tag, 19707 unsigned int format, 19708 struct snd_pcm_substream *substream) 19709{ 19710 struct alc_spec *spec = codec->spec; 19711 19712 spec->cur_adc = 0x07; 19713 spec->cur_adc_stream_tag = stream_tag; 19714 spec->cur_adc_format = format; 19715 19716 alc680_rec_autoswitch(codec); 19717 return 0; 19718} 19719 19720static int alc680_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, 19721 struct hda_codec *codec, 19722 struct snd_pcm_substream *substream) 19723{ 19724 snd_hda_codec_cleanup_stream(codec, 0x07); 19725 snd_hda_codec_cleanup_stream(codec, 0x08); 19726 snd_hda_codec_cleanup_stream(codec, 0x09); 19727 return 0; 19728} 19729 19730static struct hda_pcm_stream alc680_pcm_analog_auto_capture = { 19731 .substreams = 1, /* can be overridden */ 19732 .channels_min = 2, 19733 .channels_max = 2, 19734 /* NID is set in alc_build_pcms */ 19735 .ops = { 19736 .prepare = alc680_capture_pcm_prepare, 19737 .cleanup = alc680_capture_pcm_cleanup 19738 }, 19739}; 19740 19741static struct snd_kcontrol_new alc680_base_mixer[] = { 19742 /* output mixer control */ 19743 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), 19744 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 19745 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT), 19746 HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT), 19747 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x12, 0, HDA_INPUT), 19748 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 19749 HDA_CODEC_VOLUME("Line In Boost Volume", 0x19, 0, HDA_INPUT), 19750 { } 19751}; 19752 19753static struct hda_bind_ctls alc680_bind_cap_vol = { 19754 .ops = &snd_hda_bind_vol, 19755 .values = { 19756 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT), 19757 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT), 19758 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT), 19759 0 19760 }, 19761}; 19762 19763static struct hda_bind_ctls alc680_bind_cap_switch = { 19764 .ops = &snd_hda_bind_sw, 19765 .values = { 19766 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT), 19767 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT), 19768 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT), 19769 0 19770 }, 19771}; 19772 19773static struct snd_kcontrol_new alc680_master_capture_mixer[] = { 19774 HDA_BIND_VOL("Capture Volume", &alc680_bind_cap_vol), 19775 HDA_BIND_SW("Capture Switch", &alc680_bind_cap_switch), 19776 { } /* end */ 19777}; 19778 19779/* 19780 * generic initialization of ADC, input mixers and output mixers 19781 */ 19782static struct hda_verb alc680_init_verbs[] = { 19783 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 19784 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 19785 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 19786 19787 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 19788 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 19789 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 19790 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 19791 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 19792 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 19793 19794 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 19795 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 19796 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 19797 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 19798 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 19799 19800 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 19801 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, 19802 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, 19803 19804 { } 19805}; 19806 19807/* toggle speaker-output according to the hp-jack state */ 19808static void alc680_base_setup(struct hda_codec *codec) 19809{ 19810 struct alc_spec *spec = codec->spec; 19811 19812 spec->autocfg.hp_pins[0] = 0x16; 19813 spec->autocfg.speaker_pins[0] = 0x14; 19814 spec->autocfg.speaker_pins[1] = 0x15; 19815 spec->autocfg.num_inputs = 2; 19816 spec->autocfg.inputs[0].pin = 0x18; 19817 spec->autocfg.inputs[0].type = AUTO_PIN_MIC; 19818 spec->autocfg.inputs[1].pin = 0x19; 19819 spec->autocfg.inputs[1].type = AUTO_PIN_LINE_IN; 19820} 19821 19822static void alc680_unsol_event(struct hda_codec *codec, 19823 unsigned int res) 19824{ 19825 if ((res >> 26) == ALC880_HP_EVENT) 19826 alc_automute_amp(codec); 19827 if ((res >> 26) == ALC880_MIC_EVENT) 19828 alc680_rec_autoswitch(codec); 19829} 19830 19831static void alc680_inithook(struct hda_codec *codec) 19832{ 19833 alc_automute_amp(codec); 19834 alc680_rec_autoswitch(codec); 19835} 19836 19837/* create input playback/capture controls for the given pin */ 19838static int alc680_new_analog_output(struct alc_spec *spec, hda_nid_t nid, 19839 const char *ctlname, int idx) 19840{ 19841 hda_nid_t dac; 19842 int err; 19843 19844 switch (nid) { 19845 case 0x14: 19846 dac = 0x02; 19847 break; 19848 case 0x15: 19849 dac = 0x03; 19850 break; 19851 case 0x16: 19852 dac = 0x04; 19853 break; 19854 default: 19855 return 0; 19856 } 19857 if (spec->multiout.dac_nids[0] != dac && 19858 spec->multiout.dac_nids[1] != dac) { 19859 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname, 19860 HDA_COMPOSE_AMP_VAL(dac, 3, idx, 19861 HDA_OUTPUT)); 19862 if (err < 0) 19863 return err; 19864 19865 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname, 19866 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT)); 19867 19868 if (err < 0) 19869 return err; 19870 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac; 19871 } 19872 19873 return 0; 19874} 19875 19876/* add playback controls from the parsed DAC table */ 19877static int alc680_auto_create_multi_out_ctls(struct alc_spec *spec, 19878 const struct auto_pin_cfg *cfg) 19879{ 19880 hda_nid_t nid; 19881 int err; 19882 19883 spec->multiout.dac_nids = spec->private_dac_nids; 19884 19885 nid = cfg->line_out_pins[0]; 19886 if (nid) { 19887 const char *name; 19888 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) 19889 name = "Speaker"; 19890 else 19891 name = "Front"; 19892 err = alc680_new_analog_output(spec, nid, name, 0); 19893 if (err < 0) 19894 return err; 19895 } 19896 19897 nid = cfg->speaker_pins[0]; 19898 if (nid) { 19899 err = alc680_new_analog_output(spec, nid, "Speaker", 0); 19900 if (err < 0) 19901 return err; 19902 } 19903 nid = cfg->hp_pins[0]; 19904 if (nid) { 19905 err = alc680_new_analog_output(spec, nid, "Headphone", 0); 19906 if (err < 0) 19907 return err; 19908 } 19909 19910 return 0; 19911} 19912 19913static void alc680_auto_set_output_and_unmute(struct hda_codec *codec, 19914 hda_nid_t nid, int pin_type) 19915{ 19916 alc_set_pin_output(codec, nid, pin_type); 19917} 19918 19919static void alc680_auto_init_multi_out(struct hda_codec *codec) 19920{ 19921 struct alc_spec *spec = codec->spec; 19922 hda_nid_t nid = spec->autocfg.line_out_pins[0]; 19923 if (nid) { 19924 int pin_type = get_pin_type(spec->autocfg.line_out_type); 19925 alc680_auto_set_output_and_unmute(codec, nid, pin_type); 19926 } 19927} 19928 19929static void alc680_auto_init_hp_out(struct hda_codec *codec) 19930{ 19931 struct alc_spec *spec = codec->spec; 19932 hda_nid_t pin; 19933 19934 pin = spec->autocfg.hp_pins[0]; 19935 if (pin) 19936 alc680_auto_set_output_and_unmute(codec, pin, PIN_HP); 19937 pin = spec->autocfg.speaker_pins[0]; 19938 if (pin) 19939 alc680_auto_set_output_and_unmute(codec, pin, PIN_OUT); 19940} 19941 19942/* pcm configuration: identical with ALC880 */ 19943#define alc680_pcm_analog_playback alc880_pcm_analog_playback 19944#define alc680_pcm_analog_capture alc880_pcm_analog_capture 19945#define alc680_pcm_analog_alt_capture alc880_pcm_analog_alt_capture 19946#define alc680_pcm_digital_playback alc880_pcm_digital_playback 19947#define alc680_pcm_digital_capture alc880_pcm_digital_capture 19948 19949/* 19950 * BIOS auto configuration 19951 */ 19952static int alc680_parse_auto_config(struct hda_codec *codec) 19953{ 19954 struct alc_spec *spec = codec->spec; 19955 int err; 19956 static hda_nid_t alc680_ignore[] = { 0 }; 19957 19958 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 19959 alc680_ignore); 19960 if (err < 0) 19961 return err; 19962 19963 if (!spec->autocfg.line_outs) { 19964 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) { 19965 spec->multiout.max_channels = 2; 19966 spec->no_analog = 1; 19967 goto dig_only; 19968 } 19969 return 0; /* can't find valid BIOS pin config */ 19970 } 19971 err = alc680_auto_create_multi_out_ctls(spec, &spec->autocfg); 19972 if (err < 0) 19973 return err; 19974 19975 spec->multiout.max_channels = 2; 19976 19977 dig_only: 19978 /* digital only support output */ 19979 alc_auto_parse_digital(codec); 19980 if (spec->kctls.list) 19981 add_mixer(spec, spec->kctls.list); 19982 19983 add_verb(spec, alc680_init_verbs); 19984 19985 err = alc_auto_add_mic_boost(codec); 19986 if (err < 0) 19987 return err; 19988 19989 return 1; 19990} 19991 19992#define alc680_auto_init_analog_input alc882_auto_init_analog_input 19993 19994/* init callback for auto-configuration model -- overriding the default init */ 19995static void alc680_auto_init(struct hda_codec *codec) 19996{ 19997 struct alc_spec *spec = codec->spec; 19998 alc680_auto_init_multi_out(codec); 19999 alc680_auto_init_hp_out(codec); 20000 alc680_auto_init_analog_input(codec); 20001 alc_auto_init_digital(codec); 20002 if (spec->unsol_event) 20003 alc_inithook(codec); 20004} 20005 20006/* 20007 * configuration and preset 20008 */ 20009static const char * const alc680_models[ALC680_MODEL_LAST] = { 20010 [ALC680_BASE] = "base", 20011 [ALC680_AUTO] = "auto", 20012}; 20013 20014static struct snd_pci_quirk alc680_cfg_tbl[] = { 20015 SND_PCI_QUIRK(0x1043, 0x12f3, "ASUS NX90", ALC680_BASE), 20016 {} 20017}; 20018 20019static struct alc_config_preset alc680_presets[] = { 20020 [ALC680_BASE] = { 20021 .mixers = { alc680_base_mixer }, 20022 .cap_mixer = alc680_master_capture_mixer, 20023 .init_verbs = { alc680_init_verbs }, 20024 .num_dacs = ARRAY_SIZE(alc680_dac_nids), 20025 .dac_nids = alc680_dac_nids, 20026 .dig_out_nid = ALC680_DIGOUT_NID, 20027 .num_channel_mode = ARRAY_SIZE(alc680_modes), 20028 .channel_mode = alc680_modes, 20029 .unsol_event = alc680_unsol_event, 20030 .setup = alc680_base_setup, 20031 .init_hook = alc680_inithook, 20032 20033 }, 20034}; 20035 20036static int patch_alc680(struct hda_codec *codec) 20037{ 20038 struct alc_spec *spec; 20039 int board_config; 20040 int err; 20041 20042 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 20043 if (spec == NULL) 20044 return -ENOMEM; 20045 20046 codec->spec = spec; 20047 20048 board_config = snd_hda_check_board_config(codec, ALC680_MODEL_LAST, 20049 alc680_models, 20050 alc680_cfg_tbl); 20051 20052 if (board_config < 0 || board_config >= ALC680_MODEL_LAST) { 20053 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 20054 codec->chip_name); 20055 board_config = ALC680_AUTO; 20056 } 20057 20058 if (board_config == ALC680_AUTO) { 20059 /* automatic parse from the BIOS config */ 20060 err = alc680_parse_auto_config(codec); 20061 if (err < 0) { 20062 alc_free(codec); 20063 return err; 20064 } else if (!err) { 20065 printk(KERN_INFO 20066 "hda_codec: Cannot set up configuration " 20067 "from BIOS. Using base mode...\n"); 20068 board_config = ALC680_BASE; 20069 } 20070 } 20071 20072 if (board_config != ALC680_AUTO) 20073 setup_preset(codec, &alc680_presets[board_config]); 20074 20075 spec->stream_analog_playback = &alc680_pcm_analog_playback; 20076 spec->stream_analog_capture = &alc680_pcm_analog_auto_capture; 20077 spec->stream_digital_playback = &alc680_pcm_digital_playback; 20078 spec->stream_digital_capture = &alc680_pcm_digital_capture; 20079 20080 if (!spec->adc_nids) { 20081 spec->adc_nids = alc680_adc_nids; 20082 spec->num_adc_nids = ARRAY_SIZE(alc680_adc_nids); 20083 } 20084 20085 if (!spec->cap_mixer) 20086 set_capture_mixer(codec); 20087 20088 spec->vmaster_nid = 0x02; 20089 20090 codec->patch_ops = alc_patch_ops; 20091 if (board_config == ALC680_AUTO) 20092 spec->init_hook = alc680_auto_init; 20093 20094 return 0; 20095} 20096 20097/* 20098 * patch entries 20099 */ 20100static struct hda_codec_preset snd_hda_preset_realtek[] = { 20101 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 }, 20102 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 }, 20103 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 }, 20104 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 }, 20105 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 }, 20106 { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 }, 20107 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 }, 20108 { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 }, 20109 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660", 20110 .patch = patch_alc861 }, 20111 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd }, 20112 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 }, 20113 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd }, 20114 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2", 20115 .patch = patch_alc882 }, 20116 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1", 20117 .patch = patch_alc662 }, 20118 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 }, 20119 { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 }, 20120 { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 }, 20121 { .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 }, 20122 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 }, 20123 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 }, 20124 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 }, 20125 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A", 20126 .patch = patch_alc882 }, 20127 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A", 20128 .patch = patch_alc882 }, 20129 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 }, 20130 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc888 }, 20131 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200", 20132 .patch = patch_alc882 }, 20133 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc888 }, 20134 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 }, 20135 { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 }, 20136 {} /* terminator */ 20137}; 20138 20139MODULE_ALIAS("snd-hda-codec-id:10ec*"); 20140 20141MODULE_LICENSE("GPL"); 20142MODULE_DESCRIPTION("Realtek HD-audio codec"); 20143 20144static struct hda_codec_preset_list realtek_list = { 20145 .preset = snd_hda_preset_realtek, 20146 .owner = THIS_MODULE, 20147}; 20148 20149static int __init patch_realtek_init(void) 20150{ 20151 return snd_hda_add_codec_preset(&realtek_list); 20152} 20153 20154static void __exit patch_realtek_exit(void) 20155{ 20156 snd_hda_delete_codec_preset(&realtek_list); 20157} 20158 20159module_init(patch_realtek_init) 20160module_exit(patch_realtek_exit) 20161