patch_realtek.c revision 66ceeb6bc2809bef0cfa18b1e22ddad5fc9b58b0
1/* 2 * Universal Interface for Intel High Definition Audio Codec 3 * 4 * HD audio interface patch for ALC 260/880/882 codecs 5 * 6 * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw> 7 * PeiSen Hou <pshou@realtek.com.tw> 8 * Takashi Iwai <tiwai@suse.de> 9 * Jonathan Woithe <jwoithe@physics.adelaide.edu.au> 10 * 11 * This driver is free software; you can redistribute it and/or modify 12 * it under the terms of the GNU General Public License as published by 13 * the Free Software Foundation; either version 2 of the License, or 14 * (at your option) any later version. 15 * 16 * This driver is distributed in the hope that it will be useful, 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 * GNU General Public License for more details. 20 * 21 * You should have received a copy of the GNU General Public License 22 * along with this program; if not, write to the Free Software 23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 24 */ 25 26#include <linux/init.h> 27#include <linux/delay.h> 28#include <linux/slab.h> 29#include <linux/pci.h> 30#include <sound/core.h> 31#include "hda_codec.h" 32#include "hda_local.h" 33#include "hda_beep.h" 34 35#define ALC880_FRONT_EVENT 0x01 36#define ALC880_DCVOL_EVENT 0x02 37#define ALC880_HP_EVENT 0x04 38#define ALC880_MIC_EVENT 0x08 39 40/* ALC880 board config type */ 41enum { 42 ALC880_3ST, 43 ALC880_3ST_DIG, 44 ALC880_5ST, 45 ALC880_5ST_DIG, 46 ALC880_W810, 47 ALC880_Z71V, 48 ALC880_6ST, 49 ALC880_6ST_DIG, 50 ALC880_F1734, 51 ALC880_ASUS, 52 ALC880_ASUS_DIG, 53 ALC880_ASUS_W1V, 54 ALC880_ASUS_DIG2, 55 ALC880_FUJITSU, 56 ALC880_UNIWILL_DIG, 57 ALC880_UNIWILL, 58 ALC880_UNIWILL_P53, 59 ALC880_CLEVO, 60 ALC880_TCL_S700, 61 ALC880_LG, 62 ALC880_LG_LW, 63 ALC880_MEDION_RIM, 64#ifdef CONFIG_SND_DEBUG 65 ALC880_TEST, 66#endif 67 ALC880_AUTO, 68 ALC880_MODEL_LAST /* last tag */ 69}; 70 71/* ALC260 models */ 72enum { 73 ALC260_BASIC, 74 ALC260_HP, 75 ALC260_HP_DC7600, 76 ALC260_HP_3013, 77 ALC260_FUJITSU_S702X, 78 ALC260_ACER, 79 ALC260_WILL, 80 ALC260_REPLACER_672V, 81 ALC260_FAVORIT100, 82#ifdef CONFIG_SND_DEBUG 83 ALC260_TEST, 84#endif 85 ALC260_AUTO, 86 ALC260_MODEL_LAST /* last tag */ 87}; 88 89/* ALC262 models */ 90enum { 91 ALC262_BASIC, 92 ALC262_HIPPO, 93 ALC262_HIPPO_1, 94 ALC262_FUJITSU, 95 ALC262_HP_BPC, 96 ALC262_HP_BPC_D7000_WL, 97 ALC262_HP_BPC_D7000_WF, 98 ALC262_HP_TC_T5735, 99 ALC262_HP_RP5700, 100 ALC262_BENQ_ED8, 101 ALC262_SONY_ASSAMD, 102 ALC262_BENQ_T31, 103 ALC262_ULTRA, 104 ALC262_LENOVO_3000, 105 ALC262_NEC, 106 ALC262_TOSHIBA_S06, 107 ALC262_TOSHIBA_RX1, 108 ALC262_TYAN, 109 ALC262_AUTO, 110 ALC262_MODEL_LAST /* last tag */ 111}; 112 113/* ALC268 models */ 114enum { 115 ALC267_QUANTA_IL1, 116 ALC268_3ST, 117 ALC268_TOSHIBA, 118 ALC268_ACER, 119 ALC268_ACER_DMIC, 120 ALC268_ACER_ASPIRE_ONE, 121 ALC268_DELL, 122 ALC268_ZEPTO, 123#ifdef CONFIG_SND_DEBUG 124 ALC268_TEST, 125#endif 126 ALC268_AUTO, 127 ALC268_MODEL_LAST /* last tag */ 128}; 129 130/* ALC269 models */ 131enum { 132 ALC269_BASIC, 133 ALC269_QUANTA_FL1, 134 ALC269_AMIC, 135 ALC269_DMIC, 136 ALC269VB_AMIC, 137 ALC269VB_DMIC, 138 ALC269_FUJITSU, 139 ALC269_LIFEBOOK, 140 ALC271_ACER, 141 ALC269_AUTO, 142 ALC269_MODEL_LAST /* last tag */ 143}; 144 145/* ALC861 models */ 146enum { 147 ALC861_3ST, 148 ALC660_3ST, 149 ALC861_3ST_DIG, 150 ALC861_6ST_DIG, 151 ALC861_UNIWILL_M31, 152 ALC861_TOSHIBA, 153 ALC861_ASUS, 154 ALC861_ASUS_LAPTOP, 155 ALC861_AUTO, 156 ALC861_MODEL_LAST, 157}; 158 159/* ALC861-VD models */ 160enum { 161 ALC660VD_3ST, 162 ALC660VD_3ST_DIG, 163 ALC660VD_ASUS_V1S, 164 ALC861VD_3ST, 165 ALC861VD_3ST_DIG, 166 ALC861VD_6ST_DIG, 167 ALC861VD_LENOVO, 168 ALC861VD_DALLAS, 169 ALC861VD_HP, 170 ALC861VD_AUTO, 171 ALC861VD_MODEL_LAST, 172}; 173 174/* ALC662 models */ 175enum { 176 ALC662_3ST_2ch_DIG, 177 ALC662_3ST_6ch_DIG, 178 ALC662_3ST_6ch, 179 ALC662_5ST_DIG, 180 ALC662_LENOVO_101E, 181 ALC662_ASUS_EEEPC_P701, 182 ALC662_ASUS_EEEPC_EP20, 183 ALC663_ASUS_M51VA, 184 ALC663_ASUS_G71V, 185 ALC663_ASUS_H13, 186 ALC663_ASUS_G50V, 187 ALC662_ECS, 188 ALC663_ASUS_MODE1, 189 ALC662_ASUS_MODE2, 190 ALC663_ASUS_MODE3, 191 ALC663_ASUS_MODE4, 192 ALC663_ASUS_MODE5, 193 ALC663_ASUS_MODE6, 194 ALC663_ASUS_MODE7, 195 ALC663_ASUS_MODE8, 196 ALC272_DELL, 197 ALC272_DELL_ZM1, 198 ALC272_SAMSUNG_NC10, 199 ALC662_AUTO, 200 ALC662_MODEL_LAST, 201}; 202 203/* ALC882 models */ 204enum { 205 ALC882_3ST_DIG, 206 ALC882_6ST_DIG, 207 ALC882_ARIMA, 208 ALC882_W2JC, 209 ALC882_TARGA, 210 ALC882_ASUS_A7J, 211 ALC882_ASUS_A7M, 212 ALC885_MACPRO, 213 ALC885_MBA21, 214 ALC885_MBP3, 215 ALC885_MB5, 216 ALC885_MACMINI3, 217 ALC885_IMAC24, 218 ALC885_IMAC91, 219 ALC883_3ST_2ch_DIG, 220 ALC883_3ST_6ch_DIG, 221 ALC883_3ST_6ch, 222 ALC883_6ST_DIG, 223 ALC883_TARGA_DIG, 224 ALC883_TARGA_2ch_DIG, 225 ALC883_TARGA_8ch_DIG, 226 ALC883_ACER, 227 ALC883_ACER_ASPIRE, 228 ALC888_ACER_ASPIRE_4930G, 229 ALC888_ACER_ASPIRE_6530G, 230 ALC888_ACER_ASPIRE_8930G, 231 ALC888_ACER_ASPIRE_7730G, 232 ALC883_MEDION, 233 ALC883_MEDION_MD2, 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}; 298 299struct alc_spec { 300 /* codec parameterization */ 301 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */ 302 unsigned int num_mixers; 303 struct snd_kcontrol_new *cap_mixer; /* capture mixer */ 304 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */ 305 306 const struct hda_verb *init_verbs[10]; /* initialization verbs 307 * don't forget NULL 308 * termination! 309 */ 310 unsigned int num_init_verbs; 311 312 char stream_name_analog[32]; /* analog PCM stream */ 313 struct hda_pcm_stream *stream_analog_playback; 314 struct hda_pcm_stream *stream_analog_capture; 315 struct hda_pcm_stream *stream_analog_alt_playback; 316 struct hda_pcm_stream *stream_analog_alt_capture; 317 318 char stream_name_digital[32]; /* digital PCM stream */ 319 struct hda_pcm_stream *stream_digital_playback; 320 struct hda_pcm_stream *stream_digital_capture; 321 322 /* playback */ 323 struct hda_multi_out multiout; /* playback set-up 324 * max_channels, dacs must be set 325 * dig_out_nid and hp_nid are optional 326 */ 327 hda_nid_t alt_dac_nid; 328 hda_nid_t slave_dig_outs[3]; /* optional - for auto-parsing */ 329 int dig_out_type; 330 331 /* capture */ 332 unsigned int num_adc_nids; 333 hda_nid_t *adc_nids; 334 hda_nid_t *capsrc_nids; 335 hda_nid_t dig_in_nid; /* digital-in NID; optional */ 336 337 /* capture setup for dynamic dual-adc switch */ 338 unsigned int cur_adc_idx; 339 hda_nid_t cur_adc; 340 unsigned int cur_adc_stream_tag; 341 unsigned int cur_adc_format; 342 343 /* capture source */ 344 unsigned int num_mux_defs; 345 const struct hda_input_mux *input_mux; 346 unsigned int cur_mux[3]; 347 struct alc_mic_route ext_mic; 348 struct alc_mic_route int_mic; 349 350 /* channel model */ 351 const struct hda_channel_mode *channel_mode; 352 int num_channel_mode; 353 int need_dac_fix; 354 int const_channel_count; 355 int ext_channel_count; 356 357 /* PCM information */ 358 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */ 359 360 /* dynamic controls, init_verbs and input_mux */ 361 struct auto_pin_cfg autocfg; 362 struct alc_customize_define cdefine; 363 struct snd_array kctls; 364 struct hda_input_mux private_imux[3]; 365 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; 366 hda_nid_t private_adc_nids[AUTO_CFG_MAX_OUTS]; 367 hda_nid_t private_capsrc_nids[AUTO_CFG_MAX_OUTS]; 368 369 /* hooks */ 370 void (*init_hook)(struct hda_codec *codec); 371 void (*unsol_event)(struct hda_codec *codec, unsigned int res); 372#ifdef CONFIG_SND_HDA_POWER_SAVE 373 void (*power_hook)(struct hda_codec *codec); 374#endif 375 376 /* for pin sensing */ 377 unsigned int sense_updated: 1; 378 unsigned int jack_present: 1; 379 unsigned int master_sw: 1; 380 unsigned int auto_mic:1; 381 382 /* other flags */ 383 unsigned int no_analog :1; /* digital I/O only */ 384 unsigned int dual_adc_switch:1; /* switch ADCs (for ALC275) */ 385 int init_amp; 386 387 /* for virtual master */ 388 hda_nid_t vmaster_nid; 389#ifdef CONFIG_SND_HDA_POWER_SAVE 390 struct hda_loopback_check loopback; 391#endif 392 393 /* for PLL fix */ 394 hda_nid_t pll_nid; 395 unsigned int pll_coef_idx, pll_coef_bit; 396}; 397 398/* 399 * configuration template - to be copied to the spec instance 400 */ 401struct alc_config_preset { 402 struct snd_kcontrol_new *mixers[5]; /* should be identical size 403 * with spec 404 */ 405 struct snd_kcontrol_new *cap_mixer; /* capture mixer */ 406 const struct hda_verb *init_verbs[5]; 407 unsigned int num_dacs; 408 hda_nid_t *dac_nids; 409 hda_nid_t dig_out_nid; /* optional */ 410 hda_nid_t hp_nid; /* optional */ 411 hda_nid_t *slave_dig_outs; 412 unsigned int num_adc_nids; 413 hda_nid_t *adc_nids; 414 hda_nid_t *capsrc_nids; 415 hda_nid_t dig_in_nid; 416 unsigned int num_channel_mode; 417 const struct hda_channel_mode *channel_mode; 418 int need_dac_fix; 419 int const_channel_count; 420 unsigned int num_mux_defs; 421 const struct hda_input_mux *input_mux; 422 void (*unsol_event)(struct hda_codec *, unsigned int); 423 void (*setup)(struct hda_codec *); 424 void (*init_hook)(struct hda_codec *); 425#ifdef CONFIG_SND_HDA_POWER_SAVE 426 struct hda_amp_list *loopbacks; 427 void (*power_hook)(struct hda_codec *codec); 428#endif 429}; 430 431 432/* 433 * input MUX handling 434 */ 435static int alc_mux_enum_info(struct snd_kcontrol *kcontrol, 436 struct snd_ctl_elem_info *uinfo) 437{ 438 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 439 struct alc_spec *spec = codec->spec; 440 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id); 441 if (mux_idx >= spec->num_mux_defs) 442 mux_idx = 0; 443 if (!spec->input_mux[mux_idx].num_items && mux_idx > 0) 444 mux_idx = 0; 445 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo); 446} 447 448static int alc_mux_enum_get(struct snd_kcontrol *kcontrol, 449 struct snd_ctl_elem_value *ucontrol) 450{ 451 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 452 struct alc_spec *spec = codec->spec; 453 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 454 455 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx]; 456 return 0; 457} 458 459static int alc_mux_enum_put(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 const struct hda_input_mux *imux; 465 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 466 unsigned int mux_idx; 467 hda_nid_t nid = spec->capsrc_nids ? 468 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx]; 469 unsigned int type; 470 471 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx; 472 imux = &spec->input_mux[mux_idx]; 473 if (!imux->num_items && mux_idx > 0) 474 imux = &spec->input_mux[0]; 475 476 type = get_wcaps_type(get_wcaps(codec, nid)); 477 if (type == AC_WID_AUD_MIX) { 478 /* Matrix-mixer style (e.g. ALC882) */ 479 unsigned int *cur_val = &spec->cur_mux[adc_idx]; 480 unsigned int i, idx; 481 482 idx = ucontrol->value.enumerated.item[0]; 483 if (idx >= imux->num_items) 484 idx = imux->num_items - 1; 485 if (*cur_val == idx) 486 return 0; 487 for (i = 0; i < imux->num_items; i++) { 488 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE; 489 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 490 imux->items[i].index, 491 HDA_AMP_MUTE, v); 492 } 493 *cur_val = idx; 494 return 1; 495 } else { 496 /* MUX style (e.g. ALC880) */ 497 return snd_hda_input_mux_put(codec, imux, ucontrol, nid, 498 &spec->cur_mux[adc_idx]); 499 } 500} 501 502/* 503 * channel mode setting 504 */ 505static int alc_ch_mode_info(struct snd_kcontrol *kcontrol, 506 struct snd_ctl_elem_info *uinfo) 507{ 508 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 509 struct alc_spec *spec = codec->spec; 510 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode, 511 spec->num_channel_mode); 512} 513 514static int alc_ch_mode_get(struct snd_kcontrol *kcontrol, 515 struct snd_ctl_elem_value *ucontrol) 516{ 517 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 518 struct alc_spec *spec = codec->spec; 519 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode, 520 spec->num_channel_mode, 521 spec->ext_channel_count); 522} 523 524static int alc_ch_mode_put(struct snd_kcontrol *kcontrol, 525 struct snd_ctl_elem_value *ucontrol) 526{ 527 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 528 struct alc_spec *spec = codec->spec; 529 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode, 530 spec->num_channel_mode, 531 &spec->ext_channel_count); 532 if (err >= 0 && !spec->const_channel_count) { 533 spec->multiout.max_channels = spec->ext_channel_count; 534 if (spec->need_dac_fix) 535 spec->multiout.num_dacs = spec->multiout.max_channels / 2; 536 } 537 return err; 538} 539 540/* 541 * Control the mode of pin widget settings via the mixer. "pc" is used 542 * instead of "%" to avoid consequences of accidently treating the % as 543 * being part of a format specifier. Maximum allowed length of a value is 544 * 63 characters plus NULL terminator. 545 * 546 * Note: some retasking pin complexes seem to ignore requests for input 547 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these 548 * are requested. Therefore order this list so that this behaviour will not 549 * cause problems when mixer clients move through the enum sequentially. 550 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of 551 * March 2006. 552 */ 553static char *alc_pin_mode_names[] = { 554 "Mic 50pc bias", "Mic 80pc bias", 555 "Line in", "Line out", "Headphone out", 556}; 557static unsigned char alc_pin_mode_values[] = { 558 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP, 559}; 560/* The control can present all 5 options, or it can limit the options based 561 * in the pin being assumed to be exclusively an input or an output pin. In 562 * addition, "input" pins may or may not process the mic bias option 563 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to 564 * accept requests for bias as of chip versions up to March 2006) and/or 565 * wiring in the computer. 566 */ 567#define ALC_PIN_DIR_IN 0x00 568#define ALC_PIN_DIR_OUT 0x01 569#define ALC_PIN_DIR_INOUT 0x02 570#define ALC_PIN_DIR_IN_NOMICBIAS 0x03 571#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04 572 573/* Info about the pin modes supported by the different pin direction modes. 574 * For each direction the minimum and maximum values are given. 575 */ 576static signed char alc_pin_mode_dir_info[5][2] = { 577 { 0, 2 }, /* ALC_PIN_DIR_IN */ 578 { 3, 4 }, /* ALC_PIN_DIR_OUT */ 579 { 0, 4 }, /* ALC_PIN_DIR_INOUT */ 580 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */ 581 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */ 582}; 583#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0]) 584#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1]) 585#define alc_pin_mode_n_items(_dir) \ 586 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1) 587 588static int alc_pin_mode_info(struct snd_kcontrol *kcontrol, 589 struct snd_ctl_elem_info *uinfo) 590{ 591 unsigned int item_num = uinfo->value.enumerated.item; 592 unsigned char dir = (kcontrol->private_value >> 16) & 0xff; 593 594 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 595 uinfo->count = 1; 596 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir); 597 598 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir)) 599 item_num = alc_pin_mode_min(dir); 600 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]); 601 return 0; 602} 603 604static int alc_pin_mode_get(struct snd_kcontrol *kcontrol, 605 struct snd_ctl_elem_value *ucontrol) 606{ 607 unsigned int i; 608 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 609 hda_nid_t nid = kcontrol->private_value & 0xffff; 610 unsigned char dir = (kcontrol->private_value >> 16) & 0xff; 611 long *valp = ucontrol->value.integer.value; 612 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0, 613 AC_VERB_GET_PIN_WIDGET_CONTROL, 614 0x00); 615 616 /* Find enumerated value for current pinctl setting */ 617 i = alc_pin_mode_min(dir); 618 while (i <= alc_pin_mode_max(dir) && alc_pin_mode_values[i] != pinctl) 619 i++; 620 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir); 621 return 0; 622} 623 624static int alc_pin_mode_put(struct snd_kcontrol *kcontrol, 625 struct snd_ctl_elem_value *ucontrol) 626{ 627 signed int change; 628 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 629 hda_nid_t nid = kcontrol->private_value & 0xffff; 630 unsigned char dir = (kcontrol->private_value >> 16) & 0xff; 631 long val = *ucontrol->value.integer.value; 632 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0, 633 AC_VERB_GET_PIN_WIDGET_CONTROL, 634 0x00); 635 636 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir)) 637 val = alc_pin_mode_min(dir); 638 639 change = pinctl != alc_pin_mode_values[val]; 640 if (change) { 641 /* Set pin mode to that requested */ 642 snd_hda_codec_write_cache(codec, nid, 0, 643 AC_VERB_SET_PIN_WIDGET_CONTROL, 644 alc_pin_mode_values[val]); 645 646 /* Also enable the retasking pin's input/output as required 647 * for the requested pin mode. Enum values of 2 or less are 648 * input modes. 649 * 650 * Dynamically switching the input/output buffers probably 651 * reduces noise slightly (particularly on input) so we'll 652 * do it. However, having both input and output buffers 653 * enabled simultaneously doesn't seem to be problematic if 654 * this turns out to be necessary in the future. 655 */ 656 if (val <= 2) { 657 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, 658 HDA_AMP_MUTE, HDA_AMP_MUTE); 659 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0, 660 HDA_AMP_MUTE, 0); 661 } else { 662 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0, 663 HDA_AMP_MUTE, HDA_AMP_MUTE); 664 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, 665 HDA_AMP_MUTE, 0); 666 } 667 } 668 return change; 669} 670 671#define ALC_PIN_MODE(xname, nid, dir) \ 672 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 673 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \ 674 .info = alc_pin_mode_info, \ 675 .get = alc_pin_mode_get, \ 676 .put = alc_pin_mode_put, \ 677 .private_value = nid | (dir<<16) } 678 679/* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged 680 * together using a mask with more than one bit set. This control is 681 * currently used only by the ALC260 test model. At this stage they are not 682 * needed for any "production" models. 683 */ 684#ifdef CONFIG_SND_DEBUG 685#define alc_gpio_data_info snd_ctl_boolean_mono_info 686 687static int alc_gpio_data_get(struct snd_kcontrol *kcontrol, 688 struct snd_ctl_elem_value *ucontrol) 689{ 690 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 691 hda_nid_t nid = kcontrol->private_value & 0xffff; 692 unsigned char mask = (kcontrol->private_value >> 16) & 0xff; 693 long *valp = ucontrol->value.integer.value; 694 unsigned int val = snd_hda_codec_read(codec, nid, 0, 695 AC_VERB_GET_GPIO_DATA, 0x00); 696 697 *valp = (val & mask) != 0; 698 return 0; 699} 700static int alc_gpio_data_put(struct snd_kcontrol *kcontrol, 701 struct snd_ctl_elem_value *ucontrol) 702{ 703 signed int change; 704 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 705 hda_nid_t nid = kcontrol->private_value & 0xffff; 706 unsigned char mask = (kcontrol->private_value >> 16) & 0xff; 707 long val = *ucontrol->value.integer.value; 708 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0, 709 AC_VERB_GET_GPIO_DATA, 710 0x00); 711 712 /* Set/unset the masked GPIO bit(s) as needed */ 713 change = (val == 0 ? 0 : mask) != (gpio_data & mask); 714 if (val == 0) 715 gpio_data &= ~mask; 716 else 717 gpio_data |= mask; 718 snd_hda_codec_write_cache(codec, nid, 0, 719 AC_VERB_SET_GPIO_DATA, gpio_data); 720 721 return change; 722} 723#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \ 724 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 725 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \ 726 .info = alc_gpio_data_info, \ 727 .get = alc_gpio_data_get, \ 728 .put = alc_gpio_data_put, \ 729 .private_value = nid | (mask<<16) } 730#endif /* CONFIG_SND_DEBUG */ 731 732/* A switch control to allow the enabling of the digital IO pins on the 733 * ALC260. This is incredibly simplistic; the intention of this control is 734 * to provide something in the test model allowing digital outputs to be 735 * identified if present. If models are found which can utilise these 736 * outputs a more complete mixer control can be devised for those models if 737 * necessary. 738 */ 739#ifdef CONFIG_SND_DEBUG 740#define alc_spdif_ctrl_info snd_ctl_boolean_mono_info 741 742static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol, 743 struct snd_ctl_elem_value *ucontrol) 744{ 745 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 746 hda_nid_t nid = kcontrol->private_value & 0xffff; 747 unsigned char mask = (kcontrol->private_value >> 16) & 0xff; 748 long *valp = ucontrol->value.integer.value; 749 unsigned int val = snd_hda_codec_read(codec, nid, 0, 750 AC_VERB_GET_DIGI_CONVERT_1, 0x00); 751 752 *valp = (val & mask) != 0; 753 return 0; 754} 755static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol, 756 struct snd_ctl_elem_value *ucontrol) 757{ 758 signed int change; 759 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 760 hda_nid_t nid = kcontrol->private_value & 0xffff; 761 unsigned char mask = (kcontrol->private_value >> 16) & 0xff; 762 long val = *ucontrol->value.integer.value; 763 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0, 764 AC_VERB_GET_DIGI_CONVERT_1, 765 0x00); 766 767 /* Set/unset the masked control bit(s) as needed */ 768 change = (val == 0 ? 0 : mask) != (ctrl_data & mask); 769 if (val==0) 770 ctrl_data &= ~mask; 771 else 772 ctrl_data |= mask; 773 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, 774 ctrl_data); 775 776 return change; 777} 778#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \ 779 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 780 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \ 781 .info = alc_spdif_ctrl_info, \ 782 .get = alc_spdif_ctrl_get, \ 783 .put = alc_spdif_ctrl_put, \ 784 .private_value = nid | (mask<<16) } 785#endif /* CONFIG_SND_DEBUG */ 786 787/* A switch control to allow the enabling EAPD digital outputs on the ALC26x. 788 * Again, this is only used in the ALC26x test models to help identify when 789 * the EAPD line must be asserted for features to work. 790 */ 791#ifdef CONFIG_SND_DEBUG 792#define alc_eapd_ctrl_info snd_ctl_boolean_mono_info 793 794static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol, 795 struct snd_ctl_elem_value *ucontrol) 796{ 797 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 798 hda_nid_t nid = kcontrol->private_value & 0xffff; 799 unsigned char mask = (kcontrol->private_value >> 16) & 0xff; 800 long *valp = ucontrol->value.integer.value; 801 unsigned int val = snd_hda_codec_read(codec, nid, 0, 802 AC_VERB_GET_EAPD_BTLENABLE, 0x00); 803 804 *valp = (val & mask) != 0; 805 return 0; 806} 807 808static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol, 809 struct snd_ctl_elem_value *ucontrol) 810{ 811 int change; 812 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 813 hda_nid_t nid = kcontrol->private_value & 0xffff; 814 unsigned char mask = (kcontrol->private_value >> 16) & 0xff; 815 long val = *ucontrol->value.integer.value; 816 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0, 817 AC_VERB_GET_EAPD_BTLENABLE, 818 0x00); 819 820 /* Set/unset the masked control bit(s) as needed */ 821 change = (!val ? 0 : mask) != (ctrl_data & mask); 822 if (!val) 823 ctrl_data &= ~mask; 824 else 825 ctrl_data |= mask; 826 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE, 827 ctrl_data); 828 829 return change; 830} 831 832#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \ 833 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 834 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \ 835 .info = alc_eapd_ctrl_info, \ 836 .get = alc_eapd_ctrl_get, \ 837 .put = alc_eapd_ctrl_put, \ 838 .private_value = nid | (mask<<16) } 839#endif /* CONFIG_SND_DEBUG */ 840 841/* 842 * set up the input pin config (depending on the given auto-pin type) 843 */ 844static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid, 845 int auto_pin_type) 846{ 847 unsigned int val = PIN_IN; 848 849 if (auto_pin_type <= AUTO_PIN_FRONT_MIC) { 850 unsigned int pincap; 851 unsigned int oldval; 852 oldval = snd_hda_codec_read(codec, nid, 0, 853 AC_VERB_GET_PIN_WIDGET_CONTROL, 0); 854 pincap = snd_hda_query_pin_caps(codec, nid); 855 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT; 856 /* if the default pin setup is vref50, we give it priority */ 857 if ((pincap & AC_PINCAP_VREF_80) && oldval != PIN_VREF50) 858 val = PIN_VREF80; 859 else if (pincap & AC_PINCAP_VREF_50) 860 val = PIN_VREF50; 861 else if (pincap & AC_PINCAP_VREF_100) 862 val = PIN_VREF100; 863 else if (pincap & AC_PINCAP_VREF_GRD) 864 val = PIN_VREFGRD; 865 } 866 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val); 867} 868 869/* 870 */ 871static void add_mixer(struct alc_spec *spec, struct snd_kcontrol_new *mix) 872{ 873 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers))) 874 return; 875 spec->mixers[spec->num_mixers++] = mix; 876} 877 878static void add_verb(struct alc_spec *spec, const struct hda_verb *verb) 879{ 880 if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs))) 881 return; 882 spec->init_verbs[spec->num_init_verbs++] = verb; 883} 884 885/* 886 * set up from the preset table 887 */ 888static void setup_preset(struct hda_codec *codec, 889 const struct alc_config_preset *preset) 890{ 891 struct alc_spec *spec = codec->spec; 892 int i; 893 894 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++) 895 add_mixer(spec, preset->mixers[i]); 896 spec->cap_mixer = preset->cap_mixer; 897 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i]; 898 i++) 899 add_verb(spec, preset->init_verbs[i]); 900 901 spec->channel_mode = preset->channel_mode; 902 spec->num_channel_mode = preset->num_channel_mode; 903 spec->need_dac_fix = preset->need_dac_fix; 904 spec->const_channel_count = preset->const_channel_count; 905 906 if (preset->const_channel_count) 907 spec->multiout.max_channels = preset->const_channel_count; 908 else 909 spec->multiout.max_channels = spec->channel_mode[0].channels; 910 spec->ext_channel_count = spec->channel_mode[0].channels; 911 912 spec->multiout.num_dacs = preset->num_dacs; 913 spec->multiout.dac_nids = preset->dac_nids; 914 spec->multiout.dig_out_nid = preset->dig_out_nid; 915 spec->multiout.slave_dig_outs = preset->slave_dig_outs; 916 spec->multiout.hp_nid = preset->hp_nid; 917 918 spec->num_mux_defs = preset->num_mux_defs; 919 if (!spec->num_mux_defs) 920 spec->num_mux_defs = 1; 921 spec->input_mux = preset->input_mux; 922 923 spec->num_adc_nids = preset->num_adc_nids; 924 spec->adc_nids = preset->adc_nids; 925 spec->capsrc_nids = preset->capsrc_nids; 926 spec->dig_in_nid = preset->dig_in_nid; 927 928 spec->unsol_event = preset->unsol_event; 929 spec->init_hook = preset->init_hook; 930#ifdef CONFIG_SND_HDA_POWER_SAVE 931 spec->power_hook = preset->power_hook; 932 spec->loopback.amplist = preset->loopbacks; 933#endif 934 935 if (preset->setup) 936 preset->setup(codec); 937} 938 939/* Enable GPIO mask and set output */ 940static struct hda_verb alc_gpio1_init_verbs[] = { 941 {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, 942 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, 943 {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, 944 { } 945}; 946 947static struct hda_verb alc_gpio2_init_verbs[] = { 948 {0x01, AC_VERB_SET_GPIO_MASK, 0x02}, 949 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02}, 950 {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, 951 { } 952}; 953 954static struct hda_verb alc_gpio3_init_verbs[] = { 955 {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, 956 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03}, 957 {0x01, AC_VERB_SET_GPIO_DATA, 0x03}, 958 { } 959}; 960 961/* 962 * Fix hardware PLL issue 963 * On some codecs, the analog PLL gating control must be off while 964 * the default value is 1. 965 */ 966static void alc_fix_pll(struct hda_codec *codec) 967{ 968 struct alc_spec *spec = codec->spec; 969 unsigned int val; 970 971 if (!spec->pll_nid) 972 return; 973 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX, 974 spec->pll_coef_idx); 975 val = snd_hda_codec_read(codec, spec->pll_nid, 0, 976 AC_VERB_GET_PROC_COEF, 0); 977 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX, 978 spec->pll_coef_idx); 979 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF, 980 val & ~(1 << spec->pll_coef_bit)); 981} 982 983static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid, 984 unsigned int coef_idx, unsigned int coef_bit) 985{ 986 struct alc_spec *spec = codec->spec; 987 spec->pll_nid = nid; 988 spec->pll_coef_idx = coef_idx; 989 spec->pll_coef_bit = coef_bit; 990 alc_fix_pll(codec); 991} 992 993static void alc_automute_pin(struct hda_codec *codec) 994{ 995 struct alc_spec *spec = codec->spec; 996 unsigned int nid = spec->autocfg.hp_pins[0]; 997 int i; 998 999 if (!nid) 1000 return; 1001 spec->jack_present = snd_hda_jack_detect(codec, nid); 1002 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) { 1003 nid = spec->autocfg.speaker_pins[i]; 1004 if (!nid) 1005 break; 1006 snd_hda_codec_write(codec, nid, 0, 1007 AC_VERB_SET_PIN_WIDGET_CONTROL, 1008 spec->jack_present ? 0 : PIN_OUT); 1009 } 1010} 1011 1012static int get_connection_index(struct hda_codec *codec, hda_nid_t mux, 1013 hda_nid_t nid) 1014{ 1015 hda_nid_t conn[HDA_MAX_NUM_INPUTS]; 1016 int i, nums; 1017 1018 nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn)); 1019 for (i = 0; i < nums; i++) 1020 if (conn[i] == nid) 1021 return i; 1022 return -1; 1023} 1024 1025/* switch the current ADC according to the jack state */ 1026static void alc_dual_mic_adc_auto_switch(struct hda_codec *codec) 1027{ 1028 struct alc_spec *spec = codec->spec; 1029 unsigned int present; 1030 hda_nid_t new_adc; 1031 1032 present = snd_hda_jack_detect(codec, spec->ext_mic.pin); 1033 if (present) 1034 spec->cur_adc_idx = 1; 1035 else 1036 spec->cur_adc_idx = 0; 1037 new_adc = spec->adc_nids[spec->cur_adc_idx]; 1038 if (spec->cur_adc && spec->cur_adc != new_adc) { 1039 /* stream is running, let's swap the current ADC */ 1040 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1); 1041 spec->cur_adc = new_adc; 1042 snd_hda_codec_setup_stream(codec, new_adc, 1043 spec->cur_adc_stream_tag, 0, 1044 spec->cur_adc_format); 1045 } 1046} 1047 1048static void alc_mic_automute(struct hda_codec *codec) 1049{ 1050 struct alc_spec *spec = codec->spec; 1051 struct alc_mic_route *dead, *alive; 1052 unsigned int present, type; 1053 hda_nid_t cap_nid; 1054 1055 if (!spec->auto_mic) 1056 return; 1057 if (!spec->int_mic.pin || !spec->ext_mic.pin) 1058 return; 1059 if (snd_BUG_ON(!spec->adc_nids)) 1060 return; 1061 1062 if (spec->dual_adc_switch) { 1063 alc_dual_mic_adc_auto_switch(codec); 1064 return; 1065 } 1066 1067 cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0]; 1068 1069 present = snd_hda_jack_detect(codec, spec->ext_mic.pin); 1070 if (present) { 1071 alive = &spec->ext_mic; 1072 dead = &spec->int_mic; 1073 } else { 1074 alive = &spec->int_mic; 1075 dead = &spec->ext_mic; 1076 } 1077 1078 type = get_wcaps_type(get_wcaps(codec, cap_nid)); 1079 if (type == AC_WID_AUD_MIX) { 1080 /* Matrix-mixer style (e.g. ALC882) */ 1081 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT, 1082 alive->mux_idx, 1083 HDA_AMP_MUTE, 0); 1084 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT, 1085 dead->mux_idx, 1086 HDA_AMP_MUTE, HDA_AMP_MUTE); 1087 } else { 1088 /* MUX style (e.g. ALC880) */ 1089 snd_hda_codec_write_cache(codec, cap_nid, 0, 1090 AC_VERB_SET_CONNECT_SEL, 1091 alive->mux_idx); 1092 } 1093 1094 /* FIXME: analog mixer */ 1095} 1096 1097/* unsolicited event for HP jack sensing */ 1098static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res) 1099{ 1100 if (codec->vendor_id == 0x10ec0880) 1101 res >>= 28; 1102 else 1103 res >>= 26; 1104 switch (res) { 1105 case ALC880_HP_EVENT: 1106 alc_automute_pin(codec); 1107 break; 1108 case ALC880_MIC_EVENT: 1109 alc_mic_automute(codec); 1110 break; 1111 } 1112} 1113 1114static void alc_inithook(struct hda_codec *codec) 1115{ 1116 alc_automute_pin(codec); 1117 alc_mic_automute(codec); 1118} 1119 1120/* additional initialization for ALC888 variants */ 1121static void alc888_coef_init(struct hda_codec *codec) 1122{ 1123 unsigned int tmp; 1124 1125 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0); 1126 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0); 1127 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7); 1128 if ((tmp & 0xf0) == 0x20) 1129 /* alc888S-VC */ 1130 snd_hda_codec_read(codec, 0x20, 0, 1131 AC_VERB_SET_PROC_COEF, 0x830); 1132 else 1133 /* alc888-VB */ 1134 snd_hda_codec_read(codec, 0x20, 0, 1135 AC_VERB_SET_PROC_COEF, 0x3030); 1136} 1137 1138static void alc889_coef_init(struct hda_codec *codec) 1139{ 1140 unsigned int tmp; 1141 1142 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7); 1143 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0); 1144 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7); 1145 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, tmp|0x2010); 1146} 1147 1148/* turn on/off EAPD control (only if available) */ 1149static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on) 1150{ 1151 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN) 1152 return; 1153 if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD) 1154 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE, 1155 on ? 2 : 0); 1156} 1157 1158static void alc_auto_init_amp(struct hda_codec *codec, int type) 1159{ 1160 unsigned int tmp; 1161 1162 switch (type) { 1163 case ALC_INIT_GPIO1: 1164 snd_hda_sequence_write(codec, alc_gpio1_init_verbs); 1165 break; 1166 case ALC_INIT_GPIO2: 1167 snd_hda_sequence_write(codec, alc_gpio2_init_verbs); 1168 break; 1169 case ALC_INIT_GPIO3: 1170 snd_hda_sequence_write(codec, alc_gpio3_init_verbs); 1171 break; 1172 case ALC_INIT_DEFAULT: 1173 switch (codec->vendor_id) { 1174 case 0x10ec0260: 1175 set_eapd(codec, 0x0f, 1); 1176 set_eapd(codec, 0x10, 1); 1177 break; 1178 case 0x10ec0262: 1179 case 0x10ec0267: 1180 case 0x10ec0268: 1181 case 0x10ec0269: 1182 case 0x10ec0270: 1183 case 0x10ec0272: 1184 case 0x10ec0660: 1185 case 0x10ec0662: 1186 case 0x10ec0663: 1187 case 0x10ec0862: 1188 case 0x10ec0889: 1189 set_eapd(codec, 0x14, 1); 1190 set_eapd(codec, 0x15, 1); 1191 break; 1192 } 1193 switch (codec->vendor_id) { 1194 case 0x10ec0260: 1195 snd_hda_codec_write(codec, 0x1a, 0, 1196 AC_VERB_SET_COEF_INDEX, 7); 1197 tmp = snd_hda_codec_read(codec, 0x1a, 0, 1198 AC_VERB_GET_PROC_COEF, 0); 1199 snd_hda_codec_write(codec, 0x1a, 0, 1200 AC_VERB_SET_COEF_INDEX, 7); 1201 snd_hda_codec_write(codec, 0x1a, 0, 1202 AC_VERB_SET_PROC_COEF, 1203 tmp | 0x2010); 1204 break; 1205 case 0x10ec0262: 1206 case 0x10ec0880: 1207 case 0x10ec0882: 1208 case 0x10ec0883: 1209 case 0x10ec0885: 1210 case 0x10ec0887: 1211 case 0x10ec0889: 1212 alc889_coef_init(codec); 1213 break; 1214 case 0x10ec0888: 1215 alc888_coef_init(codec); 1216 break; 1217#if 0 /* XXX: This may cause the silent output on speaker on some machines */ 1218 case 0x10ec0267: 1219 case 0x10ec0268: 1220 snd_hda_codec_write(codec, 0x20, 0, 1221 AC_VERB_SET_COEF_INDEX, 7); 1222 tmp = snd_hda_codec_read(codec, 0x20, 0, 1223 AC_VERB_GET_PROC_COEF, 0); 1224 snd_hda_codec_write(codec, 0x20, 0, 1225 AC_VERB_SET_COEF_INDEX, 7); 1226 snd_hda_codec_write(codec, 0x20, 0, 1227 AC_VERB_SET_PROC_COEF, 1228 tmp | 0x3000); 1229 break; 1230#endif /* XXX */ 1231 } 1232 break; 1233 } 1234} 1235 1236static void alc_init_auto_hp(struct hda_codec *codec) 1237{ 1238 struct alc_spec *spec = codec->spec; 1239 1240 if (!spec->autocfg.hp_pins[0]) 1241 return; 1242 1243 if (!spec->autocfg.speaker_pins[0]) { 1244 if (spec->autocfg.line_out_pins[0] && 1245 spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT) 1246 spec->autocfg.speaker_pins[0] = 1247 spec->autocfg.line_out_pins[0]; 1248 else 1249 return; 1250 } 1251 1252 snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n", 1253 spec->autocfg.hp_pins[0]); 1254 snd_hda_codec_write_cache(codec, spec->autocfg.hp_pins[0], 0, 1255 AC_VERB_SET_UNSOLICITED_ENABLE, 1256 AC_USRSP_EN | ALC880_HP_EVENT); 1257 spec->unsol_event = alc_sku_unsol_event; 1258} 1259 1260static void alc_init_auto_mic(struct hda_codec *codec) 1261{ 1262 struct alc_spec *spec = codec->spec; 1263 struct auto_pin_cfg *cfg = &spec->autocfg; 1264 hda_nid_t fixed, ext; 1265 int i; 1266 1267 /* there must be only two mic inputs exclusively */ 1268 for (i = 0; i < cfg->num_inputs; i++) 1269 if (cfg->inputs[i].type >= AUTO_PIN_LINE) 1270 return; 1271 1272 fixed = ext = 0; 1273 for (i = 0; i < cfg->num_inputs; i++) { 1274 hda_nid_t nid = cfg->inputs[i].pin; 1275 unsigned int defcfg; 1276 defcfg = snd_hda_codec_get_pincfg(codec, nid); 1277 switch (get_defcfg_connect(defcfg)) { 1278 case AC_JACK_PORT_FIXED: 1279 if (fixed) 1280 return; /* already occupied */ 1281 fixed = nid; 1282 break; 1283 case AC_JACK_PORT_COMPLEX: 1284 if (ext) 1285 return; /* already occupied */ 1286 ext = nid; 1287 break; 1288 default: 1289 return; /* invalid entry */ 1290 } 1291 } 1292 if (!ext || !fixed) 1293 return; 1294 if (!(get_wcaps(codec, ext) & AC_WCAP_UNSOL_CAP)) 1295 return; /* no unsol support */ 1296 snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x\n", 1297 ext, fixed); 1298 spec->ext_mic.pin = ext; 1299 spec->int_mic.pin = fixed; 1300 spec->ext_mic.mux_idx = MUX_IDX_UNDEF; /* set later */ 1301 spec->int_mic.mux_idx = MUX_IDX_UNDEF; /* set later */ 1302 spec->auto_mic = 1; 1303 snd_hda_codec_write_cache(codec, spec->ext_mic.pin, 0, 1304 AC_VERB_SET_UNSOLICITED_ENABLE, 1305 AC_USRSP_EN | ALC880_MIC_EVENT); 1306 spec->unsol_event = alc_sku_unsol_event; 1307} 1308 1309static int alc_auto_parse_customize_define(struct hda_codec *codec) 1310{ 1311 unsigned int ass, tmp, i; 1312 unsigned nid = 0; 1313 struct alc_spec *spec = codec->spec; 1314 1315 spec->cdefine.enable_pcbeep = 1; /* assume always enabled */ 1316 1317 ass = codec->subsystem_id & 0xffff; 1318 if (ass != codec->bus->pci->subsystem_device && (ass & 1)) 1319 goto do_sku; 1320 1321 nid = 0x1d; 1322 if (codec->vendor_id == 0x10ec0260) 1323 nid = 0x17; 1324 ass = snd_hda_codec_get_pincfg(codec, nid); 1325 1326 if (!(ass & 1)) { 1327 printk(KERN_INFO "hda_codec: %s: SKU not ready 0x%08x\n", 1328 codec->chip_name, ass); 1329 return -1; 1330 } 1331 1332 /* check sum */ 1333 tmp = 0; 1334 for (i = 1; i < 16; i++) { 1335 if ((ass >> i) & 1) 1336 tmp++; 1337 } 1338 if (((ass >> 16) & 0xf) != tmp) 1339 return -1; 1340 1341 spec->cdefine.port_connectivity = ass >> 30; 1342 spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20; 1343 spec->cdefine.check_sum = (ass >> 16) & 0xf; 1344 spec->cdefine.customization = ass >> 8; 1345do_sku: 1346 spec->cdefine.sku_cfg = ass; 1347 spec->cdefine.external_amp = (ass & 0x38) >> 3; 1348 spec->cdefine.platform_type = (ass & 0x4) >> 2; 1349 spec->cdefine.swap = (ass & 0x2) >> 1; 1350 spec->cdefine.override = ass & 0x1; 1351 1352 snd_printd("SKU: Nid=0x%x sku_cfg=0x%08x\n", 1353 nid, spec->cdefine.sku_cfg); 1354 snd_printd("SKU: port_connectivity=0x%x\n", 1355 spec->cdefine.port_connectivity); 1356 snd_printd("SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep); 1357 snd_printd("SKU: check_sum=0x%08x\n", spec->cdefine.check_sum); 1358 snd_printd("SKU: customization=0x%08x\n", spec->cdefine.customization); 1359 snd_printd("SKU: external_amp=0x%x\n", spec->cdefine.external_amp); 1360 snd_printd("SKU: platform_type=0x%x\n", spec->cdefine.platform_type); 1361 snd_printd("SKU: swap=0x%x\n", spec->cdefine.swap); 1362 snd_printd("SKU: override=0x%x\n", spec->cdefine.override); 1363 1364 return 0; 1365} 1366 1367/* check subsystem ID and set up device-specific initialization; 1368 * return 1 if initialized, 0 if invalid SSID 1369 */ 1370/* 32-bit subsystem ID for BIOS loading in HD Audio codec. 1371 * 31 ~ 16 : Manufacture ID 1372 * 15 ~ 8 : SKU ID 1373 * 7 ~ 0 : Assembly ID 1374 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36 1375 */ 1376static int alc_subsystem_id(struct hda_codec *codec, 1377 hda_nid_t porta, hda_nid_t porte, 1378 hda_nid_t portd, hda_nid_t porti) 1379{ 1380 unsigned int ass, tmp, i; 1381 unsigned nid; 1382 struct alc_spec *spec = codec->spec; 1383 1384 ass = codec->subsystem_id & 0xffff; 1385 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1)) 1386 goto do_sku; 1387 1388 /* invalid SSID, check the special NID pin defcfg instead */ 1389 /* 1390 * 31~30 : port connectivity 1391 * 29~21 : reserve 1392 * 20 : PCBEEP input 1393 * 19~16 : Check sum (15:1) 1394 * 15~1 : Custom 1395 * 0 : override 1396 */ 1397 nid = 0x1d; 1398 if (codec->vendor_id == 0x10ec0260) 1399 nid = 0x17; 1400 ass = snd_hda_codec_get_pincfg(codec, nid); 1401 snd_printd("realtek: No valid SSID, " 1402 "checking pincfg 0x%08x for NID 0x%x\n", 1403 ass, nid); 1404 if (!(ass & 1)) 1405 return 0; 1406 if ((ass >> 30) != 1) /* no physical connection */ 1407 return 0; 1408 1409 /* check sum */ 1410 tmp = 0; 1411 for (i = 1; i < 16; i++) { 1412 if ((ass >> i) & 1) 1413 tmp++; 1414 } 1415 if (((ass >> 16) & 0xf) != tmp) 1416 return 0; 1417do_sku: 1418 snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n", 1419 ass & 0xffff, codec->vendor_id); 1420 /* 1421 * 0 : override 1422 * 1 : Swap Jack 1423 * 2 : 0 --> Desktop, 1 --> Laptop 1424 * 3~5 : External Amplifier control 1425 * 7~6 : Reserved 1426 */ 1427 tmp = (ass & 0x38) >> 3; /* external Amp control */ 1428 switch (tmp) { 1429 case 1: 1430 spec->init_amp = ALC_INIT_GPIO1; 1431 break; 1432 case 3: 1433 spec->init_amp = ALC_INIT_GPIO2; 1434 break; 1435 case 7: 1436 spec->init_amp = ALC_INIT_GPIO3; 1437 break; 1438 case 5: 1439 spec->init_amp = ALC_INIT_DEFAULT; 1440 break; 1441 } 1442 1443 /* is laptop or Desktop and enable the function "Mute internal speaker 1444 * when the external headphone out jack is plugged" 1445 */ 1446 if (!(ass & 0x8000)) 1447 return 1; 1448 /* 1449 * 10~8 : Jack location 1450 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered 1451 * 14~13: Resvered 1452 * 15 : 1 --> enable the function "Mute internal speaker 1453 * when the external headphone out jack is plugged" 1454 */ 1455 if (!spec->autocfg.hp_pins[0]) { 1456 hda_nid_t nid; 1457 tmp = (ass >> 11) & 0x3; /* HP to chassis */ 1458 if (tmp == 0) 1459 nid = porta; 1460 else if (tmp == 1) 1461 nid = porte; 1462 else if (tmp == 2) 1463 nid = portd; 1464 else if (tmp == 3) 1465 nid = porti; 1466 else 1467 return 1; 1468 for (i = 0; i < spec->autocfg.line_outs; i++) 1469 if (spec->autocfg.line_out_pins[i] == nid) 1470 return 1; 1471 spec->autocfg.hp_pins[0] = nid; 1472 } 1473 1474 alc_init_auto_hp(codec); 1475 alc_init_auto_mic(codec); 1476 return 1; 1477} 1478 1479static void alc_ssid_check(struct hda_codec *codec, 1480 hda_nid_t porta, hda_nid_t porte, 1481 hda_nid_t portd, hda_nid_t porti) 1482{ 1483 if (!alc_subsystem_id(codec, porta, porte, portd, porti)) { 1484 struct alc_spec *spec = codec->spec; 1485 snd_printd("realtek: " 1486 "Enable default setup for auto mode as fallback\n"); 1487 spec->init_amp = ALC_INIT_DEFAULT; 1488 alc_init_auto_hp(codec); 1489 alc_init_auto_mic(codec); 1490 } 1491} 1492 1493/* 1494 * Fix-up pin default configurations and add default verbs 1495 */ 1496 1497struct alc_pincfg { 1498 hda_nid_t nid; 1499 u32 val; 1500}; 1501 1502struct alc_fixup { 1503 const struct alc_pincfg *pins; 1504 const struct hda_verb *verbs; 1505}; 1506 1507static void alc_pick_fixup(struct hda_codec *codec, 1508 const struct snd_pci_quirk *quirk, 1509 const struct alc_fixup *fix, 1510 int pre_init) 1511{ 1512 const struct alc_pincfg *cfg; 1513 1514 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk); 1515 if (!quirk) 1516 return; 1517 fix += quirk->value; 1518 cfg = fix->pins; 1519 if (pre_init && cfg) { 1520#ifdef CONFIG_SND_DEBUG_VERBOSE 1521 snd_printdd(KERN_INFO "hda_codec: %s: Apply pincfg for %s\n", 1522 codec->chip_name, quirk->name); 1523#endif 1524 for (; cfg->nid; cfg++) 1525 snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val); 1526 } 1527 if (!pre_init && fix->verbs) { 1528#ifdef CONFIG_SND_DEBUG_VERBOSE 1529 snd_printdd(KERN_INFO "hda_codec: %s: Apply fix-verbs for %s\n", 1530 codec->chip_name, quirk->name); 1531#endif 1532 add_verb(codec->spec, fix->verbs); 1533 } 1534} 1535 1536static int alc_read_coef_idx(struct hda_codec *codec, 1537 unsigned int coef_idx) 1538{ 1539 unsigned int val; 1540 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 1541 coef_idx); 1542 val = snd_hda_codec_read(codec, 0x20, 0, 1543 AC_VERB_GET_PROC_COEF, 0); 1544 return val; 1545} 1546 1547/* set right pin controls for digital I/O */ 1548static void alc_auto_init_digital(struct hda_codec *codec) 1549{ 1550 struct alc_spec *spec = codec->spec; 1551 int i; 1552 hda_nid_t pin; 1553 1554 for (i = 0; i < spec->autocfg.dig_outs; i++) { 1555 pin = spec->autocfg.dig_out_pins[i]; 1556 if (pin) { 1557 snd_hda_codec_write(codec, pin, 0, 1558 AC_VERB_SET_PIN_WIDGET_CONTROL, 1559 PIN_OUT); 1560 } 1561 } 1562 pin = spec->autocfg.dig_in_pin; 1563 if (pin) 1564 snd_hda_codec_write(codec, pin, 0, 1565 AC_VERB_SET_PIN_WIDGET_CONTROL, 1566 PIN_IN); 1567} 1568 1569/* parse digital I/Os and set up NIDs in BIOS auto-parse mode */ 1570static void alc_auto_parse_digital(struct hda_codec *codec) 1571{ 1572 struct alc_spec *spec = codec->spec; 1573 int i, err; 1574 hda_nid_t dig_nid; 1575 1576 /* support multiple SPDIFs; the secondary is set up as a slave */ 1577 for (i = 0; i < spec->autocfg.dig_outs; i++) { 1578 err = snd_hda_get_connections(codec, 1579 spec->autocfg.dig_out_pins[i], 1580 &dig_nid, 1); 1581 if (err < 0) 1582 continue; 1583 if (!i) { 1584 spec->multiout.dig_out_nid = dig_nid; 1585 spec->dig_out_type = spec->autocfg.dig_out_type[0]; 1586 } else { 1587 spec->multiout.slave_dig_outs = spec->slave_dig_outs; 1588 if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1) 1589 break; 1590 spec->slave_dig_outs[i - 1] = dig_nid; 1591 } 1592 } 1593 1594 if (spec->autocfg.dig_in_pin) { 1595 hda_nid_t dig_nid; 1596 err = snd_hda_get_connections(codec, 1597 spec->autocfg.dig_in_pin, 1598 &dig_nid, 1); 1599 if (err > 0) 1600 spec->dig_in_nid = dig_nid; 1601 } 1602} 1603 1604/* 1605 * ALC888 1606 */ 1607 1608/* 1609 * 2ch mode 1610 */ 1611static struct hda_verb alc888_4ST_ch2_intel_init[] = { 1612/* Mic-in jack as mic in */ 1613 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 1614 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 1615/* Line-in jack as Line in */ 1616 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 1617 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 1618/* Line-Out as Front */ 1619 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00}, 1620 { } /* end */ 1621}; 1622 1623/* 1624 * 4ch mode 1625 */ 1626static struct hda_verb alc888_4ST_ch4_intel_init[] = { 1627/* Mic-in jack as mic in */ 1628 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 1629 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 1630/* Line-in jack as Surround */ 1631 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 1632 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 1633/* Line-Out as Front */ 1634 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00}, 1635 { } /* end */ 1636}; 1637 1638/* 1639 * 6ch mode 1640 */ 1641static struct hda_verb alc888_4ST_ch6_intel_init[] = { 1642/* Mic-in jack as CLFE */ 1643 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 1644 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 1645/* Line-in jack as Surround */ 1646 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 1647 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 1648/* Line-Out as CLFE (workaround because Mic-in is not loud enough) */ 1649 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, 1650 { } /* end */ 1651}; 1652 1653/* 1654 * 8ch mode 1655 */ 1656static struct hda_verb alc888_4ST_ch8_intel_init[] = { 1657/* Mic-in jack as CLFE */ 1658 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 1659 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 1660/* Line-in jack as Surround */ 1661 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 1662 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 1663/* Line-Out as Side */ 1664 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, 1665 { } /* end */ 1666}; 1667 1668static struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = { 1669 { 2, alc888_4ST_ch2_intel_init }, 1670 { 4, alc888_4ST_ch4_intel_init }, 1671 { 6, alc888_4ST_ch6_intel_init }, 1672 { 8, alc888_4ST_ch8_intel_init }, 1673}; 1674 1675/* 1676 * ALC888 Fujitsu Siemens Amillo xa3530 1677 */ 1678 1679static struct hda_verb alc888_fujitsu_xa3530_verbs[] = { 1680/* Front Mic: set to PIN_IN (empty by default) */ 1681 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1682/* Connect Internal HP to Front */ 1683 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1684 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1685 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 1686/* Connect Bass HP to Front */ 1687 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1688 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1689 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 1690/* Connect Line-Out side jack (SPDIF) to Side */ 1691 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1692 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1693 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, 1694/* Connect Mic jack to CLFE */ 1695 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1696 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1697 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, 1698/* Connect Line-in jack to Surround */ 1699 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1700 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1701 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, 1702/* Connect HP out jack to Front */ 1703 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1704 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1705 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 1706/* Enable unsolicited event for HP jack and Line-out jack */ 1707 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 1708 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 1709 {} 1710}; 1711 1712static void alc_automute_amp(struct hda_codec *codec) 1713{ 1714 struct alc_spec *spec = codec->spec; 1715 unsigned int mute; 1716 hda_nid_t nid; 1717 int i; 1718 1719 spec->jack_present = 0; 1720 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) { 1721 nid = spec->autocfg.hp_pins[i]; 1722 if (!nid) 1723 break; 1724 if (snd_hda_jack_detect(codec, nid)) { 1725 spec->jack_present = 1; 1726 break; 1727 } 1728 } 1729 1730 mute = spec->jack_present ? HDA_AMP_MUTE : 0; 1731 /* Toggle internal speakers muting */ 1732 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) { 1733 nid = spec->autocfg.speaker_pins[i]; 1734 if (!nid) 1735 break; 1736 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, 1737 HDA_AMP_MUTE, mute); 1738 } 1739} 1740 1741static void alc_automute_amp_unsol_event(struct hda_codec *codec, 1742 unsigned int res) 1743{ 1744 if (codec->vendor_id == 0x10ec0880) 1745 res >>= 28; 1746 else 1747 res >>= 26; 1748 if (res == ALC880_HP_EVENT) 1749 alc_automute_amp(codec); 1750} 1751 1752static void alc889_automute_setup(struct hda_codec *codec) 1753{ 1754 struct alc_spec *spec = codec->spec; 1755 1756 spec->autocfg.hp_pins[0] = 0x15; 1757 spec->autocfg.speaker_pins[0] = 0x14; 1758 spec->autocfg.speaker_pins[1] = 0x16; 1759 spec->autocfg.speaker_pins[2] = 0x17; 1760 spec->autocfg.speaker_pins[3] = 0x19; 1761 spec->autocfg.speaker_pins[4] = 0x1a; 1762} 1763 1764static void alc889_intel_init_hook(struct hda_codec *codec) 1765{ 1766 alc889_coef_init(codec); 1767 alc_automute_amp(codec); 1768} 1769 1770static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec) 1771{ 1772 struct alc_spec *spec = codec->spec; 1773 1774 spec->autocfg.hp_pins[0] = 0x17; /* line-out */ 1775 spec->autocfg.hp_pins[1] = 0x1b; /* hp */ 1776 spec->autocfg.speaker_pins[0] = 0x14; /* speaker */ 1777 spec->autocfg.speaker_pins[1] = 0x15; /* bass */ 1778} 1779 1780/* 1781 * ALC888 Acer Aspire 4930G model 1782 */ 1783 1784static struct hda_verb alc888_acer_aspire_4930g_verbs[] = { 1785/* Front Mic: set to PIN_IN (empty by default) */ 1786 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1787/* Unselect Front Mic by default in input mixer 3 */ 1788 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)}, 1789/* Enable unsolicited event for HP jack */ 1790 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 1791/* Connect Internal HP to front */ 1792 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1793 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1794 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 1795/* Connect HP out to front */ 1796 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1797 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1798 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 1799 { } 1800}; 1801 1802/* 1803 * ALC888 Acer Aspire 6530G model 1804 */ 1805 1806static struct hda_verb alc888_acer_aspire_6530g_verbs[] = { 1807/* Route to built-in subwoofer as well as speakers */ 1808 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1809 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 1810 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1811 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 1812/* Bias voltage on for external mic port */ 1813 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80}, 1814/* Front Mic: set to PIN_IN (empty by default) */ 1815 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1816/* Unselect Front Mic by default in input mixer 3 */ 1817 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)}, 1818/* Enable unsolicited event for HP jack */ 1819 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 1820/* Enable speaker output */ 1821 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1822 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1823 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 1824/* Enable headphone output */ 1825 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP}, 1826 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1827 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 1828 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, 1829 { } 1830}; 1831 1832/* 1833 * ALC889 Acer Aspire 8930G model 1834 */ 1835 1836static struct hda_verb alc889_acer_aspire_8930g_verbs[] = { 1837/* Front Mic: set to PIN_IN (empty by default) */ 1838 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1839/* Unselect Front Mic by default in input mixer 3 */ 1840 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)}, 1841/* Enable unsolicited event for HP jack */ 1842 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 1843/* Connect Internal Front to Front */ 1844 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1845 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1846 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 1847/* Connect Internal Rear to Rear */ 1848 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1849 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1850 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, 1851/* Connect Internal CLFE to CLFE */ 1852 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1853 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1854 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, 1855/* Connect HP out to Front */ 1856 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP}, 1857 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1858 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 1859/* Enable all DACs */ 1860/* DAC DISABLE/MUTE 1? */ 1861/* setting bits 1-5 disables DAC nids 0x02-0x06 apparently. Init=0x38 */ 1862 {0x20, AC_VERB_SET_COEF_INDEX, 0x03}, 1863 {0x20, AC_VERB_SET_PROC_COEF, 0x0000}, 1864/* DAC DISABLE/MUTE 2? */ 1865/* some bit here disables the other DACs. Init=0x4900 */ 1866 {0x20, AC_VERB_SET_COEF_INDEX, 0x08}, 1867 {0x20, AC_VERB_SET_PROC_COEF, 0x0000}, 1868/* DMIC fix 1869 * This laptop has a stereo digital microphone. The mics are only 1cm apart 1870 * which makes the stereo useless. However, either the mic or the ALC889 1871 * makes the signal become a difference/sum signal instead of standard 1872 * stereo, which is annoying. So instead we flip this bit which makes the 1873 * codec replicate the sum signal to both channels, turning it into a 1874 * normal mono mic. 1875 */ 1876/* DMIC_CONTROL? Init value = 0x0001 */ 1877 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b}, 1878 {0x20, AC_VERB_SET_PROC_COEF, 0x0003}, 1879 { } 1880}; 1881 1882static struct hda_input_mux alc888_2_capture_sources[2] = { 1883 /* Front mic only available on one ADC */ 1884 { 1885 .num_items = 4, 1886 .items = { 1887 { "Mic", 0x0 }, 1888 { "Line", 0x2 }, 1889 { "CD", 0x4 }, 1890 { "Front Mic", 0xb }, 1891 }, 1892 }, 1893 { 1894 .num_items = 3, 1895 .items = { 1896 { "Mic", 0x0 }, 1897 { "Line", 0x2 }, 1898 { "CD", 0x4 }, 1899 }, 1900 } 1901}; 1902 1903static struct hda_input_mux alc888_acer_aspire_6530_sources[2] = { 1904 /* Interal mic only available on one ADC */ 1905 { 1906 .num_items = 5, 1907 .items = { 1908 { "Ext Mic", 0x0 }, 1909 { "Line In", 0x2 }, 1910 { "CD", 0x4 }, 1911 { "Input Mix", 0xa }, 1912 { "Int Mic", 0xb }, 1913 }, 1914 }, 1915 { 1916 .num_items = 4, 1917 .items = { 1918 { "Ext Mic", 0x0 }, 1919 { "Line In", 0x2 }, 1920 { "CD", 0x4 }, 1921 { "Input Mix", 0xa }, 1922 }, 1923 } 1924}; 1925 1926static struct hda_input_mux alc889_capture_sources[3] = { 1927 /* Digital mic only available on first "ADC" */ 1928 { 1929 .num_items = 5, 1930 .items = { 1931 { "Mic", 0x0 }, 1932 { "Line", 0x2 }, 1933 { "CD", 0x4 }, 1934 { "Front Mic", 0xb }, 1935 { "Input Mix", 0xa }, 1936 }, 1937 }, 1938 { 1939 .num_items = 4, 1940 .items = { 1941 { "Mic", 0x0 }, 1942 { "Line", 0x2 }, 1943 { "CD", 0x4 }, 1944 { "Input Mix", 0xa }, 1945 }, 1946 }, 1947 { 1948 .num_items = 4, 1949 .items = { 1950 { "Mic", 0x0 }, 1951 { "Line", 0x2 }, 1952 { "CD", 0x4 }, 1953 { "Input Mix", 0xa }, 1954 }, 1955 } 1956}; 1957 1958static struct snd_kcontrol_new alc888_base_mixer[] = { 1959 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 1960 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 1961 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 1962 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 1963 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, 1964 HDA_OUTPUT), 1965 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 1966 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 1967 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 1968 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 1969 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 1970 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 1971 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 1972 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 1973 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 1974 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 1975 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 1976 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 1977 { } /* end */ 1978}; 1979 1980static struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = { 1981 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 1982 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 1983 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 1984 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 1985 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, 1986 HDA_OUTPUT), 1987 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 1988 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 1989 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 1990 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 1991 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 1992 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 1993 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 1994 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 1995 { } /* end */ 1996}; 1997 1998 1999static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec) 2000{ 2001 struct alc_spec *spec = codec->spec; 2002 2003 spec->autocfg.hp_pins[0] = 0x15; 2004 spec->autocfg.speaker_pins[0] = 0x14; 2005 spec->autocfg.speaker_pins[1] = 0x16; 2006 spec->autocfg.speaker_pins[2] = 0x17; 2007} 2008 2009static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec) 2010{ 2011 struct alc_spec *spec = codec->spec; 2012 2013 spec->autocfg.hp_pins[0] = 0x15; 2014 spec->autocfg.speaker_pins[0] = 0x14; 2015 spec->autocfg.speaker_pins[1] = 0x16; 2016 spec->autocfg.speaker_pins[2] = 0x17; 2017} 2018 2019static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec) 2020{ 2021 struct alc_spec *spec = codec->spec; 2022 2023 spec->autocfg.hp_pins[0] = 0x15; 2024 spec->autocfg.speaker_pins[0] = 0x14; 2025 spec->autocfg.speaker_pins[1] = 0x16; 2026 spec->autocfg.speaker_pins[2] = 0x1b; 2027} 2028 2029/* 2030 * ALC880 3-stack model 2031 * 2032 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e) 2033 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18, 2034 * F-Mic = 0x1b, HP = 0x19 2035 */ 2036 2037static hda_nid_t alc880_dac_nids[4] = { 2038 /* front, rear, clfe, rear_surr */ 2039 0x02, 0x05, 0x04, 0x03 2040}; 2041 2042static hda_nid_t alc880_adc_nids[3] = { 2043 /* ADC0-2 */ 2044 0x07, 0x08, 0x09, 2045}; 2046 2047/* The datasheet says the node 0x07 is connected from inputs, 2048 * but it shows zero connection in the real implementation on some devices. 2049 * Note: this is a 915GAV bug, fixed on 915GLV 2050 */ 2051static hda_nid_t alc880_adc_nids_alt[2] = { 2052 /* ADC1-2 */ 2053 0x08, 0x09, 2054}; 2055 2056#define ALC880_DIGOUT_NID 0x06 2057#define ALC880_DIGIN_NID 0x0a 2058 2059static struct hda_input_mux alc880_capture_source = { 2060 .num_items = 4, 2061 .items = { 2062 { "Mic", 0x0 }, 2063 { "Front Mic", 0x3 }, 2064 { "Line", 0x2 }, 2065 { "CD", 0x4 }, 2066 }, 2067}; 2068 2069/* channel source setting (2/6 channel selection for 3-stack) */ 2070/* 2ch mode */ 2071static struct hda_verb alc880_threestack_ch2_init[] = { 2072 /* set line-in to input, mute it */ 2073 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 2074 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 2075 /* set mic-in to input vref 80%, mute it */ 2076 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 2077 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 2078 { } /* end */ 2079}; 2080 2081/* 6ch mode */ 2082static struct hda_verb alc880_threestack_ch6_init[] = { 2083 /* set line-in to output, unmute it */ 2084 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 2085 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 2086 /* set mic-in to output, unmute it */ 2087 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 2088 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 2089 { } /* end */ 2090}; 2091 2092static struct hda_channel_mode alc880_threestack_modes[2] = { 2093 { 2, alc880_threestack_ch2_init }, 2094 { 6, alc880_threestack_ch6_init }, 2095}; 2096 2097static struct snd_kcontrol_new alc880_three_stack_mixer[] = { 2098 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2099 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 2100 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 2101 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT), 2102 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 2103 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 2104 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 2105 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 2106 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 2107 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 2108 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 2109 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 2110 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 2111 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 2112 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT), 2113 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT), 2114 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT), 2115 { 2116 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2117 .name = "Channel Mode", 2118 .info = alc_ch_mode_info, 2119 .get = alc_ch_mode_get, 2120 .put = alc_ch_mode_put, 2121 }, 2122 { } /* end */ 2123}; 2124 2125/* capture mixer elements */ 2126static int alc_cap_vol_info(struct snd_kcontrol *kcontrol, 2127 struct snd_ctl_elem_info *uinfo) 2128{ 2129 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2130 struct alc_spec *spec = codec->spec; 2131 int err; 2132 2133 mutex_lock(&codec->control_mutex); 2134 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0, 2135 HDA_INPUT); 2136 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo); 2137 mutex_unlock(&codec->control_mutex); 2138 return err; 2139} 2140 2141static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag, 2142 unsigned int size, unsigned int __user *tlv) 2143{ 2144 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2145 struct alc_spec *spec = codec->spec; 2146 int err; 2147 2148 mutex_lock(&codec->control_mutex); 2149 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0, 2150 HDA_INPUT); 2151 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv); 2152 mutex_unlock(&codec->control_mutex); 2153 return err; 2154} 2155 2156typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol, 2157 struct snd_ctl_elem_value *ucontrol); 2158 2159static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol, 2160 struct snd_ctl_elem_value *ucontrol, 2161 getput_call_t func) 2162{ 2163 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2164 struct alc_spec *spec = codec->spec; 2165 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 2166 int err; 2167 2168 mutex_lock(&codec->control_mutex); 2169 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx], 2170 3, 0, HDA_INPUT); 2171 err = func(kcontrol, ucontrol); 2172 mutex_unlock(&codec->control_mutex); 2173 return err; 2174} 2175 2176static int alc_cap_vol_get(struct snd_kcontrol *kcontrol, 2177 struct snd_ctl_elem_value *ucontrol) 2178{ 2179 return alc_cap_getput_caller(kcontrol, ucontrol, 2180 snd_hda_mixer_amp_volume_get); 2181} 2182 2183static int alc_cap_vol_put(struct snd_kcontrol *kcontrol, 2184 struct snd_ctl_elem_value *ucontrol) 2185{ 2186 return alc_cap_getput_caller(kcontrol, ucontrol, 2187 snd_hda_mixer_amp_volume_put); 2188} 2189 2190/* capture mixer elements */ 2191#define alc_cap_sw_info snd_ctl_boolean_stereo_info 2192 2193static int alc_cap_sw_get(struct snd_kcontrol *kcontrol, 2194 struct snd_ctl_elem_value *ucontrol) 2195{ 2196 return alc_cap_getput_caller(kcontrol, ucontrol, 2197 snd_hda_mixer_amp_switch_get); 2198} 2199 2200static int alc_cap_sw_put(struct snd_kcontrol *kcontrol, 2201 struct snd_ctl_elem_value *ucontrol) 2202{ 2203 return alc_cap_getput_caller(kcontrol, ucontrol, 2204 snd_hda_mixer_amp_switch_put); 2205} 2206 2207#define _DEFINE_CAPMIX(num) \ 2208 { \ 2209 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 2210 .name = "Capture Switch", \ 2211 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \ 2212 .count = num, \ 2213 .info = alc_cap_sw_info, \ 2214 .get = alc_cap_sw_get, \ 2215 .put = alc_cap_sw_put, \ 2216 }, \ 2217 { \ 2218 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 2219 .name = "Capture Volume", \ 2220 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \ 2221 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \ 2222 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \ 2223 .count = num, \ 2224 .info = alc_cap_vol_info, \ 2225 .get = alc_cap_vol_get, \ 2226 .put = alc_cap_vol_put, \ 2227 .tlv = { .c = alc_cap_vol_tlv }, \ 2228 } 2229 2230#define _DEFINE_CAPSRC(num) \ 2231 { \ 2232 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 2233 /* .name = "Capture Source", */ \ 2234 .name = "Input Source", \ 2235 .count = num, \ 2236 .info = alc_mux_enum_info, \ 2237 .get = alc_mux_enum_get, \ 2238 .put = alc_mux_enum_put, \ 2239 } 2240 2241#define DEFINE_CAPMIX(num) \ 2242static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \ 2243 _DEFINE_CAPMIX(num), \ 2244 _DEFINE_CAPSRC(num), \ 2245 { } /* end */ \ 2246} 2247 2248#define DEFINE_CAPMIX_NOSRC(num) \ 2249static struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \ 2250 _DEFINE_CAPMIX(num), \ 2251 { } /* end */ \ 2252} 2253 2254/* up to three ADCs */ 2255DEFINE_CAPMIX(1); 2256DEFINE_CAPMIX(2); 2257DEFINE_CAPMIX(3); 2258DEFINE_CAPMIX_NOSRC(1); 2259DEFINE_CAPMIX_NOSRC(2); 2260DEFINE_CAPMIX_NOSRC(3); 2261 2262/* 2263 * ALC880 5-stack model 2264 * 2265 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d), 2266 * Side = 0x02 (0xd) 2267 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16 2268 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19 2269 */ 2270 2271/* additional mixers to alc880_three_stack_mixer */ 2272static struct snd_kcontrol_new alc880_five_stack_mixer[] = { 2273 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2274 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT), 2275 { } /* end */ 2276}; 2277 2278/* channel source setting (6/8 channel selection for 5-stack) */ 2279/* 6ch mode */ 2280static struct hda_verb alc880_fivestack_ch6_init[] = { 2281 /* set line-in to input, mute it */ 2282 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 2283 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 2284 { } /* end */ 2285}; 2286 2287/* 8ch mode */ 2288static struct hda_verb alc880_fivestack_ch8_init[] = { 2289 /* set line-in to output, unmute it */ 2290 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 2291 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 2292 { } /* end */ 2293}; 2294 2295static struct hda_channel_mode alc880_fivestack_modes[2] = { 2296 { 6, alc880_fivestack_ch6_init }, 2297 { 8, alc880_fivestack_ch8_init }, 2298}; 2299 2300 2301/* 2302 * ALC880 6-stack model 2303 * 2304 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e), 2305 * Side = 0x05 (0x0f) 2306 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17, 2307 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b 2308 */ 2309 2310static hda_nid_t alc880_6st_dac_nids[4] = { 2311 /* front, rear, clfe, rear_surr */ 2312 0x02, 0x03, 0x04, 0x05 2313}; 2314 2315static struct hda_input_mux alc880_6stack_capture_source = { 2316 .num_items = 4, 2317 .items = { 2318 { "Mic", 0x0 }, 2319 { "Front Mic", 0x1 }, 2320 { "Line", 0x2 }, 2321 { "CD", 0x4 }, 2322 }, 2323}; 2324 2325/* fixed 8-channels */ 2326static struct hda_channel_mode alc880_sixstack_modes[1] = { 2327 { 8, NULL }, 2328}; 2329 2330static struct snd_kcontrol_new alc880_six_stack_mixer[] = { 2331 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2332 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 2333 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2334 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 2335 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 2336 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 2337 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 2338 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 2339 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 2340 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 2341 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 2342 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 2343 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 2344 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 2345 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 2346 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 2347 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 2348 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 2349 { 2350 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2351 .name = "Channel Mode", 2352 .info = alc_ch_mode_info, 2353 .get = alc_ch_mode_get, 2354 .put = alc_ch_mode_put, 2355 }, 2356 { } /* end */ 2357}; 2358 2359 2360/* 2361 * ALC880 W810 model 2362 * 2363 * W810 has rear IO for: 2364 * Front (DAC 02) 2365 * Surround (DAC 03) 2366 * Center/LFE (DAC 04) 2367 * Digital out (06) 2368 * 2369 * The system also has a pair of internal speakers, and a headphone jack. 2370 * These are both connected to Line2 on the codec, hence to DAC 02. 2371 * 2372 * There is a variable resistor to control the speaker or headphone 2373 * volume. This is a hardware-only device without a software API. 2374 * 2375 * Plugging headphones in will disable the internal speakers. This is 2376 * implemented in hardware, not via the driver using jack sense. In 2377 * a similar fashion, plugging into the rear socket marked "front" will 2378 * disable both the speakers and headphones. 2379 * 2380 * For input, there's a microphone jack, and an "audio in" jack. 2381 * These may not do anything useful with this driver yet, because I 2382 * haven't setup any initialization verbs for these yet... 2383 */ 2384 2385static hda_nid_t alc880_w810_dac_nids[3] = { 2386 /* front, rear/surround, clfe */ 2387 0x02, 0x03, 0x04 2388}; 2389 2390/* fixed 6 channels */ 2391static struct hda_channel_mode alc880_w810_modes[1] = { 2392 { 6, NULL } 2393}; 2394 2395/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */ 2396static struct snd_kcontrol_new alc880_w810_base_mixer[] = { 2397 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2398 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 2399 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2400 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 2401 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 2402 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 2403 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 2404 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 2405 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 2406 { } /* end */ 2407}; 2408 2409 2410/* 2411 * Z710V model 2412 * 2413 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d) 2414 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?), 2415 * Line = 0x1a 2416 */ 2417 2418static hda_nid_t alc880_z71v_dac_nids[1] = { 2419 0x02 2420}; 2421#define ALC880_Z71V_HP_DAC 0x03 2422 2423/* fixed 2 channels */ 2424static struct hda_channel_mode alc880_2_jack_modes[1] = { 2425 { 2, NULL } 2426}; 2427 2428static struct snd_kcontrol_new alc880_z71v_mixer[] = { 2429 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2430 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 2431 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2432 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT), 2433 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 2434 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 2435 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 2436 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 2437 { } /* end */ 2438}; 2439 2440 2441/* 2442 * ALC880 F1734 model 2443 * 2444 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d) 2445 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18 2446 */ 2447 2448static hda_nid_t alc880_f1734_dac_nids[1] = { 2449 0x03 2450}; 2451#define ALC880_F1734_HP_DAC 0x02 2452 2453static struct snd_kcontrol_new alc880_f1734_mixer[] = { 2454 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2455 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), 2456 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2457 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 2458 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 2459 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 2460 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 2461 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 2462 { } /* end */ 2463}; 2464 2465static struct hda_input_mux alc880_f1734_capture_source = { 2466 .num_items = 2, 2467 .items = { 2468 { "Mic", 0x1 }, 2469 { "CD", 0x4 }, 2470 }, 2471}; 2472 2473 2474/* 2475 * ALC880 ASUS model 2476 * 2477 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e) 2478 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16, 2479 * Mic = 0x18, Line = 0x1a 2480 */ 2481 2482#define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */ 2483#define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */ 2484 2485static struct snd_kcontrol_new alc880_asus_mixer[] = { 2486 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2487 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 2488 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2489 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 2490 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 2491 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 2492 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 2493 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 2494 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 2495 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 2496 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 2497 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 2498 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 2499 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 2500 { 2501 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2502 .name = "Channel Mode", 2503 .info = alc_ch_mode_info, 2504 .get = alc_ch_mode_get, 2505 .put = alc_ch_mode_put, 2506 }, 2507 { } /* end */ 2508}; 2509 2510/* 2511 * ALC880 ASUS W1V model 2512 * 2513 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e) 2514 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16, 2515 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b 2516 */ 2517 2518/* additional mixers to alc880_asus_mixer */ 2519static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = { 2520 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT), 2521 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT), 2522 { } /* end */ 2523}; 2524 2525/* TCL S700 */ 2526static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = { 2527 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2528 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 2529 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 2530 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT), 2531 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT), 2532 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT), 2533 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT), 2534 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 2535 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 2536 { } /* end */ 2537}; 2538 2539/* Uniwill */ 2540static struct snd_kcontrol_new alc880_uniwill_mixer[] = { 2541 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2542 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), 2543 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2544 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 2545 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 2546 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 2547 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 2548 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 2549 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 2550 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 2551 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 2552 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 2553 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 2554 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 2555 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 2556 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 2557 { 2558 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2559 .name = "Channel Mode", 2560 .info = alc_ch_mode_info, 2561 .get = alc_ch_mode_get, 2562 .put = alc_ch_mode_put, 2563 }, 2564 { } /* end */ 2565}; 2566 2567static struct snd_kcontrol_new alc880_fujitsu_mixer[] = { 2568 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2569 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), 2570 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2571 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 2572 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 2573 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 2574 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 2575 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 2576 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 2577 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 2578 { } /* end */ 2579}; 2580 2581static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = { 2582 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2583 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), 2584 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2585 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 2586 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 2587 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 2588 { } /* end */ 2589}; 2590 2591/* 2592 * virtual master controls 2593 */ 2594 2595/* 2596 * slave controls for virtual master 2597 */ 2598static const char *alc_slave_vols[] = { 2599 "Front Playback Volume", 2600 "Surround Playback Volume", 2601 "Center Playback Volume", 2602 "LFE Playback Volume", 2603 "Side Playback Volume", 2604 "Headphone Playback Volume", 2605 "Speaker Playback Volume", 2606 "Mono Playback Volume", 2607 "Line-Out Playback Volume", 2608 "PCM Playback Volume", 2609 NULL, 2610}; 2611 2612static const char *alc_slave_sws[] = { 2613 "Front Playback Switch", 2614 "Surround Playback Switch", 2615 "Center Playback Switch", 2616 "LFE Playback Switch", 2617 "Side Playback Switch", 2618 "Headphone Playback Switch", 2619 "Speaker Playback Switch", 2620 "Mono Playback Switch", 2621 "IEC958 Playback Switch", 2622 "Line-Out Playback Switch", 2623 "PCM Playback Switch", 2624 NULL, 2625}; 2626 2627/* 2628 * build control elements 2629 */ 2630 2631#define NID_MAPPING (-1) 2632 2633#define SUBDEV_SPEAKER_ (0 << 6) 2634#define SUBDEV_HP_ (1 << 6) 2635#define SUBDEV_LINE_ (2 << 6) 2636#define SUBDEV_SPEAKER(x) (SUBDEV_SPEAKER_ | ((x) & 0x3f)) 2637#define SUBDEV_HP(x) (SUBDEV_HP_ | ((x) & 0x3f)) 2638#define SUBDEV_LINE(x) (SUBDEV_LINE_ | ((x) & 0x3f)) 2639 2640static void alc_free_kctls(struct hda_codec *codec); 2641 2642#ifdef CONFIG_SND_HDA_INPUT_BEEP 2643/* additional beep mixers; the actual parameters are overwritten at build */ 2644static struct snd_kcontrol_new alc_beep_mixer[] = { 2645 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT), 2646 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT), 2647 { } /* end */ 2648}; 2649#endif 2650 2651static int alc_build_controls(struct hda_codec *codec) 2652{ 2653 struct alc_spec *spec = codec->spec; 2654 struct snd_kcontrol *kctl = NULL; 2655 struct snd_kcontrol_new *knew; 2656 int i, j, err; 2657 unsigned int u; 2658 hda_nid_t nid; 2659 2660 for (i = 0; i < spec->num_mixers; i++) { 2661 err = snd_hda_add_new_ctls(codec, spec->mixers[i]); 2662 if (err < 0) 2663 return err; 2664 } 2665 if (spec->cap_mixer) { 2666 err = snd_hda_add_new_ctls(codec, spec->cap_mixer); 2667 if (err < 0) 2668 return err; 2669 } 2670 if (spec->multiout.dig_out_nid) { 2671 err = snd_hda_create_spdif_out_ctls(codec, 2672 spec->multiout.dig_out_nid); 2673 if (err < 0) 2674 return err; 2675 if (!spec->no_analog) { 2676 err = snd_hda_create_spdif_share_sw(codec, 2677 &spec->multiout); 2678 if (err < 0) 2679 return err; 2680 spec->multiout.share_spdif = 1; 2681 } 2682 } 2683 if (spec->dig_in_nid) { 2684 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid); 2685 if (err < 0) 2686 return err; 2687 } 2688 2689#ifdef CONFIG_SND_HDA_INPUT_BEEP 2690 /* create beep controls if needed */ 2691 if (spec->beep_amp) { 2692 struct snd_kcontrol_new *knew; 2693 for (knew = alc_beep_mixer; knew->name; knew++) { 2694 struct snd_kcontrol *kctl; 2695 kctl = snd_ctl_new1(knew, codec); 2696 if (!kctl) 2697 return -ENOMEM; 2698 kctl->private_value = spec->beep_amp; 2699 err = snd_hda_ctl_add(codec, 0, kctl); 2700 if (err < 0) 2701 return err; 2702 } 2703 } 2704#endif 2705 2706 /* if we have no master control, let's create it */ 2707 if (!spec->no_analog && 2708 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) { 2709 unsigned int vmaster_tlv[4]; 2710 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid, 2711 HDA_OUTPUT, vmaster_tlv); 2712 err = snd_hda_add_vmaster(codec, "Master Playback Volume", 2713 vmaster_tlv, alc_slave_vols); 2714 if (err < 0) 2715 return err; 2716 } 2717 if (!spec->no_analog && 2718 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) { 2719 err = snd_hda_add_vmaster(codec, "Master Playback Switch", 2720 NULL, alc_slave_sws); 2721 if (err < 0) 2722 return err; 2723 } 2724 2725 /* assign Capture Source enums to NID */ 2726 if (spec->capsrc_nids || spec->adc_nids) { 2727 kctl = snd_hda_find_mixer_ctl(codec, "Capture Source"); 2728 if (!kctl) 2729 kctl = snd_hda_find_mixer_ctl(codec, "Input Source"); 2730 for (i = 0; kctl && i < kctl->count; i++) { 2731 hda_nid_t *nids = spec->capsrc_nids; 2732 if (!nids) 2733 nids = spec->adc_nids; 2734 err = snd_hda_add_nid(codec, kctl, i, nids[i]); 2735 if (err < 0) 2736 return err; 2737 } 2738 } 2739 if (spec->cap_mixer) { 2740 const char *kname = kctl ? kctl->id.name : NULL; 2741 for (knew = spec->cap_mixer; knew->name; knew++) { 2742 if (kname && strcmp(knew->name, kname) == 0) 2743 continue; 2744 kctl = snd_hda_find_mixer_ctl(codec, knew->name); 2745 for (i = 0; kctl && i < kctl->count; i++) { 2746 err = snd_hda_add_nid(codec, kctl, i, 2747 spec->adc_nids[i]); 2748 if (err < 0) 2749 return err; 2750 } 2751 } 2752 } 2753 2754 /* other nid->control mapping */ 2755 for (i = 0; i < spec->num_mixers; i++) { 2756 for (knew = spec->mixers[i]; knew->name; knew++) { 2757 if (knew->iface != NID_MAPPING) 2758 continue; 2759 kctl = snd_hda_find_mixer_ctl(codec, knew->name); 2760 if (kctl == NULL) 2761 continue; 2762 u = knew->subdevice; 2763 for (j = 0; j < 4; j++, u >>= 8) { 2764 nid = u & 0x3f; 2765 if (nid == 0) 2766 continue; 2767 switch (u & 0xc0) { 2768 case SUBDEV_SPEAKER_: 2769 nid = spec->autocfg.speaker_pins[nid]; 2770 break; 2771 case SUBDEV_LINE_: 2772 nid = spec->autocfg.line_out_pins[nid]; 2773 break; 2774 case SUBDEV_HP_: 2775 nid = spec->autocfg.hp_pins[nid]; 2776 break; 2777 default: 2778 continue; 2779 } 2780 err = snd_hda_add_nid(codec, kctl, 0, nid); 2781 if (err < 0) 2782 return err; 2783 } 2784 u = knew->private_value; 2785 for (j = 0; j < 4; j++, u >>= 8) { 2786 nid = u & 0xff; 2787 if (nid == 0) 2788 continue; 2789 err = snd_hda_add_nid(codec, kctl, 0, nid); 2790 if (err < 0) 2791 return err; 2792 } 2793 } 2794 } 2795 2796 alc_free_kctls(codec); /* no longer needed */ 2797 2798 return 0; 2799} 2800 2801 2802/* 2803 * initialize the codec volumes, etc 2804 */ 2805 2806/* 2807 * generic initialization of ADC, input mixers and output mixers 2808 */ 2809static struct hda_verb alc880_volume_init_verbs[] = { 2810 /* 2811 * Unmute ADC0-2 and set the default input to mic-in 2812 */ 2813 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 2814 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 2815 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 2816 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 2817 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 2818 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 2819 2820 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 2821 * mixer widget 2822 * Note: PASD motherboards uses the Line In 2 as the input for front 2823 * panel mic (mic 2) 2824 */ 2825 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 2826 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 2827 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 2828 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 2829 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 2830 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 2831 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, 2832 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, 2833 2834 /* 2835 * Set up output mixers (0x0c - 0x0f) 2836 */ 2837 /* set vol=0 to output mixers */ 2838 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 2839 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 2840 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 2841 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 2842 /* set up input amps for analog loopback */ 2843 /* Amp Indices: DAC = 0, mixer = 1 */ 2844 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 2845 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 2846 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 2847 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 2848 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 2849 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 2850 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 2851 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 2852 2853 { } 2854}; 2855 2856/* 2857 * 3-stack pin configuration: 2858 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b 2859 */ 2860static struct hda_verb alc880_pin_3stack_init_verbs[] = { 2861 /* 2862 * preset connection lists of input pins 2863 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround 2864 */ 2865 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ 2866 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 2867 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */ 2868 2869 /* 2870 * Set pin mode and muting 2871 */ 2872 /* set front pin widgets 0x14 for output */ 2873 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2874 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2875 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 2876 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2877 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2878 /* Mic2 (as headphone out) for HP output */ 2879 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 2880 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2881 /* Line In pin widget for input */ 2882 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2883 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2884 /* Line2 (as front mic) pin widget for input and vref at 80% */ 2885 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2886 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2887 /* CD pin widget for input */ 2888 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2889 2890 { } 2891}; 2892 2893/* 2894 * 5-stack pin configuration: 2895 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19, 2896 * line-in/side = 0x1a, f-mic = 0x1b 2897 */ 2898static struct hda_verb alc880_pin_5stack_init_verbs[] = { 2899 /* 2900 * preset connection lists of input pins 2901 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround 2902 */ 2903 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 2904 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */ 2905 2906 /* 2907 * Set pin mode and muting 2908 */ 2909 /* set pin widgets 0x14-0x17 for output */ 2910 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2911 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2912 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2913 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2914 /* unmute pins for output (no gain on this amp) */ 2915 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2916 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2917 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2918 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2919 2920 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 2921 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2922 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2923 /* Mic2 (as headphone out) for HP output */ 2924 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 2925 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2926 /* Line In pin widget for input */ 2927 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2928 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2929 /* Line2 (as front mic) pin widget for input and vref at 80% */ 2930 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2931 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2932 /* CD pin widget for input */ 2933 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2934 2935 { } 2936}; 2937 2938/* 2939 * W810 pin configuration: 2940 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b 2941 */ 2942static struct hda_verb alc880_pin_w810_init_verbs[] = { 2943 /* hphone/speaker input selector: front DAC */ 2944 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0}, 2945 2946 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2947 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2948 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2949 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2950 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2951 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2952 2953 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 2954 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2955 2956 { } 2957}; 2958 2959/* 2960 * Z71V pin configuration: 2961 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?) 2962 */ 2963static struct hda_verb alc880_pin_z71v_init_verbs[] = { 2964 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2965 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2966 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 2967 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2968 2969 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2970 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2971 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2972 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2973 2974 { } 2975}; 2976 2977/* 2978 * 6-stack pin configuration: 2979 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18, 2980 * f-mic = 0x19, line = 0x1a, HP = 0x1b 2981 */ 2982static struct hda_verb alc880_pin_6stack_init_verbs[] = { 2983 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 2984 2985 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2986 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2987 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2988 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2989 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2990 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2991 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2992 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2993 2994 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2995 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2996 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2997 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2998 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2999 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3000 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3001 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3002 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3003 3004 { } 3005}; 3006 3007/* 3008 * Uniwill pin configuration: 3009 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19, 3010 * line = 0x1a 3011 */ 3012static struct hda_verb alc880_uniwill_init_verbs[] = { 3013 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 3014 3015 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3016 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3017 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3018 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3019 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3020 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3021 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3022 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3023 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 3024 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 3025 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 3026 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 3027 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 3028 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 3029 3030 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3031 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3032 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3033 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3034 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3035 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3036 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */ 3037 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */ 3038 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3039 3040 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 3041 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 3042 3043 { } 3044}; 3045 3046/* 3047* Uniwill P53 3048* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19, 3049 */ 3050static struct hda_verb alc880_uniwill_p53_init_verbs[] = { 3051 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 3052 3053 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3054 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3055 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3056 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3057 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3058 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3059 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 3060 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 3061 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 3062 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 3063 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 3064 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 3065 3066 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3067 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3068 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3069 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3070 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3071 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3072 3073 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 3074 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT}, 3075 3076 { } 3077}; 3078 3079static struct hda_verb alc880_beep_init_verbs[] = { 3080 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) }, 3081 { } 3082}; 3083 3084/* auto-toggle front mic */ 3085static void alc880_uniwill_mic_automute(struct hda_codec *codec) 3086{ 3087 unsigned int present; 3088 unsigned char bits; 3089 3090 present = snd_hda_jack_detect(codec, 0x18); 3091 bits = present ? HDA_AMP_MUTE : 0; 3092 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits); 3093} 3094 3095static void alc880_uniwill_setup(struct hda_codec *codec) 3096{ 3097 struct alc_spec *spec = codec->spec; 3098 3099 spec->autocfg.hp_pins[0] = 0x14; 3100 spec->autocfg.speaker_pins[0] = 0x15; 3101 spec->autocfg.speaker_pins[0] = 0x16; 3102} 3103 3104static void alc880_uniwill_init_hook(struct hda_codec *codec) 3105{ 3106 alc_automute_amp(codec); 3107 alc880_uniwill_mic_automute(codec); 3108} 3109 3110static void alc880_uniwill_unsol_event(struct hda_codec *codec, 3111 unsigned int res) 3112{ 3113 /* Looks like the unsol event is incompatible with the standard 3114 * definition. 4bit tag is placed at 28 bit! 3115 */ 3116 switch (res >> 28) { 3117 case ALC880_MIC_EVENT: 3118 alc880_uniwill_mic_automute(codec); 3119 break; 3120 default: 3121 alc_automute_amp_unsol_event(codec, res); 3122 break; 3123 } 3124} 3125 3126static void alc880_uniwill_p53_setup(struct hda_codec *codec) 3127{ 3128 struct alc_spec *spec = codec->spec; 3129 3130 spec->autocfg.hp_pins[0] = 0x14; 3131 spec->autocfg.speaker_pins[0] = 0x15; 3132} 3133 3134static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec) 3135{ 3136 unsigned int present; 3137 3138 present = snd_hda_codec_read(codec, 0x21, 0, 3139 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0); 3140 present &= HDA_AMP_VOLMASK; 3141 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0, 3142 HDA_AMP_VOLMASK, present); 3143 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0, 3144 HDA_AMP_VOLMASK, present); 3145} 3146 3147static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec, 3148 unsigned int res) 3149{ 3150 /* Looks like the unsol event is incompatible with the standard 3151 * definition. 4bit tag is placed at 28 bit! 3152 */ 3153 if ((res >> 28) == ALC880_DCVOL_EVENT) 3154 alc880_uniwill_p53_dcvol_automute(codec); 3155 else 3156 alc_automute_amp_unsol_event(codec, res); 3157} 3158 3159/* 3160 * F1734 pin configuration: 3161 * HP = 0x14, speaker-out = 0x15, mic = 0x18 3162 */ 3163static struct hda_verb alc880_pin_f1734_init_verbs[] = { 3164 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01}, 3165 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, 3166 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, 3167 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, 3168 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, 3169 3170 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3171 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3172 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3173 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3174 3175 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3176 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3177 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, 3178 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3179 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3180 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3181 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3182 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3183 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3184 3185 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT}, 3186 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT}, 3187 3188 { } 3189}; 3190 3191/* 3192 * ASUS pin configuration: 3193 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a 3194 */ 3195static struct hda_verb alc880_pin_asus_init_verbs[] = { 3196 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, 3197 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, 3198 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, 3199 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, 3200 3201 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3202 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3203 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3204 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3205 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3206 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3207 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3208 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3209 3210 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3211 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3212 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3213 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3214 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3215 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3216 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3217 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3218 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3219 3220 { } 3221}; 3222 3223/* Enable GPIO mask and set output */ 3224#define alc880_gpio1_init_verbs alc_gpio1_init_verbs 3225#define alc880_gpio2_init_verbs alc_gpio2_init_verbs 3226#define alc880_gpio3_init_verbs alc_gpio3_init_verbs 3227 3228/* Clevo m520g init */ 3229static struct hda_verb alc880_pin_clevo_init_verbs[] = { 3230 /* headphone output */ 3231 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01}, 3232 /* line-out */ 3233 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3234 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3235 /* Line-in */ 3236 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3237 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3238 /* CD */ 3239 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3240 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3241 /* Mic1 (rear panel) */ 3242 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3243 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3244 /* Mic2 (front panel) */ 3245 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3246 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3247 /* headphone */ 3248 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3249 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3250 /* change to EAPD mode */ 3251 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 3252 {0x20, AC_VERB_SET_PROC_COEF, 0x3060}, 3253 3254 { } 3255}; 3256 3257static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = { 3258 /* change to EAPD mode */ 3259 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 3260 {0x20, AC_VERB_SET_PROC_COEF, 0x3060}, 3261 3262 /* Headphone output */ 3263 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3264 /* Front output*/ 3265 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3266 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 3267 3268 /* Line In pin widget for input */ 3269 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3270 /* CD pin widget for input */ 3271 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3272 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 3273 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3274 3275 /* change to EAPD mode */ 3276 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 3277 {0x20, AC_VERB_SET_PROC_COEF, 0x3070}, 3278 3279 { } 3280}; 3281 3282/* 3283 * LG m1 express dual 3284 * 3285 * Pin assignment: 3286 * Rear Line-In/Out (blue): 0x14 3287 * Build-in Mic-In: 0x15 3288 * Speaker-out: 0x17 3289 * HP-Out (green): 0x1b 3290 * Mic-In/Out (red): 0x19 3291 * SPDIF-Out: 0x1e 3292 */ 3293 3294/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */ 3295static hda_nid_t alc880_lg_dac_nids[3] = { 3296 0x05, 0x02, 0x03 3297}; 3298 3299/* seems analog CD is not working */ 3300static struct hda_input_mux alc880_lg_capture_source = { 3301 .num_items = 3, 3302 .items = { 3303 { "Mic", 0x1 }, 3304 { "Line", 0x5 }, 3305 { "Internal Mic", 0x6 }, 3306 }, 3307}; 3308 3309/* 2,4,6 channel modes */ 3310static struct hda_verb alc880_lg_ch2_init[] = { 3311 /* set line-in and mic-in to input */ 3312 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 3313 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 3314 { } 3315}; 3316 3317static struct hda_verb alc880_lg_ch4_init[] = { 3318 /* set line-in to out and mic-in to input */ 3319 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, 3320 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 3321 { } 3322}; 3323 3324static struct hda_verb alc880_lg_ch6_init[] = { 3325 /* set line-in and mic-in to output */ 3326 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, 3327 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, 3328 { } 3329}; 3330 3331static struct hda_channel_mode alc880_lg_ch_modes[3] = { 3332 { 2, alc880_lg_ch2_init }, 3333 { 4, alc880_lg_ch4_init }, 3334 { 6, alc880_lg_ch6_init }, 3335}; 3336 3337static struct snd_kcontrol_new alc880_lg_mixer[] = { 3338 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 3339 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT), 3340 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 3341 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT), 3342 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT), 3343 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT), 3344 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT), 3345 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT), 3346 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 3347 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 3348 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT), 3349 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT), 3350 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT), 3351 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT), 3352 { 3353 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 3354 .name = "Channel Mode", 3355 .info = alc_ch_mode_info, 3356 .get = alc_ch_mode_get, 3357 .put = alc_ch_mode_put, 3358 }, 3359 { } /* end */ 3360}; 3361 3362static struct hda_verb alc880_lg_init_verbs[] = { 3363 /* set capture source to mic-in */ 3364 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 3365 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 3366 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 3367 /* mute all amp mixer inputs */ 3368 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)}, 3369 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, 3370 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, 3371 /* line-in to input */ 3372 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3373 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3374 /* built-in mic */ 3375 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3376 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3377 /* speaker-out */ 3378 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3379 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3380 /* mic-in to input */ 3381 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01}, 3382 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3383 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3384 /* HP-out */ 3385 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03}, 3386 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3387 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3388 /* jack sense */ 3389 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 3390 { } 3391}; 3392 3393/* toggle speaker-output according to the hp-jack state */ 3394static void alc880_lg_setup(struct hda_codec *codec) 3395{ 3396 struct alc_spec *spec = codec->spec; 3397 3398 spec->autocfg.hp_pins[0] = 0x1b; 3399 spec->autocfg.speaker_pins[0] = 0x17; 3400} 3401 3402/* 3403 * LG LW20 3404 * 3405 * Pin assignment: 3406 * Speaker-out: 0x14 3407 * Mic-In: 0x18 3408 * Built-in Mic-In: 0x19 3409 * Line-In: 0x1b 3410 * HP-Out: 0x1a 3411 * SPDIF-Out: 0x1e 3412 */ 3413 3414static struct hda_input_mux alc880_lg_lw_capture_source = { 3415 .num_items = 3, 3416 .items = { 3417 { "Mic", 0x0 }, 3418 { "Internal Mic", 0x1 }, 3419 { "Line In", 0x2 }, 3420 }, 3421}; 3422 3423#define alc880_lg_lw_modes alc880_threestack_modes 3424 3425static struct snd_kcontrol_new alc880_lg_lw_mixer[] = { 3426 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 3427 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 3428 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 3429 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT), 3430 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 3431 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 3432 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 3433 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 3434 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 3435 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 3436 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 3437 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 3438 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 3439 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 3440 { 3441 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 3442 .name = "Channel Mode", 3443 .info = alc_ch_mode_info, 3444 .get = alc_ch_mode_get, 3445 .put = alc_ch_mode_put, 3446 }, 3447 { } /* end */ 3448}; 3449 3450static struct hda_verb alc880_lg_lw_init_verbs[] = { 3451 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 3452 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ 3453 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */ 3454 3455 /* set capture source to mic-in */ 3456 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3457 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3458 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3459 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, 3460 /* speaker-out */ 3461 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3462 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3463 /* HP-out */ 3464 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3465 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3466 /* mic-in to input */ 3467 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3468 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3469 /* built-in mic */ 3470 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3471 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3472 /* jack sense */ 3473 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 3474 { } 3475}; 3476 3477/* toggle speaker-output according to the hp-jack state */ 3478static void alc880_lg_lw_setup(struct hda_codec *codec) 3479{ 3480 struct alc_spec *spec = codec->spec; 3481 3482 spec->autocfg.hp_pins[0] = 0x1b; 3483 spec->autocfg.speaker_pins[0] = 0x14; 3484} 3485 3486static struct snd_kcontrol_new alc880_medion_rim_mixer[] = { 3487 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 3488 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT), 3489 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 3490 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 3491 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 3492 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT), 3493 { } /* end */ 3494}; 3495 3496static struct hda_input_mux alc880_medion_rim_capture_source = { 3497 .num_items = 2, 3498 .items = { 3499 { "Mic", 0x0 }, 3500 { "Internal Mic", 0x1 }, 3501 }, 3502}; 3503 3504static struct hda_verb alc880_medion_rim_init_verbs[] = { 3505 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 3506 3507 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3508 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3509 3510 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 3511 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3512 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3513 /* Mic2 (as headphone out) for HP output */ 3514 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3515 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3516 /* Internal Speaker */ 3517 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3518 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3519 3520 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 3521 {0x20, AC_VERB_SET_PROC_COEF, 0x3060}, 3522 3523 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 3524 { } 3525}; 3526 3527/* toggle speaker-output according to the hp-jack state */ 3528static void alc880_medion_rim_automute(struct hda_codec *codec) 3529{ 3530 struct alc_spec *spec = codec->spec; 3531 alc_automute_amp(codec); 3532 /* toggle EAPD */ 3533 if (spec->jack_present) 3534 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0); 3535 else 3536 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2); 3537} 3538 3539static void alc880_medion_rim_unsol_event(struct hda_codec *codec, 3540 unsigned int res) 3541{ 3542 /* Looks like the unsol event is incompatible with the standard 3543 * definition. 4bit tag is placed at 28 bit! 3544 */ 3545 if ((res >> 28) == ALC880_HP_EVENT) 3546 alc880_medion_rim_automute(codec); 3547} 3548 3549static void alc880_medion_rim_setup(struct hda_codec *codec) 3550{ 3551 struct alc_spec *spec = codec->spec; 3552 3553 spec->autocfg.hp_pins[0] = 0x14; 3554 spec->autocfg.speaker_pins[0] = 0x1b; 3555} 3556 3557#ifdef CONFIG_SND_HDA_POWER_SAVE 3558static struct hda_amp_list alc880_loopbacks[] = { 3559 { 0x0b, HDA_INPUT, 0 }, 3560 { 0x0b, HDA_INPUT, 1 }, 3561 { 0x0b, HDA_INPUT, 2 }, 3562 { 0x0b, HDA_INPUT, 3 }, 3563 { 0x0b, HDA_INPUT, 4 }, 3564 { } /* end */ 3565}; 3566 3567static struct hda_amp_list alc880_lg_loopbacks[] = { 3568 { 0x0b, HDA_INPUT, 1 }, 3569 { 0x0b, HDA_INPUT, 6 }, 3570 { 0x0b, HDA_INPUT, 7 }, 3571 { } /* end */ 3572}; 3573#endif 3574 3575/* 3576 * Common callbacks 3577 */ 3578 3579static int alc_init(struct hda_codec *codec) 3580{ 3581 struct alc_spec *spec = codec->spec; 3582 unsigned int i; 3583 3584 alc_fix_pll(codec); 3585 alc_auto_init_amp(codec, spec->init_amp); 3586 3587 for (i = 0; i < spec->num_init_verbs; i++) 3588 snd_hda_sequence_write(codec, spec->init_verbs[i]); 3589 3590 if (spec->init_hook) 3591 spec->init_hook(codec); 3592 3593#ifdef CONFIG_SND_HDA_POWER_SAVE 3594 if (codec->patch_ops.check_power_status) 3595 codec->patch_ops.check_power_status(codec, 0x01); 3596#endif 3597 return 0; 3598} 3599 3600static void alc_unsol_event(struct hda_codec *codec, unsigned int res) 3601{ 3602 struct alc_spec *spec = codec->spec; 3603 3604 if (spec->unsol_event) 3605 spec->unsol_event(codec, res); 3606} 3607 3608#ifdef CONFIG_SND_HDA_POWER_SAVE 3609static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid) 3610{ 3611 struct alc_spec *spec = codec->spec; 3612 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid); 3613} 3614#endif 3615 3616/* 3617 * Analog playback callbacks 3618 */ 3619static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo, 3620 struct hda_codec *codec, 3621 struct snd_pcm_substream *substream) 3622{ 3623 struct alc_spec *spec = codec->spec; 3624 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream, 3625 hinfo); 3626} 3627 3628static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo, 3629 struct hda_codec *codec, 3630 unsigned int stream_tag, 3631 unsigned int format, 3632 struct snd_pcm_substream *substream) 3633{ 3634 struct alc_spec *spec = codec->spec; 3635 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, 3636 stream_tag, format, substream); 3637} 3638 3639static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, 3640 struct hda_codec *codec, 3641 struct snd_pcm_substream *substream) 3642{ 3643 struct alc_spec *spec = codec->spec; 3644 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); 3645} 3646 3647/* 3648 * Digital out 3649 */ 3650static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo, 3651 struct hda_codec *codec, 3652 struct snd_pcm_substream *substream) 3653{ 3654 struct alc_spec *spec = codec->spec; 3655 return snd_hda_multi_out_dig_open(codec, &spec->multiout); 3656} 3657 3658static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, 3659 struct hda_codec *codec, 3660 unsigned int stream_tag, 3661 unsigned int format, 3662 struct snd_pcm_substream *substream) 3663{ 3664 struct alc_spec *spec = codec->spec; 3665 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, 3666 stream_tag, format, substream); 3667} 3668 3669static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, 3670 struct hda_codec *codec, 3671 struct snd_pcm_substream *substream) 3672{ 3673 struct alc_spec *spec = codec->spec; 3674 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout); 3675} 3676 3677static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, 3678 struct hda_codec *codec, 3679 struct snd_pcm_substream *substream) 3680{ 3681 struct alc_spec *spec = codec->spec; 3682 return snd_hda_multi_out_dig_close(codec, &spec->multiout); 3683} 3684 3685/* 3686 * Analog capture 3687 */ 3688static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo, 3689 struct hda_codec *codec, 3690 unsigned int stream_tag, 3691 unsigned int format, 3692 struct snd_pcm_substream *substream) 3693{ 3694 struct alc_spec *spec = codec->spec; 3695 3696 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1], 3697 stream_tag, 0, format); 3698 return 0; 3699} 3700 3701static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, 3702 struct hda_codec *codec, 3703 struct snd_pcm_substream *substream) 3704{ 3705 struct alc_spec *spec = codec->spec; 3706 3707 snd_hda_codec_cleanup_stream(codec, 3708 spec->adc_nids[substream->number + 1]); 3709 return 0; 3710} 3711 3712/* analog capture with dynamic dual-adc changes */ 3713static int dualmic_capture_pcm_prepare(struct hda_pcm_stream *hinfo, 3714 struct hda_codec *codec, 3715 unsigned int stream_tag, 3716 unsigned int format, 3717 struct snd_pcm_substream *substream) 3718{ 3719 struct alc_spec *spec = codec->spec; 3720 spec->cur_adc = spec->adc_nids[spec->cur_adc_idx]; 3721 spec->cur_adc_stream_tag = stream_tag; 3722 spec->cur_adc_format = format; 3723 snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format); 3724 return 0; 3725} 3726 3727static int dualmic_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, 3728 struct hda_codec *codec, 3729 struct snd_pcm_substream *substream) 3730{ 3731 struct alc_spec *spec = codec->spec; 3732 snd_hda_codec_cleanup_stream(codec, spec->cur_adc); 3733 spec->cur_adc = 0; 3734 return 0; 3735} 3736 3737static struct hda_pcm_stream dualmic_pcm_analog_capture = { 3738 .substreams = 1, 3739 .channels_min = 2, 3740 .channels_max = 2, 3741 .nid = 0, /* fill later */ 3742 .ops = { 3743 .prepare = dualmic_capture_pcm_prepare, 3744 .cleanup = dualmic_capture_pcm_cleanup 3745 }, 3746}; 3747 3748/* 3749 */ 3750static struct hda_pcm_stream alc880_pcm_analog_playback = { 3751 .substreams = 1, 3752 .channels_min = 2, 3753 .channels_max = 8, 3754 /* NID is set in alc_build_pcms */ 3755 .ops = { 3756 .open = alc880_playback_pcm_open, 3757 .prepare = alc880_playback_pcm_prepare, 3758 .cleanup = alc880_playback_pcm_cleanup 3759 }, 3760}; 3761 3762static struct hda_pcm_stream alc880_pcm_analog_capture = { 3763 .substreams = 1, 3764 .channels_min = 2, 3765 .channels_max = 2, 3766 /* NID is set in alc_build_pcms */ 3767}; 3768 3769static struct hda_pcm_stream alc880_pcm_analog_alt_playback = { 3770 .substreams = 1, 3771 .channels_min = 2, 3772 .channels_max = 2, 3773 /* NID is set in alc_build_pcms */ 3774}; 3775 3776static struct hda_pcm_stream alc880_pcm_analog_alt_capture = { 3777 .substreams = 2, /* can be overridden */ 3778 .channels_min = 2, 3779 .channels_max = 2, 3780 /* NID is set in alc_build_pcms */ 3781 .ops = { 3782 .prepare = alc880_alt_capture_pcm_prepare, 3783 .cleanup = alc880_alt_capture_pcm_cleanup 3784 }, 3785}; 3786 3787static struct hda_pcm_stream alc880_pcm_digital_playback = { 3788 .substreams = 1, 3789 .channels_min = 2, 3790 .channels_max = 2, 3791 /* NID is set in alc_build_pcms */ 3792 .ops = { 3793 .open = alc880_dig_playback_pcm_open, 3794 .close = alc880_dig_playback_pcm_close, 3795 .prepare = alc880_dig_playback_pcm_prepare, 3796 .cleanup = alc880_dig_playback_pcm_cleanup 3797 }, 3798}; 3799 3800static struct hda_pcm_stream alc880_pcm_digital_capture = { 3801 .substreams = 1, 3802 .channels_min = 2, 3803 .channels_max = 2, 3804 /* NID is set in alc_build_pcms */ 3805}; 3806 3807/* Used by alc_build_pcms to flag that a PCM has no playback stream */ 3808static struct hda_pcm_stream alc_pcm_null_stream = { 3809 .substreams = 0, 3810 .channels_min = 0, 3811 .channels_max = 0, 3812}; 3813 3814static int alc_build_pcms(struct hda_codec *codec) 3815{ 3816 struct alc_spec *spec = codec->spec; 3817 struct hda_pcm *info = spec->pcm_rec; 3818 int i; 3819 3820 codec->num_pcms = 1; 3821 codec->pcm_info = info; 3822 3823 if (spec->no_analog) 3824 goto skip_analog; 3825 3826 snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog), 3827 "%s Analog", codec->chip_name); 3828 info->name = spec->stream_name_analog; 3829 3830 if (spec->stream_analog_playback) { 3831 if (snd_BUG_ON(!spec->multiout.dac_nids)) 3832 return -EINVAL; 3833 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback); 3834 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0]; 3835 } 3836 if (spec->stream_analog_capture) { 3837 if (snd_BUG_ON(!spec->adc_nids)) 3838 return -EINVAL; 3839 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture); 3840 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0]; 3841 } 3842 3843 if (spec->channel_mode) { 3844 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0; 3845 for (i = 0; i < spec->num_channel_mode; i++) { 3846 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) { 3847 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels; 3848 } 3849 } 3850 } 3851 3852 skip_analog: 3853 /* SPDIF for stream index #1 */ 3854 if (spec->multiout.dig_out_nid || spec->dig_in_nid) { 3855 snprintf(spec->stream_name_digital, 3856 sizeof(spec->stream_name_digital), 3857 "%s Digital", codec->chip_name); 3858 codec->num_pcms = 2; 3859 codec->slave_dig_outs = spec->multiout.slave_dig_outs; 3860 info = spec->pcm_rec + 1; 3861 info->name = spec->stream_name_digital; 3862 if (spec->dig_out_type) 3863 info->pcm_type = spec->dig_out_type; 3864 else 3865 info->pcm_type = HDA_PCM_TYPE_SPDIF; 3866 if (spec->multiout.dig_out_nid && 3867 spec->stream_digital_playback) { 3868 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback); 3869 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid; 3870 } 3871 if (spec->dig_in_nid && 3872 spec->stream_digital_capture) { 3873 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture); 3874 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid; 3875 } 3876 /* FIXME: do we need this for all Realtek codec models? */ 3877 codec->spdif_status_reset = 1; 3878 } 3879 3880 if (spec->no_analog) 3881 return 0; 3882 3883 /* If the use of more than one ADC is requested for the current 3884 * model, configure a second analog capture-only PCM. 3885 */ 3886 /* Additional Analaog capture for index #2 */ 3887 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) || 3888 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) { 3889 codec->num_pcms = 3; 3890 info = spec->pcm_rec + 2; 3891 info->name = spec->stream_name_analog; 3892 if (spec->alt_dac_nid) { 3893 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = 3894 *spec->stream_analog_alt_playback; 3895 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 3896 spec->alt_dac_nid; 3897 } else { 3898 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = 3899 alc_pcm_null_stream; 3900 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0; 3901 } 3902 if (spec->num_adc_nids > 1) { 3903 info->stream[SNDRV_PCM_STREAM_CAPTURE] = 3904 *spec->stream_analog_alt_capture; 3905 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 3906 spec->adc_nids[1]; 3907 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = 3908 spec->num_adc_nids - 1; 3909 } else { 3910 info->stream[SNDRV_PCM_STREAM_CAPTURE] = 3911 alc_pcm_null_stream; 3912 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0; 3913 } 3914 } 3915 3916 return 0; 3917} 3918 3919static inline void alc_shutup(struct hda_codec *codec) 3920{ 3921 snd_hda_shutup_pins(codec); 3922} 3923 3924static void alc_free_kctls(struct hda_codec *codec) 3925{ 3926 struct alc_spec *spec = codec->spec; 3927 3928 if (spec->kctls.list) { 3929 struct snd_kcontrol_new *kctl = spec->kctls.list; 3930 int i; 3931 for (i = 0; i < spec->kctls.used; i++) 3932 kfree(kctl[i].name); 3933 } 3934 snd_array_free(&spec->kctls); 3935} 3936 3937static void alc_free(struct hda_codec *codec) 3938{ 3939 struct alc_spec *spec = codec->spec; 3940 3941 if (!spec) 3942 return; 3943 3944 alc_shutup(codec); 3945 alc_free_kctls(codec); 3946 kfree(spec); 3947 snd_hda_detach_beep_device(codec); 3948} 3949 3950#ifdef CONFIG_SND_HDA_POWER_SAVE 3951static void alc_power_eapd(struct hda_codec *codec) 3952{ 3953 /* We currently only handle front, HP */ 3954 switch (codec->vendor_id) { 3955 case 0x10ec0260: 3956 set_eapd(codec, 0x0f, 0); 3957 set_eapd(codec, 0x10, 0); 3958 break; 3959 case 0x10ec0262: 3960 case 0x10ec0267: 3961 case 0x10ec0268: 3962 case 0x10ec0269: 3963 case 0x10ec0270: 3964 case 0x10ec0272: 3965 case 0x10ec0660: 3966 case 0x10ec0662: 3967 case 0x10ec0663: 3968 case 0x10ec0862: 3969 case 0x10ec0889: 3970 set_eapd(codec, 0x14, 0); 3971 set_eapd(codec, 0x15, 0); 3972 break; 3973 } 3974} 3975 3976static int alc_suspend(struct hda_codec *codec, pm_message_t state) 3977{ 3978 struct alc_spec *spec = codec->spec; 3979 alc_shutup(codec); 3980 if (spec && spec->power_hook) 3981 spec->power_hook(codec); 3982 return 0; 3983} 3984#endif 3985 3986#ifdef SND_HDA_NEEDS_RESUME 3987static int alc_resume(struct hda_codec *codec) 3988{ 3989 codec->patch_ops.init(codec); 3990 snd_hda_codec_resume_amp(codec); 3991 snd_hda_codec_resume_cache(codec); 3992#ifdef CONFIG_SND_HDA_POWER_SAVE 3993 if (codec->patch_ops.check_power_status) 3994 codec->patch_ops.check_power_status(codec, 0x01); 3995#endif 3996 return 0; 3997} 3998#endif 3999 4000/* 4001 */ 4002static struct hda_codec_ops alc_patch_ops = { 4003 .build_controls = alc_build_controls, 4004 .build_pcms = alc_build_pcms, 4005 .init = alc_init, 4006 .free = alc_free, 4007 .unsol_event = alc_unsol_event, 4008#ifdef SND_HDA_NEEDS_RESUME 4009 .resume = alc_resume, 4010#endif 4011#ifdef CONFIG_SND_HDA_POWER_SAVE 4012 .suspend = alc_suspend, 4013 .check_power_status = alc_check_power_status, 4014#endif 4015 .reboot_notify = alc_shutup, 4016}; 4017 4018/* replace the codec chip_name with the given string */ 4019static int alc_codec_rename(struct hda_codec *codec, const char *name) 4020{ 4021 kfree(codec->chip_name); 4022 codec->chip_name = kstrdup(name, GFP_KERNEL); 4023 if (!codec->chip_name) { 4024 alc_free(codec); 4025 return -ENOMEM; 4026 } 4027 return 0; 4028} 4029 4030/* 4031 * Test configuration for debugging 4032 * 4033 * Almost all inputs/outputs are enabled. I/O pins can be configured via 4034 * enum controls. 4035 */ 4036#ifdef CONFIG_SND_DEBUG 4037static hda_nid_t alc880_test_dac_nids[4] = { 4038 0x02, 0x03, 0x04, 0x05 4039}; 4040 4041static struct hda_input_mux alc880_test_capture_source = { 4042 .num_items = 7, 4043 .items = { 4044 { "In-1", 0x0 }, 4045 { "In-2", 0x1 }, 4046 { "In-3", 0x2 }, 4047 { "In-4", 0x3 }, 4048 { "CD", 0x4 }, 4049 { "Front", 0x5 }, 4050 { "Surround", 0x6 }, 4051 }, 4052}; 4053 4054static struct hda_channel_mode alc880_test_modes[4] = { 4055 { 2, NULL }, 4056 { 4, NULL }, 4057 { 6, NULL }, 4058 { 8, NULL }, 4059}; 4060 4061static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol, 4062 struct snd_ctl_elem_info *uinfo) 4063{ 4064 static char *texts[] = { 4065 "N/A", "Line Out", "HP Out", 4066 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%" 4067 }; 4068 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 4069 uinfo->count = 1; 4070 uinfo->value.enumerated.items = 8; 4071 if (uinfo->value.enumerated.item >= 8) 4072 uinfo->value.enumerated.item = 7; 4073 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); 4074 return 0; 4075} 4076 4077static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol, 4078 struct snd_ctl_elem_value *ucontrol) 4079{ 4080 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 4081 hda_nid_t nid = (hda_nid_t)kcontrol->private_value; 4082 unsigned int pin_ctl, item = 0; 4083 4084 pin_ctl = snd_hda_codec_read(codec, nid, 0, 4085 AC_VERB_GET_PIN_WIDGET_CONTROL, 0); 4086 if (pin_ctl & AC_PINCTL_OUT_EN) { 4087 if (pin_ctl & AC_PINCTL_HP_EN) 4088 item = 2; 4089 else 4090 item = 1; 4091 } else if (pin_ctl & AC_PINCTL_IN_EN) { 4092 switch (pin_ctl & AC_PINCTL_VREFEN) { 4093 case AC_PINCTL_VREF_HIZ: item = 3; break; 4094 case AC_PINCTL_VREF_50: item = 4; break; 4095 case AC_PINCTL_VREF_GRD: item = 5; break; 4096 case AC_PINCTL_VREF_80: item = 6; break; 4097 case AC_PINCTL_VREF_100: item = 7; break; 4098 } 4099 } 4100 ucontrol->value.enumerated.item[0] = item; 4101 return 0; 4102} 4103 4104static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol, 4105 struct snd_ctl_elem_value *ucontrol) 4106{ 4107 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 4108 hda_nid_t nid = (hda_nid_t)kcontrol->private_value; 4109 static unsigned int ctls[] = { 4110 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN, 4111 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ, 4112 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50, 4113 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD, 4114 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80, 4115 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100, 4116 }; 4117 unsigned int old_ctl, new_ctl; 4118 4119 old_ctl = snd_hda_codec_read(codec, nid, 0, 4120 AC_VERB_GET_PIN_WIDGET_CONTROL, 0); 4121 new_ctl = ctls[ucontrol->value.enumerated.item[0]]; 4122 if (old_ctl != new_ctl) { 4123 int val; 4124 snd_hda_codec_write_cache(codec, nid, 0, 4125 AC_VERB_SET_PIN_WIDGET_CONTROL, 4126 new_ctl); 4127 val = ucontrol->value.enumerated.item[0] >= 3 ? 4128 HDA_AMP_MUTE : 0; 4129 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, 4130 HDA_AMP_MUTE, val); 4131 return 1; 4132 } 4133 return 0; 4134} 4135 4136static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol, 4137 struct snd_ctl_elem_info *uinfo) 4138{ 4139 static char *texts[] = { 4140 "Front", "Surround", "CLFE", "Side" 4141 }; 4142 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 4143 uinfo->count = 1; 4144 uinfo->value.enumerated.items = 4; 4145 if (uinfo->value.enumerated.item >= 4) 4146 uinfo->value.enumerated.item = 3; 4147 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); 4148 return 0; 4149} 4150 4151static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol, 4152 struct snd_ctl_elem_value *ucontrol) 4153{ 4154 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 4155 hda_nid_t nid = (hda_nid_t)kcontrol->private_value; 4156 unsigned int sel; 4157 4158 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0); 4159 ucontrol->value.enumerated.item[0] = sel & 3; 4160 return 0; 4161} 4162 4163static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol, 4164 struct snd_ctl_elem_value *ucontrol) 4165{ 4166 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 4167 hda_nid_t nid = (hda_nid_t)kcontrol->private_value; 4168 unsigned int sel; 4169 4170 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3; 4171 if (ucontrol->value.enumerated.item[0] != sel) { 4172 sel = ucontrol->value.enumerated.item[0] & 3; 4173 snd_hda_codec_write_cache(codec, nid, 0, 4174 AC_VERB_SET_CONNECT_SEL, sel); 4175 return 1; 4176 } 4177 return 0; 4178} 4179 4180#define PIN_CTL_TEST(xname,nid) { \ 4181 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 4182 .name = xname, \ 4183 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \ 4184 .info = alc_test_pin_ctl_info, \ 4185 .get = alc_test_pin_ctl_get, \ 4186 .put = alc_test_pin_ctl_put, \ 4187 .private_value = nid \ 4188 } 4189 4190#define PIN_SRC_TEST(xname,nid) { \ 4191 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 4192 .name = xname, \ 4193 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \ 4194 .info = alc_test_pin_src_info, \ 4195 .get = alc_test_pin_src_get, \ 4196 .put = alc_test_pin_src_put, \ 4197 .private_value = nid \ 4198 } 4199 4200static struct snd_kcontrol_new alc880_test_mixer[] = { 4201 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 4202 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 4203 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT), 4204 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 4205 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 4206 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 4207 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT), 4208 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 4209 PIN_CTL_TEST("Front Pin Mode", 0x14), 4210 PIN_CTL_TEST("Surround Pin Mode", 0x15), 4211 PIN_CTL_TEST("CLFE Pin Mode", 0x16), 4212 PIN_CTL_TEST("Side Pin Mode", 0x17), 4213 PIN_CTL_TEST("In-1 Pin Mode", 0x18), 4214 PIN_CTL_TEST("In-2 Pin Mode", 0x19), 4215 PIN_CTL_TEST("In-3 Pin Mode", 0x1a), 4216 PIN_CTL_TEST("In-4 Pin Mode", 0x1b), 4217 PIN_SRC_TEST("In-1 Pin Source", 0x18), 4218 PIN_SRC_TEST("In-2 Pin Source", 0x19), 4219 PIN_SRC_TEST("In-3 Pin Source", 0x1a), 4220 PIN_SRC_TEST("In-4 Pin Source", 0x1b), 4221 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT), 4222 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT), 4223 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT), 4224 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT), 4225 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT), 4226 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT), 4227 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT), 4228 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT), 4229 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT), 4230 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT), 4231 { 4232 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 4233 .name = "Channel Mode", 4234 .info = alc_ch_mode_info, 4235 .get = alc_ch_mode_get, 4236 .put = alc_ch_mode_put, 4237 }, 4238 { } /* end */ 4239}; 4240 4241static struct hda_verb alc880_test_init_verbs[] = { 4242 /* Unmute inputs of 0x0c - 0x0f */ 4243 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4244 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4245 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4246 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4247 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4248 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4249 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4250 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4251 /* Vol output for 0x0c-0x0f */ 4252 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4253 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4254 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4255 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4256 /* Set output pins 0x14-0x17 */ 4257 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4258 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4259 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4260 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4261 /* Unmute output pins 0x14-0x17 */ 4262 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4263 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4264 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4265 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4266 /* Set input pins 0x18-0x1c */ 4267 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 4268 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 4269 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 4270 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 4271 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 4272 /* Mute input pins 0x18-0x1b */ 4273 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 4274 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 4275 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 4276 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 4277 /* ADC set up */ 4278 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4279 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 4280 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4281 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 4282 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4283 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 4284 /* Analog input/passthru */ 4285 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4286 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4287 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 4288 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 4289 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 4290 { } 4291}; 4292#endif 4293 4294/* 4295 */ 4296 4297static const char *alc880_models[ALC880_MODEL_LAST] = { 4298 [ALC880_3ST] = "3stack", 4299 [ALC880_TCL_S700] = "tcl", 4300 [ALC880_3ST_DIG] = "3stack-digout", 4301 [ALC880_CLEVO] = "clevo", 4302 [ALC880_5ST] = "5stack", 4303 [ALC880_5ST_DIG] = "5stack-digout", 4304 [ALC880_W810] = "w810", 4305 [ALC880_Z71V] = "z71v", 4306 [ALC880_6ST] = "6stack", 4307 [ALC880_6ST_DIG] = "6stack-digout", 4308 [ALC880_ASUS] = "asus", 4309 [ALC880_ASUS_W1V] = "asus-w1v", 4310 [ALC880_ASUS_DIG] = "asus-dig", 4311 [ALC880_ASUS_DIG2] = "asus-dig2", 4312 [ALC880_UNIWILL_DIG] = "uniwill", 4313 [ALC880_UNIWILL_P53] = "uniwill-p53", 4314 [ALC880_FUJITSU] = "fujitsu", 4315 [ALC880_F1734] = "F1734", 4316 [ALC880_LG] = "lg", 4317 [ALC880_LG_LW] = "lg-lw", 4318 [ALC880_MEDION_RIM] = "medion", 4319#ifdef CONFIG_SND_DEBUG 4320 [ALC880_TEST] = "test", 4321#endif 4322 [ALC880_AUTO] = "auto", 4323}; 4324 4325static struct snd_pci_quirk alc880_cfg_tbl[] = { 4326 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810), 4327 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG), 4328 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST), 4329 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG), 4330 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG), 4331 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG), 4332 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG), 4333 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG), 4334 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST), 4335 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG), 4336 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST), 4337 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V), 4338 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG), 4339 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG), 4340 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG), 4341 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG), 4342 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG), 4343 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V), 4344 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */ 4345 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG), 4346 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG), 4347 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG), 4348 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG), 4349 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST), 4350 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST), 4351 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */ 4352 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST), 4353 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST), 4354 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST), 4355 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST), 4356 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST), 4357 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG), 4358 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG), 4359 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG), 4360 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG), 4361 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO), 4362 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO), 4363 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2), 4364 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG), 4365 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG), 4366 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734), 4367 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL), 4368 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53), 4369 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810), 4370 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM), 4371 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG), 4372 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG), 4373 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734), 4374 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU), 4375 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_F1734), 4376 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU), 4377 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW), 4378 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG), 4379 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG), 4380 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW), 4381 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700), 4382 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */ 4383 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG), 4384 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG), 4385 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG), 4386 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG), 4387 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG), 4388 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG), 4389 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG), 4390 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG), 4391 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG), 4392 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG), 4393 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG), 4394 /* default Intel */ 4395 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST), 4396 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG), 4397 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG), 4398 {} 4399}; 4400 4401/* 4402 * ALC880 codec presets 4403 */ 4404static struct alc_config_preset alc880_presets[] = { 4405 [ALC880_3ST] = { 4406 .mixers = { alc880_three_stack_mixer }, 4407 .init_verbs = { alc880_volume_init_verbs, 4408 alc880_pin_3stack_init_verbs }, 4409 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 4410 .dac_nids = alc880_dac_nids, 4411 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), 4412 .channel_mode = alc880_threestack_modes, 4413 .need_dac_fix = 1, 4414 .input_mux = &alc880_capture_source, 4415 }, 4416 [ALC880_3ST_DIG] = { 4417 .mixers = { alc880_three_stack_mixer }, 4418 .init_verbs = { alc880_volume_init_verbs, 4419 alc880_pin_3stack_init_verbs }, 4420 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 4421 .dac_nids = alc880_dac_nids, 4422 .dig_out_nid = ALC880_DIGOUT_NID, 4423 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), 4424 .channel_mode = alc880_threestack_modes, 4425 .need_dac_fix = 1, 4426 .input_mux = &alc880_capture_source, 4427 }, 4428 [ALC880_TCL_S700] = { 4429 .mixers = { alc880_tcl_s700_mixer }, 4430 .init_verbs = { alc880_volume_init_verbs, 4431 alc880_pin_tcl_S700_init_verbs, 4432 alc880_gpio2_init_verbs }, 4433 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 4434 .dac_nids = alc880_dac_nids, 4435 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */ 4436 .num_adc_nids = 1, /* single ADC */ 4437 .hp_nid = 0x03, 4438 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), 4439 .channel_mode = alc880_2_jack_modes, 4440 .input_mux = &alc880_capture_source, 4441 }, 4442 [ALC880_5ST] = { 4443 .mixers = { alc880_three_stack_mixer, 4444 alc880_five_stack_mixer}, 4445 .init_verbs = { alc880_volume_init_verbs, 4446 alc880_pin_5stack_init_verbs }, 4447 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 4448 .dac_nids = alc880_dac_nids, 4449 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes), 4450 .channel_mode = alc880_fivestack_modes, 4451 .input_mux = &alc880_capture_source, 4452 }, 4453 [ALC880_5ST_DIG] = { 4454 .mixers = { alc880_three_stack_mixer, 4455 alc880_five_stack_mixer }, 4456 .init_verbs = { alc880_volume_init_verbs, 4457 alc880_pin_5stack_init_verbs }, 4458 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 4459 .dac_nids = alc880_dac_nids, 4460 .dig_out_nid = ALC880_DIGOUT_NID, 4461 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes), 4462 .channel_mode = alc880_fivestack_modes, 4463 .input_mux = &alc880_capture_source, 4464 }, 4465 [ALC880_6ST] = { 4466 .mixers = { alc880_six_stack_mixer }, 4467 .init_verbs = { alc880_volume_init_verbs, 4468 alc880_pin_6stack_init_verbs }, 4469 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids), 4470 .dac_nids = alc880_6st_dac_nids, 4471 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes), 4472 .channel_mode = alc880_sixstack_modes, 4473 .input_mux = &alc880_6stack_capture_source, 4474 }, 4475 [ALC880_6ST_DIG] = { 4476 .mixers = { alc880_six_stack_mixer }, 4477 .init_verbs = { alc880_volume_init_verbs, 4478 alc880_pin_6stack_init_verbs }, 4479 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids), 4480 .dac_nids = alc880_6st_dac_nids, 4481 .dig_out_nid = ALC880_DIGOUT_NID, 4482 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes), 4483 .channel_mode = alc880_sixstack_modes, 4484 .input_mux = &alc880_6stack_capture_source, 4485 }, 4486 [ALC880_W810] = { 4487 .mixers = { alc880_w810_base_mixer }, 4488 .init_verbs = { alc880_volume_init_verbs, 4489 alc880_pin_w810_init_verbs, 4490 alc880_gpio2_init_verbs }, 4491 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids), 4492 .dac_nids = alc880_w810_dac_nids, 4493 .dig_out_nid = ALC880_DIGOUT_NID, 4494 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes), 4495 .channel_mode = alc880_w810_modes, 4496 .input_mux = &alc880_capture_source, 4497 }, 4498 [ALC880_Z71V] = { 4499 .mixers = { alc880_z71v_mixer }, 4500 .init_verbs = { alc880_volume_init_verbs, 4501 alc880_pin_z71v_init_verbs }, 4502 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids), 4503 .dac_nids = alc880_z71v_dac_nids, 4504 .dig_out_nid = ALC880_DIGOUT_NID, 4505 .hp_nid = 0x03, 4506 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), 4507 .channel_mode = alc880_2_jack_modes, 4508 .input_mux = &alc880_capture_source, 4509 }, 4510 [ALC880_F1734] = { 4511 .mixers = { alc880_f1734_mixer }, 4512 .init_verbs = { alc880_volume_init_verbs, 4513 alc880_pin_f1734_init_verbs }, 4514 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids), 4515 .dac_nids = alc880_f1734_dac_nids, 4516 .hp_nid = 0x02, 4517 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), 4518 .channel_mode = alc880_2_jack_modes, 4519 .input_mux = &alc880_f1734_capture_source, 4520 .unsol_event = alc880_uniwill_p53_unsol_event, 4521 .setup = alc880_uniwill_p53_setup, 4522 .init_hook = alc_automute_amp, 4523 }, 4524 [ALC880_ASUS] = { 4525 .mixers = { alc880_asus_mixer }, 4526 .init_verbs = { alc880_volume_init_verbs, 4527 alc880_pin_asus_init_verbs, 4528 alc880_gpio1_init_verbs }, 4529 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 4530 .dac_nids = alc880_asus_dac_nids, 4531 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), 4532 .channel_mode = alc880_asus_modes, 4533 .need_dac_fix = 1, 4534 .input_mux = &alc880_capture_source, 4535 }, 4536 [ALC880_ASUS_DIG] = { 4537 .mixers = { alc880_asus_mixer }, 4538 .init_verbs = { alc880_volume_init_verbs, 4539 alc880_pin_asus_init_verbs, 4540 alc880_gpio1_init_verbs }, 4541 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 4542 .dac_nids = alc880_asus_dac_nids, 4543 .dig_out_nid = ALC880_DIGOUT_NID, 4544 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), 4545 .channel_mode = alc880_asus_modes, 4546 .need_dac_fix = 1, 4547 .input_mux = &alc880_capture_source, 4548 }, 4549 [ALC880_ASUS_DIG2] = { 4550 .mixers = { alc880_asus_mixer }, 4551 .init_verbs = { alc880_volume_init_verbs, 4552 alc880_pin_asus_init_verbs, 4553 alc880_gpio2_init_verbs }, /* use GPIO2 */ 4554 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 4555 .dac_nids = alc880_asus_dac_nids, 4556 .dig_out_nid = ALC880_DIGOUT_NID, 4557 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), 4558 .channel_mode = alc880_asus_modes, 4559 .need_dac_fix = 1, 4560 .input_mux = &alc880_capture_source, 4561 }, 4562 [ALC880_ASUS_W1V] = { 4563 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer }, 4564 .init_verbs = { alc880_volume_init_verbs, 4565 alc880_pin_asus_init_verbs, 4566 alc880_gpio1_init_verbs }, 4567 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 4568 .dac_nids = alc880_asus_dac_nids, 4569 .dig_out_nid = ALC880_DIGOUT_NID, 4570 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), 4571 .channel_mode = alc880_asus_modes, 4572 .need_dac_fix = 1, 4573 .input_mux = &alc880_capture_source, 4574 }, 4575 [ALC880_UNIWILL_DIG] = { 4576 .mixers = { alc880_asus_mixer }, 4577 .init_verbs = { alc880_volume_init_verbs, 4578 alc880_pin_asus_init_verbs }, 4579 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 4580 .dac_nids = alc880_asus_dac_nids, 4581 .dig_out_nid = ALC880_DIGOUT_NID, 4582 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), 4583 .channel_mode = alc880_asus_modes, 4584 .need_dac_fix = 1, 4585 .input_mux = &alc880_capture_source, 4586 }, 4587 [ALC880_UNIWILL] = { 4588 .mixers = { alc880_uniwill_mixer }, 4589 .init_verbs = { alc880_volume_init_verbs, 4590 alc880_uniwill_init_verbs }, 4591 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 4592 .dac_nids = alc880_asus_dac_nids, 4593 .dig_out_nid = ALC880_DIGOUT_NID, 4594 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), 4595 .channel_mode = alc880_threestack_modes, 4596 .need_dac_fix = 1, 4597 .input_mux = &alc880_capture_source, 4598 .unsol_event = alc880_uniwill_unsol_event, 4599 .setup = alc880_uniwill_setup, 4600 .init_hook = alc880_uniwill_init_hook, 4601 }, 4602 [ALC880_UNIWILL_P53] = { 4603 .mixers = { alc880_uniwill_p53_mixer }, 4604 .init_verbs = { alc880_volume_init_verbs, 4605 alc880_uniwill_p53_init_verbs }, 4606 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 4607 .dac_nids = alc880_asus_dac_nids, 4608 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes), 4609 .channel_mode = alc880_threestack_modes, 4610 .input_mux = &alc880_capture_source, 4611 .unsol_event = alc880_uniwill_p53_unsol_event, 4612 .setup = alc880_uniwill_p53_setup, 4613 .init_hook = alc_automute_amp, 4614 }, 4615 [ALC880_FUJITSU] = { 4616 .mixers = { alc880_fujitsu_mixer }, 4617 .init_verbs = { alc880_volume_init_verbs, 4618 alc880_uniwill_p53_init_verbs, 4619 alc880_beep_init_verbs }, 4620 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 4621 .dac_nids = alc880_dac_nids, 4622 .dig_out_nid = ALC880_DIGOUT_NID, 4623 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), 4624 .channel_mode = alc880_2_jack_modes, 4625 .input_mux = &alc880_capture_source, 4626 .unsol_event = alc880_uniwill_p53_unsol_event, 4627 .setup = alc880_uniwill_p53_setup, 4628 .init_hook = alc_automute_amp, 4629 }, 4630 [ALC880_CLEVO] = { 4631 .mixers = { alc880_three_stack_mixer }, 4632 .init_verbs = { alc880_volume_init_verbs, 4633 alc880_pin_clevo_init_verbs }, 4634 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 4635 .dac_nids = alc880_dac_nids, 4636 .hp_nid = 0x03, 4637 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), 4638 .channel_mode = alc880_threestack_modes, 4639 .need_dac_fix = 1, 4640 .input_mux = &alc880_capture_source, 4641 }, 4642 [ALC880_LG] = { 4643 .mixers = { alc880_lg_mixer }, 4644 .init_verbs = { alc880_volume_init_verbs, 4645 alc880_lg_init_verbs }, 4646 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids), 4647 .dac_nids = alc880_lg_dac_nids, 4648 .dig_out_nid = ALC880_DIGOUT_NID, 4649 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes), 4650 .channel_mode = alc880_lg_ch_modes, 4651 .need_dac_fix = 1, 4652 .input_mux = &alc880_lg_capture_source, 4653 .unsol_event = alc_automute_amp_unsol_event, 4654 .setup = alc880_lg_setup, 4655 .init_hook = alc_automute_amp, 4656#ifdef CONFIG_SND_HDA_POWER_SAVE 4657 .loopbacks = alc880_lg_loopbacks, 4658#endif 4659 }, 4660 [ALC880_LG_LW] = { 4661 .mixers = { alc880_lg_lw_mixer }, 4662 .init_verbs = { alc880_volume_init_verbs, 4663 alc880_lg_lw_init_verbs }, 4664 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 4665 .dac_nids = alc880_dac_nids, 4666 .dig_out_nid = ALC880_DIGOUT_NID, 4667 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes), 4668 .channel_mode = alc880_lg_lw_modes, 4669 .input_mux = &alc880_lg_lw_capture_source, 4670 .unsol_event = alc_automute_amp_unsol_event, 4671 .setup = alc880_lg_lw_setup, 4672 .init_hook = alc_automute_amp, 4673 }, 4674 [ALC880_MEDION_RIM] = { 4675 .mixers = { alc880_medion_rim_mixer }, 4676 .init_verbs = { alc880_volume_init_verbs, 4677 alc880_medion_rim_init_verbs, 4678 alc_gpio2_init_verbs }, 4679 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 4680 .dac_nids = alc880_dac_nids, 4681 .dig_out_nid = ALC880_DIGOUT_NID, 4682 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), 4683 .channel_mode = alc880_2_jack_modes, 4684 .input_mux = &alc880_medion_rim_capture_source, 4685 .unsol_event = alc880_medion_rim_unsol_event, 4686 .setup = alc880_medion_rim_setup, 4687 .init_hook = alc880_medion_rim_automute, 4688 }, 4689#ifdef CONFIG_SND_DEBUG 4690 [ALC880_TEST] = { 4691 .mixers = { alc880_test_mixer }, 4692 .init_verbs = { alc880_test_init_verbs }, 4693 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids), 4694 .dac_nids = alc880_test_dac_nids, 4695 .dig_out_nid = ALC880_DIGOUT_NID, 4696 .num_channel_mode = ARRAY_SIZE(alc880_test_modes), 4697 .channel_mode = alc880_test_modes, 4698 .input_mux = &alc880_test_capture_source, 4699 }, 4700#endif 4701}; 4702 4703/* 4704 * Automatic parse of I/O pins from the BIOS configuration 4705 */ 4706 4707enum { 4708 ALC_CTL_WIDGET_VOL, 4709 ALC_CTL_WIDGET_MUTE, 4710 ALC_CTL_BIND_MUTE, 4711}; 4712static struct snd_kcontrol_new alc880_control_templates[] = { 4713 HDA_CODEC_VOLUME(NULL, 0, 0, 0), 4714 HDA_CODEC_MUTE(NULL, 0, 0, 0), 4715 HDA_BIND_MUTE(NULL, 0, 0, 0), 4716}; 4717 4718/* add dynamic controls */ 4719static int add_control(struct alc_spec *spec, int type, const char *name, 4720 int cidx, unsigned long val) 4721{ 4722 struct snd_kcontrol_new *knew; 4723 4724 snd_array_init(&spec->kctls, sizeof(*knew), 32); 4725 knew = snd_array_new(&spec->kctls); 4726 if (!knew) 4727 return -ENOMEM; 4728 *knew = alc880_control_templates[type]; 4729 knew->name = kstrdup(name, GFP_KERNEL); 4730 if (!knew->name) 4731 return -ENOMEM; 4732 knew->index = cidx; 4733 if (get_amp_nid_(val)) 4734 knew->subdevice = HDA_SUBDEV_AMP_FLAG; 4735 knew->private_value = val; 4736 return 0; 4737} 4738 4739static int add_control_with_pfx(struct alc_spec *spec, int type, 4740 const char *pfx, const char *dir, 4741 const char *sfx, int cidx, unsigned long val) 4742{ 4743 char name[32]; 4744 snprintf(name, sizeof(name), "%s %s %s", pfx, dir, sfx); 4745 return add_control(spec, type, name, cidx, val); 4746} 4747 4748#define add_pb_vol_ctrl(spec, type, pfx, val) \ 4749 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", 0, val) 4750#define add_pb_sw_ctrl(spec, type, pfx, val) \ 4751 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", 0, val) 4752#define __add_pb_vol_ctrl(spec, type, pfx, cidx, val) \ 4753 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", cidx, val) 4754#define __add_pb_sw_ctrl(spec, type, pfx, cidx, val) \ 4755 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", cidx, val) 4756 4757#define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17) 4758#define alc880_fixed_pin_idx(nid) ((nid) - 0x14) 4759#define alc880_is_multi_pin(nid) ((nid) >= 0x18) 4760#define alc880_multi_pin_idx(nid) ((nid) - 0x18) 4761#define alc880_idx_to_dac(nid) ((nid) + 0x02) 4762#define alc880_dac_to_idx(nid) ((nid) - 0x02) 4763#define alc880_idx_to_mixer(nid) ((nid) + 0x0c) 4764#define alc880_idx_to_selector(nid) ((nid) + 0x10) 4765#define ALC880_PIN_CD_NID 0x1c 4766 4767/* fill in the dac_nids table from the parsed pin configuration */ 4768static int alc880_auto_fill_dac_nids(struct alc_spec *spec, 4769 const struct auto_pin_cfg *cfg) 4770{ 4771 hda_nid_t nid; 4772 int assigned[4]; 4773 int i, j; 4774 4775 memset(assigned, 0, sizeof(assigned)); 4776 spec->multiout.dac_nids = spec->private_dac_nids; 4777 4778 /* check the pins hardwired to audio widget */ 4779 for (i = 0; i < cfg->line_outs; i++) { 4780 nid = cfg->line_out_pins[i]; 4781 if (alc880_is_fixed_pin(nid)) { 4782 int idx = alc880_fixed_pin_idx(nid); 4783 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx); 4784 assigned[idx] = 1; 4785 } 4786 } 4787 /* left pins can be connect to any audio widget */ 4788 for (i = 0; i < cfg->line_outs; i++) { 4789 nid = cfg->line_out_pins[i]; 4790 if (alc880_is_fixed_pin(nid)) 4791 continue; 4792 /* search for an empty channel */ 4793 for (j = 0; j < cfg->line_outs; j++) { 4794 if (!assigned[j]) { 4795 spec->multiout.dac_nids[i] = 4796 alc880_idx_to_dac(j); 4797 assigned[j] = 1; 4798 break; 4799 } 4800 } 4801 } 4802 spec->multiout.num_dacs = cfg->line_outs; 4803 return 0; 4804} 4805 4806/* add playback controls from the parsed DAC table */ 4807static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec, 4808 const struct auto_pin_cfg *cfg) 4809{ 4810 static const char *chname[4] = { 4811 "Front", "Surround", NULL /*CLFE*/, "Side" 4812 }; 4813 hda_nid_t nid; 4814 int i, err; 4815 4816 for (i = 0; i < cfg->line_outs; i++) { 4817 if (!spec->multiout.dac_nids[i]) 4818 continue; 4819 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i])); 4820 if (i == 2) { 4821 /* Center/LFE */ 4822 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, 4823 "Center", 4824 HDA_COMPOSE_AMP_VAL(nid, 1, 0, 4825 HDA_OUTPUT)); 4826 if (err < 0) 4827 return err; 4828 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, 4829 "LFE", 4830 HDA_COMPOSE_AMP_VAL(nid, 2, 0, 4831 HDA_OUTPUT)); 4832 if (err < 0) 4833 return err; 4834 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, 4835 "Center", 4836 HDA_COMPOSE_AMP_VAL(nid, 1, 2, 4837 HDA_INPUT)); 4838 if (err < 0) 4839 return err; 4840 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, 4841 "LFE", 4842 HDA_COMPOSE_AMP_VAL(nid, 2, 2, 4843 HDA_INPUT)); 4844 if (err < 0) 4845 return err; 4846 } else { 4847 const char *pfx; 4848 if (cfg->line_outs == 1 && 4849 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) 4850 pfx = "Speaker"; 4851 else 4852 pfx = chname[i]; 4853 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, 4854 HDA_COMPOSE_AMP_VAL(nid, 3, 0, 4855 HDA_OUTPUT)); 4856 if (err < 0) 4857 return err; 4858 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx, 4859 HDA_COMPOSE_AMP_VAL(nid, 3, 2, 4860 HDA_INPUT)); 4861 if (err < 0) 4862 return err; 4863 } 4864 } 4865 return 0; 4866} 4867 4868/* add playback controls for speaker and HP outputs */ 4869static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin, 4870 const char *pfx) 4871{ 4872 hda_nid_t nid; 4873 int err; 4874 4875 if (!pin) 4876 return 0; 4877 4878 if (alc880_is_fixed_pin(pin)) { 4879 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); 4880 /* specify the DAC as the extra output */ 4881 if (!spec->multiout.hp_nid) 4882 spec->multiout.hp_nid = nid; 4883 else 4884 spec->multiout.extra_out_nid[0] = nid; 4885 /* control HP volume/switch on the output mixer amp */ 4886 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin)); 4887 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, 4888 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); 4889 if (err < 0) 4890 return err; 4891 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx, 4892 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT)); 4893 if (err < 0) 4894 return err; 4895 } else if (alc880_is_multi_pin(pin)) { 4896 /* set manual connection */ 4897 /* we have only a switch on HP-out PIN */ 4898 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, 4899 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); 4900 if (err < 0) 4901 return err; 4902 } 4903 return 0; 4904} 4905 4906/* create input playback/capture controls for the given pin */ 4907static int new_analog_input(struct alc_spec *spec, hda_nid_t pin, 4908 const char *ctlname, int ctlidx, 4909 int idx, hda_nid_t mix_nid) 4910{ 4911 int err; 4912 4913 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname, ctlidx, 4914 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT)); 4915 if (err < 0) 4916 return err; 4917 err = __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname, ctlidx, 4918 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT)); 4919 if (err < 0) 4920 return err; 4921 return 0; 4922} 4923 4924static int alc_is_input_pin(struct hda_codec *codec, hda_nid_t nid) 4925{ 4926 unsigned int pincap = snd_hda_query_pin_caps(codec, nid); 4927 return (pincap & AC_PINCAP_IN) != 0; 4928} 4929 4930/* create playback/capture controls for input pins */ 4931static int alc_auto_create_input_ctls(struct hda_codec *codec, 4932 const struct auto_pin_cfg *cfg, 4933 hda_nid_t mixer, 4934 hda_nid_t cap1, hda_nid_t cap2) 4935{ 4936 struct alc_spec *spec = codec->spec; 4937 struct hda_input_mux *imux = &spec->private_imux[0]; 4938 int i, err, idx, type, type_idx = 0; 4939 4940 for (i = 0; i < cfg->num_inputs; i++) { 4941 hda_nid_t pin; 4942 4943 pin = cfg->inputs[i].pin; 4944 if (!alc_is_input_pin(codec, pin)) 4945 continue; 4946 4947 type = cfg->inputs[i].type; 4948 if (i > 0 && type == cfg->inputs[i - 1].type) 4949 type_idx++; 4950 else 4951 type_idx = 0; 4952 if (mixer) { 4953 idx = get_connection_index(codec, mixer, pin); 4954 if (idx >= 0) { 4955 err = new_analog_input(spec, pin, 4956 auto_pin_cfg_labels[type], 4957 type_idx, idx, mixer); 4958 if (err < 0) 4959 return err; 4960 } 4961 } 4962 4963 if (!cap1) 4964 continue; 4965 idx = get_connection_index(codec, cap1, pin); 4966 if (idx < 0 && cap2) 4967 idx = get_connection_index(codec, cap2, pin); 4968 if (idx >= 0) { 4969 imux->items[imux->num_items].label = 4970 snd_hda_get_input_pin_label(cfg, i); 4971 imux->items[imux->num_items].index = idx; 4972 imux->num_items++; 4973 } 4974 } 4975 return 0; 4976} 4977 4978static int alc880_auto_create_input_ctls(struct hda_codec *codec, 4979 const struct auto_pin_cfg *cfg) 4980{ 4981 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x08, 0x09); 4982} 4983 4984static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid, 4985 unsigned int pin_type) 4986{ 4987 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 4988 pin_type); 4989 /* unmute pin */ 4990 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, 4991 AMP_OUT_UNMUTE); 4992} 4993 4994static void alc880_auto_set_output_and_unmute(struct hda_codec *codec, 4995 hda_nid_t nid, int pin_type, 4996 int dac_idx) 4997{ 4998 alc_set_pin_output(codec, nid, pin_type); 4999 /* need the manual connection? */ 5000 if (alc880_is_multi_pin(nid)) { 5001 struct alc_spec *spec = codec->spec; 5002 int idx = alc880_multi_pin_idx(nid); 5003 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0, 5004 AC_VERB_SET_CONNECT_SEL, 5005 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx])); 5006 } 5007} 5008 5009static int get_pin_type(int line_out_type) 5010{ 5011 if (line_out_type == AUTO_PIN_HP_OUT) 5012 return PIN_HP; 5013 else 5014 return PIN_OUT; 5015} 5016 5017static void alc880_auto_init_multi_out(struct hda_codec *codec) 5018{ 5019 struct alc_spec *spec = codec->spec; 5020 int i; 5021 5022 for (i = 0; i < spec->autocfg.line_outs; i++) { 5023 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 5024 int pin_type = get_pin_type(spec->autocfg.line_out_type); 5025 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i); 5026 } 5027} 5028 5029static void alc880_auto_init_extra_out(struct hda_codec *codec) 5030{ 5031 struct alc_spec *spec = codec->spec; 5032 hda_nid_t pin; 5033 5034 pin = spec->autocfg.speaker_pins[0]; 5035 if (pin) /* connect to front */ 5036 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0); 5037 pin = spec->autocfg.hp_pins[0]; 5038 if (pin) /* connect to front */ 5039 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); 5040} 5041 5042static void alc880_auto_init_analog_input(struct hda_codec *codec) 5043{ 5044 struct alc_spec *spec = codec->spec; 5045 struct auto_pin_cfg *cfg = &spec->autocfg; 5046 int i; 5047 5048 for (i = 0; i < cfg->num_inputs; i++) { 5049 hda_nid_t nid = cfg->inputs[i].pin; 5050 if (alc_is_input_pin(codec, nid)) { 5051 alc_set_input_pin(codec, nid, i); 5052 if (nid != ALC880_PIN_CD_NID && 5053 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)) 5054 snd_hda_codec_write(codec, nid, 0, 5055 AC_VERB_SET_AMP_GAIN_MUTE, 5056 AMP_OUT_MUTE); 5057 } 5058 } 5059} 5060 5061static void alc880_auto_init_input_src(struct hda_codec *codec) 5062{ 5063 struct alc_spec *spec = codec->spec; 5064 int c; 5065 5066 for (c = 0; c < spec->num_adc_nids; c++) { 5067 unsigned int mux_idx; 5068 const struct hda_input_mux *imux; 5069 mux_idx = c >= spec->num_mux_defs ? 0 : c; 5070 imux = &spec->input_mux[mux_idx]; 5071 if (!imux->num_items && mux_idx > 0) 5072 imux = &spec->input_mux[0]; 5073 if (imux) 5074 snd_hda_codec_write(codec, spec->adc_nids[c], 0, 5075 AC_VERB_SET_CONNECT_SEL, 5076 imux->items[0].index); 5077 } 5078} 5079 5080/* parse the BIOS configuration and set up the alc_spec */ 5081/* return 1 if successful, 0 if the proper config is not found, 5082 * or a negative error code 5083 */ 5084static int alc880_parse_auto_config(struct hda_codec *codec) 5085{ 5086 struct alc_spec *spec = codec->spec; 5087 int err; 5088 static hda_nid_t alc880_ignore[] = { 0x1d, 0 }; 5089 5090 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 5091 alc880_ignore); 5092 if (err < 0) 5093 return err; 5094 if (!spec->autocfg.line_outs) 5095 return 0; /* can't find valid BIOS pin config */ 5096 5097 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); 5098 if (err < 0) 5099 return err; 5100 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg); 5101 if (err < 0) 5102 return err; 5103 err = alc880_auto_create_extra_out(spec, 5104 spec->autocfg.speaker_pins[0], 5105 "Speaker"); 5106 if (err < 0) 5107 return err; 5108 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0], 5109 "Headphone"); 5110 if (err < 0) 5111 return err; 5112 err = alc880_auto_create_input_ctls(codec, &spec->autocfg); 5113 if (err < 0) 5114 return err; 5115 5116 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 5117 5118 alc_auto_parse_digital(codec); 5119 5120 if (spec->kctls.list) 5121 add_mixer(spec, spec->kctls.list); 5122 5123 add_verb(spec, alc880_volume_init_verbs); 5124 5125 spec->num_mux_defs = 1; 5126 spec->input_mux = &spec->private_imux[0]; 5127 5128 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); 5129 5130 return 1; 5131} 5132 5133/* additional initialization for auto-configuration model */ 5134static void alc880_auto_init(struct hda_codec *codec) 5135{ 5136 struct alc_spec *spec = codec->spec; 5137 alc880_auto_init_multi_out(codec); 5138 alc880_auto_init_extra_out(codec); 5139 alc880_auto_init_analog_input(codec); 5140 alc880_auto_init_input_src(codec); 5141 alc_auto_init_digital(codec); 5142 if (spec->unsol_event) 5143 alc_inithook(codec); 5144} 5145 5146/* check the ADC/MUX contains all input pins; some ADC/MUX contains only 5147 * one of two digital mic pins, e.g. on ALC272 5148 */ 5149static void fixup_automic_adc(struct hda_codec *codec) 5150{ 5151 struct alc_spec *spec = codec->spec; 5152 int i; 5153 5154 for (i = 0; i < spec->num_adc_nids; i++) { 5155 hda_nid_t cap = spec->capsrc_nids ? 5156 spec->capsrc_nids[i] : spec->adc_nids[i]; 5157 int iidx, eidx; 5158 5159 iidx = get_connection_index(codec, cap, spec->int_mic.pin); 5160 if (iidx < 0) 5161 continue; 5162 eidx = get_connection_index(codec, cap, spec->ext_mic.pin); 5163 if (eidx < 0) 5164 continue; 5165 spec->int_mic.mux_idx = iidx; 5166 spec->ext_mic.mux_idx = eidx; 5167 if (spec->capsrc_nids) 5168 spec->capsrc_nids += i; 5169 spec->adc_nids += i; 5170 spec->num_adc_nids = 1; 5171 return; 5172 } 5173 snd_printd(KERN_INFO "hda_codec: %s: " 5174 "No ADC/MUX containing both 0x%x and 0x%x pins\n", 5175 codec->chip_name, spec->int_mic.pin, spec->ext_mic.pin); 5176 spec->auto_mic = 0; /* disable auto-mic to be sure */ 5177} 5178 5179/* select or unmute the given capsrc route */ 5180static void select_or_unmute_capsrc(struct hda_codec *codec, hda_nid_t cap, 5181 int idx) 5182{ 5183 if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) { 5184 snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx, 5185 HDA_AMP_MUTE, 0); 5186 } else { 5187 snd_hda_codec_write_cache(codec, cap, 0, 5188 AC_VERB_SET_CONNECT_SEL, idx); 5189 } 5190} 5191 5192/* set the default connection to that pin */ 5193static int init_capsrc_for_pin(struct hda_codec *codec, hda_nid_t pin) 5194{ 5195 struct alc_spec *spec = codec->spec; 5196 int i; 5197 5198 for (i = 0; i < spec->num_adc_nids; i++) { 5199 hda_nid_t cap = spec->capsrc_nids ? 5200 spec->capsrc_nids[i] : spec->adc_nids[i]; 5201 int idx; 5202 5203 idx = get_connection_index(codec, cap, pin); 5204 if (idx < 0) 5205 continue; 5206 select_or_unmute_capsrc(codec, cap, idx); 5207 return i; /* return the found index */ 5208 } 5209 return -1; /* not found */ 5210} 5211 5212/* choose the ADC/MUX containing the input pin and initialize the setup */ 5213static void fixup_single_adc(struct hda_codec *codec) 5214{ 5215 struct alc_spec *spec = codec->spec; 5216 struct auto_pin_cfg *cfg = &spec->autocfg; 5217 int i; 5218 5219 /* search for the input pin; there must be only one */ 5220 if (cfg->num_inputs != 1) 5221 return; 5222 i = init_capsrc_for_pin(codec, cfg->inputs[0].pin); 5223 if (i >= 0) { 5224 /* use only this ADC */ 5225 if (spec->capsrc_nids) 5226 spec->capsrc_nids += i; 5227 spec->adc_nids += i; 5228 spec->num_adc_nids = 1; 5229 } 5230} 5231 5232/* initialize dual adcs */ 5233static void fixup_dual_adc_switch(struct hda_codec *codec) 5234{ 5235 struct alc_spec *spec = codec->spec; 5236 init_capsrc_for_pin(codec, spec->ext_mic.pin); 5237 init_capsrc_for_pin(codec, spec->int_mic.pin); 5238} 5239 5240static void set_capture_mixer(struct hda_codec *codec) 5241{ 5242 struct alc_spec *spec = codec->spec; 5243 static struct snd_kcontrol_new *caps[2][3] = { 5244 { alc_capture_mixer_nosrc1, 5245 alc_capture_mixer_nosrc2, 5246 alc_capture_mixer_nosrc3 }, 5247 { alc_capture_mixer1, 5248 alc_capture_mixer2, 5249 alc_capture_mixer3 }, 5250 }; 5251 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) { 5252 int mux = 0; 5253 int num_adcs = spec->num_adc_nids; 5254 if (spec->dual_adc_switch) 5255 fixup_dual_adc_switch(codec); 5256 else if (spec->auto_mic) 5257 fixup_automic_adc(codec); 5258 else if (spec->input_mux) { 5259 if (spec->input_mux->num_items > 1) 5260 mux = 1; 5261 else if (spec->input_mux->num_items == 1) 5262 fixup_single_adc(codec); 5263 } 5264 if (spec->dual_adc_switch) 5265 num_adcs = 1; 5266 spec->cap_mixer = caps[mux][num_adcs - 1]; 5267 } 5268} 5269 5270/* fill adc_nids (and capsrc_nids) containing all active input pins */ 5271static void fillup_priv_adc_nids(struct hda_codec *codec, hda_nid_t *nids, 5272 int num_nids) 5273{ 5274 struct alc_spec *spec = codec->spec; 5275 struct auto_pin_cfg *cfg = &spec->autocfg; 5276 int n; 5277 hda_nid_t fallback_adc = 0, fallback_cap = 0; 5278 5279 for (n = 0; n < num_nids; n++) { 5280 hda_nid_t adc, cap; 5281 hda_nid_t conn[HDA_MAX_NUM_INPUTS]; 5282 int nconns, i, j; 5283 5284 adc = nids[n]; 5285 if (get_wcaps_type(get_wcaps(codec, adc)) != AC_WID_AUD_IN) 5286 continue; 5287 cap = adc; 5288 nconns = snd_hda_get_connections(codec, cap, conn, 5289 ARRAY_SIZE(conn)); 5290 if (nconns == 1) { 5291 cap = conn[0]; 5292 nconns = snd_hda_get_connections(codec, cap, conn, 5293 ARRAY_SIZE(conn)); 5294 } 5295 if (nconns <= 0) 5296 continue; 5297 if (!fallback_adc) { 5298 fallback_adc = adc; 5299 fallback_cap = cap; 5300 } 5301 for (i = 0; i < cfg->num_inputs; i++) { 5302 hda_nid_t nid = cfg->inputs[i].pin; 5303 for (j = 0; j < nconns; j++) { 5304 if (conn[j] == nid) 5305 break; 5306 } 5307 if (j >= nconns) 5308 break; 5309 } 5310 if (i >= cfg->num_inputs) { 5311 int num_adcs = spec->num_adc_nids; 5312 spec->private_adc_nids[num_adcs] = adc; 5313 spec->private_capsrc_nids[num_adcs] = cap; 5314 spec->num_adc_nids++; 5315 spec->adc_nids = spec->private_adc_nids; 5316 if (adc != cap) 5317 spec->capsrc_nids = spec->private_capsrc_nids; 5318 } 5319 } 5320 if (!spec->num_adc_nids) { 5321 printk(KERN_WARNING "hda_codec: %s: no valid ADC found;" 5322 " using fallback 0x%x\n", 5323 codec->chip_name, fallback_adc); 5324 spec->private_adc_nids[0] = fallback_adc; 5325 spec->adc_nids = spec->private_adc_nids; 5326 if (fallback_adc != fallback_cap) { 5327 spec->private_capsrc_nids[0] = fallback_cap; 5328 spec->capsrc_nids = spec->private_adc_nids; 5329 } 5330 } 5331} 5332 5333#ifdef CONFIG_SND_HDA_INPUT_BEEP 5334#define set_beep_amp(spec, nid, idx, dir) \ 5335 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir)) 5336 5337static struct snd_pci_quirk beep_white_list[] = { 5338 SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1), 5339 SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1), 5340 {} 5341}; 5342 5343static inline int has_cdefine_beep(struct hda_codec *codec) 5344{ 5345 struct alc_spec *spec = codec->spec; 5346 const struct snd_pci_quirk *q; 5347 q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list); 5348 if (q) 5349 return q->value; 5350 return spec->cdefine.enable_pcbeep; 5351} 5352#else 5353#define set_beep_amp(spec, nid, idx, dir) /* NOP */ 5354#define has_cdefine_beep(codec) 0 5355#endif 5356 5357/* 5358 * OK, here we have finally the patch for ALC880 5359 */ 5360 5361static int patch_alc880(struct hda_codec *codec) 5362{ 5363 struct alc_spec *spec; 5364 int board_config; 5365 int err; 5366 5367 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 5368 if (spec == NULL) 5369 return -ENOMEM; 5370 5371 codec->spec = spec; 5372 5373 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST, 5374 alc880_models, 5375 alc880_cfg_tbl); 5376 if (board_config < 0) { 5377 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 5378 codec->chip_name); 5379 board_config = ALC880_AUTO; 5380 } 5381 5382 if (board_config == ALC880_AUTO) { 5383 /* automatic parse from the BIOS config */ 5384 err = alc880_parse_auto_config(codec); 5385 if (err < 0) { 5386 alc_free(codec); 5387 return err; 5388 } else if (!err) { 5389 printk(KERN_INFO 5390 "hda_codec: Cannot set up configuration " 5391 "from BIOS. Using 3-stack mode...\n"); 5392 board_config = ALC880_3ST; 5393 } 5394 } 5395 5396 err = snd_hda_attach_beep_device(codec, 0x1); 5397 if (err < 0) { 5398 alc_free(codec); 5399 return err; 5400 } 5401 5402 if (board_config != ALC880_AUTO) 5403 setup_preset(codec, &alc880_presets[board_config]); 5404 5405 spec->stream_analog_playback = &alc880_pcm_analog_playback; 5406 spec->stream_analog_capture = &alc880_pcm_analog_capture; 5407 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture; 5408 5409 spec->stream_digital_playback = &alc880_pcm_digital_playback; 5410 spec->stream_digital_capture = &alc880_pcm_digital_capture; 5411 5412 if (!spec->adc_nids && spec->input_mux) { 5413 /* check whether NID 0x07 is valid */ 5414 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]); 5415 /* get type */ 5416 wcap = get_wcaps_type(wcap); 5417 if (wcap != AC_WID_AUD_IN) { 5418 spec->adc_nids = alc880_adc_nids_alt; 5419 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt); 5420 } else { 5421 spec->adc_nids = alc880_adc_nids; 5422 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids); 5423 } 5424 } 5425 set_capture_mixer(codec); 5426 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 5427 5428 spec->vmaster_nid = 0x0c; 5429 5430 codec->patch_ops = alc_patch_ops; 5431 if (board_config == ALC880_AUTO) 5432 spec->init_hook = alc880_auto_init; 5433#ifdef CONFIG_SND_HDA_POWER_SAVE 5434 if (!spec->loopback.amplist) 5435 spec->loopback.amplist = alc880_loopbacks; 5436#endif 5437 5438 return 0; 5439} 5440 5441 5442/* 5443 * ALC260 support 5444 */ 5445 5446static hda_nid_t alc260_dac_nids[1] = { 5447 /* front */ 5448 0x02, 5449}; 5450 5451static hda_nid_t alc260_adc_nids[1] = { 5452 /* ADC0 */ 5453 0x04, 5454}; 5455 5456static hda_nid_t alc260_adc_nids_alt[1] = { 5457 /* ADC1 */ 5458 0x05, 5459}; 5460 5461/* NIDs used when simultaneous access to both ADCs makes sense. Note that 5462 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC. 5463 */ 5464static hda_nid_t alc260_dual_adc_nids[2] = { 5465 /* ADC0, ADC1 */ 5466 0x04, 0x05 5467}; 5468 5469#define ALC260_DIGOUT_NID 0x03 5470#define ALC260_DIGIN_NID 0x06 5471 5472static struct hda_input_mux alc260_capture_source = { 5473 .num_items = 4, 5474 .items = { 5475 { "Mic", 0x0 }, 5476 { "Front Mic", 0x1 }, 5477 { "Line", 0x2 }, 5478 { "CD", 0x4 }, 5479 }, 5480}; 5481 5482/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack, 5483 * headphone jack and the internal CD lines since these are the only pins at 5484 * which audio can appear. For flexibility, also allow the option of 5485 * recording the mixer output on the second ADC (ADC0 doesn't have a 5486 * connection to the mixer output). 5487 */ 5488static struct hda_input_mux alc260_fujitsu_capture_sources[2] = { 5489 { 5490 .num_items = 3, 5491 .items = { 5492 { "Mic/Line", 0x0 }, 5493 { "CD", 0x4 }, 5494 { "Headphone", 0x2 }, 5495 }, 5496 }, 5497 { 5498 .num_items = 4, 5499 .items = { 5500 { "Mic/Line", 0x0 }, 5501 { "CD", 0x4 }, 5502 { "Headphone", 0x2 }, 5503 { "Mixer", 0x5 }, 5504 }, 5505 }, 5506 5507}; 5508 5509/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to 5510 * the Fujitsu S702x, but jacks are marked differently. 5511 */ 5512static struct hda_input_mux alc260_acer_capture_sources[2] = { 5513 { 5514 .num_items = 4, 5515 .items = { 5516 { "Mic", 0x0 }, 5517 { "Line", 0x2 }, 5518 { "CD", 0x4 }, 5519 { "Headphone", 0x5 }, 5520 }, 5521 }, 5522 { 5523 .num_items = 5, 5524 .items = { 5525 { "Mic", 0x0 }, 5526 { "Line", 0x2 }, 5527 { "CD", 0x4 }, 5528 { "Headphone", 0x6 }, 5529 { "Mixer", 0x5 }, 5530 }, 5531 }, 5532}; 5533 5534/* Maxdata Favorit 100XS */ 5535static struct hda_input_mux alc260_favorit100_capture_sources[2] = { 5536 { 5537 .num_items = 2, 5538 .items = { 5539 { "Line/Mic", 0x0 }, 5540 { "CD", 0x4 }, 5541 }, 5542 }, 5543 { 5544 .num_items = 3, 5545 .items = { 5546 { "Line/Mic", 0x0 }, 5547 { "CD", 0x4 }, 5548 { "Mixer", 0x5 }, 5549 }, 5550 }, 5551}; 5552 5553/* 5554 * This is just place-holder, so there's something for alc_build_pcms to look 5555 * at when it calculates the maximum number of channels. ALC260 has no mixer 5556 * element which allows changing the channel mode, so the verb list is 5557 * never used. 5558 */ 5559static struct hda_channel_mode alc260_modes[1] = { 5560 { 2, NULL }, 5561}; 5562 5563 5564/* Mixer combinations 5565 * 5566 * basic: base_output + input + pc_beep + capture 5567 * HP: base_output + input + capture_alt 5568 * HP_3013: hp_3013 + input + capture 5569 * fujitsu: fujitsu + capture 5570 * acer: acer + capture 5571 */ 5572 5573static struct snd_kcontrol_new alc260_base_output_mixer[] = { 5574 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT), 5575 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT), 5576 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT), 5577 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT), 5578 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), 5579 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT), 5580 { } /* end */ 5581}; 5582 5583static struct snd_kcontrol_new alc260_input_mixer[] = { 5584 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), 5585 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), 5586 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), 5587 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT), 5588 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), 5589 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT), 5590 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT), 5591 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT), 5592 { } /* end */ 5593}; 5594 5595/* update HP, line and mono out pins according to the master switch */ 5596static void alc260_hp_master_update(struct hda_codec *codec, 5597 hda_nid_t hp, hda_nid_t line, 5598 hda_nid_t mono) 5599{ 5600 struct alc_spec *spec = codec->spec; 5601 unsigned int val = spec->master_sw ? PIN_HP : 0; 5602 /* change HP and line-out pins */ 5603 snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 5604 val); 5605 snd_hda_codec_write(codec, line, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 5606 val); 5607 /* mono (speaker) depending on the HP jack sense */ 5608 val = (val && !spec->jack_present) ? PIN_OUT : 0; 5609 snd_hda_codec_write(codec, mono, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 5610 val); 5611} 5612 5613static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol, 5614 struct snd_ctl_elem_value *ucontrol) 5615{ 5616 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 5617 struct alc_spec *spec = codec->spec; 5618 *ucontrol->value.integer.value = spec->master_sw; 5619 return 0; 5620} 5621 5622static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol, 5623 struct snd_ctl_elem_value *ucontrol) 5624{ 5625 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 5626 struct alc_spec *spec = codec->spec; 5627 int val = !!*ucontrol->value.integer.value; 5628 hda_nid_t hp, line, mono; 5629 5630 if (val == spec->master_sw) 5631 return 0; 5632 spec->master_sw = val; 5633 hp = (kcontrol->private_value >> 16) & 0xff; 5634 line = (kcontrol->private_value >> 8) & 0xff; 5635 mono = kcontrol->private_value & 0xff; 5636 alc260_hp_master_update(codec, hp, line, mono); 5637 return 1; 5638} 5639 5640static struct snd_kcontrol_new alc260_hp_output_mixer[] = { 5641 { 5642 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 5643 .name = "Master Playback Switch", 5644 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11, 5645 .info = snd_ctl_boolean_mono_info, 5646 .get = alc260_hp_master_sw_get, 5647 .put = alc260_hp_master_sw_put, 5648 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11 5649 }, 5650 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT), 5651 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT), 5652 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT), 5653 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT), 5654 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, 5655 HDA_OUTPUT), 5656 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT), 5657 { } /* end */ 5658}; 5659 5660static struct hda_verb alc260_hp_unsol_verbs[] = { 5661 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 5662 {}, 5663}; 5664 5665static void alc260_hp_automute(struct hda_codec *codec) 5666{ 5667 struct alc_spec *spec = codec->spec; 5668 5669 spec->jack_present = snd_hda_jack_detect(codec, 0x10); 5670 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11); 5671} 5672 5673static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res) 5674{ 5675 if ((res >> 26) == ALC880_HP_EVENT) 5676 alc260_hp_automute(codec); 5677} 5678 5679static struct snd_kcontrol_new alc260_hp_3013_mixer[] = { 5680 { 5681 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 5682 .name = "Master Playback Switch", 5683 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11, 5684 .info = snd_ctl_boolean_mono_info, 5685 .get = alc260_hp_master_sw_get, 5686 .put = alc260_hp_master_sw_put, 5687 .private_value = (0x15 << 16) | (0x10 << 8) | 0x11 5688 }, 5689 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT), 5690 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT), 5691 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT), 5692 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT), 5693 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT), 5694 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 5695 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), 5696 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT), 5697 { } /* end */ 5698}; 5699 5700static struct hda_bind_ctls alc260_dc7600_bind_master_vol = { 5701 .ops = &snd_hda_bind_vol, 5702 .values = { 5703 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT), 5704 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT), 5705 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT), 5706 0 5707 }, 5708}; 5709 5710static struct hda_bind_ctls alc260_dc7600_bind_switch = { 5711 .ops = &snd_hda_bind_sw, 5712 .values = { 5713 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT), 5714 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT), 5715 0 5716 }, 5717}; 5718 5719static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = { 5720 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol), 5721 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch), 5722 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT), 5723 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT), 5724 { } /* end */ 5725}; 5726 5727static struct hda_verb alc260_hp_3013_unsol_verbs[] = { 5728 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 5729 {}, 5730}; 5731 5732static void alc260_hp_3013_automute(struct hda_codec *codec) 5733{ 5734 struct alc_spec *spec = codec->spec; 5735 5736 spec->jack_present = snd_hda_jack_detect(codec, 0x15); 5737 alc260_hp_master_update(codec, 0x15, 0x10, 0x11); 5738} 5739 5740static void alc260_hp_3013_unsol_event(struct hda_codec *codec, 5741 unsigned int res) 5742{ 5743 if ((res >> 26) == ALC880_HP_EVENT) 5744 alc260_hp_3013_automute(codec); 5745} 5746 5747static void alc260_hp_3012_automute(struct hda_codec *codec) 5748{ 5749 unsigned int bits = snd_hda_jack_detect(codec, 0x10) ? 0 : PIN_OUT; 5750 5751 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 5752 bits); 5753 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 5754 bits); 5755 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 5756 bits); 5757} 5758 5759static void alc260_hp_3012_unsol_event(struct hda_codec *codec, 5760 unsigned int res) 5761{ 5762 if ((res >> 26) == ALC880_HP_EVENT) 5763 alc260_hp_3012_automute(codec); 5764} 5765 5766/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12, 5767 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10. 5768 */ 5769static struct snd_kcontrol_new alc260_fujitsu_mixer[] = { 5770 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT), 5771 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT), 5772 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT), 5773 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), 5774 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), 5775 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT), 5776 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT), 5777 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN), 5778 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT), 5779 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT), 5780 { } /* end */ 5781}; 5782 5783/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current 5784 * versions of the ALC260 don't act on requests to enable mic bias from NID 5785 * 0x0f (used to drive the headphone jack in these laptops). The ALC260 5786 * datasheet doesn't mention this restriction. At this stage it's not clear 5787 * whether this behaviour is intentional or is a hardware bug in chip 5788 * revisions available in early 2006. Therefore for now allow the 5789 * "Headphone Jack Mode" control to span all choices, but if it turns out 5790 * that the lack of mic bias for this NID is intentional we could change the 5791 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS. 5792 * 5793 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006 5794 * don't appear to make the mic bias available from the "line" jack, even 5795 * though the NID used for this jack (0x14) can supply it. The theory is 5796 * that perhaps Acer have included blocking capacitors between the ALC260 5797 * and the output jack. If this turns out to be the case for all such 5798 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT 5799 * to ALC_PIN_DIR_INOUT_NOMICBIAS. 5800 * 5801 * The C20x Tablet series have a mono internal speaker which is controlled 5802 * via the chip's Mono sum widget and pin complex, so include the necessary 5803 * controls for such models. On models without a "mono speaker" the control 5804 * won't do anything. 5805 */ 5806static struct snd_kcontrol_new alc260_acer_mixer[] = { 5807 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), 5808 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT), 5809 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT), 5810 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, 5811 HDA_OUTPUT), 5812 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, 5813 HDA_INPUT), 5814 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), 5815 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), 5816 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), 5817 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT), 5818 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN), 5819 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), 5820 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT), 5821 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT), 5822 { } /* end */ 5823}; 5824 5825/* Maxdata Favorit 100XS: one output and one input (0x12) jack 5826 */ 5827static struct snd_kcontrol_new alc260_favorit100_mixer[] = { 5828 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), 5829 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT), 5830 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT), 5831 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT), 5832 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT), 5833 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN), 5834 { } /* end */ 5835}; 5836 5837/* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12, 5838 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17. 5839 */ 5840static struct snd_kcontrol_new alc260_will_mixer[] = { 5841 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), 5842 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT), 5843 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), 5844 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT), 5845 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN), 5846 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), 5847 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT), 5848 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT), 5849 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), 5850 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), 5851 { } /* end */ 5852}; 5853 5854/* Replacer 672V ALC260 pin usage: Mic jack = 0x12, 5855 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f. 5856 */ 5857static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = { 5858 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), 5859 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT), 5860 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), 5861 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT), 5862 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN), 5863 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT), 5864 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT), 5865 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), 5866 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT), 5867 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT), 5868 { } /* end */ 5869}; 5870 5871/* 5872 * initialization verbs 5873 */ 5874static struct hda_verb alc260_init_verbs[] = { 5875 /* Line In pin widget for input */ 5876 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 5877 /* CD pin widget for input */ 5878 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 5879 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 5880 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 5881 /* Mic2 (front panel) pin widget for input and vref at 80% */ 5882 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 5883 /* LINE-2 is used for line-out in rear */ 5884 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5885 /* select line-out */ 5886 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00}, 5887 /* LINE-OUT pin */ 5888 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5889 /* enable HP */ 5890 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 5891 /* enable Mono */ 5892 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5893 /* mute capture amp left and right */ 5894 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5895 /* set connection select to line in (default select for this ADC) */ 5896 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02}, 5897 /* mute capture amp left and right */ 5898 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5899 /* set connection select to line in (default select for this ADC) */ 5900 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02}, 5901 /* set vol=0 Line-Out mixer amp left and right */ 5902 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5903 /* unmute pin widget amp left and right (no gain on this amp) */ 5904 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5905 /* set vol=0 HP mixer amp left and right */ 5906 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5907 /* unmute pin widget amp left and right (no gain on this amp) */ 5908 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5909 /* set vol=0 Mono mixer amp left and right */ 5910 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5911 /* unmute pin widget amp left and right (no gain on this amp) */ 5912 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5913 /* unmute LINE-2 out pin */ 5914 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5915 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & 5916 * Line In 2 = 0x03 5917 */ 5918 /* mute analog inputs */ 5919 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5920 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 5921 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 5922 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 5923 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 5924 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */ 5925 /* mute Front out path */ 5926 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5927 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 5928 /* mute Headphone out path */ 5929 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5930 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 5931 /* mute Mono out path */ 5932 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5933 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 5934 { } 5935}; 5936 5937#if 0 /* should be identical with alc260_init_verbs? */ 5938static struct hda_verb alc260_hp_init_verbs[] = { 5939 /* Headphone and output */ 5940 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 5941 /* mono output */ 5942 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 5943 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 5944 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 5945 /* Mic2 (front panel) pin widget for input and vref at 80% */ 5946 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 5947 /* Line In pin widget for input */ 5948 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 5949 /* Line-2 pin widget for output */ 5950 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 5951 /* CD pin widget for input */ 5952 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 5953 /* unmute amp left and right */ 5954 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000}, 5955 /* set connection select to line in (default select for this ADC) */ 5956 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02}, 5957 /* unmute Line-Out mixer amp left and right (volume = 0) */ 5958 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 5959 /* mute pin widget amp left and right (no gain on this amp) */ 5960 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 5961 /* unmute HP mixer amp left and right (volume = 0) */ 5962 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 5963 /* mute pin widget amp left and right (no gain on this amp) */ 5964 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 5965 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & 5966 * Line In 2 = 0x03 5967 */ 5968 /* mute analog inputs */ 5969 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5970 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 5971 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 5972 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 5973 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 5974 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */ 5975 /* Unmute Front out path */ 5976 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 5977 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 5978 /* Unmute Headphone out path */ 5979 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 5980 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 5981 /* Unmute Mono out path */ 5982 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 5983 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 5984 { } 5985}; 5986#endif 5987 5988static struct hda_verb alc260_hp_3013_init_verbs[] = { 5989 /* Line out and output */ 5990 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 5991 /* mono output */ 5992 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 5993 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 5994 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 5995 /* Mic2 (front panel) pin widget for input and vref at 80% */ 5996 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 5997 /* Line In pin widget for input */ 5998 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 5999 /* Headphone pin widget for output */ 6000 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 6001 /* CD pin widget for input */ 6002 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 6003 /* unmute amp left and right */ 6004 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000}, 6005 /* set connection select to line in (default select for this ADC) */ 6006 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02}, 6007 /* unmute Line-Out mixer amp left and right (volume = 0) */ 6008 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 6009 /* mute pin widget amp left and right (no gain on this amp) */ 6010 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 6011 /* unmute HP mixer amp left and right (volume = 0) */ 6012 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 6013 /* mute pin widget amp left and right (no gain on this amp) */ 6014 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 6015 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & 6016 * Line In 2 = 0x03 6017 */ 6018 /* mute analog inputs */ 6019 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6020 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6021 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 6022 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 6023 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 6024 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */ 6025 /* Unmute Front out path */ 6026 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 6027 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 6028 /* Unmute Headphone out path */ 6029 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 6030 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 6031 /* Unmute Mono out path */ 6032 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 6033 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 6034 { } 6035}; 6036 6037/* Initialisation sequence for ALC260 as configured in Fujitsu S702x 6038 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD 6039 * audio = 0x16, internal speaker = 0x10. 6040 */ 6041static struct hda_verb alc260_fujitsu_init_verbs[] = { 6042 /* Disable all GPIOs */ 6043 {0x01, AC_VERB_SET_GPIO_MASK, 0}, 6044 /* Internal speaker is connected to headphone pin */ 6045 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6046 /* Headphone/Line-out jack connects to Line1 pin; make it an output */ 6047 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6048 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */ 6049 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 6050 /* Ensure all other unused pins are disabled and muted. */ 6051 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6052 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6053 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6054 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6055 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6056 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6057 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6058 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6059 6060 /* Disable digital (SPDIF) pins */ 6061 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0}, 6062 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0}, 6063 6064 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus 6065 * when acting as an output. 6066 */ 6067 {0x0d, AC_VERB_SET_CONNECT_SEL, 0}, 6068 6069 /* Start with output sum widgets muted and their output gains at min */ 6070 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6071 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6072 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6073 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6074 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6075 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6076 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6077 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6078 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6079 6080 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */ 6081 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6082 /* Unmute Line1 pin widget output buffer since it starts as an output. 6083 * If the pin mode is changed by the user the pin mode control will 6084 * take care of enabling the pin's input/output buffers as needed. 6085 * Therefore there's no need to enable the input buffer at this 6086 * stage. 6087 */ 6088 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6089 /* Unmute input buffer of pin widget used for Line-in (no equiv 6090 * mixer ctrl) 6091 */ 6092 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6093 6094 /* Mute capture amp left and right */ 6095 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6096 /* Set ADC connection select to match default mixer setting - line 6097 * in (on mic1 pin) 6098 */ 6099 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, 6100 6101 /* Do the same for the second ADC: mute capture input amp and 6102 * set ADC connection to line in (on mic1 pin) 6103 */ 6104 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6105 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, 6106 6107 /* Mute all inputs to mixer widget (even unconnected ones) */ 6108 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */ 6109 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */ 6110 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */ 6111 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */ 6112 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */ 6113 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */ 6114 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */ 6115 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */ 6116 6117 { } 6118}; 6119 6120/* Initialisation sequence for ALC260 as configured in Acer TravelMate and 6121 * similar laptops (adapted from Fujitsu init verbs). 6122 */ 6123static struct hda_verb alc260_acer_init_verbs[] = { 6124 /* On TravelMate laptops, GPIO 0 enables the internal speaker and 6125 * the headphone jack. Turn this on and rely on the standard mute 6126 * methods whenever the user wants to turn these outputs off. 6127 */ 6128 {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, 6129 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, 6130 {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, 6131 /* Internal speaker/Headphone jack is connected to Line-out pin */ 6132 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6133 /* Internal microphone/Mic jack is connected to Mic1 pin */ 6134 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, 6135 /* Line In jack is connected to Line1 pin */ 6136 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 6137 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */ 6138 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6139 /* Ensure all other unused pins are disabled and muted. */ 6140 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6141 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6142 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6143 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6144 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6145 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6146 /* Disable digital (SPDIF) pins */ 6147 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0}, 6148 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0}, 6149 6150 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum 6151 * bus when acting as outputs. 6152 */ 6153 {0x0b, AC_VERB_SET_CONNECT_SEL, 0}, 6154 {0x0d, AC_VERB_SET_CONNECT_SEL, 0}, 6155 6156 /* Start with output sum widgets muted and their output gains at min */ 6157 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6158 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6159 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6160 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6161 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6162 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6163 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6164 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6165 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6166 6167 /* Unmute Line-out pin widget amp left and right 6168 * (no equiv mixer ctrl) 6169 */ 6170 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6171 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */ 6172 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6173 /* Unmute Mic1 and Line1 pin widget input buffers since they start as 6174 * inputs. If the pin mode is changed by the user the pin mode control 6175 * will take care of enabling the pin's input/output buffers as needed. 6176 * Therefore there's no need to enable the input buffer at this 6177 * stage. 6178 */ 6179 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6180 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6181 6182 /* Mute capture amp left and right */ 6183 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6184 /* Set ADC connection select to match default mixer setting - mic 6185 * (on mic1 pin) 6186 */ 6187 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, 6188 6189 /* Do similar with the second ADC: mute capture input amp and 6190 * set ADC connection to mic to match ALSA's default state. 6191 */ 6192 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6193 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, 6194 6195 /* Mute all inputs to mixer widget (even unconnected ones) */ 6196 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */ 6197 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */ 6198 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */ 6199 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */ 6200 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */ 6201 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */ 6202 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */ 6203 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */ 6204 6205 { } 6206}; 6207 6208/* Initialisation sequence for Maxdata Favorit 100XS 6209 * (adapted from Acer init verbs). 6210 */ 6211static struct hda_verb alc260_favorit100_init_verbs[] = { 6212 /* GPIO 0 enables the output jack. 6213 * Turn this on and rely on the standard mute 6214 * methods whenever the user wants to turn these outputs off. 6215 */ 6216 {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, 6217 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, 6218 {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, 6219 /* Line/Mic input jack is connected to Mic1 pin */ 6220 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, 6221 /* Ensure all other unused pins are disabled and muted. */ 6222 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6223 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6224 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6225 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6226 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6227 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6228 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6229 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6230 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6231 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6232 /* Disable digital (SPDIF) pins */ 6233 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0}, 6234 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0}, 6235 6236 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum 6237 * bus when acting as outputs. 6238 */ 6239 {0x0b, AC_VERB_SET_CONNECT_SEL, 0}, 6240 {0x0d, AC_VERB_SET_CONNECT_SEL, 0}, 6241 6242 /* Start with output sum widgets muted and their output gains at min */ 6243 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6244 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6245 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6246 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6247 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6248 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6249 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6250 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6251 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6252 6253 /* Unmute Line-out pin widget amp left and right 6254 * (no equiv mixer ctrl) 6255 */ 6256 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6257 /* Unmute Mic1 and Line1 pin widget input buffers since they start as 6258 * inputs. If the pin mode is changed by the user the pin mode control 6259 * will take care of enabling the pin's input/output buffers as needed. 6260 * Therefore there's no need to enable the input buffer at this 6261 * stage. 6262 */ 6263 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6264 6265 /* Mute capture amp left and right */ 6266 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6267 /* Set ADC connection select to match default mixer setting - mic 6268 * (on mic1 pin) 6269 */ 6270 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, 6271 6272 /* Do similar with the second ADC: mute capture input amp and 6273 * set ADC connection to mic to match ALSA's default state. 6274 */ 6275 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6276 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, 6277 6278 /* Mute all inputs to mixer widget (even unconnected ones) */ 6279 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */ 6280 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */ 6281 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */ 6282 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */ 6283 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */ 6284 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */ 6285 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */ 6286 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */ 6287 6288 { } 6289}; 6290 6291static struct hda_verb alc260_will_verbs[] = { 6292 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6293 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00}, 6294 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00}, 6295 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02}, 6296 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07}, 6297 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040}, 6298 {} 6299}; 6300 6301static struct hda_verb alc260_replacer_672v_verbs[] = { 6302 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02}, 6303 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07}, 6304 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050}, 6305 6306 {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, 6307 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, 6308 {0x01, AC_VERB_SET_GPIO_DATA, 0x00}, 6309 6310 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 6311 {} 6312}; 6313 6314/* toggle speaker-output according to the hp-jack state */ 6315static void alc260_replacer_672v_automute(struct hda_codec *codec) 6316{ 6317 unsigned int present; 6318 6319 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */ 6320 present = snd_hda_jack_detect(codec, 0x0f); 6321 if (present) { 6322 snd_hda_codec_write_cache(codec, 0x01, 0, 6323 AC_VERB_SET_GPIO_DATA, 1); 6324 snd_hda_codec_write_cache(codec, 0x0f, 0, 6325 AC_VERB_SET_PIN_WIDGET_CONTROL, 6326 PIN_HP); 6327 } else { 6328 snd_hda_codec_write_cache(codec, 0x01, 0, 6329 AC_VERB_SET_GPIO_DATA, 0); 6330 snd_hda_codec_write_cache(codec, 0x0f, 0, 6331 AC_VERB_SET_PIN_WIDGET_CONTROL, 6332 PIN_OUT); 6333 } 6334} 6335 6336static void alc260_replacer_672v_unsol_event(struct hda_codec *codec, 6337 unsigned int res) 6338{ 6339 if ((res >> 26) == ALC880_HP_EVENT) 6340 alc260_replacer_672v_automute(codec); 6341} 6342 6343static struct hda_verb alc260_hp_dc7600_verbs[] = { 6344 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01}, 6345 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 6346 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6347 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6348 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6349 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6350 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 6351 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 6352 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 6353 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 6354 {} 6355}; 6356 6357/* Test configuration for debugging, modelled after the ALC880 test 6358 * configuration. 6359 */ 6360#ifdef CONFIG_SND_DEBUG 6361static hda_nid_t alc260_test_dac_nids[1] = { 6362 0x02, 6363}; 6364static hda_nid_t alc260_test_adc_nids[2] = { 6365 0x04, 0x05, 6366}; 6367/* For testing the ALC260, each input MUX needs its own definition since 6368 * the signal assignments are different. This assumes that the first ADC 6369 * is NID 0x04. 6370 */ 6371static struct hda_input_mux alc260_test_capture_sources[2] = { 6372 { 6373 .num_items = 7, 6374 .items = { 6375 { "MIC1 pin", 0x0 }, 6376 { "MIC2 pin", 0x1 }, 6377 { "LINE1 pin", 0x2 }, 6378 { "LINE2 pin", 0x3 }, 6379 { "CD pin", 0x4 }, 6380 { "LINE-OUT pin", 0x5 }, 6381 { "HP-OUT pin", 0x6 }, 6382 }, 6383 }, 6384 { 6385 .num_items = 8, 6386 .items = { 6387 { "MIC1 pin", 0x0 }, 6388 { "MIC2 pin", 0x1 }, 6389 { "LINE1 pin", 0x2 }, 6390 { "LINE2 pin", 0x3 }, 6391 { "CD pin", 0x4 }, 6392 { "Mixer", 0x5 }, 6393 { "LINE-OUT pin", 0x6 }, 6394 { "HP-OUT pin", 0x7 }, 6395 }, 6396 }, 6397}; 6398static struct snd_kcontrol_new alc260_test_mixer[] = { 6399 /* Output driver widgets */ 6400 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), 6401 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT), 6402 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT), 6403 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT), 6404 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT), 6405 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT), 6406 6407 /* Modes for retasking pin widgets 6408 * Note: the ALC260 doesn't seem to act on requests to enable mic 6409 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't 6410 * mention this restriction. At this stage it's not clear whether 6411 * this behaviour is intentional or is a hardware bug in chip 6412 * revisions available at least up until early 2006. Therefore for 6413 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all 6414 * choices, but if it turns out that the lack of mic bias for these 6415 * NIDs is intentional we could change their modes from 6416 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS. 6417 */ 6418 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT), 6419 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT), 6420 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT), 6421 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT), 6422 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT), 6423 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT), 6424 6425 /* Loopback mixer controls */ 6426 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT), 6427 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT), 6428 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT), 6429 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT), 6430 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT), 6431 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT), 6432 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT), 6433 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT), 6434 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), 6435 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), 6436 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT), 6437 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT), 6438 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT), 6439 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT), 6440 6441 /* Controls for GPIO pins, assuming they are configured as outputs */ 6442 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01), 6443 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02), 6444 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04), 6445 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08), 6446 6447 /* Switches to allow the digital IO pins to be enabled. The datasheet 6448 * is ambigious as to which NID is which; testing on laptops which 6449 * make this output available should provide clarification. 6450 */ 6451 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01), 6452 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01), 6453 6454 /* A switch allowing EAPD to be enabled. Some laptops seem to use 6455 * this output to turn on an external amplifier. 6456 */ 6457 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02), 6458 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02), 6459 6460 { } /* end */ 6461}; 6462static struct hda_verb alc260_test_init_verbs[] = { 6463 /* Enable all GPIOs as outputs with an initial value of 0 */ 6464 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f}, 6465 {0x01, AC_VERB_SET_GPIO_DATA, 0x00}, 6466 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f}, 6467 6468 /* Enable retasking pins as output, initially without power amp */ 6469 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6470 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6471 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6472 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6473 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6474 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6475 6476 /* Disable digital (SPDIF) pins initially, but users can enable 6477 * them via a mixer switch. In the case of SPDIF-out, this initverb 6478 * payload also sets the generation to 0, output to be in "consumer" 6479 * PCM format, copyright asserted, no pre-emphasis and no validity 6480 * control. 6481 */ 6482 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0}, 6483 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0}, 6484 6485 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the 6486 * OUT1 sum bus when acting as an output. 6487 */ 6488 {0x0b, AC_VERB_SET_CONNECT_SEL, 0}, 6489 {0x0c, AC_VERB_SET_CONNECT_SEL, 0}, 6490 {0x0d, AC_VERB_SET_CONNECT_SEL, 0}, 6491 {0x0e, AC_VERB_SET_CONNECT_SEL, 0}, 6492 6493 /* Start with output sum widgets muted and their output gains at min */ 6494 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6495 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6496 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6497 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6498 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6499 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6500 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6501 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6502 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6503 6504 /* Unmute retasking pin widget output buffers since the default 6505 * state appears to be output. As the pin mode is changed by the 6506 * user the pin mode control will take care of enabling the pin's 6507 * input/output buffers as needed. 6508 */ 6509 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6510 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6511 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6512 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6513 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6514 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6515 /* Also unmute the mono-out pin widget */ 6516 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6517 6518 /* Mute capture amp left and right */ 6519 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6520 /* Set ADC connection select to match default mixer setting (mic1 6521 * pin) 6522 */ 6523 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, 6524 6525 /* Do the same for the second ADC: mute capture input amp and 6526 * set ADC connection to mic1 pin 6527 */ 6528 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6529 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, 6530 6531 /* Mute all inputs to mixer widget (even unconnected ones) */ 6532 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */ 6533 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */ 6534 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */ 6535 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */ 6536 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */ 6537 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */ 6538 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */ 6539 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */ 6540 6541 { } 6542}; 6543#endif 6544 6545#define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback 6546#define alc260_pcm_analog_capture alc880_pcm_analog_capture 6547 6548#define alc260_pcm_digital_playback alc880_pcm_digital_playback 6549#define alc260_pcm_digital_capture alc880_pcm_digital_capture 6550 6551/* 6552 * for BIOS auto-configuration 6553 */ 6554 6555static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid, 6556 const char *pfx, int *vol_bits) 6557{ 6558 hda_nid_t nid_vol; 6559 unsigned long vol_val, sw_val; 6560 int err; 6561 6562 if (nid >= 0x0f && nid < 0x11) { 6563 nid_vol = nid - 0x7; 6564 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT); 6565 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT); 6566 } else if (nid == 0x11) { 6567 nid_vol = nid - 0x7; 6568 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT); 6569 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT); 6570 } else if (nid >= 0x12 && nid <= 0x15) { 6571 nid_vol = 0x08; 6572 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT); 6573 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT); 6574 } else 6575 return 0; /* N/A */ 6576 6577 if (!(*vol_bits & (1 << nid_vol))) { 6578 /* first control for the volume widget */ 6579 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, vol_val); 6580 if (err < 0) 6581 return err; 6582 *vol_bits |= (1 << nid_vol); 6583 } 6584 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, sw_val); 6585 if (err < 0) 6586 return err; 6587 return 1; 6588} 6589 6590/* add playback controls from the parsed DAC table */ 6591static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec, 6592 const struct auto_pin_cfg *cfg) 6593{ 6594 hda_nid_t nid; 6595 int err; 6596 int vols = 0; 6597 6598 spec->multiout.num_dacs = 1; 6599 spec->multiout.dac_nids = spec->private_dac_nids; 6600 spec->multiout.dac_nids[0] = 0x02; 6601 6602 nid = cfg->line_out_pins[0]; 6603 if (nid) { 6604 const char *pfx; 6605 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0]) 6606 pfx = "Master"; 6607 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) 6608 pfx = "Speaker"; 6609 else 6610 pfx = "Front"; 6611 err = alc260_add_playback_controls(spec, nid, pfx, &vols); 6612 if (err < 0) 6613 return err; 6614 } 6615 6616 nid = cfg->speaker_pins[0]; 6617 if (nid) { 6618 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols); 6619 if (err < 0) 6620 return err; 6621 } 6622 6623 nid = cfg->hp_pins[0]; 6624 if (nid) { 6625 err = alc260_add_playback_controls(spec, nid, "Headphone", 6626 &vols); 6627 if (err < 0) 6628 return err; 6629 } 6630 return 0; 6631} 6632 6633/* create playback/capture controls for input pins */ 6634static int alc260_auto_create_input_ctls(struct hda_codec *codec, 6635 const struct auto_pin_cfg *cfg) 6636{ 6637 return alc_auto_create_input_ctls(codec, cfg, 0x07, 0x04, 0x05); 6638} 6639 6640static void alc260_auto_set_output_and_unmute(struct hda_codec *codec, 6641 hda_nid_t nid, int pin_type, 6642 int sel_idx) 6643{ 6644 alc_set_pin_output(codec, nid, pin_type); 6645 /* need the manual connection? */ 6646 if (nid >= 0x12) { 6647 int idx = nid - 0x12; 6648 snd_hda_codec_write(codec, idx + 0x0b, 0, 6649 AC_VERB_SET_CONNECT_SEL, sel_idx); 6650 } 6651} 6652 6653static void alc260_auto_init_multi_out(struct hda_codec *codec) 6654{ 6655 struct alc_spec *spec = codec->spec; 6656 hda_nid_t nid; 6657 6658 nid = spec->autocfg.line_out_pins[0]; 6659 if (nid) { 6660 int pin_type = get_pin_type(spec->autocfg.line_out_type); 6661 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0); 6662 } 6663 6664 nid = spec->autocfg.speaker_pins[0]; 6665 if (nid) 6666 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0); 6667 6668 nid = spec->autocfg.hp_pins[0]; 6669 if (nid) 6670 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0); 6671} 6672 6673#define ALC260_PIN_CD_NID 0x16 6674static void alc260_auto_init_analog_input(struct hda_codec *codec) 6675{ 6676 struct alc_spec *spec = codec->spec; 6677 struct auto_pin_cfg *cfg = &spec->autocfg; 6678 int i; 6679 6680 for (i = 0; i < cfg->num_inputs; i++) { 6681 hda_nid_t nid = cfg->inputs[i].pin; 6682 if (nid >= 0x12) { 6683 alc_set_input_pin(codec, nid, i); 6684 if (nid != ALC260_PIN_CD_NID && 6685 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)) 6686 snd_hda_codec_write(codec, nid, 0, 6687 AC_VERB_SET_AMP_GAIN_MUTE, 6688 AMP_OUT_MUTE); 6689 } 6690 } 6691} 6692 6693#define alc260_auto_init_input_src alc880_auto_init_input_src 6694 6695/* 6696 * generic initialization of ADC, input mixers and output mixers 6697 */ 6698static struct hda_verb alc260_volume_init_verbs[] = { 6699 /* 6700 * Unmute ADC0-1 and set the default input to mic-in 6701 */ 6702 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, 6703 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6704 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, 6705 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6706 6707 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 6708 * mixer widget 6709 * Note: PASD motherboards uses the Line In 2 as the input for 6710 * front panel mic (mic 2) 6711 */ 6712 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 6713 /* mute analog inputs */ 6714 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6715 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6716 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 6717 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 6718 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 6719 6720 /* 6721 * Set up output mixers (0x08 - 0x0a) 6722 */ 6723 /* set vol=0 to output mixers */ 6724 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6725 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6726 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6727 /* set up input amps for analog loopback */ 6728 /* Amp Indices: DAC = 0, mixer = 1 */ 6729 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6730 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 6731 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6732 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 6733 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6734 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 6735 6736 { } 6737}; 6738 6739static int alc260_parse_auto_config(struct hda_codec *codec) 6740{ 6741 struct alc_spec *spec = codec->spec; 6742 int err; 6743 static hda_nid_t alc260_ignore[] = { 0x17, 0 }; 6744 6745 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 6746 alc260_ignore); 6747 if (err < 0) 6748 return err; 6749 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg); 6750 if (err < 0) 6751 return err; 6752 if (!spec->kctls.list) 6753 return 0; /* can't find valid BIOS pin config */ 6754 err = alc260_auto_create_input_ctls(codec, &spec->autocfg); 6755 if (err < 0) 6756 return err; 6757 6758 spec->multiout.max_channels = 2; 6759 6760 if (spec->autocfg.dig_outs) 6761 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID; 6762 if (spec->kctls.list) 6763 add_mixer(spec, spec->kctls.list); 6764 6765 add_verb(spec, alc260_volume_init_verbs); 6766 6767 spec->num_mux_defs = 1; 6768 spec->input_mux = &spec->private_imux[0]; 6769 6770 alc_ssid_check(codec, 0x10, 0x15, 0x0f, 0); 6771 6772 return 1; 6773} 6774 6775/* additional initialization for auto-configuration model */ 6776static void alc260_auto_init(struct hda_codec *codec) 6777{ 6778 struct alc_spec *spec = codec->spec; 6779 alc260_auto_init_multi_out(codec); 6780 alc260_auto_init_analog_input(codec); 6781 alc260_auto_init_input_src(codec); 6782 alc_auto_init_digital(codec); 6783 if (spec->unsol_event) 6784 alc_inithook(codec); 6785} 6786 6787#ifdef CONFIG_SND_HDA_POWER_SAVE 6788static struct hda_amp_list alc260_loopbacks[] = { 6789 { 0x07, HDA_INPUT, 0 }, 6790 { 0x07, HDA_INPUT, 1 }, 6791 { 0x07, HDA_INPUT, 2 }, 6792 { 0x07, HDA_INPUT, 3 }, 6793 { 0x07, HDA_INPUT, 4 }, 6794 { } /* end */ 6795}; 6796#endif 6797 6798/* 6799 * Pin config fixes 6800 */ 6801enum { 6802 PINFIX_HP_DC5750, 6803}; 6804 6805static const struct alc_fixup alc260_fixups[] = { 6806 [PINFIX_HP_DC5750] = { 6807 .pins = (const struct alc_pincfg[]) { 6808 { 0x11, 0x90130110 }, /* speaker */ 6809 { } 6810 } 6811 }, 6812}; 6813 6814static struct snd_pci_quirk alc260_fixup_tbl[] = { 6815 SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", PINFIX_HP_DC5750), 6816 {} 6817}; 6818 6819/* 6820 * ALC260 configurations 6821 */ 6822static const char *alc260_models[ALC260_MODEL_LAST] = { 6823 [ALC260_BASIC] = "basic", 6824 [ALC260_HP] = "hp", 6825 [ALC260_HP_3013] = "hp-3013", 6826 [ALC260_HP_DC7600] = "hp-dc7600", 6827 [ALC260_FUJITSU_S702X] = "fujitsu", 6828 [ALC260_ACER] = "acer", 6829 [ALC260_WILL] = "will", 6830 [ALC260_REPLACER_672V] = "replacer", 6831 [ALC260_FAVORIT100] = "favorit100", 6832#ifdef CONFIG_SND_DEBUG 6833 [ALC260_TEST] = "test", 6834#endif 6835 [ALC260_AUTO] = "auto", 6836}; 6837 6838static struct snd_pci_quirk alc260_cfg_tbl[] = { 6839 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER), 6840 SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL), 6841 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER), 6842 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100), 6843 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013), 6844 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_AUTO), /* no quirk */ 6845 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013), 6846 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013), 6847 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600), 6848 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013), 6849 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP), 6850 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP), 6851 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP), 6852 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC), 6853 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC), 6854 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC), 6855 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X), 6856 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC), 6857 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V), 6858 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL), 6859 {} 6860}; 6861 6862static struct alc_config_preset alc260_presets[] = { 6863 [ALC260_BASIC] = { 6864 .mixers = { alc260_base_output_mixer, 6865 alc260_input_mixer }, 6866 .init_verbs = { alc260_init_verbs }, 6867 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 6868 .dac_nids = alc260_dac_nids, 6869 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids), 6870 .adc_nids = alc260_dual_adc_nids, 6871 .num_channel_mode = ARRAY_SIZE(alc260_modes), 6872 .channel_mode = alc260_modes, 6873 .input_mux = &alc260_capture_source, 6874 }, 6875 [ALC260_HP] = { 6876 .mixers = { alc260_hp_output_mixer, 6877 alc260_input_mixer }, 6878 .init_verbs = { alc260_init_verbs, 6879 alc260_hp_unsol_verbs }, 6880 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 6881 .dac_nids = alc260_dac_nids, 6882 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt), 6883 .adc_nids = alc260_adc_nids_alt, 6884 .num_channel_mode = ARRAY_SIZE(alc260_modes), 6885 .channel_mode = alc260_modes, 6886 .input_mux = &alc260_capture_source, 6887 .unsol_event = alc260_hp_unsol_event, 6888 .init_hook = alc260_hp_automute, 6889 }, 6890 [ALC260_HP_DC7600] = { 6891 .mixers = { alc260_hp_dc7600_mixer, 6892 alc260_input_mixer }, 6893 .init_verbs = { alc260_init_verbs, 6894 alc260_hp_dc7600_verbs }, 6895 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 6896 .dac_nids = alc260_dac_nids, 6897 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt), 6898 .adc_nids = alc260_adc_nids_alt, 6899 .num_channel_mode = ARRAY_SIZE(alc260_modes), 6900 .channel_mode = alc260_modes, 6901 .input_mux = &alc260_capture_source, 6902 .unsol_event = alc260_hp_3012_unsol_event, 6903 .init_hook = alc260_hp_3012_automute, 6904 }, 6905 [ALC260_HP_3013] = { 6906 .mixers = { alc260_hp_3013_mixer, 6907 alc260_input_mixer }, 6908 .init_verbs = { alc260_hp_3013_init_verbs, 6909 alc260_hp_3013_unsol_verbs }, 6910 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 6911 .dac_nids = alc260_dac_nids, 6912 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt), 6913 .adc_nids = alc260_adc_nids_alt, 6914 .num_channel_mode = ARRAY_SIZE(alc260_modes), 6915 .channel_mode = alc260_modes, 6916 .input_mux = &alc260_capture_source, 6917 .unsol_event = alc260_hp_3013_unsol_event, 6918 .init_hook = alc260_hp_3013_automute, 6919 }, 6920 [ALC260_FUJITSU_S702X] = { 6921 .mixers = { alc260_fujitsu_mixer }, 6922 .init_verbs = { alc260_fujitsu_init_verbs }, 6923 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 6924 .dac_nids = alc260_dac_nids, 6925 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids), 6926 .adc_nids = alc260_dual_adc_nids, 6927 .num_channel_mode = ARRAY_SIZE(alc260_modes), 6928 .channel_mode = alc260_modes, 6929 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources), 6930 .input_mux = alc260_fujitsu_capture_sources, 6931 }, 6932 [ALC260_ACER] = { 6933 .mixers = { alc260_acer_mixer }, 6934 .init_verbs = { alc260_acer_init_verbs }, 6935 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 6936 .dac_nids = alc260_dac_nids, 6937 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids), 6938 .adc_nids = alc260_dual_adc_nids, 6939 .num_channel_mode = ARRAY_SIZE(alc260_modes), 6940 .channel_mode = alc260_modes, 6941 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources), 6942 .input_mux = alc260_acer_capture_sources, 6943 }, 6944 [ALC260_FAVORIT100] = { 6945 .mixers = { alc260_favorit100_mixer }, 6946 .init_verbs = { alc260_favorit100_init_verbs }, 6947 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 6948 .dac_nids = alc260_dac_nids, 6949 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids), 6950 .adc_nids = alc260_dual_adc_nids, 6951 .num_channel_mode = ARRAY_SIZE(alc260_modes), 6952 .channel_mode = alc260_modes, 6953 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources), 6954 .input_mux = alc260_favorit100_capture_sources, 6955 }, 6956 [ALC260_WILL] = { 6957 .mixers = { alc260_will_mixer }, 6958 .init_verbs = { alc260_init_verbs, alc260_will_verbs }, 6959 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 6960 .dac_nids = alc260_dac_nids, 6961 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids), 6962 .adc_nids = alc260_adc_nids, 6963 .dig_out_nid = ALC260_DIGOUT_NID, 6964 .num_channel_mode = ARRAY_SIZE(alc260_modes), 6965 .channel_mode = alc260_modes, 6966 .input_mux = &alc260_capture_source, 6967 }, 6968 [ALC260_REPLACER_672V] = { 6969 .mixers = { alc260_replacer_672v_mixer }, 6970 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs }, 6971 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 6972 .dac_nids = alc260_dac_nids, 6973 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids), 6974 .adc_nids = alc260_adc_nids, 6975 .dig_out_nid = ALC260_DIGOUT_NID, 6976 .num_channel_mode = ARRAY_SIZE(alc260_modes), 6977 .channel_mode = alc260_modes, 6978 .input_mux = &alc260_capture_source, 6979 .unsol_event = alc260_replacer_672v_unsol_event, 6980 .init_hook = alc260_replacer_672v_automute, 6981 }, 6982#ifdef CONFIG_SND_DEBUG 6983 [ALC260_TEST] = { 6984 .mixers = { alc260_test_mixer }, 6985 .init_verbs = { alc260_test_init_verbs }, 6986 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids), 6987 .dac_nids = alc260_test_dac_nids, 6988 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids), 6989 .adc_nids = alc260_test_adc_nids, 6990 .num_channel_mode = ARRAY_SIZE(alc260_modes), 6991 .channel_mode = alc260_modes, 6992 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources), 6993 .input_mux = alc260_test_capture_sources, 6994 }, 6995#endif 6996}; 6997 6998static int patch_alc260(struct hda_codec *codec) 6999{ 7000 struct alc_spec *spec; 7001 int err, board_config; 7002 7003 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 7004 if (spec == NULL) 7005 return -ENOMEM; 7006 7007 codec->spec = spec; 7008 7009 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST, 7010 alc260_models, 7011 alc260_cfg_tbl); 7012 if (board_config < 0) { 7013 snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 7014 codec->chip_name); 7015 board_config = ALC260_AUTO; 7016 } 7017 7018 if (board_config == ALC260_AUTO) 7019 alc_pick_fixup(codec, alc260_fixup_tbl, alc260_fixups, 1); 7020 7021 if (board_config == ALC260_AUTO) { 7022 /* automatic parse from the BIOS config */ 7023 err = alc260_parse_auto_config(codec); 7024 if (err < 0) { 7025 alc_free(codec); 7026 return err; 7027 } else if (!err) { 7028 printk(KERN_INFO 7029 "hda_codec: Cannot set up configuration " 7030 "from BIOS. Using base mode...\n"); 7031 board_config = ALC260_BASIC; 7032 } 7033 } 7034 7035 err = snd_hda_attach_beep_device(codec, 0x1); 7036 if (err < 0) { 7037 alc_free(codec); 7038 return err; 7039 } 7040 7041 if (board_config != ALC260_AUTO) 7042 setup_preset(codec, &alc260_presets[board_config]); 7043 7044 spec->stream_analog_playback = &alc260_pcm_analog_playback; 7045 spec->stream_analog_capture = &alc260_pcm_analog_capture; 7046 spec->stream_analog_alt_capture = &alc260_pcm_analog_capture; 7047 7048 spec->stream_digital_playback = &alc260_pcm_digital_playback; 7049 spec->stream_digital_capture = &alc260_pcm_digital_capture; 7050 7051 if (!spec->adc_nids && spec->input_mux) { 7052 /* check whether NID 0x04 is valid */ 7053 unsigned int wcap = get_wcaps(codec, 0x04); 7054 wcap = get_wcaps_type(wcap); 7055 /* get type */ 7056 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) { 7057 spec->adc_nids = alc260_adc_nids_alt; 7058 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt); 7059 } else { 7060 spec->adc_nids = alc260_adc_nids; 7061 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids); 7062 } 7063 } 7064 set_capture_mixer(codec); 7065 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT); 7066 7067 if (board_config == ALC260_AUTO) 7068 alc_pick_fixup(codec, alc260_fixup_tbl, alc260_fixups, 0); 7069 7070 spec->vmaster_nid = 0x08; 7071 7072 codec->patch_ops = alc_patch_ops; 7073 if (board_config == ALC260_AUTO) 7074 spec->init_hook = alc260_auto_init; 7075#ifdef CONFIG_SND_HDA_POWER_SAVE 7076 if (!spec->loopback.amplist) 7077 spec->loopback.amplist = alc260_loopbacks; 7078#endif 7079 7080 return 0; 7081} 7082 7083 7084/* 7085 * ALC882/883/885/888/889 support 7086 * 7087 * ALC882 is almost identical with ALC880 but has cleaner and more flexible 7088 * configuration. Each pin widget can choose any input DACs and a mixer. 7089 * Each ADC is connected from a mixer of all inputs. This makes possible 7090 * 6-channel independent captures. 7091 * 7092 * In addition, an independent DAC for the multi-playback (not used in this 7093 * driver yet). 7094 */ 7095#define ALC882_DIGOUT_NID 0x06 7096#define ALC882_DIGIN_NID 0x0a 7097#define ALC883_DIGOUT_NID ALC882_DIGOUT_NID 7098#define ALC883_DIGIN_NID ALC882_DIGIN_NID 7099#define ALC1200_DIGOUT_NID 0x10 7100 7101 7102static struct hda_channel_mode alc882_ch_modes[1] = { 7103 { 8, NULL } 7104}; 7105 7106/* DACs */ 7107static hda_nid_t alc882_dac_nids[4] = { 7108 /* front, rear, clfe, rear_surr */ 7109 0x02, 0x03, 0x04, 0x05 7110}; 7111#define alc883_dac_nids alc882_dac_nids 7112 7113/* ADCs */ 7114#define alc882_adc_nids alc880_adc_nids 7115#define alc882_adc_nids_alt alc880_adc_nids_alt 7116#define alc883_adc_nids alc882_adc_nids_alt 7117static hda_nid_t alc883_adc_nids_alt[1] = { 0x08 }; 7118static hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 }; 7119#define alc889_adc_nids alc880_adc_nids 7120 7121static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 }; 7122static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 }; 7123#define alc883_capsrc_nids alc882_capsrc_nids_alt 7124static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 }; 7125#define alc889_capsrc_nids alc882_capsrc_nids 7126 7127/* input MUX */ 7128/* FIXME: should be a matrix-type input source selection */ 7129 7130static struct hda_input_mux alc882_capture_source = { 7131 .num_items = 4, 7132 .items = { 7133 { "Mic", 0x0 }, 7134 { "Front Mic", 0x1 }, 7135 { "Line", 0x2 }, 7136 { "CD", 0x4 }, 7137 }, 7138}; 7139 7140#define alc883_capture_source alc882_capture_source 7141 7142static struct hda_input_mux alc889_capture_source = { 7143 .num_items = 3, 7144 .items = { 7145 { "Front Mic", 0x0 }, 7146 { "Mic", 0x3 }, 7147 { "Line", 0x2 }, 7148 }, 7149}; 7150 7151static struct hda_input_mux mb5_capture_source = { 7152 .num_items = 3, 7153 .items = { 7154 { "Mic", 0x1 }, 7155 { "Line", 0x7 }, 7156 { "CD", 0x4 }, 7157 }, 7158}; 7159 7160static struct hda_input_mux macmini3_capture_source = { 7161 .num_items = 2, 7162 .items = { 7163 { "Line", 0x2 }, 7164 { "CD", 0x4 }, 7165 }, 7166}; 7167 7168static struct hda_input_mux alc883_3stack_6ch_intel = { 7169 .num_items = 4, 7170 .items = { 7171 { "Mic", 0x1 }, 7172 { "Front Mic", 0x0 }, 7173 { "Line", 0x2 }, 7174 { "CD", 0x4 }, 7175 }, 7176}; 7177 7178static struct hda_input_mux alc883_lenovo_101e_capture_source = { 7179 .num_items = 2, 7180 .items = { 7181 { "Mic", 0x1 }, 7182 { "Line", 0x2 }, 7183 }, 7184}; 7185 7186static struct hda_input_mux alc883_lenovo_nb0763_capture_source = { 7187 .num_items = 4, 7188 .items = { 7189 { "Mic", 0x0 }, 7190 { "Int Mic", 0x1 }, 7191 { "Line", 0x2 }, 7192 { "CD", 0x4 }, 7193 }, 7194}; 7195 7196static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = { 7197 .num_items = 2, 7198 .items = { 7199 { "Mic", 0x0 }, 7200 { "Int Mic", 0x1 }, 7201 }, 7202}; 7203 7204static struct hda_input_mux alc883_lenovo_sky_capture_source = { 7205 .num_items = 3, 7206 .items = { 7207 { "Mic", 0x0 }, 7208 { "Front Mic", 0x1 }, 7209 { "Line", 0x4 }, 7210 }, 7211}; 7212 7213static struct hda_input_mux alc883_asus_eee1601_capture_source = { 7214 .num_items = 2, 7215 .items = { 7216 { "Mic", 0x0 }, 7217 { "Line", 0x2 }, 7218 }, 7219}; 7220 7221static struct hda_input_mux alc889A_mb31_capture_source = { 7222 .num_items = 2, 7223 .items = { 7224 { "Mic", 0x0 }, 7225 /* Front Mic (0x01) unused */ 7226 { "Line", 0x2 }, 7227 /* Line 2 (0x03) unused */ 7228 /* CD (0x04) unused? */ 7229 }, 7230}; 7231 7232static struct hda_input_mux alc889A_imac91_capture_source = { 7233 .num_items = 2, 7234 .items = { 7235 { "Mic", 0x01 }, 7236 { "Line", 0x2 }, /* Not sure! */ 7237 }, 7238}; 7239 7240/* 7241 * 2ch mode 7242 */ 7243static struct hda_channel_mode alc883_3ST_2ch_modes[1] = { 7244 { 2, NULL } 7245}; 7246 7247/* 7248 * 2ch mode 7249 */ 7250static struct hda_verb alc882_3ST_ch2_init[] = { 7251 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 7252 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7253 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 7254 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7255 { } /* end */ 7256}; 7257 7258/* 7259 * 4ch mode 7260 */ 7261static struct hda_verb alc882_3ST_ch4_init[] = { 7262 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 7263 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7264 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7265 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7266 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7267 { } /* end */ 7268}; 7269 7270/* 7271 * 6ch mode 7272 */ 7273static struct hda_verb alc882_3ST_ch6_init[] = { 7274 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7275 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7276 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, 7277 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7278 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7279 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7280 { } /* end */ 7281}; 7282 7283static struct hda_channel_mode alc882_3ST_6ch_modes[3] = { 7284 { 2, alc882_3ST_ch2_init }, 7285 { 4, alc882_3ST_ch4_init }, 7286 { 6, alc882_3ST_ch6_init }, 7287}; 7288 7289#define alc883_3ST_6ch_modes alc882_3ST_6ch_modes 7290 7291/* 7292 * 2ch mode 7293 */ 7294static struct hda_verb alc883_3ST_ch2_clevo_init[] = { 7295 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, 7296 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 7297 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7298 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 7299 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7300 { } /* end */ 7301}; 7302 7303/* 7304 * 4ch mode 7305 */ 7306static struct hda_verb alc883_3ST_ch4_clevo_init[] = { 7307 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7308 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 7309 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7310 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7311 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7312 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7313 { } /* end */ 7314}; 7315 7316/* 7317 * 6ch mode 7318 */ 7319static struct hda_verb alc883_3ST_ch6_clevo_init[] = { 7320 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7321 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7322 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7323 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, 7324 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7325 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7326 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7327 { } /* end */ 7328}; 7329 7330static struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = { 7331 { 2, alc883_3ST_ch2_clevo_init }, 7332 { 4, alc883_3ST_ch4_clevo_init }, 7333 { 6, alc883_3ST_ch6_clevo_init }, 7334}; 7335 7336 7337/* 7338 * 6ch mode 7339 */ 7340static struct hda_verb alc882_sixstack_ch6_init[] = { 7341 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 7342 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7343 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7344 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7345 { } /* end */ 7346}; 7347 7348/* 7349 * 8ch mode 7350 */ 7351static struct hda_verb alc882_sixstack_ch8_init[] = { 7352 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7353 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7354 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7355 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7356 { } /* end */ 7357}; 7358 7359static struct hda_channel_mode alc882_sixstack_modes[2] = { 7360 { 6, alc882_sixstack_ch6_init }, 7361 { 8, alc882_sixstack_ch8_init }, 7362}; 7363 7364 7365/* Macbook Air 2,1 */ 7366 7367static struct hda_channel_mode alc885_mba21_ch_modes[1] = { 7368 { 2, NULL }, 7369}; 7370 7371/* 7372 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic 7373 */ 7374 7375/* 7376 * 2ch mode 7377 */ 7378static struct hda_verb alc885_mbp_ch2_init[] = { 7379 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 7380 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7381 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7382 { } /* end */ 7383}; 7384 7385/* 7386 * 4ch mode 7387 */ 7388static struct hda_verb alc885_mbp_ch4_init[] = { 7389 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7390 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7391 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7392 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7393 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 7394 { } /* end */ 7395}; 7396 7397static struct hda_channel_mode alc885_mbp_4ch_modes[2] = { 7398 { 2, alc885_mbp_ch2_init }, 7399 { 4, alc885_mbp_ch4_init }, 7400}; 7401 7402/* 7403 * 2ch 7404 * Speakers/Woofer/HP = Front 7405 * LineIn = Input 7406 */ 7407static struct hda_verb alc885_mb5_ch2_init[] = { 7408 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 7409 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 7410 { } /* end */ 7411}; 7412 7413/* 7414 * 6ch mode 7415 * Speakers/HP = Front 7416 * Woofer = LFE 7417 * LineIn = Surround 7418 */ 7419static struct hda_verb alc885_mb5_ch6_init[] = { 7420 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 7421 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7422 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 7423 { } /* end */ 7424}; 7425 7426static struct hda_channel_mode alc885_mb5_6ch_modes[2] = { 7427 { 2, alc885_mb5_ch2_init }, 7428 { 6, alc885_mb5_ch6_init }, 7429}; 7430 7431#define alc885_macmini3_6ch_modes alc885_mb5_6ch_modes 7432 7433/* 7434 * 2ch mode 7435 */ 7436static struct hda_verb alc883_4ST_ch2_init[] = { 7437 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7438 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7439 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 7440 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7441 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 7442 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7443 { } /* end */ 7444}; 7445 7446/* 7447 * 4ch mode 7448 */ 7449static struct hda_verb alc883_4ST_ch4_init[] = { 7450 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7451 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7452 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 7453 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7454 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7455 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7456 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7457 { } /* end */ 7458}; 7459 7460/* 7461 * 6ch mode 7462 */ 7463static struct hda_verb alc883_4ST_ch6_init[] = { 7464 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7465 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7466 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7467 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7468 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, 7469 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7470 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7471 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7472 { } /* end */ 7473}; 7474 7475/* 7476 * 8ch mode 7477 */ 7478static struct hda_verb alc883_4ST_ch8_init[] = { 7479 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7480 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7481 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 }, 7482 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7483 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7484 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, 7485 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7486 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7487 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7488 { } /* end */ 7489}; 7490 7491static struct hda_channel_mode alc883_4ST_8ch_modes[4] = { 7492 { 2, alc883_4ST_ch2_init }, 7493 { 4, alc883_4ST_ch4_init }, 7494 { 6, alc883_4ST_ch6_init }, 7495 { 8, alc883_4ST_ch8_init }, 7496}; 7497 7498 7499/* 7500 * 2ch mode 7501 */ 7502static struct hda_verb alc883_3ST_ch2_intel_init[] = { 7503 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 7504 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7505 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 7506 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7507 { } /* end */ 7508}; 7509 7510/* 7511 * 4ch mode 7512 */ 7513static struct hda_verb alc883_3ST_ch4_intel_init[] = { 7514 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 7515 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7516 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7517 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7518 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7519 { } /* end */ 7520}; 7521 7522/* 7523 * 6ch mode 7524 */ 7525static struct hda_verb alc883_3ST_ch6_intel_init[] = { 7526 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7527 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7528 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 }, 7529 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7530 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7531 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7532 { } /* end */ 7533}; 7534 7535static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = { 7536 { 2, alc883_3ST_ch2_intel_init }, 7537 { 4, alc883_3ST_ch4_intel_init }, 7538 { 6, alc883_3ST_ch6_intel_init }, 7539}; 7540 7541/* 7542 * 2ch mode 7543 */ 7544static struct hda_verb alc889_ch2_intel_init[] = { 7545 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 }, 7546 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 }, 7547 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 }, 7548 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00 }, 7549 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 7550 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7551 { } /* end */ 7552}; 7553 7554/* 7555 * 6ch mode 7556 */ 7557static struct hda_verb alc889_ch6_intel_init[] = { 7558 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 }, 7559 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7560 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 }, 7561 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 }, 7562 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 7563 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7564 { } /* end */ 7565}; 7566 7567/* 7568 * 8ch mode 7569 */ 7570static struct hda_verb alc889_ch8_intel_init[] = { 7571 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 }, 7572 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7573 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 }, 7574 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 }, 7575 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x03 }, 7576 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7577 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7578 { } /* end */ 7579}; 7580 7581static struct hda_channel_mode alc889_8ch_intel_modes[3] = { 7582 { 2, alc889_ch2_intel_init }, 7583 { 6, alc889_ch6_intel_init }, 7584 { 8, alc889_ch8_intel_init }, 7585}; 7586 7587/* 7588 * 6ch mode 7589 */ 7590static struct hda_verb alc883_sixstack_ch6_init[] = { 7591 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 7592 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7593 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7594 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7595 { } /* end */ 7596}; 7597 7598/* 7599 * 8ch mode 7600 */ 7601static struct hda_verb alc883_sixstack_ch8_init[] = { 7602 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7603 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7604 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7605 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7606 { } /* end */ 7607}; 7608 7609static struct hda_channel_mode alc883_sixstack_modes[2] = { 7610 { 6, alc883_sixstack_ch6_init }, 7611 { 8, alc883_sixstack_ch8_init }, 7612}; 7613 7614 7615/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 7616 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b 7617 */ 7618static struct snd_kcontrol_new alc882_base_mixer[] = { 7619 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7620 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 7621 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 7622 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 7623 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 7624 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 7625 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 7626 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 7627 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 7628 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 7629 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 7630 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 7631 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 7632 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 7633 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 7634 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7635 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 7636 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7637 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 7638 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 7639 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 7640 { } /* end */ 7641}; 7642 7643/* Macbook Air 2,1 same control for HP and internal Speaker */ 7644 7645static struct snd_kcontrol_new alc885_mba21_mixer[] = { 7646 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 7647 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT), 7648 { } 7649}; 7650 7651 7652static struct snd_kcontrol_new alc885_mbp3_mixer[] = { 7653 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 7654 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT), 7655 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT), 7656 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0e, 0x02, HDA_INPUT), 7657 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT), 7658 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 7659 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 7660 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT), 7661 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT), 7662 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT), 7663 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT), 7664 { } /* end */ 7665}; 7666 7667static struct snd_kcontrol_new alc885_mb5_mixer[] = { 7668 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 7669 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT), 7670 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT), 7671 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT), 7672 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT), 7673 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT), 7674 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT), 7675 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT), 7676 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT), 7677 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT), 7678 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 7679 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 7680 HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT), 7681 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0x00, HDA_INPUT), 7682 { } /* end */ 7683}; 7684 7685static struct snd_kcontrol_new alc885_macmini3_mixer[] = { 7686 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 7687 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT), 7688 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT), 7689 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT), 7690 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT), 7691 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT), 7692 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT), 7693 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT), 7694 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT), 7695 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT), 7696 HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT), 7697 { } /* end */ 7698}; 7699 7700static struct snd_kcontrol_new alc885_imac91_mixer[] = { 7701 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 7702 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT), 7703 { } /* end */ 7704}; 7705 7706 7707static struct snd_kcontrol_new alc882_w2jc_mixer[] = { 7708 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7709 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 7710 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 7711 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 7712 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 7713 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 7714 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7715 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 7716 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7717 { } /* end */ 7718}; 7719 7720static struct snd_kcontrol_new alc882_targa_mixer[] = { 7721 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7722 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 7723 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 7724 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 7725 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 7726 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 7727 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 7728 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7729 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7730 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 7731 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 7732 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 7733 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 7734 { } /* end */ 7735}; 7736 7737/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ??? 7738 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c 7739 */ 7740static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = { 7741 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7742 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 7743 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 7744 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT), 7745 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 7746 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 7747 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 7748 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 7749 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT), 7750 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT), 7751 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7752 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7753 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 7754 { } /* end */ 7755}; 7756 7757static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = { 7758 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7759 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 7760 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 7761 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 7762 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 7763 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 7764 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 7765 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7766 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 7767 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7768 { } /* end */ 7769}; 7770 7771static struct snd_kcontrol_new alc882_chmode_mixer[] = { 7772 { 7773 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 7774 .name = "Channel Mode", 7775 .info = alc_ch_mode_info, 7776 .get = alc_ch_mode_get, 7777 .put = alc_ch_mode_put, 7778 }, 7779 { } /* end */ 7780}; 7781 7782static struct hda_verb alc882_base_init_verbs[] = { 7783 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 7784 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7785 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7786 /* Rear mixer */ 7787 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7788 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7789 /* CLFE mixer */ 7790 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7791 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7792 /* Side mixer */ 7793 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7794 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7795 7796 /* Front Pin: output 0 (0x0c) */ 7797 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 7798 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7799 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 7800 /* Rear Pin: output 1 (0x0d) */ 7801 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 7802 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7803 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 7804 /* CLFE Pin: output 2 (0x0e) */ 7805 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 7806 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7807 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, 7808 /* Side Pin: output 3 (0x0f) */ 7809 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 7810 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7811 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, 7812 /* Mic (rear) pin: input vref at 80% */ 7813 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 7814 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 7815 /* Front Mic pin: input vref at 80% */ 7816 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 7817 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 7818 /* Line In pin: input */ 7819 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 7820 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 7821 /* Line-2 In: Headphone output (output 0 - 0x0c) */ 7822 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 7823 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7824 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 7825 /* CD pin widget for input */ 7826 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 7827 7828 /* FIXME: use matrix-type input source selection */ 7829 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 7830 /* Input mixer2 */ 7831 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7832 /* Input mixer3 */ 7833 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7834 /* ADC2: mute amp left and right */ 7835 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7836 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 7837 /* ADC3: mute amp left and right */ 7838 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7839 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 7840 7841 { } 7842}; 7843 7844static struct hda_verb alc882_adc1_init_verbs[] = { 7845 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 7846 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7847 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 7848 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 7849 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 7850 /* ADC1: mute amp left and right */ 7851 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7852 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 7853 { } 7854}; 7855 7856static struct hda_verb alc882_eapd_verbs[] = { 7857 /* change to EAPD mode */ 7858 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 7859 {0x20, AC_VERB_SET_PROC_COEF, 0x3060}, 7860 { } 7861}; 7862 7863static struct hda_verb alc889_eapd_verbs[] = { 7864 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 7865 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, 7866 { } 7867}; 7868 7869static struct hda_verb alc_hp15_unsol_verbs[] = { 7870 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 7871 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 7872 {} 7873}; 7874 7875static struct hda_verb alc885_init_verbs[] = { 7876 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 7877 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7878 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 7879 /* Rear mixer */ 7880 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7881 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 7882 /* CLFE mixer */ 7883 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7884 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 7885 /* Side mixer */ 7886 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7887 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 7888 7889 /* Front HP Pin: output 0 (0x0c) */ 7890 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 7891 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7892 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 7893 /* Front Pin: output 0 (0x0c) */ 7894 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 7895 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7896 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 7897 /* Rear Pin: output 1 (0x0d) */ 7898 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 7899 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7900 {0x19, AC_VERB_SET_CONNECT_SEL, 0x01}, 7901 /* CLFE Pin: output 2 (0x0e) */ 7902 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 7903 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7904 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, 7905 /* Side Pin: output 3 (0x0f) */ 7906 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 7907 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7908 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, 7909 /* Mic (rear) pin: input vref at 80% */ 7910 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 7911 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 7912 /* Front Mic pin: input vref at 80% */ 7913 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 7914 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 7915 /* Line In pin: input */ 7916 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 7917 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 7918 7919 /* Mixer elements: 0x18, , 0x1a, 0x1b */ 7920 /* Input mixer1 */ 7921 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7922 /* Input mixer2 */ 7923 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7924 /* Input mixer3 */ 7925 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7926 /* ADC2: mute amp left and right */ 7927 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7928 /* ADC3: mute amp left and right */ 7929 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7930 7931 { } 7932}; 7933 7934static struct hda_verb alc885_init_input_verbs[] = { 7935 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7936 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 7937 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 7938 { } 7939}; 7940 7941 7942/* Unmute Selector 24h and set the default input to front mic */ 7943static struct hda_verb alc889_init_input_verbs[] = { 7944 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00}, 7945 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7946 { } 7947}; 7948 7949 7950#define alc883_init_verbs alc882_base_init_verbs 7951 7952/* Mac Pro test */ 7953static struct snd_kcontrol_new alc882_macpro_mixer[] = { 7954 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7955 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 7956 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT), 7957 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT), 7958 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT), 7959 /* FIXME: this looks suspicious... 7960 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x02, HDA_INPUT), 7961 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x02, HDA_INPUT), 7962 */ 7963 { } /* end */ 7964}; 7965 7966static struct hda_verb alc882_macpro_init_verbs[] = { 7967 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 7968 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 7969 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7970 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7971 /* Front Pin: output 0 (0x0c) */ 7972 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 7973 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7974 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 7975 /* Front Mic pin: input vref at 80% */ 7976 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 7977 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 7978 /* Speaker: output */ 7979 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 7980 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7981 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04}, 7982 /* Headphone output (output 0 - 0x0c) */ 7983 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 7984 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7985 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00}, 7986 7987 /* FIXME: use matrix-type input source selection */ 7988 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 7989 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 7990 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7991 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 7992 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 7993 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 7994 /* Input mixer2 */ 7995 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7996 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 7997 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 7998 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 7999 /* Input mixer3 */ 8000 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8001 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8002 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 8003 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8004 /* ADC1: mute amp left and right */ 8005 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8006 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 8007 /* ADC2: mute amp left and right */ 8008 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8009 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 8010 /* ADC3: mute amp left and right */ 8011 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8012 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 8013 8014 { } 8015}; 8016 8017/* Macbook 5,1 */ 8018static struct hda_verb alc885_mb5_init_verbs[] = { 8019 /* DACs */ 8020 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8021 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8022 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8023 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8024 /* Front mixer */ 8025 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8026 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8027 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8028 /* Surround mixer */ 8029 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8030 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8031 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8032 /* LFE mixer */ 8033 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8034 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8035 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8036 /* HP mixer */ 8037 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8038 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8039 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8040 /* Front Pin (0x0c) */ 8041 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01}, 8042 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8043 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00}, 8044 /* LFE Pin (0x0e) */ 8045 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01}, 8046 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8047 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, 8048 /* HP Pin (0x0f) */ 8049 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8050 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8051 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03}, 8052 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 8053 /* Front Mic pin: input vref at 80% */ 8054 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 8055 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8056 /* Line In pin */ 8057 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 8058 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8059 8060 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0x1)}, 8061 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x7)}, 8062 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x4)}, 8063 { } 8064}; 8065 8066/* Macmini 3,1 */ 8067static struct hda_verb alc885_macmini3_init_verbs[] = { 8068 /* DACs */ 8069 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8070 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8071 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8072 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8073 /* Front mixer */ 8074 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8075 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8076 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8077 /* Surround mixer */ 8078 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8079 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8080 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8081 /* LFE mixer */ 8082 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8083 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8084 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8085 /* HP mixer */ 8086 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8087 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8088 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8089 /* Front Pin (0x0c) */ 8090 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01}, 8091 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8092 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00}, 8093 /* LFE Pin (0x0e) */ 8094 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01}, 8095 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8096 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, 8097 /* HP Pin (0x0f) */ 8098 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8099 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8100 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03}, 8101 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 8102 /* Line In pin */ 8103 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 8104 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8105 8106 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8107 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8108 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 8109 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8110 { } 8111}; 8112 8113 8114static struct hda_verb alc885_mba21_init_verbs[] = { 8115 /*Internal and HP Speaker Mixer*/ 8116 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8117 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8118 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8119 /*Internal Speaker Pin (0x0c)*/ 8120 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) }, 8121 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8122 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00}, 8123 /* HP Pin: output 0 (0x0e) */ 8124 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, 8125 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8126 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 8127 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)}, 8128 /* Line in (is hp when jack connected)*/ 8129 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50}, 8130 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8131 8132 { } 8133 }; 8134 8135 8136/* Macbook Pro rev3 */ 8137static struct hda_verb alc885_mbp3_init_verbs[] = { 8138 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 8139 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8140 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8141 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8142 /* Rear mixer */ 8143 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8144 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8145 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8146 /* HP mixer */ 8147 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8148 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8149 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8150 /* Front Pin: output 0 (0x0c) */ 8151 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8152 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8153 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 8154 /* HP Pin: output 0 (0x0e) */ 8155 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, 8156 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8157 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02}, 8158 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 8159 /* Mic (rear) pin: input vref at 80% */ 8160 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 8161 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8162 /* Front Mic pin: input vref at 80% */ 8163 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 8164 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8165 /* Line In pin: use output 1 when in LineOut mode */ 8166 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 8167 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8168 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, 8169 8170 /* FIXME: use matrix-type input source selection */ 8171 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 8172 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 8173 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8174 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8175 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 8176 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8177 /* Input mixer2 */ 8178 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8179 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8180 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 8181 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8182 /* Input mixer3 */ 8183 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8184 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8185 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 8186 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8187 /* ADC1: mute amp left and right */ 8188 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8189 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 8190 /* ADC2: mute amp left and right */ 8191 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8192 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 8193 /* ADC3: mute amp left and right */ 8194 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8195 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 8196 8197 { } 8198}; 8199 8200/* iMac 9,1 */ 8201static struct hda_verb alc885_imac91_init_verbs[] = { 8202 /* Internal Speaker Pin (0x0c) */ 8203 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) }, 8204 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8205 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00}, 8206 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) }, 8207 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8208 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00}, 8209 /* HP Pin: Rear */ 8210 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8211 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8212 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 8213 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)}, 8214 /* Line in Rear */ 8215 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50}, 8216 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8217 /* Front Mic pin: input vref at 80% */ 8218 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 8219 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8220 /* Rear mixer */ 8221 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8222 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8223 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8224 /* Line-Out mixer: unmute input/output amp left and right (volume = 0) */ 8225 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8226 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8227 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8228 /* 0x24 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */ 8229 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8230 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8231 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 8232 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8233 /* 0x23 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */ 8234 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8235 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8236 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 8237 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8238 /* 0x22 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */ 8239 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8240 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8241 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 8242 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8243 /* 0x07 [Audio Input] wcaps 0x10011b: Stereo Amp-In */ 8244 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8245 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 8246 /* 0x08 [Audio Input] wcaps 0x10011b: Stereo Amp-In */ 8247 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8248 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 8249 /* 0x09 [Audio Input] wcaps 0x10011b: Stereo Amp-In */ 8250 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8251 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 8252 { } 8253}; 8254 8255/* iMac 24 mixer. */ 8256static struct snd_kcontrol_new alc885_imac24_mixer[] = { 8257 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 8258 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT), 8259 { } /* end */ 8260}; 8261 8262/* iMac 24 init verbs. */ 8263static struct hda_verb alc885_imac24_init_verbs[] = { 8264 /* Internal speakers: output 0 (0x0c) */ 8265 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8266 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8267 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00}, 8268 /* Internal speakers: output 0 (0x0c) */ 8269 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8270 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8271 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00}, 8272 /* Headphone: output 0 (0x0c) */ 8273 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8274 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8275 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 8276 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 8277 /* Front Mic: input vref at 80% */ 8278 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 8279 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8280 { } 8281}; 8282 8283/* Toggle speaker-output according to the hp-jack state */ 8284static void alc885_imac24_setup(struct hda_codec *codec) 8285{ 8286 struct alc_spec *spec = codec->spec; 8287 8288 spec->autocfg.hp_pins[0] = 0x14; 8289 spec->autocfg.speaker_pins[0] = 0x18; 8290 spec->autocfg.speaker_pins[1] = 0x1a; 8291} 8292 8293#define alc885_mb5_setup alc885_imac24_setup 8294#define alc885_macmini3_setup alc885_imac24_setup 8295 8296/* Macbook Air 2,1 */ 8297static void alc885_mba21_setup(struct hda_codec *codec) 8298{ 8299 struct alc_spec *spec = codec->spec; 8300 8301 spec->autocfg.hp_pins[0] = 0x14; 8302 spec->autocfg.speaker_pins[0] = 0x18; 8303} 8304 8305 8306 8307static void alc885_mbp3_setup(struct hda_codec *codec) 8308{ 8309 struct alc_spec *spec = codec->spec; 8310 8311 spec->autocfg.hp_pins[0] = 0x15; 8312 spec->autocfg.speaker_pins[0] = 0x14; 8313} 8314 8315static void alc885_imac91_setup(struct hda_codec *codec) 8316{ 8317 struct alc_spec *spec = codec->spec; 8318 8319 spec->autocfg.hp_pins[0] = 0x14; 8320 spec->autocfg.speaker_pins[0] = 0x18; 8321 spec->autocfg.speaker_pins[1] = 0x1a; 8322} 8323 8324static struct hda_verb alc882_targa_verbs[] = { 8325 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8326 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8327 8328 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8329 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8330 8331 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ 8332 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */ 8333 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 8334 8335 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 8336 { } /* end */ 8337}; 8338 8339/* toggle speaker-output according to the hp-jack state */ 8340static void alc882_targa_automute(struct hda_codec *codec) 8341{ 8342 struct alc_spec *spec = codec->spec; 8343 alc_automute_amp(codec); 8344 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA, 8345 spec->jack_present ? 1 : 3); 8346} 8347 8348static void alc882_targa_setup(struct hda_codec *codec) 8349{ 8350 struct alc_spec *spec = codec->spec; 8351 8352 spec->autocfg.hp_pins[0] = 0x14; 8353 spec->autocfg.speaker_pins[0] = 0x1b; 8354} 8355 8356static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res) 8357{ 8358 if ((res >> 26) == ALC880_HP_EVENT) 8359 alc882_targa_automute(codec); 8360} 8361 8362static struct hda_verb alc882_asus_a7j_verbs[] = { 8363 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8364 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8365 8366 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8367 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8368 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8369 8370 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */ 8371 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 8372 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */ 8373 8374 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ 8375 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */ 8376 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 8377 { } /* end */ 8378}; 8379 8380static struct hda_verb alc882_asus_a7m_verbs[] = { 8381 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8382 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8383 8384 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8385 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8386 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8387 8388 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */ 8389 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 8390 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */ 8391 8392 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ 8393 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */ 8394 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 8395 { } /* end */ 8396}; 8397 8398static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted) 8399{ 8400 unsigned int gpiostate, gpiomask, gpiodir; 8401 8402 gpiostate = snd_hda_codec_read(codec, codec->afg, 0, 8403 AC_VERB_GET_GPIO_DATA, 0); 8404 8405 if (!muted) 8406 gpiostate |= (1 << pin); 8407 else 8408 gpiostate &= ~(1 << pin); 8409 8410 gpiomask = snd_hda_codec_read(codec, codec->afg, 0, 8411 AC_VERB_GET_GPIO_MASK, 0); 8412 gpiomask |= (1 << pin); 8413 8414 gpiodir = snd_hda_codec_read(codec, codec->afg, 0, 8415 AC_VERB_GET_GPIO_DIRECTION, 0); 8416 gpiodir |= (1 << pin); 8417 8418 8419 snd_hda_codec_write(codec, codec->afg, 0, 8420 AC_VERB_SET_GPIO_MASK, gpiomask); 8421 snd_hda_codec_write(codec, codec->afg, 0, 8422 AC_VERB_SET_GPIO_DIRECTION, gpiodir); 8423 8424 msleep(1); 8425 8426 snd_hda_codec_write(codec, codec->afg, 0, 8427 AC_VERB_SET_GPIO_DATA, gpiostate); 8428} 8429 8430/* set up GPIO at initialization */ 8431static void alc885_macpro_init_hook(struct hda_codec *codec) 8432{ 8433 alc882_gpio_mute(codec, 0, 0); 8434 alc882_gpio_mute(codec, 1, 0); 8435} 8436 8437/* set up GPIO and update auto-muting at initialization */ 8438static void alc885_imac24_init_hook(struct hda_codec *codec) 8439{ 8440 alc885_macpro_init_hook(codec); 8441 alc_automute_amp(codec); 8442} 8443 8444/* 8445 * generic initialization of ADC, input mixers and output mixers 8446 */ 8447static struct hda_verb alc883_auto_init_verbs[] = { 8448 /* 8449 * Unmute ADC0-2 and set the default input to mic-in 8450 */ 8451 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 8452 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8453 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 8454 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8455 8456 /* 8457 * Set up output mixers (0x0c - 0x0f) 8458 */ 8459 /* set vol=0 to output mixers */ 8460 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8461 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8462 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8463 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8464 /* set up input amps for analog loopback */ 8465 /* Amp Indices: DAC = 0, mixer = 1 */ 8466 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8467 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8468 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8469 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8470 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8471 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8472 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8473 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8474 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8475 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8476 8477 /* FIXME: use matrix-type input source selection */ 8478 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 8479 /* Input mixer2 */ 8480 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8481 /* Input mixer3 */ 8482 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8483 { } 8484}; 8485 8486/* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */ 8487static struct hda_verb alc889A_mb31_ch2_init[] = { 8488 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */ 8489 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */ 8490 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */ 8491 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */ 8492 { } /* end */ 8493}; 8494 8495/* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */ 8496static struct hda_verb alc889A_mb31_ch4_init[] = { 8497 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */ 8498 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */ 8499 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */ 8500 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */ 8501 { } /* end */ 8502}; 8503 8504/* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */ 8505static struct hda_verb alc889A_mb31_ch5_init[] = { 8506 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */ 8507 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */ 8508 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */ 8509 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */ 8510 { } /* end */ 8511}; 8512 8513/* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */ 8514static struct hda_verb alc889A_mb31_ch6_init[] = { 8515 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */ 8516 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */ 8517 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */ 8518 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */ 8519 { } /* end */ 8520}; 8521 8522static struct hda_channel_mode alc889A_mb31_6ch_modes[4] = { 8523 { 2, alc889A_mb31_ch2_init }, 8524 { 4, alc889A_mb31_ch4_init }, 8525 { 5, alc889A_mb31_ch5_init }, 8526 { 6, alc889A_mb31_ch6_init }, 8527}; 8528 8529static struct hda_verb alc883_medion_eapd_verbs[] = { 8530 /* eanable EAPD on medion laptop */ 8531 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 8532 {0x20, AC_VERB_SET_PROC_COEF, 0x3070}, 8533 { } 8534}; 8535 8536#define alc883_base_mixer alc882_base_mixer 8537 8538static struct snd_kcontrol_new alc883_mitac_mixer[] = { 8539 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8540 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8541 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 8542 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 8543 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 8544 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 8545 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 8546 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8547 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8548 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8549 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8550 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 8551 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8552 { } /* end */ 8553}; 8554 8555static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = { 8556 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8557 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), 8558 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 8559 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 8560 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8561 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8562 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8563 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8564 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 8565 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8566 { } /* end */ 8567}; 8568 8569static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = { 8570 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8571 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), 8572 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 8573 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 8574 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8575 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8576 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8577 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8578 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 8579 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8580 { } /* end */ 8581}; 8582 8583static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = { 8584 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8585 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8586 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 8587 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 8588 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 8589 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8590 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8591 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8592 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8593 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8594 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8595 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 8596 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8597 { } /* end */ 8598}; 8599 8600static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = { 8601 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8602 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8603 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 8604 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 8605 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 8606 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 8607 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 8608 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 8609 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 8610 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 8611 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 8612 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8613 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8614 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8615 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8616 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8617 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8618 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 8619 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8620 { } /* end */ 8621}; 8622 8623static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = { 8624 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8625 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8626 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 8627 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 8628 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, 8629 HDA_OUTPUT), 8630 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 8631 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 8632 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 8633 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 8634 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 8635 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 8636 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8637 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8638 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8639 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT), 8640 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8641 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8642 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT), 8643 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8644 { } /* end */ 8645}; 8646 8647static struct snd_kcontrol_new alc885_8ch_intel_mixer[] = { 8648 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8649 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8650 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 8651 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 8652 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, 8653 HDA_OUTPUT), 8654 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 8655 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 8656 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 8657 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 8658 HDA_BIND_MUTE("Speaker Playback Switch", 0x0f, 2, HDA_INPUT), 8659 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 8660 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8661 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8662 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT), 8663 HDA_CODEC_VOLUME("Mic Boost", 0x1b, 0, HDA_INPUT), 8664 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT), 8665 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8666 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT), 8667 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8668 { } /* end */ 8669}; 8670 8671static struct snd_kcontrol_new alc883_fivestack_mixer[] = { 8672 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8673 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8674 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 8675 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 8676 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 8677 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 8678 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 8679 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 8680 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 8681 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 8682 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 8683 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8684 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8685 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8686 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8687 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8688 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8689 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 8690 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8691 { } /* end */ 8692}; 8693 8694static struct snd_kcontrol_new alc883_targa_mixer[] = { 8695 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8696 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8697 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 8698 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 8699 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 8700 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 8701 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 8702 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 8703 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 8704 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 8705 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 8706 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 8707 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8708 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8709 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8710 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8711 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8712 { } /* end */ 8713}; 8714 8715static struct snd_kcontrol_new alc883_targa_2ch_mixer[] = { 8716 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8717 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8718 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 8719 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 8720 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 8721 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 8722 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8723 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8724 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8725 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8726 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 8727 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8728 { } /* end */ 8729}; 8730 8731static struct snd_kcontrol_new alc883_targa_8ch_mixer[] = { 8732 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 8733 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 8734 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8735 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 8736 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8737 { } /* end */ 8738}; 8739 8740static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = { 8741 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8742 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8743 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 8744 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 8745 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 8746 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8747 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8748 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8749 { } /* end */ 8750}; 8751 8752static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = { 8753 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8754 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT), 8755 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 8756 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 8757 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 8758 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8759 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8760 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8761 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8762 { } /* end */ 8763}; 8764 8765static struct snd_kcontrol_new alc883_medion_md2_mixer[] = { 8766 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8767 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 8768 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT), 8769 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 8770 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 8771 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8772 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8773 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8774 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8775 { } /* end */ 8776}; 8777 8778static struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = { 8779 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8780 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8781 HDA_CODEC_MUTE("Speaker Playback Switch", 0x15, 0x0, HDA_OUTPUT), 8782 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT), 8783 HDA_CODEC_VOLUME("Line Playback Volume", 0x08, 0x0, HDA_INPUT), 8784 HDA_CODEC_MUTE("Line Playback Switch", 0x08, 0x0, HDA_INPUT), 8785 { } /* end */ 8786}; 8787 8788static struct hda_verb alc883_medion_wim2160_verbs[] = { 8789 /* Unmute front mixer */ 8790 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8791 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8792 8793 /* Set speaker pin to front mixer */ 8794 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 8795 8796 /* Init headphone pin */ 8797 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8798 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8799 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00}, 8800 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 8801 8802 { } /* end */ 8803}; 8804 8805/* toggle speaker-output according to the hp-jack state */ 8806static void alc883_medion_wim2160_setup(struct hda_codec *codec) 8807{ 8808 struct alc_spec *spec = codec->spec; 8809 8810 spec->autocfg.hp_pins[0] = 0x1a; 8811 spec->autocfg.speaker_pins[0] = 0x15; 8812} 8813 8814static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = { 8815 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8816 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8817 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 8818 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8819 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8820 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8821 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8822 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8823 { } /* end */ 8824}; 8825 8826static struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = { 8827 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8828 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 8829 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8830 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8831 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 8832 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 8833 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8834 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8835 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8836 { } /* end */ 8837}; 8838 8839static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = { 8840 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8841 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8842 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT), 8843 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT), 8844 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 8845 0x0d, 1, 0x0, HDA_OUTPUT), 8846 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT), 8847 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT), 8848 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT), 8849 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 8850 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 8851 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 8852 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 8853 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8854 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8855 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8856 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8857 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8858 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8859 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 8860 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8861 { } /* end */ 8862}; 8863 8864static struct snd_kcontrol_new alc889A_mb31_mixer[] = { 8865 /* Output mixers */ 8866 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 8867 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT), 8868 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT), 8869 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT), 8870 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00, 8871 HDA_OUTPUT), 8872 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT), 8873 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT), 8874 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT), 8875 /* Output switches */ 8876 HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT), 8877 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT), 8878 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT), 8879 /* Boost mixers */ 8880 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT), 8881 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT), 8882 /* Input mixers */ 8883 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT), 8884 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT), 8885 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8886 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8887 { } /* end */ 8888}; 8889 8890static struct snd_kcontrol_new alc883_vaiott_mixer[] = { 8891 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8892 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8893 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 8894 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8895 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT), 8896 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8897 { } /* end */ 8898}; 8899 8900static struct hda_bind_ctls alc883_bind_cap_vol = { 8901 .ops = &snd_hda_bind_vol, 8902 .values = { 8903 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT), 8904 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT), 8905 0 8906 }, 8907}; 8908 8909static struct hda_bind_ctls alc883_bind_cap_switch = { 8910 .ops = &snd_hda_bind_sw, 8911 .values = { 8912 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT), 8913 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT), 8914 0 8915 }, 8916}; 8917 8918static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = { 8919 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8920 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8921 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 8922 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8923 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8924 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8925 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8926 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8927 { } /* end */ 8928}; 8929 8930static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = { 8931 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol), 8932 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch), 8933 { 8934 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 8935 /* .name = "Capture Source", */ 8936 .name = "Input Source", 8937 .count = 1, 8938 .info = alc_mux_enum_info, 8939 .get = alc_mux_enum_get, 8940 .put = alc_mux_enum_put, 8941 }, 8942 { } /* end */ 8943}; 8944 8945static struct snd_kcontrol_new alc883_chmode_mixer[] = { 8946 { 8947 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 8948 .name = "Channel Mode", 8949 .info = alc_ch_mode_info, 8950 .get = alc_ch_mode_get, 8951 .put = alc_ch_mode_put, 8952 }, 8953 { } /* end */ 8954}; 8955 8956/* toggle speaker-output according to the hp-jack state */ 8957static void alc883_mitac_setup(struct hda_codec *codec) 8958{ 8959 struct alc_spec *spec = codec->spec; 8960 8961 spec->autocfg.hp_pins[0] = 0x15; 8962 spec->autocfg.speaker_pins[0] = 0x14; 8963 spec->autocfg.speaker_pins[1] = 0x17; 8964} 8965 8966/* auto-toggle front mic */ 8967/* 8968static void alc883_mitac_mic_automute(struct hda_codec *codec) 8969{ 8970 unsigned char bits = snd_hda_jack_detect(codec, 0x18) ? HDA_AMP_MUTE : 0; 8971 8972 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits); 8973} 8974*/ 8975 8976static struct hda_verb alc883_mitac_verbs[] = { 8977 /* HP */ 8978 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 8979 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8980 /* Subwoofer */ 8981 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02}, 8982 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8983 8984 /* enable unsolicited event */ 8985 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 8986 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */ 8987 8988 { } /* end */ 8989}; 8990 8991static struct hda_verb alc883_clevo_m540r_verbs[] = { 8992 /* HP */ 8993 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 8994 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8995 /* Int speaker */ 8996 /*{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},*/ 8997 8998 /* enable unsolicited event */ 8999 /* 9000 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9001 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, 9002 */ 9003 9004 { } /* end */ 9005}; 9006 9007static struct hda_verb alc883_clevo_m720_verbs[] = { 9008 /* HP */ 9009 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9010 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9011 /* Int speaker */ 9012 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01}, 9013 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9014 9015 /* enable unsolicited event */ 9016 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9017 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, 9018 9019 { } /* end */ 9020}; 9021 9022static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = { 9023 /* HP */ 9024 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 9025 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9026 /* Subwoofer */ 9027 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 9028 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9029 9030 /* enable unsolicited event */ 9031 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9032 9033 { } /* end */ 9034}; 9035 9036static struct hda_verb alc883_targa_verbs[] = { 9037 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9038 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9039 9040 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9041 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9042 9043/* Connect Line-Out side jack (SPDIF) to Side */ 9044 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9045 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9046 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, 9047/* Connect Mic jack to CLFE */ 9048 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9049 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9050 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, 9051/* Connect Line-in jack to Surround */ 9052 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9053 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9054 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, 9055/* Connect HP out jack to Front */ 9056 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9057 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9058 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 9059 9060 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9061 9062 { } /* end */ 9063}; 9064 9065static struct hda_verb alc883_lenovo_101e_verbs[] = { 9066 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9067 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN}, 9068 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN}, 9069 { } /* end */ 9070}; 9071 9072static struct hda_verb alc883_lenovo_nb0763_verbs[] = { 9073 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9074 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9075 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9076 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9077 { } /* end */ 9078}; 9079 9080static struct hda_verb alc888_lenovo_ms7195_verbs[] = { 9081 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9082 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9083 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9084 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN}, 9085 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9086 { } /* end */ 9087}; 9088 9089static struct hda_verb alc883_haier_w66_verbs[] = { 9090 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9091 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9092 9093 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9094 9095 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 9096 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9097 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9098 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9099 { } /* end */ 9100}; 9101 9102static struct hda_verb alc888_lenovo_sky_verbs[] = { 9103 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9104 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9105 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9106 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9107 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9108 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9109 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00}, 9110 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9111 { } /* end */ 9112}; 9113 9114static struct hda_verb alc888_6st_dell_verbs[] = { 9115 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9116 { } 9117}; 9118 9119static struct hda_verb alc883_vaiott_verbs[] = { 9120 /* HP */ 9121 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9122 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9123 9124 /* enable unsolicited event */ 9125 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9126 9127 { } /* end */ 9128}; 9129 9130static void alc888_3st_hp_setup(struct hda_codec *codec) 9131{ 9132 struct alc_spec *spec = codec->spec; 9133 9134 spec->autocfg.hp_pins[0] = 0x1b; 9135 spec->autocfg.speaker_pins[0] = 0x14; 9136 spec->autocfg.speaker_pins[1] = 0x16; 9137 spec->autocfg.speaker_pins[2] = 0x18; 9138} 9139 9140static struct hda_verb alc888_3st_hp_verbs[] = { 9141 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */ 9142 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */ 9143 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */ 9144 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9145 { } /* end */ 9146}; 9147 9148/* 9149 * 2ch mode 9150 */ 9151static struct hda_verb alc888_3st_hp_2ch_init[] = { 9152 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 9153 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 9154 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 9155 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 9156 { } /* end */ 9157}; 9158 9159/* 9160 * 4ch mode 9161 */ 9162static struct hda_verb alc888_3st_hp_4ch_init[] = { 9163 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 9164 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 9165 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 9166 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 9167 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 }, 9168 { } /* end */ 9169}; 9170 9171/* 9172 * 6ch mode 9173 */ 9174static struct hda_verb alc888_3st_hp_6ch_init[] = { 9175 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 9176 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 9177 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, 9178 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 9179 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 9180 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 }, 9181 { } /* end */ 9182}; 9183 9184static struct hda_channel_mode alc888_3st_hp_modes[3] = { 9185 { 2, alc888_3st_hp_2ch_init }, 9186 { 4, alc888_3st_hp_4ch_init }, 9187 { 6, alc888_3st_hp_6ch_init }, 9188}; 9189 9190/* toggle front-jack and RCA according to the hp-jack state */ 9191static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec) 9192{ 9193 unsigned int present = snd_hda_jack_detect(codec, 0x1b); 9194 9195 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 9196 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 9197 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 9198 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 9199} 9200 9201/* toggle RCA according to the front-jack state */ 9202static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec) 9203{ 9204 unsigned int present = snd_hda_jack_detect(codec, 0x14); 9205 9206 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 9207 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 9208} 9209 9210static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec, 9211 unsigned int res) 9212{ 9213 if ((res >> 26) == ALC880_HP_EVENT) 9214 alc888_lenovo_ms7195_front_automute(codec); 9215 if ((res >> 26) == ALC880_FRONT_EVENT) 9216 alc888_lenovo_ms7195_rca_automute(codec); 9217} 9218 9219static struct hda_verb alc883_medion_md2_verbs[] = { 9220 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9221 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9222 9223 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9224 9225 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9226 { } /* end */ 9227}; 9228 9229/* toggle speaker-output according to the hp-jack state */ 9230static void alc883_medion_md2_setup(struct hda_codec *codec) 9231{ 9232 struct alc_spec *spec = codec->spec; 9233 9234 spec->autocfg.hp_pins[0] = 0x14; 9235 spec->autocfg.speaker_pins[0] = 0x15; 9236} 9237 9238/* toggle speaker-output according to the hp-jack state */ 9239#define alc883_targa_init_hook alc882_targa_init_hook 9240#define alc883_targa_unsol_event alc882_targa_unsol_event 9241 9242static void alc883_clevo_m720_mic_automute(struct hda_codec *codec) 9243{ 9244 unsigned int present; 9245 9246 present = snd_hda_jack_detect(codec, 0x18); 9247 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, 9248 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 9249} 9250 9251static void alc883_clevo_m720_setup(struct hda_codec *codec) 9252{ 9253 struct alc_spec *spec = codec->spec; 9254 9255 spec->autocfg.hp_pins[0] = 0x15; 9256 spec->autocfg.speaker_pins[0] = 0x14; 9257} 9258 9259static void alc883_clevo_m720_init_hook(struct hda_codec *codec) 9260{ 9261 alc_automute_amp(codec); 9262 alc883_clevo_m720_mic_automute(codec); 9263} 9264 9265static void alc883_clevo_m720_unsol_event(struct hda_codec *codec, 9266 unsigned int res) 9267{ 9268 switch (res >> 26) { 9269 case ALC880_MIC_EVENT: 9270 alc883_clevo_m720_mic_automute(codec); 9271 break; 9272 default: 9273 alc_automute_amp_unsol_event(codec, res); 9274 break; 9275 } 9276} 9277 9278/* toggle speaker-output according to the hp-jack state */ 9279static void alc883_2ch_fujitsu_pi2515_setup(struct hda_codec *codec) 9280{ 9281 struct alc_spec *spec = codec->spec; 9282 9283 spec->autocfg.hp_pins[0] = 0x14; 9284 spec->autocfg.speaker_pins[0] = 0x15; 9285} 9286 9287static void alc883_haier_w66_setup(struct hda_codec *codec) 9288{ 9289 struct alc_spec *spec = codec->spec; 9290 9291 spec->autocfg.hp_pins[0] = 0x1b; 9292 spec->autocfg.speaker_pins[0] = 0x14; 9293} 9294 9295static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec) 9296{ 9297 int bits = snd_hda_jack_detect(codec, 0x14) ? HDA_AMP_MUTE : 0; 9298 9299 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 9300 HDA_AMP_MUTE, bits); 9301} 9302 9303static void alc883_lenovo_101e_all_automute(struct hda_codec *codec) 9304{ 9305 int bits = snd_hda_jack_detect(codec, 0x1b) ? HDA_AMP_MUTE : 0; 9306 9307 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 9308 HDA_AMP_MUTE, bits); 9309 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 9310 HDA_AMP_MUTE, bits); 9311} 9312 9313static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec, 9314 unsigned int res) 9315{ 9316 if ((res >> 26) == ALC880_HP_EVENT) 9317 alc883_lenovo_101e_all_automute(codec); 9318 if ((res >> 26) == ALC880_FRONT_EVENT) 9319 alc883_lenovo_101e_ispeaker_automute(codec); 9320} 9321 9322/* toggle speaker-output according to the hp-jack state */ 9323static void alc883_acer_aspire_setup(struct hda_codec *codec) 9324{ 9325 struct alc_spec *spec = codec->spec; 9326 9327 spec->autocfg.hp_pins[0] = 0x14; 9328 spec->autocfg.speaker_pins[0] = 0x15; 9329 spec->autocfg.speaker_pins[1] = 0x16; 9330} 9331 9332static struct hda_verb alc883_acer_eapd_verbs[] = { 9333 /* HP Pin: output 0 (0x0c) */ 9334 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9335 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9336 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 9337 /* Front Pin: output 0 (0x0c) */ 9338 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9339 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9340 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9341 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, 9342 /* eanable EAPD on medion laptop */ 9343 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 9344 {0x20, AC_VERB_SET_PROC_COEF, 0x3050}, 9345 /* enable unsolicited event */ 9346 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9347 { } 9348}; 9349 9350static struct hda_verb alc888_acer_aspire_7730G_verbs[] = { 9351 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9352 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02}, 9353 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9354 { } /* end */ 9355}; 9356 9357static void alc888_6st_dell_setup(struct hda_codec *codec) 9358{ 9359 struct alc_spec *spec = codec->spec; 9360 9361 spec->autocfg.hp_pins[0] = 0x1b; 9362 spec->autocfg.speaker_pins[0] = 0x14; 9363 spec->autocfg.speaker_pins[1] = 0x15; 9364 spec->autocfg.speaker_pins[2] = 0x16; 9365 spec->autocfg.speaker_pins[3] = 0x17; 9366} 9367 9368static void alc888_lenovo_sky_setup(struct hda_codec *codec) 9369{ 9370 struct alc_spec *spec = codec->spec; 9371 9372 spec->autocfg.hp_pins[0] = 0x1b; 9373 spec->autocfg.speaker_pins[0] = 0x14; 9374 spec->autocfg.speaker_pins[1] = 0x15; 9375 spec->autocfg.speaker_pins[2] = 0x16; 9376 spec->autocfg.speaker_pins[3] = 0x17; 9377 spec->autocfg.speaker_pins[4] = 0x1a; 9378} 9379 9380static void alc883_vaiott_setup(struct hda_codec *codec) 9381{ 9382 struct alc_spec *spec = codec->spec; 9383 9384 spec->autocfg.hp_pins[0] = 0x15; 9385 spec->autocfg.speaker_pins[0] = 0x14; 9386 spec->autocfg.speaker_pins[1] = 0x17; 9387} 9388 9389static struct hda_verb alc888_asus_m90v_verbs[] = { 9390 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 9391 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 9392 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9393 /* enable unsolicited event */ 9394 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9395 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, 9396 { } /* end */ 9397}; 9398 9399static void alc883_mode2_setup(struct hda_codec *codec) 9400{ 9401 struct alc_spec *spec = codec->spec; 9402 9403 spec->autocfg.hp_pins[0] = 0x1b; 9404 spec->autocfg.speaker_pins[0] = 0x14; 9405 spec->autocfg.speaker_pins[1] = 0x15; 9406 spec->autocfg.speaker_pins[2] = 0x16; 9407 spec->ext_mic.pin = 0x18; 9408 spec->int_mic.pin = 0x19; 9409 spec->ext_mic.mux_idx = 0; 9410 spec->int_mic.mux_idx = 1; 9411 spec->auto_mic = 1; 9412} 9413 9414static struct hda_verb alc888_asus_eee1601_verbs[] = { 9415 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9416 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9417 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 9418 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9419 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 9420 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b}, 9421 {0x20, AC_VERB_SET_PROC_COEF, 0x0838}, 9422 /* enable unsolicited event */ 9423 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9424 { } /* end */ 9425}; 9426 9427static void alc883_eee1601_inithook(struct hda_codec *codec) 9428{ 9429 struct alc_spec *spec = codec->spec; 9430 9431 spec->autocfg.hp_pins[0] = 0x14; 9432 spec->autocfg.speaker_pins[0] = 0x1b; 9433 alc_automute_pin(codec); 9434} 9435 9436static struct hda_verb alc889A_mb31_verbs[] = { 9437 /* Init rear pin (used as headphone output) */ 9438 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */ 9439 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */ 9440 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9441 /* Init line pin (used as output in 4ch and 6ch mode) */ 9442 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */ 9443 /* Init line 2 pin (used as headphone out by default) */ 9444 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */ 9445 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */ 9446 { } /* end */ 9447}; 9448 9449/* Mute speakers according to the headphone jack state */ 9450static void alc889A_mb31_automute(struct hda_codec *codec) 9451{ 9452 unsigned int present; 9453 9454 /* Mute only in 2ch or 4ch mode */ 9455 if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0) 9456 == 0x00) { 9457 present = snd_hda_jack_detect(codec, 0x15); 9458 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 9459 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 9460 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0, 9461 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 9462 } 9463} 9464 9465static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res) 9466{ 9467 if ((res >> 26) == ALC880_HP_EVENT) 9468 alc889A_mb31_automute(codec); 9469} 9470 9471 9472#ifdef CONFIG_SND_HDA_POWER_SAVE 9473#define alc882_loopbacks alc880_loopbacks 9474#endif 9475 9476/* pcm configuration: identical with ALC880 */ 9477#define alc882_pcm_analog_playback alc880_pcm_analog_playback 9478#define alc882_pcm_analog_capture alc880_pcm_analog_capture 9479#define alc882_pcm_digital_playback alc880_pcm_digital_playback 9480#define alc882_pcm_digital_capture alc880_pcm_digital_capture 9481 9482static hda_nid_t alc883_slave_dig_outs[] = { 9483 ALC1200_DIGOUT_NID, 0, 9484}; 9485 9486static hda_nid_t alc1200_slave_dig_outs[] = { 9487 ALC883_DIGOUT_NID, 0, 9488}; 9489 9490/* 9491 * configuration and preset 9492 */ 9493static const char *alc882_models[ALC882_MODEL_LAST] = { 9494 [ALC882_3ST_DIG] = "3stack-dig", 9495 [ALC882_6ST_DIG] = "6stack-dig", 9496 [ALC882_ARIMA] = "arima", 9497 [ALC882_W2JC] = "w2jc", 9498 [ALC882_TARGA] = "targa", 9499 [ALC882_ASUS_A7J] = "asus-a7j", 9500 [ALC882_ASUS_A7M] = "asus-a7m", 9501 [ALC885_MACPRO] = "macpro", 9502 [ALC885_MB5] = "mb5", 9503 [ALC885_MACMINI3] = "macmini3", 9504 [ALC885_MBA21] = "mba21", 9505 [ALC885_MBP3] = "mbp3", 9506 [ALC885_IMAC24] = "imac24", 9507 [ALC885_IMAC91] = "imac91", 9508 [ALC883_3ST_2ch_DIG] = "3stack-2ch-dig", 9509 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig", 9510 [ALC883_3ST_6ch] = "3stack-6ch", 9511 [ALC883_6ST_DIG] = "alc883-6stack-dig", 9512 [ALC883_TARGA_DIG] = "targa-dig", 9513 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig", 9514 [ALC883_TARGA_8ch_DIG] = "targa-8ch-dig", 9515 [ALC883_ACER] = "acer", 9516 [ALC883_ACER_ASPIRE] = "acer-aspire", 9517 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g", 9518 [ALC888_ACER_ASPIRE_6530G] = "acer-aspire-6530g", 9519 [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g", 9520 [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g", 9521 [ALC883_MEDION] = "medion", 9522 [ALC883_MEDION_MD2] = "medion-md2", 9523 [ALC883_MEDION_WIM2160] = "medion-wim2160", 9524 [ALC883_LAPTOP_EAPD] = "laptop-eapd", 9525 [ALC883_LENOVO_101E_2ch] = "lenovo-101e", 9526 [ALC883_LENOVO_NB0763] = "lenovo-nb0763", 9527 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig", 9528 [ALC888_LENOVO_SKY] = "lenovo-sky", 9529 [ALC883_HAIER_W66] = "haier-w66", 9530 [ALC888_3ST_HP] = "3stack-hp", 9531 [ALC888_6ST_DELL] = "6stack-dell", 9532 [ALC883_MITAC] = "mitac", 9533 [ALC883_CLEVO_M540R] = "clevo-m540r", 9534 [ALC883_CLEVO_M720] = "clevo-m720", 9535 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515", 9536 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530", 9537 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel", 9538 [ALC889A_INTEL] = "intel-alc889a", 9539 [ALC889_INTEL] = "intel-x58", 9540 [ALC1200_ASUS_P5Q] = "asus-p5q", 9541 [ALC889A_MB31] = "mb31", 9542 [ALC883_SONY_VAIO_TT] = "sony-vaio-tt", 9543 [ALC882_AUTO] = "auto", 9544}; 9545 9546static struct snd_pci_quirk alc882_cfg_tbl[] = { 9547 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG), 9548 9549 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE), 9550 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE), 9551 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE), 9552 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE), 9553 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE), 9554 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE), 9555 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G", 9556 ALC888_ACER_ASPIRE_4930G), 9557 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G", 9558 ALC888_ACER_ASPIRE_4930G), 9559 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G", 9560 ALC888_ACER_ASPIRE_8930G), 9561 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G", 9562 ALC888_ACER_ASPIRE_8930G), 9563 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC882_AUTO), 9564 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC882_AUTO), 9565 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G", 9566 ALC888_ACER_ASPIRE_6530G), 9567 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G", 9568 ALC888_ACER_ASPIRE_6530G), 9569 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G", 9570 ALC888_ACER_ASPIRE_7730G), 9571 /* default Acer -- disabled as it causes more problems. 9572 * model=auto should work fine now 9573 */ 9574 /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */ 9575 9576 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL), 9577 9578 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG), 9579 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP), 9580 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP), 9581 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG), 9582 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP), 9583 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP), 9584 9585 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J), 9586 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J), 9587 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M), 9588 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V), 9589 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC), 9590 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG), 9591 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG), 9592 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG), 9593 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG), 9594 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q), 9595 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601), 9596 9597 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT), 9598 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG), 9599 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG), 9600 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC), 9601 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC), 9602 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD), 9603 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL), 9604 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch), 9605 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG), 9606 9607 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG), 9608 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG), 9609 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG), 9610 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */ 9611 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC882_AUTO), 9612 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG), 9613 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG), 9614 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG), 9615 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG), 9616 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG), 9617 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG), 9618 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG), 9619 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG), 9620 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG), 9621 SND_PCI_QUIRK(0x1462, 0x42cd, "MSI", ALC883_TARGA_DIG), 9622 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG), 9623 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG), 9624 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG), 9625 SND_PCI_QUIRK(0x1462, 0x4570, "MSI Wind Top AE2220", ALC883_TARGA_DIG), 9626 SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG), 9627 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG), 9628 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG), 9629 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG), 9630 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG), 9631 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG), 9632 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG), 9633 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG), 9634 SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG), 9635 SND_PCI_QUIRK(0x1462, 0x7437, "MSI NetOn AP1900", ALC883_TARGA_DIG), 9636 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG), 9637 SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG), 9638 9639 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG), 9640 SND_PCI_QUIRK(0x1558, 0x0571, "Clevo laptop M570U", ALC883_3ST_6ch_DIG), 9641 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720), 9642 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720), 9643 SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R), 9644 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD), 9645 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch), 9646 /* SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), */ 9647 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION), 9648 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx", 9649 ALC883_FUJITSU_PI2515), 9650 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx", 9651 ALC888_FUJITSU_XA3530), 9652 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch), 9653 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763), 9654 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763), 9655 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763), 9656 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY), 9657 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2), 9658 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG), 9659 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG), 9660 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66), 9661 9662 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL), 9663 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL), 9664 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC), 9665 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL), 9666 SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL), 9667 SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL), 9668 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC882_6ST_DIG), 9669 9670 {} 9671}; 9672 9673/* codec SSID table for Intel Mac */ 9674static struct snd_pci_quirk alc882_ssid_cfg_tbl[] = { 9675 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3), 9676 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3), 9677 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3), 9678 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_MACPRO), 9679 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24), 9680 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24), 9681 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3), 9682 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889A_MB31), 9683 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_ASUS_A7M), 9684 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC885_MBP3), 9685 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC885_MBA21), 9686 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31), 9687 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3), 9688 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24), 9689 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC885_IMAC91), 9690 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5), 9691 SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC885_MB5), 9692 /* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2, 9693 * so apparently no perfect solution yet 9694 */ 9695 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5), 9696 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5), 9697 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC885_MACMINI3), 9698 {} /* terminator */ 9699}; 9700 9701static struct alc_config_preset alc882_presets[] = { 9702 [ALC882_3ST_DIG] = { 9703 .mixers = { alc882_base_mixer }, 9704 .init_verbs = { alc882_base_init_verbs, 9705 alc882_adc1_init_verbs }, 9706 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 9707 .dac_nids = alc882_dac_nids, 9708 .dig_out_nid = ALC882_DIGOUT_NID, 9709 .dig_in_nid = ALC882_DIGIN_NID, 9710 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes), 9711 .channel_mode = alc882_ch_modes, 9712 .need_dac_fix = 1, 9713 .input_mux = &alc882_capture_source, 9714 }, 9715 [ALC882_6ST_DIG] = { 9716 .mixers = { alc882_base_mixer, alc882_chmode_mixer }, 9717 .init_verbs = { alc882_base_init_verbs, 9718 alc882_adc1_init_verbs }, 9719 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 9720 .dac_nids = alc882_dac_nids, 9721 .dig_out_nid = ALC882_DIGOUT_NID, 9722 .dig_in_nid = ALC882_DIGIN_NID, 9723 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes), 9724 .channel_mode = alc882_sixstack_modes, 9725 .input_mux = &alc882_capture_source, 9726 }, 9727 [ALC882_ARIMA] = { 9728 .mixers = { alc882_base_mixer, alc882_chmode_mixer }, 9729 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs, 9730 alc882_eapd_verbs }, 9731 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 9732 .dac_nids = alc882_dac_nids, 9733 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes), 9734 .channel_mode = alc882_sixstack_modes, 9735 .input_mux = &alc882_capture_source, 9736 }, 9737 [ALC882_W2JC] = { 9738 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer }, 9739 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs, 9740 alc882_eapd_verbs, alc880_gpio1_init_verbs }, 9741 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 9742 .dac_nids = alc882_dac_nids, 9743 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), 9744 .channel_mode = alc880_threestack_modes, 9745 .need_dac_fix = 1, 9746 .input_mux = &alc882_capture_source, 9747 .dig_out_nid = ALC882_DIGOUT_NID, 9748 }, 9749 [ALC885_MBA21] = { 9750 .mixers = { alc885_mba21_mixer }, 9751 .init_verbs = { alc885_mba21_init_verbs, alc880_gpio1_init_verbs }, 9752 .num_dacs = 2, 9753 .dac_nids = alc882_dac_nids, 9754 .channel_mode = alc885_mba21_ch_modes, 9755 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes), 9756 .input_mux = &alc882_capture_source, 9757 .unsol_event = alc_automute_amp_unsol_event, 9758 .setup = alc885_mba21_setup, 9759 .init_hook = alc_automute_amp, 9760 }, 9761 [ALC885_MBP3] = { 9762 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer }, 9763 .init_verbs = { alc885_mbp3_init_verbs, 9764 alc880_gpio1_init_verbs }, 9765 .num_dacs = 2, 9766 .dac_nids = alc882_dac_nids, 9767 .hp_nid = 0x04, 9768 .channel_mode = alc885_mbp_4ch_modes, 9769 .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes), 9770 .input_mux = &alc882_capture_source, 9771 .dig_out_nid = ALC882_DIGOUT_NID, 9772 .dig_in_nid = ALC882_DIGIN_NID, 9773 .unsol_event = alc_automute_amp_unsol_event, 9774 .setup = alc885_mbp3_setup, 9775 .init_hook = alc_automute_amp, 9776 }, 9777 [ALC885_MB5] = { 9778 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer }, 9779 .init_verbs = { alc885_mb5_init_verbs, 9780 alc880_gpio1_init_verbs }, 9781 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 9782 .dac_nids = alc882_dac_nids, 9783 .channel_mode = alc885_mb5_6ch_modes, 9784 .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes), 9785 .input_mux = &mb5_capture_source, 9786 .dig_out_nid = ALC882_DIGOUT_NID, 9787 .dig_in_nid = ALC882_DIGIN_NID, 9788 .unsol_event = alc_automute_amp_unsol_event, 9789 .setup = alc885_mb5_setup, 9790 .init_hook = alc_automute_amp, 9791 }, 9792 [ALC885_MACMINI3] = { 9793 .mixers = { alc885_macmini3_mixer, alc882_chmode_mixer }, 9794 .init_verbs = { alc885_macmini3_init_verbs, 9795 alc880_gpio1_init_verbs }, 9796 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 9797 .dac_nids = alc882_dac_nids, 9798 .channel_mode = alc885_macmini3_6ch_modes, 9799 .num_channel_mode = ARRAY_SIZE(alc885_macmini3_6ch_modes), 9800 .input_mux = &macmini3_capture_source, 9801 .dig_out_nid = ALC882_DIGOUT_NID, 9802 .dig_in_nid = ALC882_DIGIN_NID, 9803 .unsol_event = alc_automute_amp_unsol_event, 9804 .setup = alc885_macmini3_setup, 9805 .init_hook = alc_automute_amp, 9806 }, 9807 [ALC885_MACPRO] = { 9808 .mixers = { alc882_macpro_mixer }, 9809 .init_verbs = { alc882_macpro_init_verbs }, 9810 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 9811 .dac_nids = alc882_dac_nids, 9812 .dig_out_nid = ALC882_DIGOUT_NID, 9813 .dig_in_nid = ALC882_DIGIN_NID, 9814 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes), 9815 .channel_mode = alc882_ch_modes, 9816 .input_mux = &alc882_capture_source, 9817 .init_hook = alc885_macpro_init_hook, 9818 }, 9819 [ALC885_IMAC24] = { 9820 .mixers = { alc885_imac24_mixer }, 9821 .init_verbs = { alc885_imac24_init_verbs }, 9822 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 9823 .dac_nids = alc882_dac_nids, 9824 .dig_out_nid = ALC882_DIGOUT_NID, 9825 .dig_in_nid = ALC882_DIGIN_NID, 9826 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes), 9827 .channel_mode = alc882_ch_modes, 9828 .input_mux = &alc882_capture_source, 9829 .unsol_event = alc_automute_amp_unsol_event, 9830 .setup = alc885_imac24_setup, 9831 .init_hook = alc885_imac24_init_hook, 9832 }, 9833 [ALC885_IMAC91] = { 9834 .mixers = {alc885_imac91_mixer}, 9835 .init_verbs = { alc885_imac91_init_verbs, 9836 alc880_gpio1_init_verbs }, 9837 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 9838 .dac_nids = alc882_dac_nids, 9839 .channel_mode = alc885_mba21_ch_modes, 9840 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes), 9841 .input_mux = &alc889A_imac91_capture_source, 9842 .dig_out_nid = ALC882_DIGOUT_NID, 9843 .dig_in_nid = ALC882_DIGIN_NID, 9844 .unsol_event = alc_automute_amp_unsol_event, 9845 .setup = alc885_imac91_setup, 9846 .init_hook = alc_automute_amp, 9847 }, 9848 [ALC882_TARGA] = { 9849 .mixers = { alc882_targa_mixer, alc882_chmode_mixer }, 9850 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs, 9851 alc880_gpio3_init_verbs, alc882_targa_verbs}, 9852 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 9853 .dac_nids = alc882_dac_nids, 9854 .dig_out_nid = ALC882_DIGOUT_NID, 9855 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids), 9856 .adc_nids = alc882_adc_nids, 9857 .capsrc_nids = alc882_capsrc_nids, 9858 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes), 9859 .channel_mode = alc882_3ST_6ch_modes, 9860 .need_dac_fix = 1, 9861 .input_mux = &alc882_capture_source, 9862 .unsol_event = alc882_targa_unsol_event, 9863 .setup = alc882_targa_setup, 9864 .init_hook = alc882_targa_automute, 9865 }, 9866 [ALC882_ASUS_A7J] = { 9867 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer }, 9868 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs, 9869 alc882_asus_a7j_verbs}, 9870 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 9871 .dac_nids = alc882_dac_nids, 9872 .dig_out_nid = ALC882_DIGOUT_NID, 9873 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids), 9874 .adc_nids = alc882_adc_nids, 9875 .capsrc_nids = alc882_capsrc_nids, 9876 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes), 9877 .channel_mode = alc882_3ST_6ch_modes, 9878 .need_dac_fix = 1, 9879 .input_mux = &alc882_capture_source, 9880 }, 9881 [ALC882_ASUS_A7M] = { 9882 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer }, 9883 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs, 9884 alc882_eapd_verbs, alc880_gpio1_init_verbs, 9885 alc882_asus_a7m_verbs }, 9886 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 9887 .dac_nids = alc882_dac_nids, 9888 .dig_out_nid = ALC882_DIGOUT_NID, 9889 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), 9890 .channel_mode = alc880_threestack_modes, 9891 .need_dac_fix = 1, 9892 .input_mux = &alc882_capture_source, 9893 }, 9894 [ALC883_3ST_2ch_DIG] = { 9895 .mixers = { alc883_3ST_2ch_mixer }, 9896 .init_verbs = { alc883_init_verbs }, 9897 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 9898 .dac_nids = alc883_dac_nids, 9899 .dig_out_nid = ALC883_DIGOUT_NID, 9900 .dig_in_nid = ALC883_DIGIN_NID, 9901 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 9902 .channel_mode = alc883_3ST_2ch_modes, 9903 .input_mux = &alc883_capture_source, 9904 }, 9905 [ALC883_3ST_6ch_DIG] = { 9906 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, 9907 .init_verbs = { alc883_init_verbs }, 9908 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 9909 .dac_nids = alc883_dac_nids, 9910 .dig_out_nid = ALC883_DIGOUT_NID, 9911 .dig_in_nid = ALC883_DIGIN_NID, 9912 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 9913 .channel_mode = alc883_3ST_6ch_modes, 9914 .need_dac_fix = 1, 9915 .input_mux = &alc883_capture_source, 9916 }, 9917 [ALC883_3ST_6ch] = { 9918 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, 9919 .init_verbs = { alc883_init_verbs }, 9920 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 9921 .dac_nids = alc883_dac_nids, 9922 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 9923 .channel_mode = alc883_3ST_6ch_modes, 9924 .need_dac_fix = 1, 9925 .input_mux = &alc883_capture_source, 9926 }, 9927 [ALC883_3ST_6ch_INTEL] = { 9928 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer }, 9929 .init_verbs = { alc883_init_verbs }, 9930 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 9931 .dac_nids = alc883_dac_nids, 9932 .dig_out_nid = ALC883_DIGOUT_NID, 9933 .dig_in_nid = ALC883_DIGIN_NID, 9934 .slave_dig_outs = alc883_slave_dig_outs, 9935 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes), 9936 .channel_mode = alc883_3ST_6ch_intel_modes, 9937 .need_dac_fix = 1, 9938 .input_mux = &alc883_3stack_6ch_intel, 9939 }, 9940 [ALC889A_INTEL] = { 9941 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer }, 9942 .init_verbs = { alc885_init_verbs, alc885_init_input_verbs, 9943 alc_hp15_unsol_verbs }, 9944 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 9945 .dac_nids = alc883_dac_nids, 9946 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids), 9947 .adc_nids = alc889_adc_nids, 9948 .dig_out_nid = ALC883_DIGOUT_NID, 9949 .dig_in_nid = ALC883_DIGIN_NID, 9950 .slave_dig_outs = alc883_slave_dig_outs, 9951 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes), 9952 .channel_mode = alc889_8ch_intel_modes, 9953 .capsrc_nids = alc889_capsrc_nids, 9954 .input_mux = &alc889_capture_source, 9955 .setup = alc889_automute_setup, 9956 .init_hook = alc_automute_amp, 9957 .unsol_event = alc_automute_amp_unsol_event, 9958 .need_dac_fix = 1, 9959 }, 9960 [ALC889_INTEL] = { 9961 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer }, 9962 .init_verbs = { alc885_init_verbs, alc889_init_input_verbs, 9963 alc889_eapd_verbs, alc_hp15_unsol_verbs}, 9964 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 9965 .dac_nids = alc883_dac_nids, 9966 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids), 9967 .adc_nids = alc889_adc_nids, 9968 .dig_out_nid = ALC883_DIGOUT_NID, 9969 .dig_in_nid = ALC883_DIGIN_NID, 9970 .slave_dig_outs = alc883_slave_dig_outs, 9971 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes), 9972 .channel_mode = alc889_8ch_intel_modes, 9973 .capsrc_nids = alc889_capsrc_nids, 9974 .input_mux = &alc889_capture_source, 9975 .setup = alc889_automute_setup, 9976 .init_hook = alc889_intel_init_hook, 9977 .unsol_event = alc_automute_amp_unsol_event, 9978 .need_dac_fix = 1, 9979 }, 9980 [ALC883_6ST_DIG] = { 9981 .mixers = { alc883_base_mixer, alc883_chmode_mixer }, 9982 .init_verbs = { alc883_init_verbs }, 9983 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 9984 .dac_nids = alc883_dac_nids, 9985 .dig_out_nid = ALC883_DIGOUT_NID, 9986 .dig_in_nid = ALC883_DIGIN_NID, 9987 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), 9988 .channel_mode = alc883_sixstack_modes, 9989 .input_mux = &alc883_capture_source, 9990 }, 9991 [ALC883_TARGA_DIG] = { 9992 .mixers = { alc883_targa_mixer, alc883_chmode_mixer }, 9993 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs, 9994 alc883_targa_verbs}, 9995 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 9996 .dac_nids = alc883_dac_nids, 9997 .dig_out_nid = ALC883_DIGOUT_NID, 9998 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 9999 .channel_mode = alc883_3ST_6ch_modes, 10000 .need_dac_fix = 1, 10001 .input_mux = &alc883_capture_source, 10002 .unsol_event = alc883_targa_unsol_event, 10003 .setup = alc882_targa_setup, 10004 .init_hook = alc882_targa_automute, 10005 }, 10006 [ALC883_TARGA_2ch_DIG] = { 10007 .mixers = { alc883_targa_2ch_mixer}, 10008 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs, 10009 alc883_targa_verbs}, 10010 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10011 .dac_nids = alc883_dac_nids, 10012 .adc_nids = alc883_adc_nids_alt, 10013 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt), 10014 .capsrc_nids = alc883_capsrc_nids, 10015 .dig_out_nid = ALC883_DIGOUT_NID, 10016 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10017 .channel_mode = alc883_3ST_2ch_modes, 10018 .input_mux = &alc883_capture_source, 10019 .unsol_event = alc883_targa_unsol_event, 10020 .setup = alc882_targa_setup, 10021 .init_hook = alc882_targa_automute, 10022 }, 10023 [ALC883_TARGA_8ch_DIG] = { 10024 .mixers = { alc883_targa_mixer, alc883_targa_8ch_mixer, 10025 alc883_chmode_mixer }, 10026 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs, 10027 alc883_targa_verbs }, 10028 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10029 .dac_nids = alc883_dac_nids, 10030 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev), 10031 .adc_nids = alc883_adc_nids_rev, 10032 .capsrc_nids = alc883_capsrc_nids_rev, 10033 .dig_out_nid = ALC883_DIGOUT_NID, 10034 .dig_in_nid = ALC883_DIGIN_NID, 10035 .num_channel_mode = ARRAY_SIZE(alc883_4ST_8ch_modes), 10036 .channel_mode = alc883_4ST_8ch_modes, 10037 .need_dac_fix = 1, 10038 .input_mux = &alc883_capture_source, 10039 .unsol_event = alc883_targa_unsol_event, 10040 .setup = alc882_targa_setup, 10041 .init_hook = alc882_targa_automute, 10042 }, 10043 [ALC883_ACER] = { 10044 .mixers = { alc883_base_mixer }, 10045 /* On TravelMate laptops, GPIO 0 enables the internal speaker 10046 * and the headphone jack. Turn this on and rely on the 10047 * standard mute methods whenever the user wants to turn 10048 * these outputs off. 10049 */ 10050 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs }, 10051 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10052 .dac_nids = alc883_dac_nids, 10053 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10054 .channel_mode = alc883_3ST_2ch_modes, 10055 .input_mux = &alc883_capture_source, 10056 }, 10057 [ALC883_ACER_ASPIRE] = { 10058 .mixers = { alc883_acer_aspire_mixer }, 10059 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs }, 10060 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10061 .dac_nids = alc883_dac_nids, 10062 .dig_out_nid = ALC883_DIGOUT_NID, 10063 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10064 .channel_mode = alc883_3ST_2ch_modes, 10065 .input_mux = &alc883_capture_source, 10066 .unsol_event = alc_automute_amp_unsol_event, 10067 .setup = alc883_acer_aspire_setup, 10068 .init_hook = alc_automute_amp, 10069 }, 10070 [ALC888_ACER_ASPIRE_4930G] = { 10071 .mixers = { alc888_base_mixer, 10072 alc883_chmode_mixer }, 10073 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs, 10074 alc888_acer_aspire_4930g_verbs }, 10075 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10076 .dac_nids = alc883_dac_nids, 10077 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev), 10078 .adc_nids = alc883_adc_nids_rev, 10079 .capsrc_nids = alc883_capsrc_nids_rev, 10080 .dig_out_nid = ALC883_DIGOUT_NID, 10081 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 10082 .channel_mode = alc883_3ST_6ch_modes, 10083 .need_dac_fix = 1, 10084 .const_channel_count = 6, 10085 .num_mux_defs = 10086 ARRAY_SIZE(alc888_2_capture_sources), 10087 .input_mux = alc888_2_capture_sources, 10088 .unsol_event = alc_automute_amp_unsol_event, 10089 .setup = alc888_acer_aspire_4930g_setup, 10090 .init_hook = alc_automute_amp, 10091 }, 10092 [ALC888_ACER_ASPIRE_6530G] = { 10093 .mixers = { alc888_acer_aspire_6530_mixer }, 10094 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs, 10095 alc888_acer_aspire_6530g_verbs }, 10096 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10097 .dac_nids = alc883_dac_nids, 10098 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev), 10099 .adc_nids = alc883_adc_nids_rev, 10100 .capsrc_nids = alc883_capsrc_nids_rev, 10101 .dig_out_nid = ALC883_DIGOUT_NID, 10102 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10103 .channel_mode = alc883_3ST_2ch_modes, 10104 .num_mux_defs = 10105 ARRAY_SIZE(alc888_2_capture_sources), 10106 .input_mux = alc888_acer_aspire_6530_sources, 10107 .unsol_event = alc_automute_amp_unsol_event, 10108 .setup = alc888_acer_aspire_6530g_setup, 10109 .init_hook = alc_automute_amp, 10110 }, 10111 [ALC888_ACER_ASPIRE_8930G] = { 10112 .mixers = { alc889_acer_aspire_8930g_mixer, 10113 alc883_chmode_mixer }, 10114 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs, 10115 alc889_acer_aspire_8930g_verbs, 10116 alc889_eapd_verbs}, 10117 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10118 .dac_nids = alc883_dac_nids, 10119 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids), 10120 .adc_nids = alc889_adc_nids, 10121 .capsrc_nids = alc889_capsrc_nids, 10122 .dig_out_nid = ALC883_DIGOUT_NID, 10123 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 10124 .channel_mode = alc883_3ST_6ch_modes, 10125 .need_dac_fix = 1, 10126 .const_channel_count = 6, 10127 .num_mux_defs = 10128 ARRAY_SIZE(alc889_capture_sources), 10129 .input_mux = alc889_capture_sources, 10130 .unsol_event = alc_automute_amp_unsol_event, 10131 .setup = alc889_acer_aspire_8930g_setup, 10132 .init_hook = alc_automute_amp, 10133#ifdef CONFIG_SND_HDA_POWER_SAVE 10134 .power_hook = alc_power_eapd, 10135#endif 10136 }, 10137 [ALC888_ACER_ASPIRE_7730G] = { 10138 .mixers = { alc883_3ST_6ch_mixer, 10139 alc883_chmode_mixer }, 10140 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs, 10141 alc888_acer_aspire_7730G_verbs }, 10142 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10143 .dac_nids = alc883_dac_nids, 10144 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev), 10145 .adc_nids = alc883_adc_nids_rev, 10146 .capsrc_nids = alc883_capsrc_nids_rev, 10147 .dig_out_nid = ALC883_DIGOUT_NID, 10148 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 10149 .channel_mode = alc883_3ST_6ch_modes, 10150 .need_dac_fix = 1, 10151 .const_channel_count = 6, 10152 .input_mux = &alc883_capture_source, 10153 .unsol_event = alc_automute_amp_unsol_event, 10154 .setup = alc888_acer_aspire_6530g_setup, 10155 .init_hook = alc_automute_amp, 10156 }, 10157 [ALC883_MEDION] = { 10158 .mixers = { alc883_fivestack_mixer, 10159 alc883_chmode_mixer }, 10160 .init_verbs = { alc883_init_verbs, 10161 alc883_medion_eapd_verbs }, 10162 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10163 .dac_nids = alc883_dac_nids, 10164 .adc_nids = alc883_adc_nids_alt, 10165 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt), 10166 .capsrc_nids = alc883_capsrc_nids, 10167 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), 10168 .channel_mode = alc883_sixstack_modes, 10169 .input_mux = &alc883_capture_source, 10170 }, 10171 [ALC883_MEDION_MD2] = { 10172 .mixers = { alc883_medion_md2_mixer}, 10173 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs}, 10174 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10175 .dac_nids = alc883_dac_nids, 10176 .dig_out_nid = ALC883_DIGOUT_NID, 10177 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10178 .channel_mode = alc883_3ST_2ch_modes, 10179 .input_mux = &alc883_capture_source, 10180 .unsol_event = alc_automute_amp_unsol_event, 10181 .setup = alc883_medion_md2_setup, 10182 .init_hook = alc_automute_amp, 10183 }, 10184 [ALC883_MEDION_WIM2160] = { 10185 .mixers = { alc883_medion_wim2160_mixer }, 10186 .init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs }, 10187 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10188 .dac_nids = alc883_dac_nids, 10189 .dig_out_nid = ALC883_DIGOUT_NID, 10190 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 10191 .adc_nids = alc883_adc_nids, 10192 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10193 .channel_mode = alc883_3ST_2ch_modes, 10194 .input_mux = &alc883_capture_source, 10195 .unsol_event = alc_automute_amp_unsol_event, 10196 .setup = alc883_medion_wim2160_setup, 10197 .init_hook = alc_automute_amp, 10198 }, 10199 [ALC883_LAPTOP_EAPD] = { 10200 .mixers = { alc883_base_mixer }, 10201 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs }, 10202 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10203 .dac_nids = alc883_dac_nids, 10204 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10205 .channel_mode = alc883_3ST_2ch_modes, 10206 .input_mux = &alc883_capture_source, 10207 }, 10208 [ALC883_CLEVO_M540R] = { 10209 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, 10210 .init_verbs = { alc883_init_verbs, alc883_clevo_m540r_verbs }, 10211 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10212 .dac_nids = alc883_dac_nids, 10213 .dig_out_nid = ALC883_DIGOUT_NID, 10214 .dig_in_nid = ALC883_DIGIN_NID, 10215 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_clevo_modes), 10216 .channel_mode = alc883_3ST_6ch_clevo_modes, 10217 .need_dac_fix = 1, 10218 .input_mux = &alc883_capture_source, 10219 /* This machine has the hardware HP auto-muting, thus 10220 * we need no software mute via unsol event 10221 */ 10222 }, 10223 [ALC883_CLEVO_M720] = { 10224 .mixers = { alc883_clevo_m720_mixer }, 10225 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs }, 10226 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10227 .dac_nids = alc883_dac_nids, 10228 .dig_out_nid = ALC883_DIGOUT_NID, 10229 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10230 .channel_mode = alc883_3ST_2ch_modes, 10231 .input_mux = &alc883_capture_source, 10232 .unsol_event = alc883_clevo_m720_unsol_event, 10233 .setup = alc883_clevo_m720_setup, 10234 .init_hook = alc883_clevo_m720_init_hook, 10235 }, 10236 [ALC883_LENOVO_101E_2ch] = { 10237 .mixers = { alc883_lenovo_101e_2ch_mixer}, 10238 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs}, 10239 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10240 .dac_nids = alc883_dac_nids, 10241 .adc_nids = alc883_adc_nids_alt, 10242 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt), 10243 .capsrc_nids = alc883_capsrc_nids, 10244 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10245 .channel_mode = alc883_3ST_2ch_modes, 10246 .input_mux = &alc883_lenovo_101e_capture_source, 10247 .unsol_event = alc883_lenovo_101e_unsol_event, 10248 .init_hook = alc883_lenovo_101e_all_automute, 10249 }, 10250 [ALC883_LENOVO_NB0763] = { 10251 .mixers = { alc883_lenovo_nb0763_mixer }, 10252 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs}, 10253 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10254 .dac_nids = alc883_dac_nids, 10255 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10256 .channel_mode = alc883_3ST_2ch_modes, 10257 .need_dac_fix = 1, 10258 .input_mux = &alc883_lenovo_nb0763_capture_source, 10259 .unsol_event = alc_automute_amp_unsol_event, 10260 .setup = alc883_medion_md2_setup, 10261 .init_hook = alc_automute_amp, 10262 }, 10263 [ALC888_LENOVO_MS7195_DIG] = { 10264 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, 10265 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs}, 10266 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10267 .dac_nids = alc883_dac_nids, 10268 .dig_out_nid = ALC883_DIGOUT_NID, 10269 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 10270 .channel_mode = alc883_3ST_6ch_modes, 10271 .need_dac_fix = 1, 10272 .input_mux = &alc883_capture_source, 10273 .unsol_event = alc883_lenovo_ms7195_unsol_event, 10274 .init_hook = alc888_lenovo_ms7195_front_automute, 10275 }, 10276 [ALC883_HAIER_W66] = { 10277 .mixers = { alc883_targa_2ch_mixer}, 10278 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs}, 10279 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10280 .dac_nids = alc883_dac_nids, 10281 .dig_out_nid = ALC883_DIGOUT_NID, 10282 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10283 .channel_mode = alc883_3ST_2ch_modes, 10284 .input_mux = &alc883_capture_source, 10285 .unsol_event = alc_automute_amp_unsol_event, 10286 .setup = alc883_haier_w66_setup, 10287 .init_hook = alc_automute_amp, 10288 }, 10289 [ALC888_3ST_HP] = { 10290 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, 10291 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs }, 10292 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10293 .dac_nids = alc883_dac_nids, 10294 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes), 10295 .channel_mode = alc888_3st_hp_modes, 10296 .need_dac_fix = 1, 10297 .input_mux = &alc883_capture_source, 10298 .unsol_event = alc_automute_amp_unsol_event, 10299 .setup = alc888_3st_hp_setup, 10300 .init_hook = alc_automute_amp, 10301 }, 10302 [ALC888_6ST_DELL] = { 10303 .mixers = { alc883_base_mixer, alc883_chmode_mixer }, 10304 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs }, 10305 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10306 .dac_nids = alc883_dac_nids, 10307 .dig_out_nid = ALC883_DIGOUT_NID, 10308 .dig_in_nid = ALC883_DIGIN_NID, 10309 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), 10310 .channel_mode = alc883_sixstack_modes, 10311 .input_mux = &alc883_capture_source, 10312 .unsol_event = alc_automute_amp_unsol_event, 10313 .setup = alc888_6st_dell_setup, 10314 .init_hook = alc_automute_amp, 10315 }, 10316 [ALC883_MITAC] = { 10317 .mixers = { alc883_mitac_mixer }, 10318 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs }, 10319 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10320 .dac_nids = alc883_dac_nids, 10321 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10322 .channel_mode = alc883_3ST_2ch_modes, 10323 .input_mux = &alc883_capture_source, 10324 .unsol_event = alc_automute_amp_unsol_event, 10325 .setup = alc883_mitac_setup, 10326 .init_hook = alc_automute_amp, 10327 }, 10328 [ALC883_FUJITSU_PI2515] = { 10329 .mixers = { alc883_2ch_fujitsu_pi2515_mixer }, 10330 .init_verbs = { alc883_init_verbs, 10331 alc883_2ch_fujitsu_pi2515_verbs}, 10332 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10333 .dac_nids = alc883_dac_nids, 10334 .dig_out_nid = ALC883_DIGOUT_NID, 10335 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10336 .channel_mode = alc883_3ST_2ch_modes, 10337 .input_mux = &alc883_fujitsu_pi2515_capture_source, 10338 .unsol_event = alc_automute_amp_unsol_event, 10339 .setup = alc883_2ch_fujitsu_pi2515_setup, 10340 .init_hook = alc_automute_amp, 10341 }, 10342 [ALC888_FUJITSU_XA3530] = { 10343 .mixers = { alc888_base_mixer, alc883_chmode_mixer }, 10344 .init_verbs = { alc883_init_verbs, 10345 alc888_fujitsu_xa3530_verbs }, 10346 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10347 .dac_nids = alc883_dac_nids, 10348 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev), 10349 .adc_nids = alc883_adc_nids_rev, 10350 .capsrc_nids = alc883_capsrc_nids_rev, 10351 .dig_out_nid = ALC883_DIGOUT_NID, 10352 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes), 10353 .channel_mode = alc888_4ST_8ch_intel_modes, 10354 .num_mux_defs = 10355 ARRAY_SIZE(alc888_2_capture_sources), 10356 .input_mux = alc888_2_capture_sources, 10357 .unsol_event = alc_automute_amp_unsol_event, 10358 .setup = alc888_fujitsu_xa3530_setup, 10359 .init_hook = alc_automute_amp, 10360 }, 10361 [ALC888_LENOVO_SKY] = { 10362 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer }, 10363 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs}, 10364 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10365 .dac_nids = alc883_dac_nids, 10366 .dig_out_nid = ALC883_DIGOUT_NID, 10367 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), 10368 .channel_mode = alc883_sixstack_modes, 10369 .need_dac_fix = 1, 10370 .input_mux = &alc883_lenovo_sky_capture_source, 10371 .unsol_event = alc_automute_amp_unsol_event, 10372 .setup = alc888_lenovo_sky_setup, 10373 .init_hook = alc_automute_amp, 10374 }, 10375 [ALC888_ASUS_M90V] = { 10376 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, 10377 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs }, 10378 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10379 .dac_nids = alc883_dac_nids, 10380 .dig_out_nid = ALC883_DIGOUT_NID, 10381 .dig_in_nid = ALC883_DIGIN_NID, 10382 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 10383 .channel_mode = alc883_3ST_6ch_modes, 10384 .need_dac_fix = 1, 10385 .input_mux = &alc883_fujitsu_pi2515_capture_source, 10386 .unsol_event = alc_sku_unsol_event, 10387 .setup = alc883_mode2_setup, 10388 .init_hook = alc_inithook, 10389 }, 10390 [ALC888_ASUS_EEE1601] = { 10391 .mixers = { alc883_asus_eee1601_mixer }, 10392 .cap_mixer = alc883_asus_eee1601_cap_mixer, 10393 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs }, 10394 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10395 .dac_nids = alc883_dac_nids, 10396 .dig_out_nid = ALC883_DIGOUT_NID, 10397 .dig_in_nid = ALC883_DIGIN_NID, 10398 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10399 .channel_mode = alc883_3ST_2ch_modes, 10400 .need_dac_fix = 1, 10401 .input_mux = &alc883_asus_eee1601_capture_source, 10402 .unsol_event = alc_sku_unsol_event, 10403 .init_hook = alc883_eee1601_inithook, 10404 }, 10405 [ALC1200_ASUS_P5Q] = { 10406 .mixers = { alc883_base_mixer, alc883_chmode_mixer }, 10407 .init_verbs = { alc883_init_verbs }, 10408 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10409 .dac_nids = alc883_dac_nids, 10410 .dig_out_nid = ALC1200_DIGOUT_NID, 10411 .dig_in_nid = ALC883_DIGIN_NID, 10412 .slave_dig_outs = alc1200_slave_dig_outs, 10413 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), 10414 .channel_mode = alc883_sixstack_modes, 10415 .input_mux = &alc883_capture_source, 10416 }, 10417 [ALC889A_MB31] = { 10418 .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer}, 10419 .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs, 10420 alc880_gpio1_init_verbs }, 10421 .adc_nids = alc883_adc_nids, 10422 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 10423 .capsrc_nids = alc883_capsrc_nids, 10424 .dac_nids = alc883_dac_nids, 10425 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10426 .channel_mode = alc889A_mb31_6ch_modes, 10427 .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes), 10428 .input_mux = &alc889A_mb31_capture_source, 10429 .dig_out_nid = ALC883_DIGOUT_NID, 10430 .unsol_event = alc889A_mb31_unsol_event, 10431 .init_hook = alc889A_mb31_automute, 10432 }, 10433 [ALC883_SONY_VAIO_TT] = { 10434 .mixers = { alc883_vaiott_mixer }, 10435 .init_verbs = { alc883_init_verbs, alc883_vaiott_verbs }, 10436 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10437 .dac_nids = alc883_dac_nids, 10438 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10439 .channel_mode = alc883_3ST_2ch_modes, 10440 .input_mux = &alc883_capture_source, 10441 .unsol_event = alc_automute_amp_unsol_event, 10442 .setup = alc883_vaiott_setup, 10443 .init_hook = alc_automute_amp, 10444 }, 10445}; 10446 10447 10448/* 10449 * Pin config fixes 10450 */ 10451enum { 10452 PINFIX_ABIT_AW9D_MAX, 10453 PINFIX_PB_M5210, 10454}; 10455 10456static const struct alc_fixup alc882_fixups[] = { 10457 [PINFIX_ABIT_AW9D_MAX] = { 10458 .pins = (const struct alc_pincfg[]) { 10459 { 0x15, 0x01080104 }, /* side */ 10460 { 0x16, 0x01011012 }, /* rear */ 10461 { 0x17, 0x01016011 }, /* clfe */ 10462 { } 10463 } 10464 }, 10465 [PINFIX_PB_M5210] = { 10466 .verbs = (const struct hda_verb[]) { 10467 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 }, 10468 {} 10469 } 10470 }, 10471}; 10472 10473static struct snd_pci_quirk alc882_fixup_tbl[] = { 10474 SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", PINFIX_PB_M5210), 10475 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX), 10476 {} 10477}; 10478 10479/* 10480 * BIOS auto configuration 10481 */ 10482static int alc882_auto_create_input_ctls(struct hda_codec *codec, 10483 const struct auto_pin_cfg *cfg) 10484{ 10485 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x23, 0x22); 10486} 10487 10488static void alc882_auto_set_output_and_unmute(struct hda_codec *codec, 10489 hda_nid_t nid, int pin_type, 10490 hda_nid_t dac) 10491{ 10492 int idx; 10493 10494 /* set as output */ 10495 alc_set_pin_output(codec, nid, pin_type); 10496 10497 if (dac == 0x25) 10498 idx = 4; 10499 else if (dac >= 0x02 && dac <= 0x05) 10500 idx = dac - 2; 10501 else 10502 return; 10503 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx); 10504} 10505 10506static void alc882_auto_init_multi_out(struct hda_codec *codec) 10507{ 10508 struct alc_spec *spec = codec->spec; 10509 int i; 10510 10511 for (i = 0; i <= HDA_SIDE; i++) { 10512 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 10513 int pin_type = get_pin_type(spec->autocfg.line_out_type); 10514 if (nid) 10515 alc882_auto_set_output_and_unmute(codec, nid, pin_type, 10516 spec->multiout.dac_nids[i]); 10517 } 10518} 10519 10520static void alc882_auto_init_hp_out(struct hda_codec *codec) 10521{ 10522 struct alc_spec *spec = codec->spec; 10523 hda_nid_t pin, dac; 10524 10525 pin = spec->autocfg.hp_pins[0]; 10526 if (pin) { 10527 dac = spec->multiout.hp_nid; 10528 if (!dac) 10529 dac = spec->multiout.dac_nids[0]; /* to front */ 10530 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, dac); 10531 } 10532 pin = spec->autocfg.speaker_pins[0]; 10533 if (pin) { 10534 dac = spec->multiout.extra_out_nid[0]; 10535 if (!dac) 10536 dac = spec->multiout.dac_nids[0]; /* to front */ 10537 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac); 10538 } 10539} 10540 10541static void alc882_auto_init_analog_input(struct hda_codec *codec) 10542{ 10543 struct alc_spec *spec = codec->spec; 10544 struct auto_pin_cfg *cfg = &spec->autocfg; 10545 int i; 10546 10547 for (i = 0; i < cfg->num_inputs; i++) { 10548 hda_nid_t nid = cfg->inputs[i].pin; 10549 alc_set_input_pin(codec, nid, i); 10550 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP) 10551 snd_hda_codec_write(codec, nid, 0, 10552 AC_VERB_SET_AMP_GAIN_MUTE, 10553 AMP_OUT_MUTE); 10554 } 10555} 10556 10557static void alc882_auto_init_input_src(struct hda_codec *codec) 10558{ 10559 struct alc_spec *spec = codec->spec; 10560 int c; 10561 10562 for (c = 0; c < spec->num_adc_nids; c++) { 10563 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS]; 10564 hda_nid_t nid = spec->capsrc_nids[c]; 10565 unsigned int mux_idx; 10566 const struct hda_input_mux *imux; 10567 int conns, mute, idx, item; 10568 10569 conns = snd_hda_get_connections(codec, nid, conn_list, 10570 ARRAY_SIZE(conn_list)); 10571 if (conns < 0) 10572 continue; 10573 mux_idx = c >= spec->num_mux_defs ? 0 : c; 10574 imux = &spec->input_mux[mux_idx]; 10575 if (!imux->num_items && mux_idx > 0) 10576 imux = &spec->input_mux[0]; 10577 for (idx = 0; idx < conns; idx++) { 10578 /* if the current connection is the selected one, 10579 * unmute it as default - otherwise mute it 10580 */ 10581 mute = AMP_IN_MUTE(idx); 10582 for (item = 0; item < imux->num_items; item++) { 10583 if (imux->items[item].index == idx) { 10584 if (spec->cur_mux[c] == item) 10585 mute = AMP_IN_UNMUTE(idx); 10586 break; 10587 } 10588 } 10589 /* check if we have a selector or mixer 10590 * we could check for the widget type instead, but 10591 * just check for Amp-In presence (in case of mixer 10592 * without amp-in there is something wrong, this 10593 * function shouldn't be used or capsrc nid is wrong) 10594 */ 10595 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) 10596 snd_hda_codec_write(codec, nid, 0, 10597 AC_VERB_SET_AMP_GAIN_MUTE, 10598 mute); 10599 else if (mute != AMP_IN_MUTE(idx)) 10600 snd_hda_codec_write(codec, nid, 0, 10601 AC_VERB_SET_CONNECT_SEL, 10602 idx); 10603 } 10604 } 10605} 10606 10607/* add mic boosts if needed */ 10608static int alc_auto_add_mic_boost(struct hda_codec *codec) 10609{ 10610 struct alc_spec *spec = codec->spec; 10611 struct auto_pin_cfg *cfg = &spec->autocfg; 10612 int i, err; 10613 hda_nid_t nid; 10614 10615 for (i = 0; i < cfg->num_inputs; i++) { 10616 if (cfg->inputs[i].type > AUTO_PIN_FRONT_MIC) 10617 break; 10618 nid = cfg->inputs[i].pin; 10619 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) { 10620 char label[32]; 10621 snprintf(label, sizeof(label), "%s Boost", 10622 snd_hda_get_input_pin_label(cfg, i)); 10623 err = add_control(spec, ALC_CTL_WIDGET_VOL, label, 0, 10624 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT)); 10625 if (err < 0) 10626 return err; 10627 } 10628 } 10629 return 0; 10630} 10631 10632/* almost identical with ALC880 parser... */ 10633static int alc882_parse_auto_config(struct hda_codec *codec) 10634{ 10635 struct alc_spec *spec = codec->spec; 10636 static hda_nid_t alc882_ignore[] = { 0x1d, 0 }; 10637 int err; 10638 10639 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 10640 alc882_ignore); 10641 if (err < 0) 10642 return err; 10643 if (!spec->autocfg.line_outs) 10644 return 0; /* can't find valid BIOS pin config */ 10645 10646 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); 10647 if (err < 0) 10648 return err; 10649 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg); 10650 if (err < 0) 10651 return err; 10652 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0], 10653 "Headphone"); 10654 if (err < 0) 10655 return err; 10656 err = alc880_auto_create_extra_out(spec, 10657 spec->autocfg.speaker_pins[0], 10658 "Speaker"); 10659 if (err < 0) 10660 return err; 10661 err = alc882_auto_create_input_ctls(codec, &spec->autocfg); 10662 if (err < 0) 10663 return err; 10664 10665 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 10666 10667 alc_auto_parse_digital(codec); 10668 10669 if (spec->kctls.list) 10670 add_mixer(spec, spec->kctls.list); 10671 10672 add_verb(spec, alc883_auto_init_verbs); 10673 /* if ADC 0x07 is available, initialize it, too */ 10674 if (get_wcaps_type(get_wcaps(codec, 0x07)) == AC_WID_AUD_IN) 10675 add_verb(spec, alc882_adc1_init_verbs); 10676 10677 spec->num_mux_defs = 1; 10678 spec->input_mux = &spec->private_imux[0]; 10679 10680 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); 10681 10682 err = alc_auto_add_mic_boost(codec); 10683 if (err < 0) 10684 return err; 10685 10686 return 1; /* config found */ 10687} 10688 10689/* additional initialization for auto-configuration model */ 10690static void alc882_auto_init(struct hda_codec *codec) 10691{ 10692 struct alc_spec *spec = codec->spec; 10693 alc882_auto_init_multi_out(codec); 10694 alc882_auto_init_hp_out(codec); 10695 alc882_auto_init_analog_input(codec); 10696 alc882_auto_init_input_src(codec); 10697 alc_auto_init_digital(codec); 10698 if (spec->unsol_event) 10699 alc_inithook(codec); 10700} 10701 10702static int patch_alc882(struct hda_codec *codec) 10703{ 10704 struct alc_spec *spec; 10705 int err, board_config; 10706 10707 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 10708 if (spec == NULL) 10709 return -ENOMEM; 10710 10711 codec->spec = spec; 10712 10713 alc_auto_parse_customize_define(codec); 10714 10715 switch (codec->vendor_id) { 10716 case 0x10ec0882: 10717 case 0x10ec0885: 10718 break; 10719 default: 10720 /* ALC883 and variants */ 10721 alc_fix_pll_init(codec, 0x20, 0x0a, 10); 10722 break; 10723 } 10724 10725 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST, 10726 alc882_models, 10727 alc882_cfg_tbl); 10728 10729 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) 10730 board_config = snd_hda_check_board_codec_sid_config(codec, 10731 ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl); 10732 10733 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) { 10734 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 10735 codec->chip_name); 10736 board_config = ALC882_AUTO; 10737 } 10738 10739 if (board_config == ALC882_AUTO) 10740 alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups, 1); 10741 10742 if (board_config == ALC882_AUTO) { 10743 /* automatic parse from the BIOS config */ 10744 err = alc882_parse_auto_config(codec); 10745 if (err < 0) { 10746 alc_free(codec); 10747 return err; 10748 } else if (!err) { 10749 printk(KERN_INFO 10750 "hda_codec: Cannot set up configuration " 10751 "from BIOS. Using base mode...\n"); 10752 board_config = ALC882_3ST_DIG; 10753 } 10754 } 10755 10756 if (has_cdefine_beep(codec)) { 10757 err = snd_hda_attach_beep_device(codec, 0x1); 10758 if (err < 0) { 10759 alc_free(codec); 10760 return err; 10761 } 10762 } 10763 10764 if (board_config != ALC882_AUTO) 10765 setup_preset(codec, &alc882_presets[board_config]); 10766 10767 spec->stream_analog_playback = &alc882_pcm_analog_playback; 10768 spec->stream_analog_capture = &alc882_pcm_analog_capture; 10769 /* FIXME: setup DAC5 */ 10770 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/ 10771 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture; 10772 10773 spec->stream_digital_playback = &alc882_pcm_digital_playback; 10774 spec->stream_digital_capture = &alc882_pcm_digital_capture; 10775 10776 if (!spec->adc_nids && spec->input_mux) { 10777 int i, j; 10778 spec->num_adc_nids = 0; 10779 for (i = 0; i < ARRAY_SIZE(alc882_adc_nids); i++) { 10780 const struct hda_input_mux *imux = spec->input_mux; 10781 hda_nid_t cap; 10782 hda_nid_t items[16]; 10783 hda_nid_t nid = alc882_adc_nids[i]; 10784 unsigned int wcap = get_wcaps(codec, nid); 10785 /* get type */ 10786 wcap = get_wcaps_type(wcap); 10787 if (wcap != AC_WID_AUD_IN) 10788 continue; 10789 spec->private_adc_nids[spec->num_adc_nids] = nid; 10790 err = snd_hda_get_connections(codec, nid, &cap, 1); 10791 if (err < 0) 10792 continue; 10793 err = snd_hda_get_connections(codec, cap, items, 10794 ARRAY_SIZE(items)); 10795 if (err < 0) 10796 continue; 10797 for (j = 0; j < imux->num_items; j++) 10798 if (imux->items[j].index >= err) 10799 break; 10800 if (j < imux->num_items) 10801 continue; 10802 spec->private_capsrc_nids[spec->num_adc_nids] = cap; 10803 spec->num_adc_nids++; 10804 } 10805 spec->adc_nids = spec->private_adc_nids; 10806 spec->capsrc_nids = spec->private_capsrc_nids; 10807 } 10808 10809 set_capture_mixer(codec); 10810 10811 if (has_cdefine_beep(codec)) 10812 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 10813 10814 if (board_config == ALC882_AUTO) 10815 alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups, 0); 10816 10817 spec->vmaster_nid = 0x0c; 10818 10819 codec->patch_ops = alc_patch_ops; 10820 if (board_config == ALC882_AUTO) 10821 spec->init_hook = alc882_auto_init; 10822#ifdef CONFIG_SND_HDA_POWER_SAVE 10823 if (!spec->loopback.amplist) 10824 spec->loopback.amplist = alc882_loopbacks; 10825#endif 10826 10827 return 0; 10828} 10829 10830 10831/* 10832 * ALC262 support 10833 */ 10834 10835#define ALC262_DIGOUT_NID ALC880_DIGOUT_NID 10836#define ALC262_DIGIN_NID ALC880_DIGIN_NID 10837 10838#define alc262_dac_nids alc260_dac_nids 10839#define alc262_adc_nids alc882_adc_nids 10840#define alc262_adc_nids_alt alc882_adc_nids_alt 10841#define alc262_capsrc_nids alc882_capsrc_nids 10842#define alc262_capsrc_nids_alt alc882_capsrc_nids_alt 10843 10844#define alc262_modes alc260_modes 10845#define alc262_capture_source alc882_capture_source 10846 10847static hda_nid_t alc262_dmic_adc_nids[1] = { 10848 /* ADC0 */ 10849 0x09 10850}; 10851 10852static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 }; 10853 10854static struct snd_kcontrol_new alc262_base_mixer[] = { 10855 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 10856 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 10857 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 10858 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 10859 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 10860 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 10861 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 10862 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 10863 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 10864 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 10865 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 10866 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 10867 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT), 10868 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 10869 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 10870 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT), 10871 { } /* end */ 10872}; 10873 10874/* update HP, line and mono-out pins according to the master switch */ 10875static void alc262_hp_master_update(struct hda_codec *codec) 10876{ 10877 struct alc_spec *spec = codec->spec; 10878 int val = spec->master_sw; 10879 10880 /* HP & line-out */ 10881 snd_hda_codec_write_cache(codec, 0x1b, 0, 10882 AC_VERB_SET_PIN_WIDGET_CONTROL, 10883 val ? PIN_HP : 0); 10884 snd_hda_codec_write_cache(codec, 0x15, 0, 10885 AC_VERB_SET_PIN_WIDGET_CONTROL, 10886 val ? PIN_HP : 0); 10887 /* mono (speaker) depending on the HP jack sense */ 10888 val = val && !spec->jack_present; 10889 snd_hda_codec_write_cache(codec, 0x16, 0, 10890 AC_VERB_SET_PIN_WIDGET_CONTROL, 10891 val ? PIN_OUT : 0); 10892} 10893 10894static void alc262_hp_bpc_automute(struct hda_codec *codec) 10895{ 10896 struct alc_spec *spec = codec->spec; 10897 10898 spec->jack_present = snd_hda_jack_detect(codec, 0x1b); 10899 alc262_hp_master_update(codec); 10900} 10901 10902static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res) 10903{ 10904 if ((res >> 26) != ALC880_HP_EVENT) 10905 return; 10906 alc262_hp_bpc_automute(codec); 10907} 10908 10909static void alc262_hp_wildwest_automute(struct hda_codec *codec) 10910{ 10911 struct alc_spec *spec = codec->spec; 10912 10913 spec->jack_present = snd_hda_jack_detect(codec, 0x15); 10914 alc262_hp_master_update(codec); 10915} 10916 10917static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec, 10918 unsigned int res) 10919{ 10920 if ((res >> 26) != ALC880_HP_EVENT) 10921 return; 10922 alc262_hp_wildwest_automute(codec); 10923} 10924 10925#define alc262_hp_master_sw_get alc260_hp_master_sw_get 10926 10927static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol, 10928 struct snd_ctl_elem_value *ucontrol) 10929{ 10930 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 10931 struct alc_spec *spec = codec->spec; 10932 int val = !!*ucontrol->value.integer.value; 10933 10934 if (val == spec->master_sw) 10935 return 0; 10936 spec->master_sw = val; 10937 alc262_hp_master_update(codec); 10938 return 1; 10939} 10940 10941#define ALC262_HP_MASTER_SWITCH \ 10942 { \ 10943 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 10944 .name = "Master Playback Switch", \ 10945 .info = snd_ctl_boolean_mono_info, \ 10946 .get = alc262_hp_master_sw_get, \ 10947 .put = alc262_hp_master_sw_put, \ 10948 }, \ 10949 { \ 10950 .iface = NID_MAPPING, \ 10951 .name = "Master Playback Switch", \ 10952 .private_value = 0x15 | (0x16 << 8) | (0x1b << 16), \ 10953 } 10954 10955 10956static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = { 10957 ALC262_HP_MASTER_SWITCH, 10958 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 10959 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT), 10960 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 10961 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0, 10962 HDA_OUTPUT), 10963 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0, 10964 HDA_OUTPUT), 10965 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 10966 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 10967 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 10968 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 10969 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 10970 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 10971 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 10972 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 10973 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 10974 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 10975 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT), 10976 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT), 10977 { } /* end */ 10978}; 10979 10980static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = { 10981 ALC262_HP_MASTER_SWITCH, 10982 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 10983 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 10984 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 10985 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 10986 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0, 10987 HDA_OUTPUT), 10988 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0, 10989 HDA_OUTPUT), 10990 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT), 10991 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT), 10992 HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT), 10993 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT), 10994 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT), 10995 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 10996 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 10997 { } /* end */ 10998}; 10999 11000static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = { 11001 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11002 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11003 HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT), 11004 { } /* end */ 11005}; 11006 11007/* mute/unmute internal speaker according to the hp jack and mute state */ 11008static void alc262_hp_t5735_setup(struct hda_codec *codec) 11009{ 11010 struct alc_spec *spec = codec->spec; 11011 11012 spec->autocfg.hp_pins[0] = 0x15; 11013 spec->autocfg.speaker_pins[0] = 0x14; 11014} 11015 11016static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = { 11017 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11018 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 11019 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 11020 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 11021 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11022 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11023 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 11024 { } /* end */ 11025}; 11026 11027static struct hda_verb alc262_hp_t5735_verbs[] = { 11028 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 11029 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11030 11031 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 11032 { } 11033}; 11034 11035static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = { 11036 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11037 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 11038 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT), 11039 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT), 11040 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT), 11041 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT), 11042 { } /* end */ 11043}; 11044 11045static struct hda_verb alc262_hp_rp5700_verbs[] = { 11046 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 11047 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 11048 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 11049 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 11050 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 11051 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 11052 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 11053 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 11054 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))}, 11055 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))}, 11056 {} 11057}; 11058 11059static struct hda_input_mux alc262_hp_rp5700_capture_source = { 11060 .num_items = 1, 11061 .items = { 11062 { "Line", 0x1 }, 11063 }, 11064}; 11065 11066/* bind hp and internal speaker mute (with plug check) as master switch */ 11067static void alc262_hippo_master_update(struct hda_codec *codec) 11068{ 11069 struct alc_spec *spec = codec->spec; 11070 hda_nid_t hp_nid = spec->autocfg.hp_pins[0]; 11071 hda_nid_t line_nid = spec->autocfg.line_out_pins[0]; 11072 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0]; 11073 unsigned int mute; 11074 11075 /* HP */ 11076 mute = spec->master_sw ? 0 : HDA_AMP_MUTE; 11077 snd_hda_codec_amp_stereo(codec, hp_nid, HDA_OUTPUT, 0, 11078 HDA_AMP_MUTE, mute); 11079 /* mute internal speaker per jack sense */ 11080 if (spec->jack_present) 11081 mute = HDA_AMP_MUTE; 11082 if (line_nid) 11083 snd_hda_codec_amp_stereo(codec, line_nid, HDA_OUTPUT, 0, 11084 HDA_AMP_MUTE, mute); 11085 if (speaker_nid && speaker_nid != line_nid) 11086 snd_hda_codec_amp_stereo(codec, speaker_nid, HDA_OUTPUT, 0, 11087 HDA_AMP_MUTE, mute); 11088} 11089 11090#define alc262_hippo_master_sw_get alc262_hp_master_sw_get 11091 11092static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol, 11093 struct snd_ctl_elem_value *ucontrol) 11094{ 11095 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 11096 struct alc_spec *spec = codec->spec; 11097 int val = !!*ucontrol->value.integer.value; 11098 11099 if (val == spec->master_sw) 11100 return 0; 11101 spec->master_sw = val; 11102 alc262_hippo_master_update(codec); 11103 return 1; 11104} 11105 11106#define ALC262_HIPPO_MASTER_SWITCH \ 11107 { \ 11108 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 11109 .name = "Master Playback Switch", \ 11110 .info = snd_ctl_boolean_mono_info, \ 11111 .get = alc262_hippo_master_sw_get, \ 11112 .put = alc262_hippo_master_sw_put, \ 11113 }, \ 11114 { \ 11115 .iface = NID_MAPPING, \ 11116 .name = "Master Playback Switch", \ 11117 .subdevice = SUBDEV_HP(0) | (SUBDEV_LINE(0) << 8) | \ 11118 (SUBDEV_SPEAKER(0) << 16), \ 11119 } 11120 11121static struct snd_kcontrol_new alc262_hippo_mixer[] = { 11122 ALC262_HIPPO_MASTER_SWITCH, 11123 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11124 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 11125 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 11126 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 11127 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 11128 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11129 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11130 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 11131 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 11132 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 11133 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 11134 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 11135 { } /* end */ 11136}; 11137 11138static struct snd_kcontrol_new alc262_hippo1_mixer[] = { 11139 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11140 ALC262_HIPPO_MASTER_SWITCH, 11141 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 11142 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 11143 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 11144 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 11145 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11146 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11147 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 11148 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 11149 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 11150 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 11151 { } /* end */ 11152}; 11153 11154/* mute/unmute internal speaker according to the hp jack and mute state */ 11155static void alc262_hippo_automute(struct hda_codec *codec) 11156{ 11157 struct alc_spec *spec = codec->spec; 11158 hda_nid_t hp_nid = spec->autocfg.hp_pins[0]; 11159 11160 spec->jack_present = snd_hda_jack_detect(codec, hp_nid); 11161 alc262_hippo_master_update(codec); 11162} 11163 11164static void alc262_hippo_unsol_event(struct hda_codec *codec, unsigned int res) 11165{ 11166 if ((res >> 26) != ALC880_HP_EVENT) 11167 return; 11168 alc262_hippo_automute(codec); 11169} 11170 11171static void alc262_hippo_setup(struct hda_codec *codec) 11172{ 11173 struct alc_spec *spec = codec->spec; 11174 11175 spec->autocfg.hp_pins[0] = 0x15; 11176 spec->autocfg.speaker_pins[0] = 0x14; 11177} 11178 11179static void alc262_hippo1_setup(struct hda_codec *codec) 11180{ 11181 struct alc_spec *spec = codec->spec; 11182 11183 spec->autocfg.hp_pins[0] = 0x1b; 11184 spec->autocfg.speaker_pins[0] = 0x14; 11185} 11186 11187 11188static struct snd_kcontrol_new alc262_sony_mixer[] = { 11189 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11190 ALC262_HIPPO_MASTER_SWITCH, 11191 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11192 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11193 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 11194 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 11195 { } /* end */ 11196}; 11197 11198static struct snd_kcontrol_new alc262_benq_t31_mixer[] = { 11199 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11200 ALC262_HIPPO_MASTER_SWITCH, 11201 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 11202 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11203 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11204 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 11205 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 11206 { } /* end */ 11207}; 11208 11209static struct snd_kcontrol_new alc262_tyan_mixer[] = { 11210 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11211 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT), 11212 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT), 11213 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT), 11214 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 11215 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 11216 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11217 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11218 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 11219 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 11220 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 11221 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 11222 { } /* end */ 11223}; 11224 11225static struct hda_verb alc262_tyan_verbs[] = { 11226 /* Headphone automute */ 11227 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 11228 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11229 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 11230 11231 /* P11 AUX_IN, white 4-pin connector */ 11232 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 11233 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1}, 11234 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93}, 11235 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19}, 11236 11237 {} 11238}; 11239 11240/* unsolicited event for HP jack sensing */ 11241static void alc262_tyan_setup(struct hda_codec *codec) 11242{ 11243 struct alc_spec *spec = codec->spec; 11244 11245 spec->autocfg.hp_pins[0] = 0x1b; 11246 spec->autocfg.speaker_pins[0] = 0x15; 11247} 11248 11249 11250#define alc262_capture_mixer alc882_capture_mixer 11251#define alc262_capture_alt_mixer alc882_capture_alt_mixer 11252 11253/* 11254 * generic initialization of ADC, input mixers and output mixers 11255 */ 11256static struct hda_verb alc262_init_verbs[] = { 11257 /* 11258 * Unmute ADC0-2 and set the default input to mic-in 11259 */ 11260 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 11261 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11262 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 11263 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11264 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 11265 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11266 11267 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 11268 * mixer widget 11269 * Note: PASD motherboards uses the Line In 2 as the input for 11270 * front panel mic (mic 2) 11271 */ 11272 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 11273 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 11274 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 11275 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 11276 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 11277 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 11278 11279 /* 11280 * Set up output mixers (0x0c - 0x0e) 11281 */ 11282 /* set vol=0 to output mixers */ 11283 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 11284 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 11285 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 11286 /* set up input amps for analog loopback */ 11287 /* Amp Indices: DAC = 0, mixer = 1 */ 11288 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11289 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11290 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11291 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11292 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11293 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11294 11295 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 11296 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 11297 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 11298 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 11299 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 11300 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 11301 11302 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 11303 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 11304 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 11305 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 11306 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 11307 11308 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 11309 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 11310 11311 /* FIXME: use matrix-type input source selection */ 11312 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 11313 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 11314 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 11315 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 11316 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 11317 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 11318 /* Input mixer2 */ 11319 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 11320 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 11321 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 11322 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 11323 /* Input mixer3 */ 11324 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 11325 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 11326 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 11327 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 11328 11329 { } 11330}; 11331 11332static struct hda_verb alc262_eapd_verbs[] = { 11333 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 11334 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, 11335 { } 11336}; 11337 11338static struct hda_verb alc262_hippo1_unsol_verbs[] = { 11339 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 11340 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 11341 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 11342 11343 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 11344 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11345 {} 11346}; 11347 11348static struct hda_verb alc262_sony_unsol_verbs[] = { 11349 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 11350 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 11351 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic 11352 11353 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 11354 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11355 {} 11356}; 11357 11358static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = { 11359 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11360 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 11361 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 11362 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11363 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11364 { } /* end */ 11365}; 11366 11367static struct hda_verb alc262_toshiba_s06_verbs[] = { 11368 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 11369 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 11370 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11371 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 11372 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09}, 11373 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 11374 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 11375 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 11376 {} 11377}; 11378 11379static void alc262_toshiba_s06_setup(struct hda_codec *codec) 11380{ 11381 struct alc_spec *spec = codec->spec; 11382 11383 spec->autocfg.hp_pins[0] = 0x15; 11384 spec->autocfg.speaker_pins[0] = 0x14; 11385 spec->ext_mic.pin = 0x18; 11386 spec->ext_mic.mux_idx = 0; 11387 spec->int_mic.pin = 0x12; 11388 spec->int_mic.mux_idx = 9; 11389 spec->auto_mic = 1; 11390} 11391 11392/* 11393 * nec model 11394 * 0x15 = headphone 11395 * 0x16 = internal speaker 11396 * 0x18 = external mic 11397 */ 11398 11399static struct snd_kcontrol_new alc262_nec_mixer[] = { 11400 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 11401 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT), 11402 11403 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11404 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11405 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 11406 11407 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 11408 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 11409 { } /* end */ 11410}; 11411 11412static struct hda_verb alc262_nec_verbs[] = { 11413 /* Unmute Speaker */ 11414 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 11415 11416 /* Headphone */ 11417 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 11418 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 11419 11420 /* External mic to headphone */ 11421 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11422 /* External mic to speaker */ 11423 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11424 {} 11425}; 11426 11427/* 11428 * fujitsu model 11429 * 0x14 = headphone/spdif-out, 0x15 = internal speaker, 11430 * 0x1b = port replicator headphone out 11431 */ 11432 11433#define ALC_HP_EVENT 0x37 11434 11435static struct hda_verb alc262_fujitsu_unsol_verbs[] = { 11436 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, 11437 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11438 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, 11439 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11440 {} 11441}; 11442 11443static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = { 11444 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, 11445 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11446 {} 11447}; 11448 11449static struct hda_verb alc262_lenovo_3000_init_verbs[] = { 11450 /* Front Mic pin: input vref at 50% */ 11451 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, 11452 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 11453 {} 11454}; 11455 11456static struct hda_input_mux alc262_fujitsu_capture_source = { 11457 .num_items = 3, 11458 .items = { 11459 { "Mic", 0x0 }, 11460 { "Int Mic", 0x1 }, 11461 { "CD", 0x4 }, 11462 }, 11463}; 11464 11465static struct hda_input_mux alc262_HP_capture_source = { 11466 .num_items = 5, 11467 .items = { 11468 { "Mic", 0x0 }, 11469 { "Front Mic", 0x1 }, 11470 { "Line", 0x2 }, 11471 { "CD", 0x4 }, 11472 { "AUX IN", 0x6 }, 11473 }, 11474}; 11475 11476static struct hda_input_mux alc262_HP_D7000_capture_source = { 11477 .num_items = 4, 11478 .items = { 11479 { "Mic", 0x0 }, 11480 { "Front Mic", 0x2 }, 11481 { "Line", 0x1 }, 11482 { "CD", 0x4 }, 11483 }, 11484}; 11485 11486/* mute/unmute internal speaker according to the hp jacks and mute state */ 11487static void alc262_fujitsu_automute(struct hda_codec *codec, int force) 11488{ 11489 struct alc_spec *spec = codec->spec; 11490 unsigned int mute; 11491 11492 if (force || !spec->sense_updated) { 11493 spec->jack_present = snd_hda_jack_detect(codec, 0x14) || 11494 snd_hda_jack_detect(codec, 0x1b); 11495 spec->sense_updated = 1; 11496 } 11497 /* unmute internal speaker only if both HPs are unplugged and 11498 * master switch is on 11499 */ 11500 if (spec->jack_present) 11501 mute = HDA_AMP_MUTE; 11502 else 11503 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0); 11504 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 11505 HDA_AMP_MUTE, mute); 11506} 11507 11508/* unsolicited event for HP jack sensing */ 11509static void alc262_fujitsu_unsol_event(struct hda_codec *codec, 11510 unsigned int res) 11511{ 11512 if ((res >> 26) != ALC_HP_EVENT) 11513 return; 11514 alc262_fujitsu_automute(codec, 1); 11515} 11516 11517static void alc262_fujitsu_init_hook(struct hda_codec *codec) 11518{ 11519 alc262_fujitsu_automute(codec, 1); 11520} 11521 11522/* bind volumes of both NID 0x0c and 0x0d */ 11523static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = { 11524 .ops = &snd_hda_bind_vol, 11525 .values = { 11526 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT), 11527 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT), 11528 0 11529 }, 11530}; 11531 11532/* mute/unmute internal speaker according to the hp jack and mute state */ 11533static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force) 11534{ 11535 struct alc_spec *spec = codec->spec; 11536 unsigned int mute; 11537 11538 if (force || !spec->sense_updated) { 11539 spec->jack_present = snd_hda_jack_detect(codec, 0x1b); 11540 spec->sense_updated = 1; 11541 } 11542 if (spec->jack_present) { 11543 /* mute internal speaker */ 11544 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 11545 HDA_AMP_MUTE, HDA_AMP_MUTE); 11546 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0, 11547 HDA_AMP_MUTE, HDA_AMP_MUTE); 11548 } else { 11549 /* unmute internal speaker if necessary */ 11550 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0); 11551 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 11552 HDA_AMP_MUTE, mute); 11553 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0, 11554 HDA_AMP_MUTE, mute); 11555 } 11556} 11557 11558/* unsolicited event for HP jack sensing */ 11559static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec, 11560 unsigned int res) 11561{ 11562 if ((res >> 26) != ALC_HP_EVENT) 11563 return; 11564 alc262_lenovo_3000_automute(codec, 1); 11565} 11566 11567static int amp_stereo_mute_update(struct hda_codec *codec, hda_nid_t nid, 11568 int dir, int idx, long *valp) 11569{ 11570 int i, change = 0; 11571 11572 for (i = 0; i < 2; i++, valp++) 11573 change |= snd_hda_codec_amp_update(codec, nid, i, dir, idx, 11574 HDA_AMP_MUTE, 11575 *valp ? 0 : HDA_AMP_MUTE); 11576 return change; 11577} 11578 11579/* bind hp and internal speaker mute (with plug check) */ 11580static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol, 11581 struct snd_ctl_elem_value *ucontrol) 11582{ 11583 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 11584 long *valp = ucontrol->value.integer.value; 11585 int change; 11586 11587 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp); 11588 change |= amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp); 11589 if (change) 11590 alc262_fujitsu_automute(codec, 0); 11591 return change; 11592} 11593 11594static struct snd_kcontrol_new alc262_fujitsu_mixer[] = { 11595 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol), 11596 { 11597 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 11598 .name = "Master Playback Switch", 11599 .subdevice = HDA_SUBDEV_AMP_FLAG, 11600 .info = snd_hda_mixer_amp_switch_info, 11601 .get = snd_hda_mixer_amp_switch_get, 11602 .put = alc262_fujitsu_master_sw_put, 11603 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 11604 }, 11605 { 11606 .iface = NID_MAPPING, 11607 .name = "Master Playback Switch", 11608 .private_value = 0x1b, 11609 }, 11610 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 11611 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 11612 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 11613 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11614 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11615 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 11616 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 11617 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 11618 { } /* end */ 11619}; 11620 11621/* bind hp and internal speaker mute (with plug check) */ 11622static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol, 11623 struct snd_ctl_elem_value *ucontrol) 11624{ 11625 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 11626 long *valp = ucontrol->value.integer.value; 11627 int change; 11628 11629 change = amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp); 11630 if (change) 11631 alc262_lenovo_3000_automute(codec, 0); 11632 return change; 11633} 11634 11635static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = { 11636 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol), 11637 { 11638 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 11639 .name = "Master Playback Switch", 11640 .subdevice = HDA_SUBDEV_AMP_FLAG, 11641 .info = snd_hda_mixer_amp_switch_info, 11642 .get = snd_hda_mixer_amp_switch_get, 11643 .put = alc262_lenovo_3000_master_sw_put, 11644 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT), 11645 }, 11646 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 11647 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 11648 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 11649 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11650 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11651 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 11652 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 11653 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 11654 { } /* end */ 11655}; 11656 11657static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = { 11658 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol), 11659 ALC262_HIPPO_MASTER_SWITCH, 11660 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11661 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11662 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 11663 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 11664 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 11665 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 11666 { } /* end */ 11667}; 11668 11669/* additional init verbs for Benq laptops */ 11670static struct hda_verb alc262_EAPD_verbs[] = { 11671 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 11672 {0x20, AC_VERB_SET_PROC_COEF, 0x3070}, 11673 {} 11674}; 11675 11676static struct hda_verb alc262_benq_t31_EAPD_verbs[] = { 11677 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 11678 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 11679 11680 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 11681 {0x20, AC_VERB_SET_PROC_COEF, 0x3050}, 11682 {} 11683}; 11684 11685/* Samsung Q1 Ultra Vista model setup */ 11686static struct snd_kcontrol_new alc262_ultra_mixer[] = { 11687 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11688 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT), 11689 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 11690 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 11691 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT), 11692 HDA_CODEC_VOLUME("Headphone Mic Boost", 0x15, 0, HDA_INPUT), 11693 { } /* end */ 11694}; 11695 11696static struct hda_verb alc262_ultra_verbs[] = { 11697 /* output mixer */ 11698 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 11699 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 11700 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 11701 /* speaker */ 11702 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 11703 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 11704 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11705 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 11706 /* HP */ 11707 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11708 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 11709 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11710 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 11711 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 11712 /* internal mic */ 11713 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 11714 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 11715 /* ADC, choose mic */ 11716 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 11717 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 11718 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11719 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 11720 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 11721 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 11722 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, 11723 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, 11724 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, 11725 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)}, 11726 {} 11727}; 11728 11729/* mute/unmute internal speaker according to the hp jack and mute state */ 11730static void alc262_ultra_automute(struct hda_codec *codec) 11731{ 11732 struct alc_spec *spec = codec->spec; 11733 unsigned int mute; 11734 11735 mute = 0; 11736 /* auto-mute only when HP is used as HP */ 11737 if (!spec->cur_mux[0]) { 11738 spec->jack_present = snd_hda_jack_detect(codec, 0x15); 11739 if (spec->jack_present) 11740 mute = HDA_AMP_MUTE; 11741 } 11742 /* mute/unmute internal speaker */ 11743 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 11744 HDA_AMP_MUTE, mute); 11745 /* mute/unmute HP */ 11746 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 11747 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE); 11748} 11749 11750/* unsolicited event for HP jack sensing */ 11751static void alc262_ultra_unsol_event(struct hda_codec *codec, 11752 unsigned int res) 11753{ 11754 if ((res >> 26) != ALC880_HP_EVENT) 11755 return; 11756 alc262_ultra_automute(codec); 11757} 11758 11759static struct hda_input_mux alc262_ultra_capture_source = { 11760 .num_items = 2, 11761 .items = { 11762 { "Mic", 0x1 }, 11763 { "Headphone", 0x7 }, 11764 }, 11765}; 11766 11767static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol, 11768 struct snd_ctl_elem_value *ucontrol) 11769{ 11770 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 11771 struct alc_spec *spec = codec->spec; 11772 int ret; 11773 11774 ret = alc_mux_enum_put(kcontrol, ucontrol); 11775 if (!ret) 11776 return 0; 11777 /* reprogram the HP pin as mic or HP according to the input source */ 11778 snd_hda_codec_write_cache(codec, 0x15, 0, 11779 AC_VERB_SET_PIN_WIDGET_CONTROL, 11780 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP); 11781 alc262_ultra_automute(codec); /* mute/unmute HP */ 11782 return ret; 11783} 11784 11785static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = { 11786 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT), 11787 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT), 11788 { 11789 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 11790 .name = "Capture Source", 11791 .info = alc_mux_enum_info, 11792 .get = alc_mux_enum_get, 11793 .put = alc262_ultra_mux_enum_put, 11794 }, 11795 { 11796 .iface = NID_MAPPING, 11797 .name = "Capture Source", 11798 .private_value = 0x15, 11799 }, 11800 { } /* end */ 11801}; 11802 11803/* We use two mixers depending on the output pin; 0x16 is a mono output 11804 * and thus it's bound with a different mixer. 11805 * This function returns which mixer amp should be used. 11806 */ 11807static int alc262_check_volbit(hda_nid_t nid) 11808{ 11809 if (!nid) 11810 return 0; 11811 else if (nid == 0x16) 11812 return 2; 11813 else 11814 return 1; 11815} 11816 11817static int alc262_add_out_vol_ctl(struct alc_spec *spec, hda_nid_t nid, 11818 const char *pfx, int *vbits) 11819{ 11820 unsigned long val; 11821 int vbit; 11822 11823 vbit = alc262_check_volbit(nid); 11824 if (!vbit) 11825 return 0; 11826 if (*vbits & vbit) /* a volume control for this mixer already there */ 11827 return 0; 11828 *vbits |= vbit; 11829 if (vbit == 2) 11830 val = HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT); 11831 else 11832 val = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT); 11833 return add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, val); 11834} 11835 11836static int alc262_add_out_sw_ctl(struct alc_spec *spec, hda_nid_t nid, 11837 const char *pfx) 11838{ 11839 unsigned long val; 11840 11841 if (!nid) 11842 return 0; 11843 if (nid == 0x16) 11844 val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT); 11845 else 11846 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT); 11847 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, val); 11848} 11849 11850/* add playback controls from the parsed DAC table */ 11851static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, 11852 const struct auto_pin_cfg *cfg) 11853{ 11854 const char *pfx; 11855 int vbits; 11856 int err; 11857 11858 spec->multiout.num_dacs = 1; /* only use one dac */ 11859 spec->multiout.dac_nids = spec->private_dac_nids; 11860 spec->multiout.dac_nids[0] = 2; 11861 11862 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0]) 11863 pfx = "Master"; 11864 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) 11865 pfx = "Speaker"; 11866 else 11867 pfx = "Front"; 11868 err = alc262_add_out_sw_ctl(spec, cfg->line_out_pins[0], pfx); 11869 if (err < 0) 11870 return err; 11871 err = alc262_add_out_sw_ctl(spec, cfg->speaker_pins[0], "Speaker"); 11872 if (err < 0) 11873 return err; 11874 err = alc262_add_out_sw_ctl(spec, cfg->hp_pins[0], "Headphone"); 11875 if (err < 0) 11876 return err; 11877 11878 vbits = alc262_check_volbit(cfg->line_out_pins[0]) | 11879 alc262_check_volbit(cfg->speaker_pins[0]) | 11880 alc262_check_volbit(cfg->hp_pins[0]); 11881 if (vbits == 1 || vbits == 2) 11882 pfx = "Master"; /* only one mixer is used */ 11883 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) 11884 pfx = "Speaker"; 11885 else 11886 pfx = "Front"; 11887 vbits = 0; 11888 err = alc262_add_out_vol_ctl(spec, cfg->line_out_pins[0], pfx, &vbits); 11889 if (err < 0) 11890 return err; 11891 err = alc262_add_out_vol_ctl(spec, cfg->speaker_pins[0], "Speaker", 11892 &vbits); 11893 if (err < 0) 11894 return err; 11895 err = alc262_add_out_vol_ctl(spec, cfg->hp_pins[0], "Headphone", 11896 &vbits); 11897 if (err < 0) 11898 return err; 11899 return 0; 11900} 11901 11902#define alc262_auto_create_input_ctls \ 11903 alc882_auto_create_input_ctls 11904 11905/* 11906 * generic initialization of ADC, input mixers and output mixers 11907 */ 11908static struct hda_verb alc262_volume_init_verbs[] = { 11909 /* 11910 * Unmute ADC0-2 and set the default input to mic-in 11911 */ 11912 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 11913 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11914 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 11915 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11916 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 11917 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11918 11919 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 11920 * mixer widget 11921 * Note: PASD motherboards uses the Line In 2 as the input for 11922 * front panel mic (mic 2) 11923 */ 11924 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 11925 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 11926 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 11927 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 11928 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 11929 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 11930 11931 /* 11932 * Set up output mixers (0x0c - 0x0f) 11933 */ 11934 /* set vol=0 to output mixers */ 11935 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 11936 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 11937 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 11938 11939 /* set up input amps for analog loopback */ 11940 /* Amp Indices: DAC = 0, mixer = 1 */ 11941 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11942 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11943 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11944 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11945 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11946 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11947 11948 /* FIXME: use matrix-type input source selection */ 11949 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 11950 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 11951 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 11952 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 11953 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 11954 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 11955 /* Input mixer2 */ 11956 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 11957 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 11958 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 11959 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 11960 /* Input mixer3 */ 11961 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 11962 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 11963 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 11964 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 11965 11966 { } 11967}; 11968 11969static struct hda_verb alc262_HP_BPC_init_verbs[] = { 11970 /* 11971 * Unmute ADC0-2 and set the default input to mic-in 11972 */ 11973 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 11974 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11975 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 11976 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11977 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 11978 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11979 11980 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 11981 * mixer widget 11982 * Note: PASD motherboards uses the Line In 2 as the input for 11983 * front panel mic (mic 2) 11984 */ 11985 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 11986 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 11987 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 11988 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 11989 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 11990 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 11991 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, 11992 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, 11993 11994 /* 11995 * Set up output mixers (0x0c - 0x0e) 11996 */ 11997 /* set vol=0 to output mixers */ 11998 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 11999 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 12000 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 12001 12002 /* set up input amps for analog loopback */ 12003 /* Amp Indices: DAC = 0, mixer = 1 */ 12004 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12005 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12006 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12007 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12008 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12009 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12010 12011 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 12012 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 12013 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 12014 12015 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 12016 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 12017 12018 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 12019 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 12020 12021 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 12022 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 12023 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 12024 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 12025 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 12026 12027 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 12028 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 12029 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 12030 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 12031 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 12032 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 12033 12034 12035 /* FIXME: use matrix-type input source selection */ 12036 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */ 12037 /* Input mixer1: only unmute Mic */ 12038 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 12039 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))}, 12040 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 12041 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 12042 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 12043 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))}, 12044 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))}, 12045 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))}, 12046 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))}, 12047 /* Input mixer2 */ 12048 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 12049 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))}, 12050 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 12051 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 12052 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 12053 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))}, 12054 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))}, 12055 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))}, 12056 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))}, 12057 /* Input mixer3 */ 12058 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 12059 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))}, 12060 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 12061 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 12062 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 12063 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))}, 12064 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))}, 12065 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))}, 12066 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))}, 12067 12068 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 12069 12070 { } 12071}; 12072 12073static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = { 12074 /* 12075 * Unmute ADC0-2 and set the default input to mic-in 12076 */ 12077 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 12078 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12079 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 12080 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12081 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 12082 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12083 12084 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 12085 * mixer widget 12086 * Note: PASD motherboards uses the Line In 2 as the input for front 12087 * panel mic (mic 2) 12088 */ 12089 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 12090 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 12091 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 12092 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 12093 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 12094 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 12095 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, 12096 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, 12097 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, 12098 /* 12099 * Set up output mixers (0x0c - 0x0e) 12100 */ 12101 /* set vol=0 to output mixers */ 12102 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 12103 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 12104 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 12105 12106 /* set up input amps for analog loopback */ 12107 /* Amp Indices: DAC = 0, mixer = 1 */ 12108 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12109 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12110 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12111 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12112 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12113 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12114 12115 12116 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */ 12117 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */ 12118 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */ 12119 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */ 12120 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */ 12121 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */ 12122 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */ 12123 12124 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 12125 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 12126 12127 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 12128 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 12129 12130 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */ 12131 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 12132 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 12133 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, 12134 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 12135 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 12136 12137 /* FIXME: use matrix-type input source selection */ 12138 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 12139 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 12140 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/ 12141 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/ 12142 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/ 12143 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/ 12144 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/ 12145 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */ 12146 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/ 12147 /* Input mixer2 */ 12148 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 12149 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 12150 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, 12151 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, 12152 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, 12153 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */ 12154 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, 12155 /* Input mixer3 */ 12156 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 12157 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 12158 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, 12159 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, 12160 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, 12161 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */ 12162 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, 12163 12164 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 12165 12166 { } 12167}; 12168 12169static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = { 12170 12171 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */ 12172 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 12173 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01}, 12174 12175 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */ 12176 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */ 12177 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) }, 12178 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) }, 12179 12180 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */ 12181 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 12182 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 12183 {} 12184}; 12185 12186 12187#ifdef CONFIG_SND_HDA_POWER_SAVE 12188#define alc262_loopbacks alc880_loopbacks 12189#endif 12190 12191/* pcm configuration: identical with ALC880 */ 12192#define alc262_pcm_analog_playback alc880_pcm_analog_playback 12193#define alc262_pcm_analog_capture alc880_pcm_analog_capture 12194#define alc262_pcm_digital_playback alc880_pcm_digital_playback 12195#define alc262_pcm_digital_capture alc880_pcm_digital_capture 12196 12197/* 12198 * BIOS auto configuration 12199 */ 12200static int alc262_parse_auto_config(struct hda_codec *codec) 12201{ 12202 struct alc_spec *spec = codec->spec; 12203 int err; 12204 static hda_nid_t alc262_ignore[] = { 0x1d, 0 }; 12205 12206 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 12207 alc262_ignore); 12208 if (err < 0) 12209 return err; 12210 if (!spec->autocfg.line_outs) { 12211 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) { 12212 spec->multiout.max_channels = 2; 12213 spec->no_analog = 1; 12214 goto dig_only; 12215 } 12216 return 0; /* can't find valid BIOS pin config */ 12217 } 12218 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg); 12219 if (err < 0) 12220 return err; 12221 err = alc262_auto_create_input_ctls(codec, &spec->autocfg); 12222 if (err < 0) 12223 return err; 12224 12225 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 12226 12227 dig_only: 12228 alc_auto_parse_digital(codec); 12229 12230 if (spec->kctls.list) 12231 add_mixer(spec, spec->kctls.list); 12232 12233 add_verb(spec, alc262_volume_init_verbs); 12234 spec->num_mux_defs = 1; 12235 spec->input_mux = &spec->private_imux[0]; 12236 12237 err = alc_auto_add_mic_boost(codec); 12238 if (err < 0) 12239 return err; 12240 12241 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); 12242 12243 return 1; 12244} 12245 12246#define alc262_auto_init_multi_out alc882_auto_init_multi_out 12247#define alc262_auto_init_hp_out alc882_auto_init_hp_out 12248#define alc262_auto_init_analog_input alc882_auto_init_analog_input 12249#define alc262_auto_init_input_src alc882_auto_init_input_src 12250 12251 12252/* init callback for auto-configuration model -- overriding the default init */ 12253static void alc262_auto_init(struct hda_codec *codec) 12254{ 12255 struct alc_spec *spec = codec->spec; 12256 alc262_auto_init_multi_out(codec); 12257 alc262_auto_init_hp_out(codec); 12258 alc262_auto_init_analog_input(codec); 12259 alc262_auto_init_input_src(codec); 12260 alc_auto_init_digital(codec); 12261 if (spec->unsol_event) 12262 alc_inithook(codec); 12263} 12264 12265/* 12266 * configuration and preset 12267 */ 12268static const char *alc262_models[ALC262_MODEL_LAST] = { 12269 [ALC262_BASIC] = "basic", 12270 [ALC262_HIPPO] = "hippo", 12271 [ALC262_HIPPO_1] = "hippo_1", 12272 [ALC262_FUJITSU] = "fujitsu", 12273 [ALC262_HP_BPC] = "hp-bpc", 12274 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000", 12275 [ALC262_HP_TC_T5735] = "hp-tc-t5735", 12276 [ALC262_HP_RP5700] = "hp-rp5700", 12277 [ALC262_BENQ_ED8] = "benq", 12278 [ALC262_BENQ_T31] = "benq-t31", 12279 [ALC262_SONY_ASSAMD] = "sony-assamd", 12280 [ALC262_TOSHIBA_S06] = "toshiba-s06", 12281 [ALC262_TOSHIBA_RX1] = "toshiba-rx1", 12282 [ALC262_ULTRA] = "ultra", 12283 [ALC262_LENOVO_3000] = "lenovo-3000", 12284 [ALC262_NEC] = "nec", 12285 [ALC262_TYAN] = "tyan", 12286 [ALC262_AUTO] = "auto", 12287}; 12288 12289static struct snd_pci_quirk alc262_cfg_tbl[] = { 12290 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO), 12291 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC), 12292 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series", 12293 ALC262_HP_BPC), 12294 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series", 12295 ALC262_HP_BPC), 12296 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series", 12297 ALC262_HP_BPC), 12298 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL), 12299 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF), 12300 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL), 12301 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF), 12302 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL), 12303 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF), 12304 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL), 12305 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF), 12306 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC), 12307 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC), 12308 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC), 12309 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735", 12310 ALC262_HP_TC_T5735), 12311 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700), 12312 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD), 12313 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO), 12314 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD), 12315 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */ 12316 SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06), 12317 SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO), 12318 SND_PCI_QUIRK(0x104d, 0x9047, "Sony VAIO Type G", ALC262_AUTO), 12319#if 0 /* disable the quirk since model=auto works better in recent versions */ 12320 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO", 12321 ALC262_SONY_ASSAMD), 12322#endif 12323 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1", 12324 ALC262_TOSHIBA_RX1), 12325 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06), 12326 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU), 12327 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU), 12328 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN), 12329 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1", 12330 ALC262_ULTRA), 12331 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO), 12332 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000), 12333 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8), 12334 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31), 12335 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1), 12336 {} 12337}; 12338 12339static struct alc_config_preset alc262_presets[] = { 12340 [ALC262_BASIC] = { 12341 .mixers = { alc262_base_mixer }, 12342 .init_verbs = { alc262_init_verbs }, 12343 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12344 .dac_nids = alc262_dac_nids, 12345 .hp_nid = 0x03, 12346 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12347 .channel_mode = alc262_modes, 12348 .input_mux = &alc262_capture_source, 12349 }, 12350 [ALC262_HIPPO] = { 12351 .mixers = { alc262_hippo_mixer }, 12352 .init_verbs = { alc262_init_verbs, alc_hp15_unsol_verbs}, 12353 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12354 .dac_nids = alc262_dac_nids, 12355 .hp_nid = 0x03, 12356 .dig_out_nid = ALC262_DIGOUT_NID, 12357 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12358 .channel_mode = alc262_modes, 12359 .input_mux = &alc262_capture_source, 12360 .unsol_event = alc262_hippo_unsol_event, 12361 .setup = alc262_hippo_setup, 12362 .init_hook = alc262_hippo_automute, 12363 }, 12364 [ALC262_HIPPO_1] = { 12365 .mixers = { alc262_hippo1_mixer }, 12366 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs}, 12367 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12368 .dac_nids = alc262_dac_nids, 12369 .hp_nid = 0x02, 12370 .dig_out_nid = ALC262_DIGOUT_NID, 12371 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12372 .channel_mode = alc262_modes, 12373 .input_mux = &alc262_capture_source, 12374 .unsol_event = alc262_hippo_unsol_event, 12375 .setup = alc262_hippo1_setup, 12376 .init_hook = alc262_hippo_automute, 12377 }, 12378 [ALC262_FUJITSU] = { 12379 .mixers = { alc262_fujitsu_mixer }, 12380 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs, 12381 alc262_fujitsu_unsol_verbs }, 12382 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12383 .dac_nids = alc262_dac_nids, 12384 .hp_nid = 0x03, 12385 .dig_out_nid = ALC262_DIGOUT_NID, 12386 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12387 .channel_mode = alc262_modes, 12388 .input_mux = &alc262_fujitsu_capture_source, 12389 .unsol_event = alc262_fujitsu_unsol_event, 12390 .init_hook = alc262_fujitsu_init_hook, 12391 }, 12392 [ALC262_HP_BPC] = { 12393 .mixers = { alc262_HP_BPC_mixer }, 12394 .init_verbs = { alc262_HP_BPC_init_verbs }, 12395 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12396 .dac_nids = alc262_dac_nids, 12397 .hp_nid = 0x03, 12398 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12399 .channel_mode = alc262_modes, 12400 .input_mux = &alc262_HP_capture_source, 12401 .unsol_event = alc262_hp_bpc_unsol_event, 12402 .init_hook = alc262_hp_bpc_automute, 12403 }, 12404 [ALC262_HP_BPC_D7000_WF] = { 12405 .mixers = { alc262_HP_BPC_WildWest_mixer }, 12406 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs }, 12407 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12408 .dac_nids = alc262_dac_nids, 12409 .hp_nid = 0x03, 12410 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12411 .channel_mode = alc262_modes, 12412 .input_mux = &alc262_HP_D7000_capture_source, 12413 .unsol_event = alc262_hp_wildwest_unsol_event, 12414 .init_hook = alc262_hp_wildwest_automute, 12415 }, 12416 [ALC262_HP_BPC_D7000_WL] = { 12417 .mixers = { alc262_HP_BPC_WildWest_mixer, 12418 alc262_HP_BPC_WildWest_option_mixer }, 12419 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs }, 12420 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12421 .dac_nids = alc262_dac_nids, 12422 .hp_nid = 0x03, 12423 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12424 .channel_mode = alc262_modes, 12425 .input_mux = &alc262_HP_D7000_capture_source, 12426 .unsol_event = alc262_hp_wildwest_unsol_event, 12427 .init_hook = alc262_hp_wildwest_automute, 12428 }, 12429 [ALC262_HP_TC_T5735] = { 12430 .mixers = { alc262_hp_t5735_mixer }, 12431 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs }, 12432 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12433 .dac_nids = alc262_dac_nids, 12434 .hp_nid = 0x03, 12435 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12436 .channel_mode = alc262_modes, 12437 .input_mux = &alc262_capture_source, 12438 .unsol_event = alc_sku_unsol_event, 12439 .setup = alc262_hp_t5735_setup, 12440 .init_hook = alc_inithook, 12441 }, 12442 [ALC262_HP_RP5700] = { 12443 .mixers = { alc262_hp_rp5700_mixer }, 12444 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs }, 12445 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12446 .dac_nids = alc262_dac_nids, 12447 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12448 .channel_mode = alc262_modes, 12449 .input_mux = &alc262_hp_rp5700_capture_source, 12450 }, 12451 [ALC262_BENQ_ED8] = { 12452 .mixers = { alc262_base_mixer }, 12453 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs }, 12454 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12455 .dac_nids = alc262_dac_nids, 12456 .hp_nid = 0x03, 12457 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12458 .channel_mode = alc262_modes, 12459 .input_mux = &alc262_capture_source, 12460 }, 12461 [ALC262_SONY_ASSAMD] = { 12462 .mixers = { alc262_sony_mixer }, 12463 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs}, 12464 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12465 .dac_nids = alc262_dac_nids, 12466 .hp_nid = 0x02, 12467 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12468 .channel_mode = alc262_modes, 12469 .input_mux = &alc262_capture_source, 12470 .unsol_event = alc262_hippo_unsol_event, 12471 .setup = alc262_hippo_setup, 12472 .init_hook = alc262_hippo_automute, 12473 }, 12474 [ALC262_BENQ_T31] = { 12475 .mixers = { alc262_benq_t31_mixer }, 12476 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, 12477 alc_hp15_unsol_verbs }, 12478 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12479 .dac_nids = alc262_dac_nids, 12480 .hp_nid = 0x03, 12481 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12482 .channel_mode = alc262_modes, 12483 .input_mux = &alc262_capture_source, 12484 .unsol_event = alc262_hippo_unsol_event, 12485 .setup = alc262_hippo_setup, 12486 .init_hook = alc262_hippo_automute, 12487 }, 12488 [ALC262_ULTRA] = { 12489 .mixers = { alc262_ultra_mixer }, 12490 .cap_mixer = alc262_ultra_capture_mixer, 12491 .init_verbs = { alc262_ultra_verbs }, 12492 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12493 .dac_nids = alc262_dac_nids, 12494 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12495 .channel_mode = alc262_modes, 12496 .input_mux = &alc262_ultra_capture_source, 12497 .adc_nids = alc262_adc_nids, /* ADC0 */ 12498 .capsrc_nids = alc262_capsrc_nids, 12499 .num_adc_nids = 1, /* single ADC */ 12500 .unsol_event = alc262_ultra_unsol_event, 12501 .init_hook = alc262_ultra_automute, 12502 }, 12503 [ALC262_LENOVO_3000] = { 12504 .mixers = { alc262_lenovo_3000_mixer }, 12505 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs, 12506 alc262_lenovo_3000_unsol_verbs, 12507 alc262_lenovo_3000_init_verbs }, 12508 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12509 .dac_nids = alc262_dac_nids, 12510 .hp_nid = 0x03, 12511 .dig_out_nid = ALC262_DIGOUT_NID, 12512 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12513 .channel_mode = alc262_modes, 12514 .input_mux = &alc262_fujitsu_capture_source, 12515 .unsol_event = alc262_lenovo_3000_unsol_event, 12516 }, 12517 [ALC262_NEC] = { 12518 .mixers = { alc262_nec_mixer }, 12519 .init_verbs = { alc262_nec_verbs }, 12520 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12521 .dac_nids = alc262_dac_nids, 12522 .hp_nid = 0x03, 12523 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12524 .channel_mode = alc262_modes, 12525 .input_mux = &alc262_capture_source, 12526 }, 12527 [ALC262_TOSHIBA_S06] = { 12528 .mixers = { alc262_toshiba_s06_mixer }, 12529 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs, 12530 alc262_eapd_verbs }, 12531 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12532 .capsrc_nids = alc262_dmic_capsrc_nids, 12533 .dac_nids = alc262_dac_nids, 12534 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */ 12535 .num_adc_nids = 1, /* single ADC */ 12536 .dig_out_nid = ALC262_DIGOUT_NID, 12537 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12538 .channel_mode = alc262_modes, 12539 .unsol_event = alc_sku_unsol_event, 12540 .setup = alc262_toshiba_s06_setup, 12541 .init_hook = alc_inithook, 12542 }, 12543 [ALC262_TOSHIBA_RX1] = { 12544 .mixers = { alc262_toshiba_rx1_mixer }, 12545 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs }, 12546 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12547 .dac_nids = alc262_dac_nids, 12548 .hp_nid = 0x03, 12549 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12550 .channel_mode = alc262_modes, 12551 .input_mux = &alc262_capture_source, 12552 .unsol_event = alc262_hippo_unsol_event, 12553 .setup = alc262_hippo_setup, 12554 .init_hook = alc262_hippo_automute, 12555 }, 12556 [ALC262_TYAN] = { 12557 .mixers = { alc262_tyan_mixer }, 12558 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs}, 12559 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12560 .dac_nids = alc262_dac_nids, 12561 .hp_nid = 0x02, 12562 .dig_out_nid = ALC262_DIGOUT_NID, 12563 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12564 .channel_mode = alc262_modes, 12565 .input_mux = &alc262_capture_source, 12566 .unsol_event = alc_automute_amp_unsol_event, 12567 .setup = alc262_tyan_setup, 12568 .init_hook = alc_automute_amp, 12569 }, 12570}; 12571 12572static int patch_alc262(struct hda_codec *codec) 12573{ 12574 struct alc_spec *spec; 12575 int board_config; 12576 int err; 12577 12578 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 12579 if (spec == NULL) 12580 return -ENOMEM; 12581 12582 codec->spec = spec; 12583#if 0 12584 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is 12585 * under-run 12586 */ 12587 { 12588 int tmp; 12589 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7); 12590 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0); 12591 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7); 12592 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80); 12593 } 12594#endif 12595 alc_auto_parse_customize_define(codec); 12596 12597 alc_fix_pll_init(codec, 0x20, 0x0a, 10); 12598 12599 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST, 12600 alc262_models, 12601 alc262_cfg_tbl); 12602 12603 if (board_config < 0) { 12604 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 12605 codec->chip_name); 12606 board_config = ALC262_AUTO; 12607 } 12608 12609 if (board_config == ALC262_AUTO) { 12610 /* automatic parse from the BIOS config */ 12611 err = alc262_parse_auto_config(codec); 12612 if (err < 0) { 12613 alc_free(codec); 12614 return err; 12615 } else if (!err) { 12616 printk(KERN_INFO 12617 "hda_codec: Cannot set up configuration " 12618 "from BIOS. Using base mode...\n"); 12619 board_config = ALC262_BASIC; 12620 } 12621 } 12622 12623 if (!spec->no_analog && has_cdefine_beep(codec)) { 12624 err = snd_hda_attach_beep_device(codec, 0x1); 12625 if (err < 0) { 12626 alc_free(codec); 12627 return err; 12628 } 12629 } 12630 12631 if (board_config != ALC262_AUTO) 12632 setup_preset(codec, &alc262_presets[board_config]); 12633 12634 spec->stream_analog_playback = &alc262_pcm_analog_playback; 12635 spec->stream_analog_capture = &alc262_pcm_analog_capture; 12636 12637 spec->stream_digital_playback = &alc262_pcm_digital_playback; 12638 spec->stream_digital_capture = &alc262_pcm_digital_capture; 12639 12640 if (!spec->adc_nids && spec->input_mux) { 12641 int i; 12642 /* check whether the digital-mic has to be supported */ 12643 for (i = 0; i < spec->input_mux->num_items; i++) { 12644 if (spec->input_mux->items[i].index >= 9) 12645 break; 12646 } 12647 if (i < spec->input_mux->num_items) { 12648 /* use only ADC0 */ 12649 spec->adc_nids = alc262_dmic_adc_nids; 12650 spec->num_adc_nids = 1; 12651 spec->capsrc_nids = alc262_dmic_capsrc_nids; 12652 } else { 12653 /* all analog inputs */ 12654 /* check whether NID 0x07 is valid */ 12655 unsigned int wcap = get_wcaps(codec, 0x07); 12656 12657 /* get type */ 12658 wcap = get_wcaps_type(wcap); 12659 if (wcap != AC_WID_AUD_IN) { 12660 spec->adc_nids = alc262_adc_nids_alt; 12661 spec->num_adc_nids = 12662 ARRAY_SIZE(alc262_adc_nids_alt); 12663 spec->capsrc_nids = alc262_capsrc_nids_alt; 12664 } else { 12665 spec->adc_nids = alc262_adc_nids; 12666 spec->num_adc_nids = 12667 ARRAY_SIZE(alc262_adc_nids); 12668 spec->capsrc_nids = alc262_capsrc_nids; 12669 } 12670 } 12671 } 12672 if (!spec->cap_mixer && !spec->no_analog) 12673 set_capture_mixer(codec); 12674 if (!spec->no_analog && has_cdefine_beep(codec)) 12675 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 12676 12677 spec->vmaster_nid = 0x0c; 12678 12679 codec->patch_ops = alc_patch_ops; 12680 if (board_config == ALC262_AUTO) 12681 spec->init_hook = alc262_auto_init; 12682#ifdef CONFIG_SND_HDA_POWER_SAVE 12683 if (!spec->loopback.amplist) 12684 spec->loopback.amplist = alc262_loopbacks; 12685#endif 12686 12687 return 0; 12688} 12689 12690/* 12691 * ALC268 channel source setting (2 channel) 12692 */ 12693#define ALC268_DIGOUT_NID ALC880_DIGOUT_NID 12694#define alc268_modes alc260_modes 12695 12696static hda_nid_t alc268_dac_nids[2] = { 12697 /* front, hp */ 12698 0x02, 0x03 12699}; 12700 12701static hda_nid_t alc268_adc_nids[2] = { 12702 /* ADC0-1 */ 12703 0x08, 0x07 12704}; 12705 12706static hda_nid_t alc268_adc_nids_alt[1] = { 12707 /* ADC0 */ 12708 0x08 12709}; 12710 12711static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 }; 12712 12713static struct snd_kcontrol_new alc268_base_mixer[] = { 12714 /* output mixer control */ 12715 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), 12716 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 12717 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT), 12718 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 12719 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 12720 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 12721 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT), 12722 { } 12723}; 12724 12725static struct snd_kcontrol_new alc268_toshiba_mixer[] = { 12726 /* output mixer control */ 12727 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), 12728 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT), 12729 ALC262_HIPPO_MASTER_SWITCH, 12730 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 12731 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 12732 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT), 12733 { } 12734}; 12735 12736/* bind Beep switches of both NID 0x0f and 0x10 */ 12737static struct hda_bind_ctls alc268_bind_beep_sw = { 12738 .ops = &snd_hda_bind_sw, 12739 .values = { 12740 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT), 12741 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT), 12742 0 12743 }, 12744}; 12745 12746static struct snd_kcontrol_new alc268_beep_mixer[] = { 12747 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT), 12748 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw), 12749 { } 12750}; 12751 12752static struct hda_verb alc268_eapd_verbs[] = { 12753 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 12754 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, 12755 { } 12756}; 12757 12758/* Toshiba specific */ 12759static struct hda_verb alc268_toshiba_verbs[] = { 12760 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 12761 { } /* end */ 12762}; 12763 12764/* Acer specific */ 12765/* bind volumes of both NID 0x02 and 0x03 */ 12766static struct hda_bind_ctls alc268_acer_bind_master_vol = { 12767 .ops = &snd_hda_bind_vol, 12768 .values = { 12769 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), 12770 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT), 12771 0 12772 }, 12773}; 12774 12775/* mute/unmute internal speaker according to the hp jack and mute state */ 12776static void alc268_acer_automute(struct hda_codec *codec, int force) 12777{ 12778 struct alc_spec *spec = codec->spec; 12779 unsigned int mute; 12780 12781 if (force || !spec->sense_updated) { 12782 spec->jack_present = snd_hda_jack_detect(codec, 0x14); 12783 spec->sense_updated = 1; 12784 } 12785 if (spec->jack_present) 12786 mute = HDA_AMP_MUTE; /* mute internal speaker */ 12787 else /* unmute internal speaker if necessary */ 12788 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0); 12789 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 12790 HDA_AMP_MUTE, mute); 12791} 12792 12793 12794/* bind hp and internal speaker mute (with plug check) */ 12795static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol, 12796 struct snd_ctl_elem_value *ucontrol) 12797{ 12798 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 12799 long *valp = ucontrol->value.integer.value; 12800 int change; 12801 12802 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp); 12803 if (change) 12804 alc268_acer_automute(codec, 0); 12805 return change; 12806} 12807 12808static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = { 12809 /* output mixer control */ 12810 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), 12811 { 12812 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 12813 .name = "Master Playback Switch", 12814 .subdevice = HDA_SUBDEV_AMP_FLAG, 12815 .info = snd_hda_mixer_amp_switch_info, 12816 .get = snd_hda_mixer_amp_switch_get, 12817 .put = alc268_acer_master_sw_put, 12818 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 12819 }, 12820 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT), 12821 { } 12822}; 12823 12824static struct snd_kcontrol_new alc268_acer_mixer[] = { 12825 /* output mixer control */ 12826 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), 12827 { 12828 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 12829 .name = "Master Playback Switch", 12830 .subdevice = HDA_SUBDEV_AMP_FLAG, 12831 .info = snd_hda_mixer_amp_switch_info, 12832 .get = snd_hda_mixer_amp_switch_get, 12833 .put = alc268_acer_master_sw_put, 12834 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 12835 }, 12836 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 12837 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), 12838 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT), 12839 { } 12840}; 12841 12842static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = { 12843 /* output mixer control */ 12844 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), 12845 { 12846 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 12847 .name = "Master Playback Switch", 12848 .subdevice = HDA_SUBDEV_AMP_FLAG, 12849 .info = snd_hda_mixer_amp_switch_info, 12850 .get = snd_hda_mixer_amp_switch_get, 12851 .put = alc268_acer_master_sw_put, 12852 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 12853 }, 12854 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 12855 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT), 12856 { } 12857}; 12858 12859static struct hda_verb alc268_acer_aspire_one_verbs[] = { 12860 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 12861 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 12862 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 12863 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 12864 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06}, 12865 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017}, 12866 { } 12867}; 12868 12869static struct hda_verb alc268_acer_verbs[] = { 12870 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */ 12871 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 12872 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 12873 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 12874 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 12875 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 12876 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 12877 { } 12878}; 12879 12880/* unsolicited event for HP jack sensing */ 12881#define alc268_toshiba_unsol_event alc262_hippo_unsol_event 12882#define alc268_toshiba_setup alc262_hippo_setup 12883#define alc268_toshiba_automute alc262_hippo_automute 12884 12885static void alc268_acer_unsol_event(struct hda_codec *codec, 12886 unsigned int res) 12887{ 12888 if ((res >> 26) != ALC880_HP_EVENT) 12889 return; 12890 alc268_acer_automute(codec, 1); 12891} 12892 12893static void alc268_acer_init_hook(struct hda_codec *codec) 12894{ 12895 alc268_acer_automute(codec, 1); 12896} 12897 12898/* toggle speaker-output according to the hp-jack state */ 12899static void alc268_aspire_one_speaker_automute(struct hda_codec *codec) 12900{ 12901 unsigned int present; 12902 unsigned char bits; 12903 12904 present = snd_hda_jack_detect(codec, 0x15); 12905 bits = present ? HDA_AMP_MUTE : 0; 12906 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0, 12907 HDA_AMP_MUTE, bits); 12908 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1, 12909 HDA_AMP_MUTE, bits); 12910} 12911 12912static void alc268_acer_lc_unsol_event(struct hda_codec *codec, 12913 unsigned int res) 12914{ 12915 switch (res >> 26) { 12916 case ALC880_HP_EVENT: 12917 alc268_aspire_one_speaker_automute(codec); 12918 break; 12919 case ALC880_MIC_EVENT: 12920 alc_mic_automute(codec); 12921 break; 12922 } 12923} 12924 12925static void alc268_acer_lc_setup(struct hda_codec *codec) 12926{ 12927 struct alc_spec *spec = codec->spec; 12928 spec->ext_mic.pin = 0x18; 12929 spec->ext_mic.mux_idx = 0; 12930 spec->int_mic.pin = 0x12; 12931 spec->int_mic.mux_idx = 6; 12932 spec->auto_mic = 1; 12933} 12934 12935static void alc268_acer_lc_init_hook(struct hda_codec *codec) 12936{ 12937 alc268_aspire_one_speaker_automute(codec); 12938 alc_mic_automute(codec); 12939} 12940 12941static struct snd_kcontrol_new alc268_dell_mixer[] = { 12942 /* output mixer control */ 12943 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 12944 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 12945 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 12946 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 12947 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 12948 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), 12949 { } 12950}; 12951 12952static struct hda_verb alc268_dell_verbs[] = { 12953 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 12954 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 12955 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 12956 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, 12957 { } 12958}; 12959 12960/* mute/unmute internal speaker according to the hp jack and mute state */ 12961static void alc268_dell_setup(struct hda_codec *codec) 12962{ 12963 struct alc_spec *spec = codec->spec; 12964 12965 spec->autocfg.hp_pins[0] = 0x15; 12966 spec->autocfg.speaker_pins[0] = 0x14; 12967 spec->ext_mic.pin = 0x18; 12968 spec->ext_mic.mux_idx = 0; 12969 spec->int_mic.pin = 0x19; 12970 spec->int_mic.mux_idx = 1; 12971 spec->auto_mic = 1; 12972} 12973 12974static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = { 12975 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT), 12976 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 12977 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT), 12978 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 12979 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT), 12980 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT), 12981 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT), 12982 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 12983 { } 12984}; 12985 12986static struct hda_verb alc267_quanta_il1_verbs[] = { 12987 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 12988 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, 12989 { } 12990}; 12991 12992static void alc267_quanta_il1_setup(struct hda_codec *codec) 12993{ 12994 struct alc_spec *spec = codec->spec; 12995 spec->autocfg.hp_pins[0] = 0x15; 12996 spec->autocfg.speaker_pins[0] = 0x14; 12997 spec->ext_mic.pin = 0x18; 12998 spec->ext_mic.mux_idx = 0; 12999 spec->int_mic.pin = 0x19; 13000 spec->int_mic.mux_idx = 1; 13001 spec->auto_mic = 1; 13002} 13003 13004/* 13005 * generic initialization of ADC, input mixers and output mixers 13006 */ 13007static struct hda_verb alc268_base_init_verbs[] = { 13008 /* Unmute DAC0-1 and set vol = 0 */ 13009 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 13010 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 13011 13012 /* 13013 * Set up output mixers (0x0c - 0x0e) 13014 */ 13015 /* set vol=0 to output mixers */ 13016 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13017 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00}, 13018 13019 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13020 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13021 13022 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 13023 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 13024 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 13025 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 13026 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 13027 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 13028 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 13029 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 13030 13031 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 13032 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 13033 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 13034 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 13035 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 13036 13037 /* set PCBEEP vol = 0, mute connections */ 13038 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13039 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 13040 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 13041 13042 /* Unmute Selector 23h,24h and set the default input to mic-in */ 13043 13044 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00}, 13045 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 13046 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00}, 13047 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 13048 13049 { } 13050}; 13051 13052/* 13053 * generic initialization of ADC, input mixers and output mixers 13054 */ 13055static struct hda_verb alc268_volume_init_verbs[] = { 13056 /* set output DAC */ 13057 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 13058 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 13059 13060 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 13061 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 13062 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 13063 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 13064 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 13065 13066 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13067 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13068 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13069 13070 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 13071 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 13072 13073 /* set PCBEEP vol = 0, mute connections */ 13074 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13075 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 13076 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 13077 13078 { } 13079}; 13080 13081static struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = { 13082 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT), 13083 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT), 13084 { } /* end */ 13085}; 13086 13087static struct snd_kcontrol_new alc268_capture_alt_mixer[] = { 13088 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT), 13089 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT), 13090 _DEFINE_CAPSRC(1), 13091 { } /* end */ 13092}; 13093 13094static struct snd_kcontrol_new alc268_capture_mixer[] = { 13095 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT), 13096 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT), 13097 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT), 13098 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT), 13099 _DEFINE_CAPSRC(2), 13100 { } /* end */ 13101}; 13102 13103static struct hda_input_mux alc268_capture_source = { 13104 .num_items = 4, 13105 .items = { 13106 { "Mic", 0x0 }, 13107 { "Front Mic", 0x1 }, 13108 { "Line", 0x2 }, 13109 { "CD", 0x3 }, 13110 }, 13111}; 13112 13113static struct hda_input_mux alc268_acer_capture_source = { 13114 .num_items = 3, 13115 .items = { 13116 { "Mic", 0x0 }, 13117 { "Internal Mic", 0x1 }, 13118 { "Line", 0x2 }, 13119 }, 13120}; 13121 13122static struct hda_input_mux alc268_acer_dmic_capture_source = { 13123 .num_items = 3, 13124 .items = { 13125 { "Mic", 0x0 }, 13126 { "Internal Mic", 0x6 }, 13127 { "Line", 0x2 }, 13128 }, 13129}; 13130 13131#ifdef CONFIG_SND_DEBUG 13132static struct snd_kcontrol_new alc268_test_mixer[] = { 13133 /* Volume widgets */ 13134 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT), 13135 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT), 13136 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT), 13137 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT), 13138 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT), 13139 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT), 13140 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT), 13141 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT), 13142 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT), 13143 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT), 13144 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT), 13145 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT), 13146 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT), 13147 /* The below appears problematic on some hardwares */ 13148 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/ 13149 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT), 13150 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT), 13151 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT), 13152 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT), 13153 13154 /* Modes for retasking pin widgets */ 13155 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT), 13156 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT), 13157 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT), 13158 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT), 13159 13160 /* Controls for GPIO pins, assuming they are configured as outputs */ 13161 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01), 13162 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02), 13163 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04), 13164 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08), 13165 13166 /* Switches to allow the digital SPDIF output pin to be enabled. 13167 * The ALC268 does not have an SPDIF input. 13168 */ 13169 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01), 13170 13171 /* A switch allowing EAPD to be enabled. Some laptops seem to use 13172 * this output to turn on an external amplifier. 13173 */ 13174 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02), 13175 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02), 13176 13177 { } /* end */ 13178}; 13179#endif 13180 13181/* create input playback/capture controls for the given pin */ 13182static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid, 13183 const char *ctlname, int idx) 13184{ 13185 hda_nid_t dac; 13186 int err; 13187 13188 switch (nid) { 13189 case 0x14: 13190 case 0x16: 13191 dac = 0x02; 13192 break; 13193 case 0x15: 13194 case 0x1a: /* ALC259/269 only */ 13195 case 0x1b: /* ALC259/269 only */ 13196 case 0x21: /* ALC269vb has this pin, too */ 13197 dac = 0x03; 13198 break; 13199 default: 13200 snd_printd(KERN_WARNING "hda_codec: " 13201 "ignoring pin 0x%x as unknown\n", nid); 13202 return 0; 13203 } 13204 if (spec->multiout.dac_nids[0] != dac && 13205 spec->multiout.dac_nids[1] != dac) { 13206 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname, 13207 HDA_COMPOSE_AMP_VAL(dac, 3, idx, 13208 HDA_OUTPUT)); 13209 if (err < 0) 13210 return err; 13211 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac; 13212 } 13213 13214 if (nid != 0x16) 13215 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname, 13216 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT)); 13217 else /* mono */ 13218 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname, 13219 HDA_COMPOSE_AMP_VAL(nid, 2, idx, HDA_OUTPUT)); 13220 if (err < 0) 13221 return err; 13222 return 0; 13223} 13224 13225/* add playback controls from the parsed DAC table */ 13226static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec, 13227 const struct auto_pin_cfg *cfg) 13228{ 13229 hda_nid_t nid; 13230 int err; 13231 13232 spec->multiout.dac_nids = spec->private_dac_nids; 13233 13234 nid = cfg->line_out_pins[0]; 13235 if (nid) { 13236 const char *name; 13237 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) 13238 name = "Speaker"; 13239 else 13240 name = "Front"; 13241 err = alc268_new_analog_output(spec, nid, name, 0); 13242 if (err < 0) 13243 return err; 13244 } 13245 13246 nid = cfg->speaker_pins[0]; 13247 if (nid == 0x1d) { 13248 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, "Speaker", 13249 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT)); 13250 if (err < 0) 13251 return err; 13252 } else if (nid) { 13253 err = alc268_new_analog_output(spec, nid, "Speaker", 0); 13254 if (err < 0) 13255 return err; 13256 } 13257 nid = cfg->hp_pins[0]; 13258 if (nid) { 13259 err = alc268_new_analog_output(spec, nid, "Headphone", 0); 13260 if (err < 0) 13261 return err; 13262 } 13263 13264 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2]; 13265 if (nid == 0x16) { 13266 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, "Mono", 13267 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT)); 13268 if (err < 0) 13269 return err; 13270 } 13271 return 0; 13272} 13273 13274/* create playback/capture controls for input pins */ 13275static int alc268_auto_create_input_ctls(struct hda_codec *codec, 13276 const struct auto_pin_cfg *cfg) 13277{ 13278 return alc_auto_create_input_ctls(codec, cfg, 0, 0x23, 0x24); 13279} 13280 13281static void alc268_auto_set_output_and_unmute(struct hda_codec *codec, 13282 hda_nid_t nid, int pin_type) 13283{ 13284 int idx; 13285 13286 alc_set_pin_output(codec, nid, pin_type); 13287 if (nid == 0x14 || nid == 0x16) 13288 idx = 0; 13289 else 13290 idx = 1; 13291 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx); 13292} 13293 13294static void alc268_auto_init_multi_out(struct hda_codec *codec) 13295{ 13296 struct alc_spec *spec = codec->spec; 13297 hda_nid_t nid = spec->autocfg.line_out_pins[0]; 13298 if (nid) { 13299 int pin_type = get_pin_type(spec->autocfg.line_out_type); 13300 alc268_auto_set_output_and_unmute(codec, nid, pin_type); 13301 } 13302} 13303 13304static void alc268_auto_init_hp_out(struct hda_codec *codec) 13305{ 13306 struct alc_spec *spec = codec->spec; 13307 hda_nid_t pin; 13308 13309 pin = spec->autocfg.hp_pins[0]; 13310 if (pin) 13311 alc268_auto_set_output_and_unmute(codec, pin, PIN_HP); 13312 pin = spec->autocfg.speaker_pins[0]; 13313 if (pin) 13314 alc268_auto_set_output_and_unmute(codec, pin, PIN_OUT); 13315} 13316 13317static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec) 13318{ 13319 struct alc_spec *spec = codec->spec; 13320 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0]; 13321 hda_nid_t hp_nid = spec->autocfg.hp_pins[0]; 13322 hda_nid_t line_nid = spec->autocfg.line_out_pins[0]; 13323 unsigned int dac_vol1, dac_vol2; 13324 13325 if (line_nid == 0x1d || speaker_nid == 0x1d) { 13326 snd_hda_codec_write(codec, speaker_nid, 0, 13327 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); 13328 /* mute mixer inputs from 0x1d */ 13329 snd_hda_codec_write(codec, 0x0f, 0, 13330 AC_VERB_SET_AMP_GAIN_MUTE, 13331 AMP_IN_UNMUTE(1)); 13332 snd_hda_codec_write(codec, 0x10, 0, 13333 AC_VERB_SET_AMP_GAIN_MUTE, 13334 AMP_IN_UNMUTE(1)); 13335 } else { 13336 /* unmute mixer inputs from 0x1d */ 13337 snd_hda_codec_write(codec, 0x0f, 0, 13338 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)); 13339 snd_hda_codec_write(codec, 0x10, 0, 13340 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)); 13341 } 13342 13343 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */ 13344 if (line_nid == 0x14) 13345 dac_vol2 = AMP_OUT_ZERO; 13346 else if (line_nid == 0x15) 13347 dac_vol1 = AMP_OUT_ZERO; 13348 if (hp_nid == 0x14) 13349 dac_vol2 = AMP_OUT_ZERO; 13350 else if (hp_nid == 0x15) 13351 dac_vol1 = AMP_OUT_ZERO; 13352 if (line_nid != 0x16 || hp_nid != 0x16 || 13353 spec->autocfg.line_out_pins[1] != 0x16 || 13354 spec->autocfg.line_out_pins[2] != 0x16) 13355 dac_vol1 = dac_vol2 = AMP_OUT_ZERO; 13356 13357 snd_hda_codec_write(codec, 0x02, 0, 13358 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1); 13359 snd_hda_codec_write(codec, 0x03, 0, 13360 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2); 13361} 13362 13363/* pcm configuration: identical with ALC880 */ 13364#define alc268_pcm_analog_playback alc880_pcm_analog_playback 13365#define alc268_pcm_analog_capture alc880_pcm_analog_capture 13366#define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture 13367#define alc268_pcm_digital_playback alc880_pcm_digital_playback 13368 13369/* 13370 * BIOS auto configuration 13371 */ 13372static int alc268_parse_auto_config(struct hda_codec *codec) 13373{ 13374 struct alc_spec *spec = codec->spec; 13375 int err; 13376 static hda_nid_t alc268_ignore[] = { 0 }; 13377 13378 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 13379 alc268_ignore); 13380 if (err < 0) 13381 return err; 13382 if (!spec->autocfg.line_outs) { 13383 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) { 13384 spec->multiout.max_channels = 2; 13385 spec->no_analog = 1; 13386 goto dig_only; 13387 } 13388 return 0; /* can't find valid BIOS pin config */ 13389 } 13390 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg); 13391 if (err < 0) 13392 return err; 13393 err = alc268_auto_create_input_ctls(codec, &spec->autocfg); 13394 if (err < 0) 13395 return err; 13396 13397 spec->multiout.max_channels = 2; 13398 13399 dig_only: 13400 /* digital only support output */ 13401 alc_auto_parse_digital(codec); 13402 if (spec->kctls.list) 13403 add_mixer(spec, spec->kctls.list); 13404 13405 if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d) 13406 add_mixer(spec, alc268_beep_mixer); 13407 13408 add_verb(spec, alc268_volume_init_verbs); 13409 spec->num_mux_defs = 2; 13410 spec->input_mux = &spec->private_imux[0]; 13411 13412 err = alc_auto_add_mic_boost(codec); 13413 if (err < 0) 13414 return err; 13415 13416 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); 13417 13418 return 1; 13419} 13420 13421#define alc268_auto_init_analog_input alc882_auto_init_analog_input 13422 13423/* init callback for auto-configuration model -- overriding the default init */ 13424static void alc268_auto_init(struct hda_codec *codec) 13425{ 13426 struct alc_spec *spec = codec->spec; 13427 alc268_auto_init_multi_out(codec); 13428 alc268_auto_init_hp_out(codec); 13429 alc268_auto_init_mono_speaker_out(codec); 13430 alc268_auto_init_analog_input(codec); 13431 alc_auto_init_digital(codec); 13432 if (spec->unsol_event) 13433 alc_inithook(codec); 13434} 13435 13436/* 13437 * configuration and preset 13438 */ 13439static const char *alc268_models[ALC268_MODEL_LAST] = { 13440 [ALC267_QUANTA_IL1] = "quanta-il1", 13441 [ALC268_3ST] = "3stack", 13442 [ALC268_TOSHIBA] = "toshiba", 13443 [ALC268_ACER] = "acer", 13444 [ALC268_ACER_DMIC] = "acer-dmic", 13445 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire", 13446 [ALC268_DELL] = "dell", 13447 [ALC268_ZEPTO] = "zepto", 13448#ifdef CONFIG_SND_DEBUG 13449 [ALC268_TEST] = "test", 13450#endif 13451 [ALC268_AUTO] = "auto", 13452}; 13453 13454static struct snd_pci_quirk alc268_cfg_tbl[] = { 13455 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER), 13456 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER), 13457 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER), 13458 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER), 13459 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER), 13460 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One", 13461 ALC268_ACER_ASPIRE_ONE), 13462 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL), 13463 SND_PCI_QUIRK_MASK(0x1028, 0xfff0, 0x02b0, 13464 "Dell Inspiron Mini9/Vostro A90", ALC268_DELL), 13465 /* almost compatible with toshiba but with optional digital outs; 13466 * auto-probing seems working fine 13467 */ 13468 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series", 13469 ALC268_AUTO), 13470 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST), 13471 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO), 13472 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA), 13473 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER), 13474 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1), 13475 {} 13476}; 13477 13478/* Toshiba laptops have no unique PCI SSID but only codec SSID */ 13479static struct snd_pci_quirk alc268_ssid_cfg_tbl[] = { 13480 SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO), 13481 SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO), 13482 SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05", 13483 ALC268_TOSHIBA), 13484 {} 13485}; 13486 13487static struct alc_config_preset alc268_presets[] = { 13488 [ALC267_QUANTA_IL1] = { 13489 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer, 13490 alc268_capture_nosrc_mixer }, 13491 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 13492 alc267_quanta_il1_verbs }, 13493 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 13494 .dac_nids = alc268_dac_nids, 13495 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 13496 .adc_nids = alc268_adc_nids_alt, 13497 .hp_nid = 0x03, 13498 .num_channel_mode = ARRAY_SIZE(alc268_modes), 13499 .channel_mode = alc268_modes, 13500 .unsol_event = alc_sku_unsol_event, 13501 .setup = alc267_quanta_il1_setup, 13502 .init_hook = alc_inithook, 13503 }, 13504 [ALC268_3ST] = { 13505 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer, 13506 alc268_beep_mixer }, 13507 .init_verbs = { alc268_base_init_verbs }, 13508 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 13509 .dac_nids = alc268_dac_nids, 13510 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 13511 .adc_nids = alc268_adc_nids_alt, 13512 .capsrc_nids = alc268_capsrc_nids, 13513 .hp_nid = 0x03, 13514 .dig_out_nid = ALC268_DIGOUT_NID, 13515 .num_channel_mode = ARRAY_SIZE(alc268_modes), 13516 .channel_mode = alc268_modes, 13517 .input_mux = &alc268_capture_source, 13518 }, 13519 [ALC268_TOSHIBA] = { 13520 .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer, 13521 alc268_beep_mixer }, 13522 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 13523 alc268_toshiba_verbs }, 13524 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 13525 .dac_nids = alc268_dac_nids, 13526 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 13527 .adc_nids = alc268_adc_nids_alt, 13528 .capsrc_nids = alc268_capsrc_nids, 13529 .hp_nid = 0x03, 13530 .num_channel_mode = ARRAY_SIZE(alc268_modes), 13531 .channel_mode = alc268_modes, 13532 .input_mux = &alc268_capture_source, 13533 .unsol_event = alc268_toshiba_unsol_event, 13534 .setup = alc268_toshiba_setup, 13535 .init_hook = alc268_toshiba_automute, 13536 }, 13537 [ALC268_ACER] = { 13538 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer, 13539 alc268_beep_mixer }, 13540 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 13541 alc268_acer_verbs }, 13542 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 13543 .dac_nids = alc268_dac_nids, 13544 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 13545 .adc_nids = alc268_adc_nids_alt, 13546 .capsrc_nids = alc268_capsrc_nids, 13547 .hp_nid = 0x02, 13548 .num_channel_mode = ARRAY_SIZE(alc268_modes), 13549 .channel_mode = alc268_modes, 13550 .input_mux = &alc268_acer_capture_source, 13551 .unsol_event = alc268_acer_unsol_event, 13552 .init_hook = alc268_acer_init_hook, 13553 }, 13554 [ALC268_ACER_DMIC] = { 13555 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer, 13556 alc268_beep_mixer }, 13557 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 13558 alc268_acer_verbs }, 13559 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 13560 .dac_nids = alc268_dac_nids, 13561 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 13562 .adc_nids = alc268_adc_nids_alt, 13563 .capsrc_nids = alc268_capsrc_nids, 13564 .hp_nid = 0x02, 13565 .num_channel_mode = ARRAY_SIZE(alc268_modes), 13566 .channel_mode = alc268_modes, 13567 .input_mux = &alc268_acer_dmic_capture_source, 13568 .unsol_event = alc268_acer_unsol_event, 13569 .init_hook = alc268_acer_init_hook, 13570 }, 13571 [ALC268_ACER_ASPIRE_ONE] = { 13572 .mixers = { alc268_acer_aspire_one_mixer, 13573 alc268_beep_mixer, 13574 alc268_capture_nosrc_mixer }, 13575 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 13576 alc268_acer_aspire_one_verbs }, 13577 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 13578 .dac_nids = alc268_dac_nids, 13579 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 13580 .adc_nids = alc268_adc_nids_alt, 13581 .capsrc_nids = alc268_capsrc_nids, 13582 .hp_nid = 0x03, 13583 .num_channel_mode = ARRAY_SIZE(alc268_modes), 13584 .channel_mode = alc268_modes, 13585 .unsol_event = alc268_acer_lc_unsol_event, 13586 .setup = alc268_acer_lc_setup, 13587 .init_hook = alc268_acer_lc_init_hook, 13588 }, 13589 [ALC268_DELL] = { 13590 .mixers = { alc268_dell_mixer, alc268_beep_mixer, 13591 alc268_capture_nosrc_mixer }, 13592 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 13593 alc268_dell_verbs }, 13594 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 13595 .dac_nids = alc268_dac_nids, 13596 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 13597 .adc_nids = alc268_adc_nids_alt, 13598 .capsrc_nids = alc268_capsrc_nids, 13599 .hp_nid = 0x02, 13600 .num_channel_mode = ARRAY_SIZE(alc268_modes), 13601 .channel_mode = alc268_modes, 13602 .unsol_event = alc_sku_unsol_event, 13603 .setup = alc268_dell_setup, 13604 .init_hook = alc_inithook, 13605 }, 13606 [ALC268_ZEPTO] = { 13607 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer, 13608 alc268_beep_mixer }, 13609 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 13610 alc268_toshiba_verbs }, 13611 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 13612 .dac_nids = alc268_dac_nids, 13613 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 13614 .adc_nids = alc268_adc_nids_alt, 13615 .capsrc_nids = alc268_capsrc_nids, 13616 .hp_nid = 0x03, 13617 .dig_out_nid = ALC268_DIGOUT_NID, 13618 .num_channel_mode = ARRAY_SIZE(alc268_modes), 13619 .channel_mode = alc268_modes, 13620 .input_mux = &alc268_capture_source, 13621 .setup = alc268_toshiba_setup, 13622 .init_hook = alc268_toshiba_automute, 13623 }, 13624#ifdef CONFIG_SND_DEBUG 13625 [ALC268_TEST] = { 13626 .mixers = { alc268_test_mixer, alc268_capture_mixer }, 13627 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 13628 alc268_volume_init_verbs }, 13629 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 13630 .dac_nids = alc268_dac_nids, 13631 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 13632 .adc_nids = alc268_adc_nids_alt, 13633 .capsrc_nids = alc268_capsrc_nids, 13634 .hp_nid = 0x03, 13635 .dig_out_nid = ALC268_DIGOUT_NID, 13636 .num_channel_mode = ARRAY_SIZE(alc268_modes), 13637 .channel_mode = alc268_modes, 13638 .input_mux = &alc268_capture_source, 13639 }, 13640#endif 13641}; 13642 13643static int patch_alc268(struct hda_codec *codec) 13644{ 13645 struct alc_spec *spec; 13646 int board_config; 13647 int i, has_beep, err; 13648 13649 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 13650 if (spec == NULL) 13651 return -ENOMEM; 13652 13653 codec->spec = spec; 13654 13655 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST, 13656 alc268_models, 13657 alc268_cfg_tbl); 13658 13659 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) 13660 board_config = snd_hda_check_board_codec_sid_config(codec, 13661 ALC268_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl); 13662 13663 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) { 13664 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 13665 codec->chip_name); 13666 board_config = ALC268_AUTO; 13667 } 13668 13669 if (board_config == ALC268_AUTO) { 13670 /* automatic parse from the BIOS config */ 13671 err = alc268_parse_auto_config(codec); 13672 if (err < 0) { 13673 alc_free(codec); 13674 return err; 13675 } else if (!err) { 13676 printk(KERN_INFO 13677 "hda_codec: Cannot set up configuration " 13678 "from BIOS. Using base mode...\n"); 13679 board_config = ALC268_3ST; 13680 } 13681 } 13682 13683 if (board_config != ALC268_AUTO) 13684 setup_preset(codec, &alc268_presets[board_config]); 13685 13686 spec->stream_analog_playback = &alc268_pcm_analog_playback; 13687 spec->stream_analog_capture = &alc268_pcm_analog_capture; 13688 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture; 13689 13690 spec->stream_digital_playback = &alc268_pcm_digital_playback; 13691 13692 has_beep = 0; 13693 for (i = 0; i < spec->num_mixers; i++) { 13694 if (spec->mixers[i] == alc268_beep_mixer) { 13695 has_beep = 1; 13696 break; 13697 } 13698 } 13699 13700 if (has_beep) { 13701 err = snd_hda_attach_beep_device(codec, 0x1); 13702 if (err < 0) { 13703 alc_free(codec); 13704 return err; 13705 } 13706 if (!query_amp_caps(codec, 0x1d, HDA_INPUT)) 13707 /* override the amp caps for beep generator */ 13708 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT, 13709 (0x0c << AC_AMPCAP_OFFSET_SHIFT) | 13710 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) | 13711 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) | 13712 (0 << AC_AMPCAP_MUTE_SHIFT)); 13713 } 13714 13715 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) { 13716 /* check whether NID 0x07 is valid */ 13717 unsigned int wcap = get_wcaps(codec, 0x07); 13718 int i; 13719 13720 spec->capsrc_nids = alc268_capsrc_nids; 13721 /* get type */ 13722 wcap = get_wcaps_type(wcap); 13723 if (spec->auto_mic || 13724 wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) { 13725 spec->adc_nids = alc268_adc_nids_alt; 13726 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt); 13727 if (spec->auto_mic) 13728 fixup_automic_adc(codec); 13729 if (spec->auto_mic || spec->input_mux->num_items == 1) 13730 add_mixer(spec, alc268_capture_nosrc_mixer); 13731 else 13732 add_mixer(spec, alc268_capture_alt_mixer); 13733 } else { 13734 spec->adc_nids = alc268_adc_nids; 13735 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids); 13736 add_mixer(spec, alc268_capture_mixer); 13737 } 13738 /* set default input source */ 13739 for (i = 0; i < spec->num_adc_nids; i++) 13740 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i], 13741 0, AC_VERB_SET_CONNECT_SEL, 13742 i < spec->num_mux_defs ? 13743 spec->input_mux[i].items[0].index : 13744 spec->input_mux->items[0].index); 13745 } 13746 13747 spec->vmaster_nid = 0x02; 13748 13749 codec->patch_ops = alc_patch_ops; 13750 if (board_config == ALC268_AUTO) 13751 spec->init_hook = alc268_auto_init; 13752 13753 return 0; 13754} 13755 13756/* 13757 * ALC269 channel source setting (2 channel) 13758 */ 13759#define ALC269_DIGOUT_NID ALC880_DIGOUT_NID 13760 13761#define alc269_dac_nids alc260_dac_nids 13762 13763static hda_nid_t alc269_adc_nids[1] = { 13764 /* ADC1 */ 13765 0x08, 13766}; 13767 13768static hda_nid_t alc269_capsrc_nids[1] = { 13769 0x23, 13770}; 13771 13772static hda_nid_t alc269vb_adc_nids[1] = { 13773 /* ADC1 */ 13774 0x09, 13775}; 13776 13777static hda_nid_t alc269vb_capsrc_nids[1] = { 13778 0x22, 13779}; 13780 13781static hda_nid_t alc269_adc_candidates[] = { 13782 0x08, 0x09, 0x07, 13783}; 13784 13785#define alc269_modes alc260_modes 13786#define alc269_capture_source alc880_lg_lw_capture_source 13787 13788static struct snd_kcontrol_new alc269_base_mixer[] = { 13789 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 13790 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 13791 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 13792 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 13793 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 13794 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 13795 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 13796 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 13797 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 13798 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 13799 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 13800 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT), 13801 { } /* end */ 13802}; 13803 13804static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = { 13805 /* output mixer control */ 13806 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), 13807 { 13808 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 13809 .name = "Master Playback Switch", 13810 .subdevice = HDA_SUBDEV_AMP_FLAG, 13811 .info = snd_hda_mixer_amp_switch_info, 13812 .get = snd_hda_mixer_amp_switch_get, 13813 .put = alc268_acer_master_sw_put, 13814 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 13815 }, 13816 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 13817 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 13818 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 13819 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 13820 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 13821 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), 13822 { } 13823}; 13824 13825static struct snd_kcontrol_new alc269_lifebook_mixer[] = { 13826 /* output mixer control */ 13827 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), 13828 { 13829 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 13830 .name = "Master Playback Switch", 13831 .subdevice = HDA_SUBDEV_AMP_FLAG, 13832 .info = snd_hda_mixer_amp_switch_info, 13833 .get = snd_hda_mixer_amp_switch_get, 13834 .put = alc268_acer_master_sw_put, 13835 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 13836 }, 13837 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 13838 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 13839 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 13840 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 13841 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 13842 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), 13843 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT), 13844 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT), 13845 HDA_CODEC_VOLUME("Dock Mic Boost", 0x1b, 0, HDA_INPUT), 13846 { } 13847}; 13848 13849static struct snd_kcontrol_new alc269_laptop_mixer[] = { 13850 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 13851 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 13852 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 13853 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 13854 { } /* end */ 13855}; 13856 13857static struct snd_kcontrol_new alc269vb_laptop_mixer[] = { 13858 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 13859 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 13860 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT), 13861 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 13862 { } /* end */ 13863}; 13864 13865static struct snd_kcontrol_new alc269_asus_mixer[] = { 13866 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT), 13867 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x0, HDA_INPUT), 13868 { } /* end */ 13869}; 13870 13871/* capture mixer elements */ 13872static struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = { 13873 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 13874 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 13875 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 13876 HDA_CODEC_VOLUME("IntMic Boost", 0x19, 0, HDA_INPUT), 13877 { } /* end */ 13878}; 13879 13880static struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = { 13881 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 13882 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 13883 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 13884 { } /* end */ 13885}; 13886 13887static struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = { 13888 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), 13889 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), 13890 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 13891 HDA_CODEC_VOLUME("IntMic Boost", 0x19, 0, HDA_INPUT), 13892 { } /* end */ 13893}; 13894 13895static struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = { 13896 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), 13897 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), 13898 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 13899 { } /* end */ 13900}; 13901 13902/* FSC amilo */ 13903#define alc269_fujitsu_mixer alc269_laptop_mixer 13904 13905static struct hda_verb alc269_quanta_fl1_verbs[] = { 13906 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 13907 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 13908 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 13909 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 13910 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 13911 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 13912 { } 13913}; 13914 13915static struct hda_verb alc269_lifebook_verbs[] = { 13916 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 13917 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, 13918 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 13919 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 13920 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 13921 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 13922 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 13923 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 13924 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 13925 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 13926 { } 13927}; 13928 13929/* toggle speaker-output according to the hp-jack state */ 13930static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec) 13931{ 13932 unsigned int present; 13933 unsigned char bits; 13934 13935 present = snd_hda_jack_detect(codec, 0x15); 13936 bits = present ? HDA_AMP_MUTE : 0; 13937 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 13938 HDA_AMP_MUTE, bits); 13939 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 13940 HDA_AMP_MUTE, bits); 13941 13942 snd_hda_codec_write(codec, 0x20, 0, 13943 AC_VERB_SET_COEF_INDEX, 0x0c); 13944 snd_hda_codec_write(codec, 0x20, 0, 13945 AC_VERB_SET_PROC_COEF, 0x680); 13946 13947 snd_hda_codec_write(codec, 0x20, 0, 13948 AC_VERB_SET_COEF_INDEX, 0x0c); 13949 snd_hda_codec_write(codec, 0x20, 0, 13950 AC_VERB_SET_PROC_COEF, 0x480); 13951} 13952 13953/* toggle speaker-output according to the hp-jacks state */ 13954static void alc269_lifebook_speaker_automute(struct hda_codec *codec) 13955{ 13956 unsigned int present; 13957 unsigned char bits; 13958 13959 /* Check laptop headphone socket */ 13960 present = snd_hda_jack_detect(codec, 0x15); 13961 13962 /* Check port replicator headphone socket */ 13963 present |= snd_hda_jack_detect(codec, 0x1a); 13964 13965 bits = present ? HDA_AMP_MUTE : 0; 13966 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 13967 HDA_AMP_MUTE, bits); 13968 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 13969 HDA_AMP_MUTE, bits); 13970 13971 snd_hda_codec_write(codec, 0x20, 0, 13972 AC_VERB_SET_COEF_INDEX, 0x0c); 13973 snd_hda_codec_write(codec, 0x20, 0, 13974 AC_VERB_SET_PROC_COEF, 0x680); 13975 13976 snd_hda_codec_write(codec, 0x20, 0, 13977 AC_VERB_SET_COEF_INDEX, 0x0c); 13978 snd_hda_codec_write(codec, 0x20, 0, 13979 AC_VERB_SET_PROC_COEF, 0x480); 13980} 13981 13982static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec) 13983{ 13984 unsigned int present_laptop; 13985 unsigned int present_dock; 13986 13987 present_laptop = snd_hda_jack_detect(codec, 0x18); 13988 present_dock = snd_hda_jack_detect(codec, 0x1b); 13989 13990 /* Laptop mic port overrides dock mic port, design decision */ 13991 if (present_dock) 13992 snd_hda_codec_write(codec, 0x23, 0, 13993 AC_VERB_SET_CONNECT_SEL, 0x3); 13994 if (present_laptop) 13995 snd_hda_codec_write(codec, 0x23, 0, 13996 AC_VERB_SET_CONNECT_SEL, 0x0); 13997 if (!present_dock && !present_laptop) 13998 snd_hda_codec_write(codec, 0x23, 0, 13999 AC_VERB_SET_CONNECT_SEL, 0x1); 14000} 14001 14002static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec, 14003 unsigned int res) 14004{ 14005 switch (res >> 26) { 14006 case ALC880_HP_EVENT: 14007 alc269_quanta_fl1_speaker_automute(codec); 14008 break; 14009 case ALC880_MIC_EVENT: 14010 alc_mic_automute(codec); 14011 break; 14012 } 14013} 14014 14015static void alc269_lifebook_unsol_event(struct hda_codec *codec, 14016 unsigned int res) 14017{ 14018 if ((res >> 26) == ALC880_HP_EVENT) 14019 alc269_lifebook_speaker_automute(codec); 14020 if ((res >> 26) == ALC880_MIC_EVENT) 14021 alc269_lifebook_mic_autoswitch(codec); 14022} 14023 14024static void alc269_quanta_fl1_setup(struct hda_codec *codec) 14025{ 14026 struct alc_spec *spec = codec->spec; 14027 spec->autocfg.hp_pins[0] = 0x15; 14028 spec->autocfg.speaker_pins[0] = 0x14; 14029 spec->ext_mic.pin = 0x18; 14030 spec->ext_mic.mux_idx = 0; 14031 spec->int_mic.pin = 0x19; 14032 spec->int_mic.mux_idx = 1; 14033 spec->auto_mic = 1; 14034} 14035 14036static void alc269_quanta_fl1_init_hook(struct hda_codec *codec) 14037{ 14038 alc269_quanta_fl1_speaker_automute(codec); 14039 alc_mic_automute(codec); 14040} 14041 14042static void alc269_lifebook_init_hook(struct hda_codec *codec) 14043{ 14044 alc269_lifebook_speaker_automute(codec); 14045 alc269_lifebook_mic_autoswitch(codec); 14046} 14047 14048static struct hda_verb alc269_laptop_dmic_init_verbs[] = { 14049 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 14050 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05}, 14051 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 }, 14052 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))}, 14053 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14054 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 14055 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 14056 {} 14057}; 14058 14059static struct hda_verb alc269_laptop_amic_init_verbs[] = { 14060 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 14061 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01}, 14062 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 }, 14063 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))}, 14064 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 14065 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 14066 {} 14067}; 14068 14069static struct hda_verb alc269vb_laptop_dmic_init_verbs[] = { 14070 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, 14071 {0x22, AC_VERB_SET_CONNECT_SEL, 0x06}, 14072 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 }, 14073 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))}, 14074 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14075 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 14076 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 14077 {} 14078}; 14079 14080static struct hda_verb alc269vb_laptop_amic_init_verbs[] = { 14081 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, 14082 {0x22, AC_VERB_SET_CONNECT_SEL, 0x01}, 14083 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 }, 14084 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))}, 14085 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14086 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 14087 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 14088 {} 14089}; 14090 14091static struct hda_verb alc271_acer_dmic_verbs[] = { 14092 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d}, 14093 {0x20, AC_VERB_SET_PROC_COEF, 0x4000}, 14094 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14095 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 14096 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 14097 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 14098 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, 14099 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 14100 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 14101 {0x22, AC_VERB_SET_CONNECT_SEL, 6}, 14102 { } 14103}; 14104 14105/* toggle speaker-output according to the hp-jack state */ 14106static void alc269_speaker_automute(struct hda_codec *codec) 14107{ 14108 struct alc_spec *spec = codec->spec; 14109 unsigned int nid = spec->autocfg.hp_pins[0]; 14110 unsigned int present; 14111 unsigned char bits; 14112 14113 present = snd_hda_jack_detect(codec, nid); 14114 bits = present ? HDA_AMP_MUTE : 0; 14115 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 14116 HDA_AMP_MUTE, bits); 14117 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 14118 HDA_AMP_MUTE, bits); 14119} 14120 14121/* unsolicited event for HP jack sensing */ 14122static void alc269_laptop_unsol_event(struct hda_codec *codec, 14123 unsigned int res) 14124{ 14125 switch (res >> 26) { 14126 case ALC880_HP_EVENT: 14127 alc269_speaker_automute(codec); 14128 break; 14129 case ALC880_MIC_EVENT: 14130 alc_mic_automute(codec); 14131 break; 14132 } 14133} 14134 14135static void alc269_laptop_amic_setup(struct hda_codec *codec) 14136{ 14137 struct alc_spec *spec = codec->spec; 14138 spec->autocfg.hp_pins[0] = 0x15; 14139 spec->autocfg.speaker_pins[0] = 0x14; 14140 spec->ext_mic.pin = 0x18; 14141 spec->ext_mic.mux_idx = 0; 14142 spec->int_mic.pin = 0x19; 14143 spec->int_mic.mux_idx = 1; 14144 spec->auto_mic = 1; 14145} 14146 14147static void alc269_laptop_dmic_setup(struct hda_codec *codec) 14148{ 14149 struct alc_spec *spec = codec->spec; 14150 spec->autocfg.hp_pins[0] = 0x15; 14151 spec->autocfg.speaker_pins[0] = 0x14; 14152 spec->ext_mic.pin = 0x18; 14153 spec->ext_mic.mux_idx = 0; 14154 spec->int_mic.pin = 0x12; 14155 spec->int_mic.mux_idx = 5; 14156 spec->auto_mic = 1; 14157} 14158 14159static void alc269vb_laptop_amic_setup(struct hda_codec *codec) 14160{ 14161 struct alc_spec *spec = codec->spec; 14162 spec->autocfg.hp_pins[0] = 0x21; 14163 spec->autocfg.speaker_pins[0] = 0x14; 14164 spec->ext_mic.pin = 0x18; 14165 spec->ext_mic.mux_idx = 0; 14166 spec->int_mic.pin = 0x19; 14167 spec->int_mic.mux_idx = 1; 14168 spec->auto_mic = 1; 14169} 14170 14171static void alc269vb_laptop_dmic_setup(struct hda_codec *codec) 14172{ 14173 struct alc_spec *spec = codec->spec; 14174 spec->autocfg.hp_pins[0] = 0x21; 14175 spec->autocfg.speaker_pins[0] = 0x14; 14176 spec->ext_mic.pin = 0x18; 14177 spec->ext_mic.mux_idx = 0; 14178 spec->int_mic.pin = 0x12; 14179 spec->int_mic.mux_idx = 6; 14180 spec->auto_mic = 1; 14181} 14182 14183static void alc269_laptop_inithook(struct hda_codec *codec) 14184{ 14185 alc269_speaker_automute(codec); 14186 alc_mic_automute(codec); 14187} 14188 14189/* 14190 * generic initialization of ADC, input mixers and output mixers 14191 */ 14192static struct hda_verb alc269_init_verbs[] = { 14193 /* 14194 * Unmute ADC0 and set the default input to mic-in 14195 */ 14196 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14197 14198 /* 14199 * Set up output mixers (0x02 - 0x03) 14200 */ 14201 /* set vol=0 to output mixers */ 14202 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 14203 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 14204 14205 /* set up input amps for analog loopback */ 14206 /* Amp Indices: DAC = 0, mixer = 1 */ 14207 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14208 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 14209 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14210 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 14211 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14212 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 14213 14214 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 14215 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 14216 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 14217 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 14218 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 14219 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14220 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14221 14222 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 14223 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 14224 14225 /* FIXME: use Mux-type input source selection */ 14226 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */ 14227 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 14228 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00}, 14229 14230 /* set EAPD */ 14231 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 14232 { } 14233}; 14234 14235static struct hda_verb alc269vb_init_verbs[] = { 14236 /* 14237 * Unmute ADC0 and set the default input to mic-in 14238 */ 14239 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14240 14241 /* 14242 * Set up output mixers (0x02 - 0x03) 14243 */ 14244 /* set vol=0 to output mixers */ 14245 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 14246 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 14247 14248 /* set up input amps for analog loopback */ 14249 /* Amp Indices: DAC = 0, mixer = 1 */ 14250 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14251 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 14252 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14253 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 14254 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14255 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 14256 14257 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 14258 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 14259 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 14260 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 14261 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 14262 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14263 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14264 14265 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 14266 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 14267 14268 /* FIXME: use Mux-type input source selection */ 14269 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */ 14270 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 14271 {0x22, AC_VERB_SET_CONNECT_SEL, 0x00}, 14272 14273 /* set EAPD */ 14274 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 14275 { } 14276}; 14277 14278#define alc269_auto_create_multi_out_ctls \ 14279 alc268_auto_create_multi_out_ctls 14280#define alc269_auto_create_input_ctls \ 14281 alc268_auto_create_input_ctls 14282 14283#ifdef CONFIG_SND_HDA_POWER_SAVE 14284#define alc269_loopbacks alc880_loopbacks 14285#endif 14286 14287/* pcm configuration: identical with ALC880 */ 14288#define alc269_pcm_analog_playback alc880_pcm_analog_playback 14289#define alc269_pcm_analog_capture alc880_pcm_analog_capture 14290#define alc269_pcm_digital_playback alc880_pcm_digital_playback 14291#define alc269_pcm_digital_capture alc880_pcm_digital_capture 14292 14293static struct hda_pcm_stream alc269_44k_pcm_analog_playback = { 14294 .substreams = 1, 14295 .channels_min = 2, 14296 .channels_max = 8, 14297 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */ 14298 /* NID is set in alc_build_pcms */ 14299 .ops = { 14300 .open = alc880_playback_pcm_open, 14301 .prepare = alc880_playback_pcm_prepare, 14302 .cleanup = alc880_playback_pcm_cleanup 14303 }, 14304}; 14305 14306static struct hda_pcm_stream alc269_44k_pcm_analog_capture = { 14307 .substreams = 1, 14308 .channels_min = 2, 14309 .channels_max = 2, 14310 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */ 14311 /* NID is set in alc_build_pcms */ 14312}; 14313 14314#ifdef CONFIG_SND_HDA_POWER_SAVE 14315static int alc269_mic2_for_mute_led(struct hda_codec *codec) 14316{ 14317 switch (codec->subsystem_id) { 14318 case 0x103c1586: 14319 return 1; 14320 } 14321 return 0; 14322} 14323 14324static int alc269_mic2_mute_check_ps(struct hda_codec *codec, hda_nid_t nid) 14325{ 14326 /* update mute-LED according to the speaker mute state */ 14327 if (nid == 0x01 || nid == 0x14) { 14328 int pinval; 14329 if (snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0) & 14330 HDA_AMP_MUTE) 14331 pinval = 0x24; 14332 else 14333 pinval = 0x20; 14334 /* mic2 vref pin is used for mute LED control */ 14335 snd_hda_codec_update_cache(codec, 0x19, 0, 14336 AC_VERB_SET_PIN_WIDGET_CONTROL, 14337 pinval); 14338 } 14339 return alc_check_power_status(codec, nid); 14340} 14341#endif /* CONFIG_SND_HDA_POWER_SAVE */ 14342 14343static int alc275_setup_dual_adc(struct hda_codec *codec) 14344{ 14345 struct alc_spec *spec = codec->spec; 14346 14347 if (codec->vendor_id != 0x10ec0275 || !spec->auto_mic) 14348 return 0; 14349 if ((spec->ext_mic.pin >= 0x18 && spec->int_mic.pin <= 0x13) || 14350 (spec->ext_mic.pin <= 0x12 && spec->int_mic.pin >= 0x18)) { 14351 if (spec->ext_mic.pin <= 0x12) { 14352 spec->private_adc_nids[0] = 0x08; 14353 spec->private_adc_nids[1] = 0x11; 14354 spec->private_capsrc_nids[0] = 0x23; 14355 spec->private_capsrc_nids[1] = 0x22; 14356 } else { 14357 spec->private_adc_nids[0] = 0x11; 14358 spec->private_adc_nids[1] = 0x08; 14359 spec->private_capsrc_nids[0] = 0x22; 14360 spec->private_capsrc_nids[1] = 0x23; 14361 } 14362 spec->adc_nids = spec->private_adc_nids; 14363 spec->capsrc_nids = spec->private_capsrc_nids; 14364 spec->num_adc_nids = 2; 14365 spec->dual_adc_switch = 1; 14366 snd_printdd("realtek: enabling dual ADC switchg (%02x:%02x)\n", 14367 spec->adc_nids[0], spec->adc_nids[1]); 14368 return 1; 14369 } 14370 return 0; 14371} 14372 14373/* 14374 * BIOS auto configuration 14375 */ 14376static int alc269_parse_auto_config(struct hda_codec *codec) 14377{ 14378 struct alc_spec *spec = codec->spec; 14379 int err; 14380 static hda_nid_t alc269_ignore[] = { 0x1d, 0 }; 14381 14382 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 14383 alc269_ignore); 14384 if (err < 0) 14385 return err; 14386 14387 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg); 14388 if (err < 0) 14389 return err; 14390 err = alc269_auto_create_input_ctls(codec, &spec->autocfg); 14391 if (err < 0) 14392 return err; 14393 14394 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 14395 14396 alc_auto_parse_digital(codec); 14397 14398 if (spec->kctls.list) 14399 add_mixer(spec, spec->kctls.list); 14400 14401 if ((alc_read_coef_idx(codec, 0) & 0x00f0) == 0x0010) { 14402 add_verb(spec, alc269vb_init_verbs); 14403 alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21); 14404 } else { 14405 add_verb(spec, alc269_init_verbs); 14406 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); 14407 } 14408 14409 spec->num_mux_defs = 1; 14410 spec->input_mux = &spec->private_imux[0]; 14411 14412 if (!alc275_setup_dual_adc(codec)) 14413 fillup_priv_adc_nids(codec, alc269_adc_candidates, 14414 sizeof(alc269_adc_candidates)); 14415 14416 /* set default input source */ 14417 if (!spec->dual_adc_switch) 14418 select_or_unmute_capsrc(codec, spec->capsrc_nids[0], 14419 spec->input_mux->items[0].index); 14420 14421 err = alc_auto_add_mic_boost(codec); 14422 if (err < 0) 14423 return err; 14424 14425 if (!spec->cap_mixer && !spec->no_analog) 14426 set_capture_mixer(codec); 14427 14428 return 1; 14429} 14430 14431#define alc269_auto_init_multi_out alc268_auto_init_multi_out 14432#define alc269_auto_init_hp_out alc268_auto_init_hp_out 14433#define alc269_auto_init_analog_input alc882_auto_init_analog_input 14434 14435 14436/* init callback for auto-configuration model -- overriding the default init */ 14437static void alc269_auto_init(struct hda_codec *codec) 14438{ 14439 struct alc_spec *spec = codec->spec; 14440 alc269_auto_init_multi_out(codec); 14441 alc269_auto_init_hp_out(codec); 14442 alc269_auto_init_analog_input(codec); 14443 alc_auto_init_digital(codec); 14444 if (spec->unsol_event) 14445 alc_inithook(codec); 14446} 14447 14448enum { 14449 ALC269_FIXUP_SONY_VAIO, 14450}; 14451 14452static const struct alc_fixup alc269_fixups[] = { 14453 [ALC269_FIXUP_SONY_VAIO] = { 14454 .verbs = (const struct hda_verb[]) { 14455 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD}, 14456 {} 14457 } 14458 }, 14459}; 14460 14461static struct snd_pci_quirk alc269_fixup_tbl[] = { 14462 SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_FIXUP_SONY_VAIO), 14463 SND_PCI_QUIRK(0x104d, 0x9077, "Sony VAIO", ALC269_FIXUP_SONY_VAIO), 14464 {} 14465}; 14466 14467 14468/* 14469 * configuration and preset 14470 */ 14471static const char *alc269_models[ALC269_MODEL_LAST] = { 14472 [ALC269_BASIC] = "basic", 14473 [ALC269_QUANTA_FL1] = "quanta", 14474 [ALC269_AMIC] = "laptop-amic", 14475 [ALC269_DMIC] = "laptop-dmic", 14476 [ALC269_FUJITSU] = "fujitsu", 14477 [ALC269_LIFEBOOK] = "lifebook", 14478 [ALC269_AUTO] = "auto", 14479}; 14480 14481static struct snd_pci_quirk alc269_cfg_tbl[] = { 14482 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1), 14483 SND_PCI_QUIRK(0x1025, 0x047c, "ACER ZGA", ALC271_ACER), 14484 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A", 14485 ALC269_AMIC), 14486 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269VB_AMIC), 14487 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269VB_AMIC), 14488 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269VB_AMIC), 14489 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_AMIC), 14490 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269VB_AMIC), 14491 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269VB_AMIC), 14492 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269VB_AMIC), 14493 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269VB_AMIC), 14494 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_AMIC), 14495 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82Jv", ALC269_AMIC), 14496 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_AMIC), 14497 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_AMIC), 14498 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_AMIC), 14499 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_AMIC), 14500 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_AMIC), 14501 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_AMIC), 14502 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_AMIC), 14503 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_AMIC), 14504 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_AMIC), 14505 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_AMIC), 14506 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_AMIC), 14507 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_AMIC), 14508 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_AMIC), 14509 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_AMIC), 14510 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_AMIC), 14511 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_AMIC), 14512 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_AMIC), 14513 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_AMIC), 14514 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_AMIC), 14515 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_AMIC), 14516 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_AMIC), 14517 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_DMIC), 14518 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_AMIC), 14519 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_AMIC), 14520 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_AMIC), 14521 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_AMIC), 14522 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901", 14523 ALC269_DMIC), 14524 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101", 14525 ALC269_DMIC), 14526 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC), 14527 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC), 14528 SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_AUTO), 14529 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK), 14530 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC), 14531 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU), 14532 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_AMIC), 14533 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_AMIC), 14534 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_DMIC), 14535 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_DMIC), 14536 {} 14537}; 14538 14539static struct alc_config_preset alc269_presets[] = { 14540 [ALC269_BASIC] = { 14541 .mixers = { alc269_base_mixer }, 14542 .init_verbs = { alc269_init_verbs }, 14543 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 14544 .dac_nids = alc269_dac_nids, 14545 .hp_nid = 0x03, 14546 .num_channel_mode = ARRAY_SIZE(alc269_modes), 14547 .channel_mode = alc269_modes, 14548 .input_mux = &alc269_capture_source, 14549 }, 14550 [ALC269_QUANTA_FL1] = { 14551 .mixers = { alc269_quanta_fl1_mixer }, 14552 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs }, 14553 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 14554 .dac_nids = alc269_dac_nids, 14555 .hp_nid = 0x03, 14556 .num_channel_mode = ARRAY_SIZE(alc269_modes), 14557 .channel_mode = alc269_modes, 14558 .input_mux = &alc269_capture_source, 14559 .unsol_event = alc269_quanta_fl1_unsol_event, 14560 .setup = alc269_quanta_fl1_setup, 14561 .init_hook = alc269_quanta_fl1_init_hook, 14562 }, 14563 [ALC269_AMIC] = { 14564 .mixers = { alc269_laptop_mixer }, 14565 .cap_mixer = alc269_laptop_analog_capture_mixer, 14566 .init_verbs = { alc269_init_verbs, 14567 alc269_laptop_amic_init_verbs }, 14568 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 14569 .dac_nids = alc269_dac_nids, 14570 .hp_nid = 0x03, 14571 .num_channel_mode = ARRAY_SIZE(alc269_modes), 14572 .channel_mode = alc269_modes, 14573 .unsol_event = alc269_laptop_unsol_event, 14574 .setup = alc269_laptop_amic_setup, 14575 .init_hook = alc269_laptop_inithook, 14576 }, 14577 [ALC269_DMIC] = { 14578 .mixers = { alc269_laptop_mixer }, 14579 .cap_mixer = alc269_laptop_digital_capture_mixer, 14580 .init_verbs = { alc269_init_verbs, 14581 alc269_laptop_dmic_init_verbs }, 14582 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 14583 .dac_nids = alc269_dac_nids, 14584 .hp_nid = 0x03, 14585 .num_channel_mode = ARRAY_SIZE(alc269_modes), 14586 .channel_mode = alc269_modes, 14587 .unsol_event = alc269_laptop_unsol_event, 14588 .setup = alc269_laptop_dmic_setup, 14589 .init_hook = alc269_laptop_inithook, 14590 }, 14591 [ALC269VB_AMIC] = { 14592 .mixers = { alc269vb_laptop_mixer }, 14593 .cap_mixer = alc269vb_laptop_analog_capture_mixer, 14594 .init_verbs = { alc269vb_init_verbs, 14595 alc269vb_laptop_amic_init_verbs }, 14596 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 14597 .dac_nids = alc269_dac_nids, 14598 .hp_nid = 0x03, 14599 .num_channel_mode = ARRAY_SIZE(alc269_modes), 14600 .channel_mode = alc269_modes, 14601 .unsol_event = alc269_laptop_unsol_event, 14602 .setup = alc269vb_laptop_amic_setup, 14603 .init_hook = alc269_laptop_inithook, 14604 }, 14605 [ALC269VB_DMIC] = { 14606 .mixers = { alc269vb_laptop_mixer }, 14607 .cap_mixer = alc269vb_laptop_digital_capture_mixer, 14608 .init_verbs = { alc269vb_init_verbs, 14609 alc269vb_laptop_dmic_init_verbs }, 14610 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 14611 .dac_nids = alc269_dac_nids, 14612 .hp_nid = 0x03, 14613 .num_channel_mode = ARRAY_SIZE(alc269_modes), 14614 .channel_mode = alc269_modes, 14615 .unsol_event = alc269_laptop_unsol_event, 14616 .setup = alc269vb_laptop_dmic_setup, 14617 .init_hook = alc269_laptop_inithook, 14618 }, 14619 [ALC269_FUJITSU] = { 14620 .mixers = { alc269_fujitsu_mixer }, 14621 .cap_mixer = alc269_laptop_digital_capture_mixer, 14622 .init_verbs = { alc269_init_verbs, 14623 alc269_laptop_dmic_init_verbs }, 14624 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 14625 .dac_nids = alc269_dac_nids, 14626 .hp_nid = 0x03, 14627 .num_channel_mode = ARRAY_SIZE(alc269_modes), 14628 .channel_mode = alc269_modes, 14629 .unsol_event = alc269_laptop_unsol_event, 14630 .setup = alc269_laptop_dmic_setup, 14631 .init_hook = alc269_laptop_inithook, 14632 }, 14633 [ALC269_LIFEBOOK] = { 14634 .mixers = { alc269_lifebook_mixer }, 14635 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs }, 14636 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 14637 .dac_nids = alc269_dac_nids, 14638 .hp_nid = 0x03, 14639 .num_channel_mode = ARRAY_SIZE(alc269_modes), 14640 .channel_mode = alc269_modes, 14641 .input_mux = &alc269_capture_source, 14642 .unsol_event = alc269_lifebook_unsol_event, 14643 .init_hook = alc269_lifebook_init_hook, 14644 }, 14645 [ALC271_ACER] = { 14646 .mixers = { alc269_asus_mixer }, 14647 .cap_mixer = alc269vb_laptop_digital_capture_mixer, 14648 .init_verbs = { alc269_init_verbs, alc271_acer_dmic_verbs }, 14649 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 14650 .dac_nids = alc269_dac_nids, 14651 .adc_nids = alc262_dmic_adc_nids, 14652 .num_adc_nids = ARRAY_SIZE(alc262_dmic_adc_nids), 14653 .capsrc_nids = alc262_dmic_capsrc_nids, 14654 .num_channel_mode = ARRAY_SIZE(alc269_modes), 14655 .channel_mode = alc269_modes, 14656 .input_mux = &alc269_capture_source, 14657 .dig_out_nid = ALC880_DIGOUT_NID, 14658 .unsol_event = alc_sku_unsol_event, 14659 .setup = alc269vb_laptop_dmic_setup, 14660 .init_hook = alc_inithook, 14661 }, 14662}; 14663 14664static int patch_alc269(struct hda_codec *codec) 14665{ 14666 struct alc_spec *spec; 14667 int board_config; 14668 int err; 14669 int is_alc269vb = 0; 14670 14671 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 14672 if (spec == NULL) 14673 return -ENOMEM; 14674 14675 codec->spec = spec; 14676 14677 alc_auto_parse_customize_define(codec); 14678 14679 if ((alc_read_coef_idx(codec, 0) & 0x00f0) == 0x0010){ 14680 if (codec->bus->pci->subsystem_vendor == 0x1025 && 14681 spec->cdefine.platform_type == 1) 14682 alc_codec_rename(codec, "ALC271X"); 14683 else 14684 alc_codec_rename(codec, "ALC259"); 14685 is_alc269vb = 1; 14686 } else 14687 alc_fix_pll_init(codec, 0x20, 0x04, 15); 14688 14689 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST, 14690 alc269_models, 14691 alc269_cfg_tbl); 14692 14693 if (board_config < 0) { 14694 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 14695 codec->chip_name); 14696 board_config = ALC269_AUTO; 14697 } 14698 14699 if (board_config == ALC269_AUTO) 14700 alc_pick_fixup(codec, alc269_fixup_tbl, alc269_fixups, 1); 14701 14702 if (board_config == ALC269_AUTO) { 14703 /* automatic parse from the BIOS config */ 14704 err = alc269_parse_auto_config(codec); 14705 if (err < 0) { 14706 alc_free(codec); 14707 return err; 14708 } else if (!err) { 14709 printk(KERN_INFO 14710 "hda_codec: Cannot set up configuration " 14711 "from BIOS. Using base mode...\n"); 14712 board_config = ALC269_BASIC; 14713 } 14714 } 14715 14716 if (has_cdefine_beep(codec)) { 14717 err = snd_hda_attach_beep_device(codec, 0x1); 14718 if (err < 0) { 14719 alc_free(codec); 14720 return err; 14721 } 14722 } 14723 14724 if (board_config != ALC269_AUTO) 14725 setup_preset(codec, &alc269_presets[board_config]); 14726 14727 if (board_config == ALC269_QUANTA_FL1) { 14728 /* Due to a hardware problem on Lenovo Ideadpad, we need to 14729 * fix the sample rate of analog I/O to 44.1kHz 14730 */ 14731 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback; 14732 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture; 14733 } else if (spec->dual_adc_switch) { 14734 spec->stream_analog_playback = &alc269_pcm_analog_playback; 14735 /* switch ADC dynamically */ 14736 spec->stream_analog_capture = &dualmic_pcm_analog_capture; 14737 } else { 14738 spec->stream_analog_playback = &alc269_pcm_analog_playback; 14739 spec->stream_analog_capture = &alc269_pcm_analog_capture; 14740 } 14741 spec->stream_digital_playback = &alc269_pcm_digital_playback; 14742 spec->stream_digital_capture = &alc269_pcm_digital_capture; 14743 14744 if (!spec->adc_nids) { /* wasn't filled automatically? use default */ 14745 if (!is_alc269vb) { 14746 spec->adc_nids = alc269_adc_nids; 14747 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids); 14748 spec->capsrc_nids = alc269_capsrc_nids; 14749 } else { 14750 spec->adc_nids = alc269vb_adc_nids; 14751 spec->num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids); 14752 spec->capsrc_nids = alc269vb_capsrc_nids; 14753 } 14754 } 14755 14756 if (!spec->cap_mixer) 14757 set_capture_mixer(codec); 14758 if (has_cdefine_beep(codec)) 14759 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); 14760 14761 if (board_config == ALC269_AUTO) 14762 alc_pick_fixup(codec, alc269_fixup_tbl, alc269_fixups, 0); 14763 14764 spec->vmaster_nid = 0x02; 14765 14766 codec->patch_ops = alc_patch_ops; 14767 if (board_config == ALC269_AUTO) 14768 spec->init_hook = alc269_auto_init; 14769#ifdef CONFIG_SND_HDA_POWER_SAVE 14770 if (!spec->loopback.amplist) 14771 spec->loopback.amplist = alc269_loopbacks; 14772 if (alc269_mic2_for_mute_led(codec)) 14773 codec->patch_ops.check_power_status = alc269_mic2_mute_check_ps; 14774#endif 14775 14776 return 0; 14777} 14778 14779/* 14780 * ALC861 channel source setting (2/6 channel selection for 3-stack) 14781 */ 14782 14783/* 14784 * set the path ways for 2 channel output 14785 * need to set the codec line out and mic 1 pin widgets to inputs 14786 */ 14787static struct hda_verb alc861_threestack_ch2_init[] = { 14788 /* set pin widget 1Ah (line in) for input */ 14789 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 14790 /* set pin widget 18h (mic1/2) for input, for mic also enable 14791 * the vref 14792 */ 14793 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 14794 14795 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, 14796#if 0 14797 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/ 14798 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/ 14799#endif 14800 { } /* end */ 14801}; 14802/* 14803 * 6ch mode 14804 * need to set the codec line out and mic 1 pin widgets to outputs 14805 */ 14806static struct hda_verb alc861_threestack_ch6_init[] = { 14807 /* set pin widget 1Ah (line in) for output (Back Surround)*/ 14808 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 14809 /* set pin widget 18h (mic1) for output (CLFE)*/ 14810 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 14811 14812 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 }, 14813 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 }, 14814 14815 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 }, 14816#if 0 14817 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/ 14818 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/ 14819#endif 14820 { } /* end */ 14821}; 14822 14823static struct hda_channel_mode alc861_threestack_modes[2] = { 14824 { 2, alc861_threestack_ch2_init }, 14825 { 6, alc861_threestack_ch6_init }, 14826}; 14827/* Set mic1 as input and unmute the mixer */ 14828static struct hda_verb alc861_uniwill_m31_ch2_init[] = { 14829 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 14830 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/ 14831 { } /* end */ 14832}; 14833/* Set mic1 as output and mute mixer */ 14834static struct hda_verb alc861_uniwill_m31_ch4_init[] = { 14835 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 14836 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/ 14837 { } /* end */ 14838}; 14839 14840static struct hda_channel_mode alc861_uniwill_m31_modes[2] = { 14841 { 2, alc861_uniwill_m31_ch2_init }, 14842 { 4, alc861_uniwill_m31_ch4_init }, 14843}; 14844 14845/* Set mic1 and line-in as input and unmute the mixer */ 14846static struct hda_verb alc861_asus_ch2_init[] = { 14847 /* set pin widget 1Ah (line in) for input */ 14848 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 14849 /* set pin widget 18h (mic1/2) for input, for mic also enable 14850 * the vref 14851 */ 14852 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 14853 14854 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, 14855#if 0 14856 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/ 14857 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/ 14858#endif 14859 { } /* end */ 14860}; 14861/* Set mic1 nad line-in as output and mute mixer */ 14862static struct hda_verb alc861_asus_ch6_init[] = { 14863 /* set pin widget 1Ah (line in) for output (Back Surround)*/ 14864 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 14865 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */ 14866 /* set pin widget 18h (mic1) for output (CLFE)*/ 14867 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 14868 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */ 14869 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 }, 14870 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 }, 14871 14872 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 }, 14873#if 0 14874 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/ 14875 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/ 14876#endif 14877 { } /* end */ 14878}; 14879 14880static struct hda_channel_mode alc861_asus_modes[2] = { 14881 { 2, alc861_asus_ch2_init }, 14882 { 6, alc861_asus_ch6_init }, 14883}; 14884 14885/* patch-ALC861 */ 14886 14887static struct snd_kcontrol_new alc861_base_mixer[] = { 14888 /* output mixer control */ 14889 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), 14890 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), 14891 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT), 14892 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT), 14893 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), 14894 14895 /*Input mixer control */ 14896 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT), 14897 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */ 14898 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), 14899 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), 14900 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT), 14901 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT), 14902 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), 14903 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), 14904 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), 14905 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT), 14906 14907 { } /* end */ 14908}; 14909 14910static struct snd_kcontrol_new alc861_3ST_mixer[] = { 14911 /* output mixer control */ 14912 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), 14913 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), 14914 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT), 14915 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT), 14916 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */ 14917 14918 /* Input mixer control */ 14919 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT), 14920 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */ 14921 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), 14922 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), 14923 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT), 14924 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT), 14925 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), 14926 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), 14927 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), 14928 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT), 14929 14930 { 14931 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 14932 .name = "Channel Mode", 14933 .info = alc_ch_mode_info, 14934 .get = alc_ch_mode_get, 14935 .put = alc_ch_mode_put, 14936 .private_value = ARRAY_SIZE(alc861_threestack_modes), 14937 }, 14938 { } /* end */ 14939}; 14940 14941static struct snd_kcontrol_new alc861_toshiba_mixer[] = { 14942 /* output mixer control */ 14943 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT), 14944 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), 14945 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), 14946 14947 { } /* end */ 14948}; 14949 14950static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = { 14951 /* output mixer control */ 14952 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), 14953 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), 14954 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT), 14955 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT), 14956 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */ 14957 14958 /* Input mixer control */ 14959 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT), 14960 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */ 14961 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), 14962 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), 14963 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT), 14964 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT), 14965 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), 14966 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), 14967 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), 14968 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT), 14969 14970 { 14971 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 14972 .name = "Channel Mode", 14973 .info = alc_ch_mode_info, 14974 .get = alc_ch_mode_get, 14975 .put = alc_ch_mode_put, 14976 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes), 14977 }, 14978 { } /* end */ 14979}; 14980 14981static struct snd_kcontrol_new alc861_asus_mixer[] = { 14982 /* output mixer control */ 14983 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), 14984 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), 14985 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT), 14986 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT), 14987 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), 14988 14989 /* Input mixer control */ 14990 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT), 14991 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), 14992 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), 14993 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), 14994 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT), 14995 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT), 14996 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), 14997 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), 14998 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), 14999 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT), 15000 15001 { 15002 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 15003 .name = "Channel Mode", 15004 .info = alc_ch_mode_info, 15005 .get = alc_ch_mode_get, 15006 .put = alc_ch_mode_put, 15007 .private_value = ARRAY_SIZE(alc861_asus_modes), 15008 }, 15009 { } 15010}; 15011 15012/* additional mixer */ 15013static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = { 15014 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), 15015 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), 15016 { } 15017}; 15018 15019/* 15020 * generic initialization of ADC, input mixers and output mixers 15021 */ 15022static struct hda_verb alc861_base_init_verbs[] = { 15023 /* 15024 * Unmute ADC0 and set the default input to mic-in 15025 */ 15026 /* port-A for surround (rear panel) */ 15027 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15028 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15029 /* port-B for mic-in (rear panel) with vref */ 15030 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15031 /* port-C for line-in (rear panel) */ 15032 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 15033 /* port-D for Front */ 15034 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15035 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15036 /* port-E for HP out (front panel) */ 15037 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, 15038 /* route front PCM to HP */ 15039 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15040 /* port-F for mic-in (front panel) with vref */ 15041 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15042 /* port-G for CLFE (rear panel) */ 15043 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15044 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15045 /* port-H for side (rear panel) */ 15046 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15047 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15048 /* CD-in */ 15049 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 15050 /* route front mic to ADC1*/ 15051 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 15052 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15053 15054 /* Unmute DAC0~3 & spdif out*/ 15055 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15056 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15057 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15058 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15059 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15060 15061 /* Unmute Mixer 14 (mic) 1c (Line in)*/ 15062 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15063 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15064 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15065 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15066 15067 /* Unmute Stereo Mixer 15 */ 15068 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15069 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15070 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 15071 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */ 15072 15073 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15074 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15075 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15076 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15077 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15078 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15079 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15080 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15081 /* hp used DAC 3 (Front) */ 15082 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 15083 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 15084 15085 { } 15086}; 15087 15088static struct hda_verb alc861_threestack_init_verbs[] = { 15089 /* 15090 * Unmute ADC0 and set the default input to mic-in 15091 */ 15092 /* port-A for surround (rear panel) */ 15093 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 15094 /* port-B for mic-in (rear panel) with vref */ 15095 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15096 /* port-C for line-in (rear panel) */ 15097 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 15098 /* port-D for Front */ 15099 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15100 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15101 /* port-E for HP out (front panel) */ 15102 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, 15103 /* route front PCM to HP */ 15104 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15105 /* port-F for mic-in (front panel) with vref */ 15106 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15107 /* port-G for CLFE (rear panel) */ 15108 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 15109 /* port-H for side (rear panel) */ 15110 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 15111 /* CD-in */ 15112 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 15113 /* route front mic to ADC1*/ 15114 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 15115 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15116 /* Unmute DAC0~3 & spdif out*/ 15117 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15118 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15119 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15120 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15121 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15122 15123 /* Unmute Mixer 14 (mic) 1c (Line in)*/ 15124 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15125 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15126 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15127 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15128 15129 /* Unmute Stereo Mixer 15 */ 15130 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15131 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15132 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 15133 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */ 15134 15135 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15136 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15137 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15138 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15139 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15140 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15141 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15142 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15143 /* hp used DAC 3 (Front) */ 15144 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 15145 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 15146 { } 15147}; 15148 15149static struct hda_verb alc861_uniwill_m31_init_verbs[] = { 15150 /* 15151 * Unmute ADC0 and set the default input to mic-in 15152 */ 15153 /* port-A for surround (rear panel) */ 15154 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 15155 /* port-B for mic-in (rear panel) with vref */ 15156 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15157 /* port-C for line-in (rear panel) */ 15158 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 15159 /* port-D for Front */ 15160 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15161 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15162 /* port-E for HP out (front panel) */ 15163 /* this has to be set to VREF80 */ 15164 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15165 /* route front PCM to HP */ 15166 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15167 /* port-F for mic-in (front panel) with vref */ 15168 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15169 /* port-G for CLFE (rear panel) */ 15170 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 15171 /* port-H for side (rear panel) */ 15172 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 15173 /* CD-in */ 15174 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 15175 /* route front mic to ADC1*/ 15176 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 15177 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15178 /* Unmute DAC0~3 & spdif out*/ 15179 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15180 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15181 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15182 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15183 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15184 15185 /* Unmute Mixer 14 (mic) 1c (Line in)*/ 15186 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15187 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15188 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15189 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15190 15191 /* Unmute Stereo Mixer 15 */ 15192 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15193 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15194 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 15195 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */ 15196 15197 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15198 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15199 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15200 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15201 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15202 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15203 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15204 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15205 /* hp used DAC 3 (Front) */ 15206 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 15207 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 15208 { } 15209}; 15210 15211static struct hda_verb alc861_asus_init_verbs[] = { 15212 /* 15213 * Unmute ADC0 and set the default input to mic-in 15214 */ 15215 /* port-A for surround (rear panel) 15216 * according to codec#0 this is the HP jack 15217 */ 15218 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */ 15219 /* route front PCM to HP */ 15220 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 }, 15221 /* port-B for mic-in (rear panel) with vref */ 15222 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15223 /* port-C for line-in (rear panel) */ 15224 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 15225 /* port-D for Front */ 15226 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15227 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15228 /* port-E for HP out (front panel) */ 15229 /* this has to be set to VREF80 */ 15230 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15231 /* route front PCM to HP */ 15232 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15233 /* port-F for mic-in (front panel) with vref */ 15234 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15235 /* port-G for CLFE (rear panel) */ 15236 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15237 /* port-H for side (rear panel) */ 15238 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15239 /* CD-in */ 15240 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 15241 /* route front mic to ADC1*/ 15242 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 15243 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15244 /* Unmute DAC0~3 & spdif out*/ 15245 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15246 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15247 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15248 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15249 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15250 /* Unmute Mixer 14 (mic) 1c (Line in)*/ 15251 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15252 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15253 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15254 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15255 15256 /* Unmute Stereo Mixer 15 */ 15257 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15258 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15259 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 15260 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */ 15261 15262 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15263 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15264 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15265 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15266 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15267 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15268 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15269 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15270 /* hp used DAC 3 (Front) */ 15271 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 15272 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 15273 { } 15274}; 15275 15276/* additional init verbs for ASUS laptops */ 15277static struct hda_verb alc861_asus_laptop_init_verbs[] = { 15278 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */ 15279 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */ 15280 { } 15281}; 15282 15283/* 15284 * generic initialization of ADC, input mixers and output mixers 15285 */ 15286static struct hda_verb alc861_auto_init_verbs[] = { 15287 /* 15288 * Unmute ADC0 and set the default input to mic-in 15289 */ 15290 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */ 15291 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15292 15293 /* Unmute DAC0~3 & spdif out*/ 15294 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 15295 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 15296 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 15297 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 15298 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15299 15300 /* Unmute Mixer 14 (mic) 1c (Line in)*/ 15301 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15302 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15303 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15304 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15305 15306 /* Unmute Stereo Mixer 15 */ 15307 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15308 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15309 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 15310 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, 15311 15312 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 15313 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 15314 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 15315 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 15316 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 15317 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 15318 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 15319 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 15320 15321 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 15322 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 15323 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 15324 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 15325 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 15326 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 15327 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 15328 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 15329 15330 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */ 15331 15332 { } 15333}; 15334 15335static struct hda_verb alc861_toshiba_init_verbs[] = { 15336 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 15337 15338 { } 15339}; 15340 15341/* toggle speaker-output according to the hp-jack state */ 15342static void alc861_toshiba_automute(struct hda_codec *codec) 15343{ 15344 unsigned int present = snd_hda_jack_detect(codec, 0x0f); 15345 15346 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0, 15347 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 15348 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3, 15349 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE); 15350} 15351 15352static void alc861_toshiba_unsol_event(struct hda_codec *codec, 15353 unsigned int res) 15354{ 15355 if ((res >> 26) == ALC880_HP_EVENT) 15356 alc861_toshiba_automute(codec); 15357} 15358 15359/* pcm configuration: identical with ALC880 */ 15360#define alc861_pcm_analog_playback alc880_pcm_analog_playback 15361#define alc861_pcm_analog_capture alc880_pcm_analog_capture 15362#define alc861_pcm_digital_playback alc880_pcm_digital_playback 15363#define alc861_pcm_digital_capture alc880_pcm_digital_capture 15364 15365 15366#define ALC861_DIGOUT_NID 0x07 15367 15368static struct hda_channel_mode alc861_8ch_modes[1] = { 15369 { 8, NULL } 15370}; 15371 15372static hda_nid_t alc861_dac_nids[4] = { 15373 /* front, surround, clfe, side */ 15374 0x03, 0x06, 0x05, 0x04 15375}; 15376 15377static hda_nid_t alc660_dac_nids[3] = { 15378 /* front, clfe, surround */ 15379 0x03, 0x05, 0x06 15380}; 15381 15382static hda_nid_t alc861_adc_nids[1] = { 15383 /* ADC0-2 */ 15384 0x08, 15385}; 15386 15387static struct hda_input_mux alc861_capture_source = { 15388 .num_items = 5, 15389 .items = { 15390 { "Mic", 0x0 }, 15391 { "Front Mic", 0x3 }, 15392 { "Line", 0x1 }, 15393 { "CD", 0x4 }, 15394 { "Mixer", 0x5 }, 15395 }, 15396}; 15397 15398static hda_nid_t alc861_look_for_dac(struct hda_codec *codec, hda_nid_t pin) 15399{ 15400 struct alc_spec *spec = codec->spec; 15401 hda_nid_t mix, srcs[5]; 15402 int i, j, num; 15403 15404 if (snd_hda_get_connections(codec, pin, &mix, 1) != 1) 15405 return 0; 15406 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs)); 15407 if (num < 0) 15408 return 0; 15409 for (i = 0; i < num; i++) { 15410 unsigned int type; 15411 type = get_wcaps_type(get_wcaps(codec, srcs[i])); 15412 if (type != AC_WID_AUD_OUT) 15413 continue; 15414 for (j = 0; j < spec->multiout.num_dacs; j++) 15415 if (spec->multiout.dac_nids[j] == srcs[i]) 15416 break; 15417 if (j >= spec->multiout.num_dacs) 15418 return srcs[i]; 15419 } 15420 return 0; 15421} 15422 15423/* fill in the dac_nids table from the parsed pin configuration */ 15424static int alc861_auto_fill_dac_nids(struct hda_codec *codec, 15425 const struct auto_pin_cfg *cfg) 15426{ 15427 struct alc_spec *spec = codec->spec; 15428 int i; 15429 hda_nid_t nid, dac; 15430 15431 spec->multiout.dac_nids = spec->private_dac_nids; 15432 for (i = 0; i < cfg->line_outs; i++) { 15433 nid = cfg->line_out_pins[i]; 15434 dac = alc861_look_for_dac(codec, nid); 15435 if (!dac) 15436 continue; 15437 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac; 15438 } 15439 return 0; 15440} 15441 15442static int alc861_create_out_sw(struct hda_codec *codec, const char *pfx, 15443 hda_nid_t nid, unsigned int chs) 15444{ 15445 return add_pb_sw_ctrl(codec->spec, ALC_CTL_WIDGET_MUTE, pfx, 15446 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT)); 15447} 15448 15449/* add playback controls from the parsed DAC table */ 15450static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec, 15451 const struct auto_pin_cfg *cfg) 15452{ 15453 struct alc_spec *spec = codec->spec; 15454 static const char *chname[4] = { 15455 "Front", "Surround", NULL /*CLFE*/, "Side" 15456 }; 15457 hda_nid_t nid; 15458 int i, err; 15459 15460 if (cfg->line_outs == 1) { 15461 const char *pfx = NULL; 15462 if (!cfg->hp_outs) 15463 pfx = "Master"; 15464 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) 15465 pfx = "Speaker"; 15466 if (pfx) { 15467 nid = spec->multiout.dac_nids[0]; 15468 return alc861_create_out_sw(codec, pfx, nid, 3); 15469 } 15470 } 15471 15472 for (i = 0; i < cfg->line_outs; i++) { 15473 nid = spec->multiout.dac_nids[i]; 15474 if (!nid) 15475 continue; 15476 if (i == 2) { 15477 /* Center/LFE */ 15478 err = alc861_create_out_sw(codec, "Center", nid, 1); 15479 if (err < 0) 15480 return err; 15481 err = alc861_create_out_sw(codec, "LFE", nid, 2); 15482 if (err < 0) 15483 return err; 15484 } else { 15485 err = alc861_create_out_sw(codec, chname[i], nid, 3); 15486 if (err < 0) 15487 return err; 15488 } 15489 } 15490 return 0; 15491} 15492 15493static int alc861_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin) 15494{ 15495 struct alc_spec *spec = codec->spec; 15496 int err; 15497 hda_nid_t nid; 15498 15499 if (!pin) 15500 return 0; 15501 15502 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) { 15503 nid = alc861_look_for_dac(codec, pin); 15504 if (nid) { 15505 err = alc861_create_out_sw(codec, "Headphone", nid, 3); 15506 if (err < 0) 15507 return err; 15508 spec->multiout.hp_nid = nid; 15509 } 15510 } 15511 return 0; 15512} 15513 15514/* create playback/capture controls for input pins */ 15515static int alc861_auto_create_input_ctls(struct hda_codec *codec, 15516 const struct auto_pin_cfg *cfg) 15517{ 15518 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x08, 0); 15519} 15520 15521static void alc861_auto_set_output_and_unmute(struct hda_codec *codec, 15522 hda_nid_t nid, 15523 int pin_type, hda_nid_t dac) 15524{ 15525 hda_nid_t mix, srcs[5]; 15526 int i, num; 15527 15528 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 15529 pin_type); 15530 snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE, 15531 AMP_OUT_UNMUTE); 15532 if (snd_hda_get_connections(codec, nid, &mix, 1) != 1) 15533 return; 15534 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs)); 15535 if (num < 0) 15536 return; 15537 for (i = 0; i < num; i++) { 15538 unsigned int mute; 15539 if (srcs[i] == dac || srcs[i] == 0x15) 15540 mute = AMP_IN_UNMUTE(i); 15541 else 15542 mute = AMP_IN_MUTE(i); 15543 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE, 15544 mute); 15545 } 15546} 15547 15548static void alc861_auto_init_multi_out(struct hda_codec *codec) 15549{ 15550 struct alc_spec *spec = codec->spec; 15551 int i; 15552 15553 for (i = 0; i < spec->autocfg.line_outs; i++) { 15554 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 15555 int pin_type = get_pin_type(spec->autocfg.line_out_type); 15556 if (nid) 15557 alc861_auto_set_output_and_unmute(codec, nid, pin_type, 15558 spec->multiout.dac_nids[i]); 15559 } 15560} 15561 15562static void alc861_auto_init_hp_out(struct hda_codec *codec) 15563{ 15564 struct alc_spec *spec = codec->spec; 15565 15566 if (spec->autocfg.hp_outs) 15567 alc861_auto_set_output_and_unmute(codec, 15568 spec->autocfg.hp_pins[0], 15569 PIN_HP, 15570 spec->multiout.hp_nid); 15571 if (spec->autocfg.speaker_outs) 15572 alc861_auto_set_output_and_unmute(codec, 15573 spec->autocfg.speaker_pins[0], 15574 PIN_OUT, 15575 spec->multiout.dac_nids[0]); 15576} 15577 15578static void alc861_auto_init_analog_input(struct hda_codec *codec) 15579{ 15580 struct alc_spec *spec = codec->spec; 15581 struct auto_pin_cfg *cfg = &spec->autocfg; 15582 int i; 15583 15584 for (i = 0; i < cfg->num_inputs; i++) { 15585 hda_nid_t nid = cfg->inputs[i].pin; 15586 if (nid >= 0x0c && nid <= 0x11) 15587 alc_set_input_pin(codec, nid, i); 15588 } 15589} 15590 15591/* parse the BIOS configuration and set up the alc_spec */ 15592/* return 1 if successful, 0 if the proper config is not found, 15593 * or a negative error code 15594 */ 15595static int alc861_parse_auto_config(struct hda_codec *codec) 15596{ 15597 struct alc_spec *spec = codec->spec; 15598 int err; 15599 static hda_nid_t alc861_ignore[] = { 0x1d, 0 }; 15600 15601 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 15602 alc861_ignore); 15603 if (err < 0) 15604 return err; 15605 if (!spec->autocfg.line_outs) 15606 return 0; /* can't find valid BIOS pin config */ 15607 15608 err = alc861_auto_fill_dac_nids(codec, &spec->autocfg); 15609 if (err < 0) 15610 return err; 15611 err = alc861_auto_create_multi_out_ctls(codec, &spec->autocfg); 15612 if (err < 0) 15613 return err; 15614 err = alc861_auto_create_hp_ctls(codec, spec->autocfg.hp_pins[0]); 15615 if (err < 0) 15616 return err; 15617 err = alc861_auto_create_input_ctls(codec, &spec->autocfg); 15618 if (err < 0) 15619 return err; 15620 15621 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 15622 15623 alc_auto_parse_digital(codec); 15624 15625 if (spec->kctls.list) 15626 add_mixer(spec, spec->kctls.list); 15627 15628 add_verb(spec, alc861_auto_init_verbs); 15629 15630 spec->num_mux_defs = 1; 15631 spec->input_mux = &spec->private_imux[0]; 15632 15633 spec->adc_nids = alc861_adc_nids; 15634 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids); 15635 set_capture_mixer(codec); 15636 15637 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b, 0); 15638 15639 return 1; 15640} 15641 15642/* additional initialization for auto-configuration model */ 15643static void alc861_auto_init(struct hda_codec *codec) 15644{ 15645 struct alc_spec *spec = codec->spec; 15646 alc861_auto_init_multi_out(codec); 15647 alc861_auto_init_hp_out(codec); 15648 alc861_auto_init_analog_input(codec); 15649 alc_auto_init_digital(codec); 15650 if (spec->unsol_event) 15651 alc_inithook(codec); 15652} 15653 15654#ifdef CONFIG_SND_HDA_POWER_SAVE 15655static struct hda_amp_list alc861_loopbacks[] = { 15656 { 0x15, HDA_INPUT, 0 }, 15657 { 0x15, HDA_INPUT, 1 }, 15658 { 0x15, HDA_INPUT, 2 }, 15659 { 0x15, HDA_INPUT, 3 }, 15660 { } /* end */ 15661}; 15662#endif 15663 15664 15665/* 15666 * configuration and preset 15667 */ 15668static const char *alc861_models[ALC861_MODEL_LAST] = { 15669 [ALC861_3ST] = "3stack", 15670 [ALC660_3ST] = "3stack-660", 15671 [ALC861_3ST_DIG] = "3stack-dig", 15672 [ALC861_6ST_DIG] = "6stack-dig", 15673 [ALC861_UNIWILL_M31] = "uniwill-m31", 15674 [ALC861_TOSHIBA] = "toshiba", 15675 [ALC861_ASUS] = "asus", 15676 [ALC861_ASUS_LAPTOP] = "asus-laptop", 15677 [ALC861_AUTO] = "auto", 15678}; 15679 15680static struct snd_pci_quirk alc861_cfg_tbl[] = { 15681 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST), 15682 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP), 15683 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP), 15684 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS), 15685 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP), 15686 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG), 15687 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA), 15688 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!) 15689 * Any other models that need this preset? 15690 */ 15691 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */ 15692 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST), 15693 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST), 15694 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31), 15695 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31), 15696 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP), 15697 /* FIXME: the below seems conflict */ 15698 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */ 15699 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST), 15700 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST), 15701 {} 15702}; 15703 15704static struct alc_config_preset alc861_presets[] = { 15705 [ALC861_3ST] = { 15706 .mixers = { alc861_3ST_mixer }, 15707 .init_verbs = { alc861_threestack_init_verbs }, 15708 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 15709 .dac_nids = alc861_dac_nids, 15710 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes), 15711 .channel_mode = alc861_threestack_modes, 15712 .need_dac_fix = 1, 15713 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 15714 .adc_nids = alc861_adc_nids, 15715 .input_mux = &alc861_capture_source, 15716 }, 15717 [ALC861_3ST_DIG] = { 15718 .mixers = { alc861_base_mixer }, 15719 .init_verbs = { alc861_threestack_init_verbs }, 15720 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 15721 .dac_nids = alc861_dac_nids, 15722 .dig_out_nid = ALC861_DIGOUT_NID, 15723 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes), 15724 .channel_mode = alc861_threestack_modes, 15725 .need_dac_fix = 1, 15726 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 15727 .adc_nids = alc861_adc_nids, 15728 .input_mux = &alc861_capture_source, 15729 }, 15730 [ALC861_6ST_DIG] = { 15731 .mixers = { alc861_base_mixer }, 15732 .init_verbs = { alc861_base_init_verbs }, 15733 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 15734 .dac_nids = alc861_dac_nids, 15735 .dig_out_nid = ALC861_DIGOUT_NID, 15736 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes), 15737 .channel_mode = alc861_8ch_modes, 15738 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 15739 .adc_nids = alc861_adc_nids, 15740 .input_mux = &alc861_capture_source, 15741 }, 15742 [ALC660_3ST] = { 15743 .mixers = { alc861_3ST_mixer }, 15744 .init_verbs = { alc861_threestack_init_verbs }, 15745 .num_dacs = ARRAY_SIZE(alc660_dac_nids), 15746 .dac_nids = alc660_dac_nids, 15747 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes), 15748 .channel_mode = alc861_threestack_modes, 15749 .need_dac_fix = 1, 15750 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 15751 .adc_nids = alc861_adc_nids, 15752 .input_mux = &alc861_capture_source, 15753 }, 15754 [ALC861_UNIWILL_M31] = { 15755 .mixers = { alc861_uniwill_m31_mixer }, 15756 .init_verbs = { alc861_uniwill_m31_init_verbs }, 15757 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 15758 .dac_nids = alc861_dac_nids, 15759 .dig_out_nid = ALC861_DIGOUT_NID, 15760 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes), 15761 .channel_mode = alc861_uniwill_m31_modes, 15762 .need_dac_fix = 1, 15763 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 15764 .adc_nids = alc861_adc_nids, 15765 .input_mux = &alc861_capture_source, 15766 }, 15767 [ALC861_TOSHIBA] = { 15768 .mixers = { alc861_toshiba_mixer }, 15769 .init_verbs = { alc861_base_init_verbs, 15770 alc861_toshiba_init_verbs }, 15771 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 15772 .dac_nids = alc861_dac_nids, 15773 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 15774 .channel_mode = alc883_3ST_2ch_modes, 15775 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 15776 .adc_nids = alc861_adc_nids, 15777 .input_mux = &alc861_capture_source, 15778 .unsol_event = alc861_toshiba_unsol_event, 15779 .init_hook = alc861_toshiba_automute, 15780 }, 15781 [ALC861_ASUS] = { 15782 .mixers = { alc861_asus_mixer }, 15783 .init_verbs = { alc861_asus_init_verbs }, 15784 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 15785 .dac_nids = alc861_dac_nids, 15786 .dig_out_nid = ALC861_DIGOUT_NID, 15787 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes), 15788 .channel_mode = alc861_asus_modes, 15789 .need_dac_fix = 1, 15790 .hp_nid = 0x06, 15791 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 15792 .adc_nids = alc861_adc_nids, 15793 .input_mux = &alc861_capture_source, 15794 }, 15795 [ALC861_ASUS_LAPTOP] = { 15796 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer }, 15797 .init_verbs = { alc861_asus_init_verbs, 15798 alc861_asus_laptop_init_verbs }, 15799 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 15800 .dac_nids = alc861_dac_nids, 15801 .dig_out_nid = ALC861_DIGOUT_NID, 15802 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 15803 .channel_mode = alc883_3ST_2ch_modes, 15804 .need_dac_fix = 1, 15805 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 15806 .adc_nids = alc861_adc_nids, 15807 .input_mux = &alc861_capture_source, 15808 }, 15809}; 15810 15811/* Pin config fixes */ 15812enum { 15813 PINFIX_FSC_AMILO_PI1505, 15814}; 15815 15816static const struct alc_fixup alc861_fixups[] = { 15817 [PINFIX_FSC_AMILO_PI1505] = { 15818 .pins = (const struct alc_pincfg[]) { 15819 { 0x0b, 0x0221101f }, /* HP */ 15820 { 0x0f, 0x90170310 }, /* speaker */ 15821 { } 15822 } 15823 }, 15824}; 15825 15826static struct snd_pci_quirk alc861_fixup_tbl[] = { 15827 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505), 15828 {} 15829}; 15830 15831static int patch_alc861(struct hda_codec *codec) 15832{ 15833 struct alc_spec *spec; 15834 int board_config; 15835 int err; 15836 15837 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 15838 if (spec == NULL) 15839 return -ENOMEM; 15840 15841 codec->spec = spec; 15842 15843 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST, 15844 alc861_models, 15845 alc861_cfg_tbl); 15846 15847 if (board_config < 0) { 15848 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 15849 codec->chip_name); 15850 board_config = ALC861_AUTO; 15851 } 15852 15853 if (board_config == ALC861_AUTO) 15854 alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups, 1); 15855 15856 if (board_config == ALC861_AUTO) { 15857 /* automatic parse from the BIOS config */ 15858 err = alc861_parse_auto_config(codec); 15859 if (err < 0) { 15860 alc_free(codec); 15861 return err; 15862 } else if (!err) { 15863 printk(KERN_INFO 15864 "hda_codec: Cannot set up configuration " 15865 "from BIOS. Using base mode...\n"); 15866 board_config = ALC861_3ST_DIG; 15867 } 15868 } 15869 15870 err = snd_hda_attach_beep_device(codec, 0x23); 15871 if (err < 0) { 15872 alc_free(codec); 15873 return err; 15874 } 15875 15876 if (board_config != ALC861_AUTO) 15877 setup_preset(codec, &alc861_presets[board_config]); 15878 15879 spec->stream_analog_playback = &alc861_pcm_analog_playback; 15880 spec->stream_analog_capture = &alc861_pcm_analog_capture; 15881 15882 spec->stream_digital_playback = &alc861_pcm_digital_playback; 15883 spec->stream_digital_capture = &alc861_pcm_digital_capture; 15884 15885 if (!spec->cap_mixer) 15886 set_capture_mixer(codec); 15887 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT); 15888 15889 spec->vmaster_nid = 0x03; 15890 15891 if (board_config == ALC861_AUTO) 15892 alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups, 0); 15893 15894 codec->patch_ops = alc_patch_ops; 15895 if (board_config == ALC861_AUTO) { 15896 spec->init_hook = alc861_auto_init; 15897#ifdef CONFIG_SND_HDA_POWER_SAVE 15898 spec->power_hook = alc_power_eapd; 15899#endif 15900 } 15901#ifdef CONFIG_SND_HDA_POWER_SAVE 15902 if (!spec->loopback.amplist) 15903 spec->loopback.amplist = alc861_loopbacks; 15904#endif 15905 15906 return 0; 15907} 15908 15909/* 15910 * ALC861-VD support 15911 * 15912 * Based on ALC882 15913 * 15914 * In addition, an independent DAC 15915 */ 15916#define ALC861VD_DIGOUT_NID 0x06 15917 15918static hda_nid_t alc861vd_dac_nids[4] = { 15919 /* front, surr, clfe, side surr */ 15920 0x02, 0x03, 0x04, 0x05 15921}; 15922 15923/* dac_nids for ALC660vd are in a different order - according to 15924 * Realtek's driver. 15925 * This should probably result in a different mixer for 6stack models 15926 * of ALC660vd codecs, but for now there is only 3stack mixer 15927 * - and it is the same as in 861vd. 15928 * adc_nids in ALC660vd are (is) the same as in 861vd 15929 */ 15930static hda_nid_t alc660vd_dac_nids[3] = { 15931 /* front, rear, clfe, rear_surr */ 15932 0x02, 0x04, 0x03 15933}; 15934 15935static hda_nid_t alc861vd_adc_nids[1] = { 15936 /* ADC0 */ 15937 0x09, 15938}; 15939 15940static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 }; 15941 15942/* input MUX */ 15943/* FIXME: should be a matrix-type input source selection */ 15944static struct hda_input_mux alc861vd_capture_source = { 15945 .num_items = 4, 15946 .items = { 15947 { "Mic", 0x0 }, 15948 { "Front Mic", 0x1 }, 15949 { "Line", 0x2 }, 15950 { "CD", 0x4 }, 15951 }, 15952}; 15953 15954static struct hda_input_mux alc861vd_dallas_capture_source = { 15955 .num_items = 2, 15956 .items = { 15957 { "Ext Mic", 0x0 }, 15958 { "Int Mic", 0x1 }, 15959 }, 15960}; 15961 15962static struct hda_input_mux alc861vd_hp_capture_source = { 15963 .num_items = 2, 15964 .items = { 15965 { "Front Mic", 0x0 }, 15966 { "ATAPI Mic", 0x1 }, 15967 }, 15968}; 15969 15970/* 15971 * 2ch mode 15972 */ 15973static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = { 15974 { 2, NULL } 15975}; 15976 15977/* 15978 * 6ch mode 15979 */ 15980static struct hda_verb alc861vd_6stack_ch6_init[] = { 15981 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 15982 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 15983 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 15984 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 15985 { } /* end */ 15986}; 15987 15988/* 15989 * 8ch mode 15990 */ 15991static struct hda_verb alc861vd_6stack_ch8_init[] = { 15992 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 15993 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 15994 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 15995 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 15996 { } /* end */ 15997}; 15998 15999static struct hda_channel_mode alc861vd_6stack_modes[2] = { 16000 { 6, alc861vd_6stack_ch6_init }, 16001 { 8, alc861vd_6stack_ch8_init }, 16002}; 16003 16004static struct snd_kcontrol_new alc861vd_chmode_mixer[] = { 16005 { 16006 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 16007 .name = "Channel Mode", 16008 .info = alc_ch_mode_info, 16009 .get = alc_ch_mode_get, 16010 .put = alc_ch_mode_put, 16011 }, 16012 { } /* end */ 16013}; 16014 16015/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 16016 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b 16017 */ 16018static struct snd_kcontrol_new alc861vd_6st_mixer[] = { 16019 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 16020 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 16021 16022 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT), 16023 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 16024 16025 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, 16026 HDA_OUTPUT), 16027 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, 16028 HDA_OUTPUT), 16029 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 16030 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 16031 16032 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT), 16033 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 16034 16035 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 16036 16037 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 16038 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 16039 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 16040 16041 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 16042 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 16043 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 16044 16045 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 16046 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 16047 16048 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 16049 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 16050 16051 { } /* end */ 16052}; 16053 16054static struct snd_kcontrol_new alc861vd_3st_mixer[] = { 16055 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 16056 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 16057 16058 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 16059 16060 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 16061 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 16062 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 16063 16064 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 16065 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 16066 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 16067 16068 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 16069 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 16070 16071 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 16072 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 16073 16074 { } /* end */ 16075}; 16076 16077static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = { 16078 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 16079 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/ 16080 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 16081 16082 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 16083 16084 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 16085 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 16086 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 16087 16088 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 16089 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 16090 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 16091 16092 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 16093 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 16094 16095 { } /* end */ 16096}; 16097 16098/* Pin assignment: Speaker=0x14, HP = 0x15, 16099 * Ext Mic=0x18, Int Mic = 0x19, CD = 0x1c, PC Beep = 0x1d 16100 */ 16101static struct snd_kcontrol_new alc861vd_dallas_mixer[] = { 16102 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 16103 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT), 16104 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 16105 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT), 16106 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT), 16107 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 16108 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 16109 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 16110 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 16111 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 16112 { } /* end */ 16113}; 16114 16115/* Pin assignment: Speaker=0x14, Line-out = 0x15, 16116 * Front Mic=0x18, ATAPI Mic = 0x19, 16117 */ 16118static struct snd_kcontrol_new alc861vd_hp_mixer[] = { 16119 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 16120 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 16121 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 16122 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT), 16123 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 16124 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 16125 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 16126 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 16127 16128 { } /* end */ 16129}; 16130 16131/* 16132 * generic initialization of ADC, input mixers and output mixers 16133 */ 16134static struct hda_verb alc861vd_volume_init_verbs[] = { 16135 /* 16136 * Unmute ADC0 and set the default input to mic-in 16137 */ 16138 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 16139 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 16140 16141 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of 16142 * the analog-loopback mixer widget 16143 */ 16144 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 16145 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 16146 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 16147 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 16148 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 16149 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 16150 16151 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */ 16152 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 16153 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 16154 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 16155 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, 16156 16157 /* 16158 * Set up output mixers (0x02 - 0x05) 16159 */ 16160 /* set vol=0 to output mixers */ 16161 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 16162 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 16163 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 16164 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 16165 16166 /* set up input amps for analog loopback */ 16167 /* Amp Indices: DAC = 0, mixer = 1 */ 16168 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 16169 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 16170 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 16171 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 16172 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 16173 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 16174 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 16175 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 16176 16177 { } 16178}; 16179 16180/* 16181 * 3-stack pin configuration: 16182 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b 16183 */ 16184static struct hda_verb alc861vd_3stack_init_verbs[] = { 16185 /* 16186 * Set pin mode and muting 16187 */ 16188 /* set front pin widgets 0x14 for output */ 16189 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 16190 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 16191 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 16192 16193 /* Mic (rear) pin: input vref at 80% */ 16194 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 16195 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 16196 /* Front Mic pin: input vref at 80% */ 16197 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 16198 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 16199 /* Line In pin: input */ 16200 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 16201 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 16202 /* Line-2 In: Headphone output (output 0 - 0x0c) */ 16203 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 16204 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 16205 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 16206 /* CD pin widget for input */ 16207 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 16208 16209 { } 16210}; 16211 16212/* 16213 * 6-stack pin configuration: 16214 */ 16215static struct hda_verb alc861vd_6stack_init_verbs[] = { 16216 /* 16217 * Set pin mode and muting 16218 */ 16219 /* set front pin widgets 0x14 for output */ 16220 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 16221 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 16222 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 16223 16224 /* Rear Pin: output 1 (0x0d) */ 16225 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 16226 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 16227 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 16228 /* CLFE Pin: output 2 (0x0e) */ 16229 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 16230 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 16231 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, 16232 /* Side Pin: output 3 (0x0f) */ 16233 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 16234 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 16235 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, 16236 16237 /* Mic (rear) pin: input vref at 80% */ 16238 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 16239 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 16240 /* Front Mic pin: input vref at 80% */ 16241 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 16242 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 16243 /* Line In pin: input */ 16244 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 16245 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 16246 /* Line-2 In: Headphone output (output 0 - 0x0c) */ 16247 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 16248 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 16249 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 16250 /* CD pin widget for input */ 16251 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 16252 16253 { } 16254}; 16255 16256static struct hda_verb alc861vd_eapd_verbs[] = { 16257 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 16258 { } 16259}; 16260 16261static struct hda_verb alc660vd_eapd_verbs[] = { 16262 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 16263 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, 16264 { } 16265}; 16266 16267static struct hda_verb alc861vd_lenovo_unsol_verbs[] = { 16268 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 16269 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 16270 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, 16271 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 16272 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 16273 {} 16274}; 16275 16276static void alc861vd_lenovo_mic_automute(struct hda_codec *codec) 16277{ 16278 unsigned int present; 16279 unsigned char bits; 16280 16281 present = snd_hda_jack_detect(codec, 0x18); 16282 bits = present ? HDA_AMP_MUTE : 0; 16283 16284 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, 16285 HDA_AMP_MUTE, bits); 16286} 16287 16288static void alc861vd_lenovo_setup(struct hda_codec *codec) 16289{ 16290 struct alc_spec *spec = codec->spec; 16291 spec->autocfg.hp_pins[0] = 0x1b; 16292 spec->autocfg.speaker_pins[0] = 0x14; 16293} 16294 16295static void alc861vd_lenovo_init_hook(struct hda_codec *codec) 16296{ 16297 alc_automute_amp(codec); 16298 alc861vd_lenovo_mic_automute(codec); 16299} 16300 16301static void alc861vd_lenovo_unsol_event(struct hda_codec *codec, 16302 unsigned int res) 16303{ 16304 switch (res >> 26) { 16305 case ALC880_MIC_EVENT: 16306 alc861vd_lenovo_mic_automute(codec); 16307 break; 16308 default: 16309 alc_automute_amp_unsol_event(codec, res); 16310 break; 16311 } 16312} 16313 16314static struct hda_verb alc861vd_dallas_verbs[] = { 16315 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 16316 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 16317 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 16318 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 16319 16320 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 16321 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 16322 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 16323 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 16324 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 16325 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 16326 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 16327 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 16328 16329 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 16330 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 16331 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 16332 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 16333 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 16334 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 16335 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 16336 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 16337 16338 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, 16339 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 16340 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, 16341 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 16342 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 16343 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 16344 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 16345 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 16346 16347 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 16348 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 16349 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 16350 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 16351 16352 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 16353 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 16354 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 16355 16356 { } /* end */ 16357}; 16358 16359/* toggle speaker-output according to the hp-jack state */ 16360static void alc861vd_dallas_setup(struct hda_codec *codec) 16361{ 16362 struct alc_spec *spec = codec->spec; 16363 16364 spec->autocfg.hp_pins[0] = 0x15; 16365 spec->autocfg.speaker_pins[0] = 0x14; 16366} 16367 16368#ifdef CONFIG_SND_HDA_POWER_SAVE 16369#define alc861vd_loopbacks alc880_loopbacks 16370#endif 16371 16372/* pcm configuration: identical with ALC880 */ 16373#define alc861vd_pcm_analog_playback alc880_pcm_analog_playback 16374#define alc861vd_pcm_analog_capture alc880_pcm_analog_capture 16375#define alc861vd_pcm_digital_playback alc880_pcm_digital_playback 16376#define alc861vd_pcm_digital_capture alc880_pcm_digital_capture 16377 16378/* 16379 * configuration and preset 16380 */ 16381static const char *alc861vd_models[ALC861VD_MODEL_LAST] = { 16382 [ALC660VD_3ST] = "3stack-660", 16383 [ALC660VD_3ST_DIG] = "3stack-660-digout", 16384 [ALC660VD_ASUS_V1S] = "asus-v1s", 16385 [ALC861VD_3ST] = "3stack", 16386 [ALC861VD_3ST_DIG] = "3stack-digout", 16387 [ALC861VD_6ST_DIG] = "6stack-digout", 16388 [ALC861VD_LENOVO] = "lenovo", 16389 [ALC861VD_DALLAS] = "dallas", 16390 [ALC861VD_HP] = "hp", 16391 [ALC861VD_AUTO] = "auto", 16392}; 16393 16394static struct snd_pci_quirk alc861vd_cfg_tbl[] = { 16395 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST), 16396 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP), 16397 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST), 16398 /*SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),*/ /* auto */ 16399 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S), 16400 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG), 16401 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST), 16402 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO), 16403 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/ 16404 SND_PCI_QUIRK(0x1179, 0xff01, "Toshiba A135", ALC861VD_LENOVO), 16405 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO), 16406 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS), 16407 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG), 16408 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO), 16409 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG), 16410 {} 16411}; 16412 16413static struct alc_config_preset alc861vd_presets[] = { 16414 [ALC660VD_3ST] = { 16415 .mixers = { alc861vd_3st_mixer }, 16416 .init_verbs = { alc861vd_volume_init_verbs, 16417 alc861vd_3stack_init_verbs }, 16418 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids), 16419 .dac_nids = alc660vd_dac_nids, 16420 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 16421 .channel_mode = alc861vd_3stack_2ch_modes, 16422 .input_mux = &alc861vd_capture_source, 16423 }, 16424 [ALC660VD_3ST_DIG] = { 16425 .mixers = { alc861vd_3st_mixer }, 16426 .init_verbs = { alc861vd_volume_init_verbs, 16427 alc861vd_3stack_init_verbs }, 16428 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids), 16429 .dac_nids = alc660vd_dac_nids, 16430 .dig_out_nid = ALC861VD_DIGOUT_NID, 16431 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 16432 .channel_mode = alc861vd_3stack_2ch_modes, 16433 .input_mux = &alc861vd_capture_source, 16434 }, 16435 [ALC861VD_3ST] = { 16436 .mixers = { alc861vd_3st_mixer }, 16437 .init_verbs = { alc861vd_volume_init_verbs, 16438 alc861vd_3stack_init_verbs }, 16439 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids), 16440 .dac_nids = alc861vd_dac_nids, 16441 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 16442 .channel_mode = alc861vd_3stack_2ch_modes, 16443 .input_mux = &alc861vd_capture_source, 16444 }, 16445 [ALC861VD_3ST_DIG] = { 16446 .mixers = { alc861vd_3st_mixer }, 16447 .init_verbs = { alc861vd_volume_init_verbs, 16448 alc861vd_3stack_init_verbs }, 16449 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids), 16450 .dac_nids = alc861vd_dac_nids, 16451 .dig_out_nid = ALC861VD_DIGOUT_NID, 16452 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 16453 .channel_mode = alc861vd_3stack_2ch_modes, 16454 .input_mux = &alc861vd_capture_source, 16455 }, 16456 [ALC861VD_6ST_DIG] = { 16457 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer }, 16458 .init_verbs = { alc861vd_volume_init_verbs, 16459 alc861vd_6stack_init_verbs }, 16460 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids), 16461 .dac_nids = alc861vd_dac_nids, 16462 .dig_out_nid = ALC861VD_DIGOUT_NID, 16463 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes), 16464 .channel_mode = alc861vd_6stack_modes, 16465 .input_mux = &alc861vd_capture_source, 16466 }, 16467 [ALC861VD_LENOVO] = { 16468 .mixers = { alc861vd_lenovo_mixer }, 16469 .init_verbs = { alc861vd_volume_init_verbs, 16470 alc861vd_3stack_init_verbs, 16471 alc861vd_eapd_verbs, 16472 alc861vd_lenovo_unsol_verbs }, 16473 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids), 16474 .dac_nids = alc660vd_dac_nids, 16475 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 16476 .channel_mode = alc861vd_3stack_2ch_modes, 16477 .input_mux = &alc861vd_capture_source, 16478 .unsol_event = alc861vd_lenovo_unsol_event, 16479 .setup = alc861vd_lenovo_setup, 16480 .init_hook = alc861vd_lenovo_init_hook, 16481 }, 16482 [ALC861VD_DALLAS] = { 16483 .mixers = { alc861vd_dallas_mixer }, 16484 .init_verbs = { alc861vd_dallas_verbs }, 16485 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids), 16486 .dac_nids = alc861vd_dac_nids, 16487 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 16488 .channel_mode = alc861vd_3stack_2ch_modes, 16489 .input_mux = &alc861vd_dallas_capture_source, 16490 .unsol_event = alc_automute_amp_unsol_event, 16491 .setup = alc861vd_dallas_setup, 16492 .init_hook = alc_automute_amp, 16493 }, 16494 [ALC861VD_HP] = { 16495 .mixers = { alc861vd_hp_mixer }, 16496 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs }, 16497 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids), 16498 .dac_nids = alc861vd_dac_nids, 16499 .dig_out_nid = ALC861VD_DIGOUT_NID, 16500 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 16501 .channel_mode = alc861vd_3stack_2ch_modes, 16502 .input_mux = &alc861vd_hp_capture_source, 16503 .unsol_event = alc_automute_amp_unsol_event, 16504 .setup = alc861vd_dallas_setup, 16505 .init_hook = alc_automute_amp, 16506 }, 16507 [ALC660VD_ASUS_V1S] = { 16508 .mixers = { alc861vd_lenovo_mixer }, 16509 .init_verbs = { alc861vd_volume_init_verbs, 16510 alc861vd_3stack_init_verbs, 16511 alc861vd_eapd_verbs, 16512 alc861vd_lenovo_unsol_verbs }, 16513 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids), 16514 .dac_nids = alc660vd_dac_nids, 16515 .dig_out_nid = ALC861VD_DIGOUT_NID, 16516 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 16517 .channel_mode = alc861vd_3stack_2ch_modes, 16518 .input_mux = &alc861vd_capture_source, 16519 .unsol_event = alc861vd_lenovo_unsol_event, 16520 .setup = alc861vd_lenovo_setup, 16521 .init_hook = alc861vd_lenovo_init_hook, 16522 }, 16523}; 16524 16525/* 16526 * BIOS auto configuration 16527 */ 16528static int alc861vd_auto_create_input_ctls(struct hda_codec *codec, 16529 const struct auto_pin_cfg *cfg) 16530{ 16531 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x09, 0); 16532} 16533 16534 16535static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec, 16536 hda_nid_t nid, int pin_type, int dac_idx) 16537{ 16538 alc_set_pin_output(codec, nid, pin_type); 16539} 16540 16541static void alc861vd_auto_init_multi_out(struct hda_codec *codec) 16542{ 16543 struct alc_spec *spec = codec->spec; 16544 int i; 16545 16546 for (i = 0; i <= HDA_SIDE; i++) { 16547 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 16548 int pin_type = get_pin_type(spec->autocfg.line_out_type); 16549 if (nid) 16550 alc861vd_auto_set_output_and_unmute(codec, nid, 16551 pin_type, i); 16552 } 16553} 16554 16555 16556static void alc861vd_auto_init_hp_out(struct hda_codec *codec) 16557{ 16558 struct alc_spec *spec = codec->spec; 16559 hda_nid_t pin; 16560 16561 pin = spec->autocfg.hp_pins[0]; 16562 if (pin) /* connect to front and use dac 0 */ 16563 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); 16564 pin = spec->autocfg.speaker_pins[0]; 16565 if (pin) 16566 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0); 16567} 16568 16569#define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID 16570 16571static void alc861vd_auto_init_analog_input(struct hda_codec *codec) 16572{ 16573 struct alc_spec *spec = codec->spec; 16574 struct auto_pin_cfg *cfg = &spec->autocfg; 16575 int i; 16576 16577 for (i = 0; i < cfg->num_inputs; i++) { 16578 hda_nid_t nid = cfg->inputs[i].pin; 16579 if (alc_is_input_pin(codec, nid)) { 16580 alc_set_input_pin(codec, nid, i); 16581 if (nid != ALC861VD_PIN_CD_NID && 16582 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)) 16583 snd_hda_codec_write(codec, nid, 0, 16584 AC_VERB_SET_AMP_GAIN_MUTE, 16585 AMP_OUT_MUTE); 16586 } 16587 } 16588} 16589 16590#define alc861vd_auto_init_input_src alc882_auto_init_input_src 16591 16592#define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02) 16593#define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c) 16594 16595/* add playback controls from the parsed DAC table */ 16596/* Based on ALC880 version. But ALC861VD has separate, 16597 * different NIDs for mute/unmute switch and volume control */ 16598static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec, 16599 const struct auto_pin_cfg *cfg) 16600{ 16601 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"}; 16602 hda_nid_t nid_v, nid_s; 16603 int i, err; 16604 16605 for (i = 0; i < cfg->line_outs; i++) { 16606 if (!spec->multiout.dac_nids[i]) 16607 continue; 16608 nid_v = alc861vd_idx_to_mixer_vol( 16609 alc880_dac_to_idx( 16610 spec->multiout.dac_nids[i])); 16611 nid_s = alc861vd_idx_to_mixer_switch( 16612 alc880_dac_to_idx( 16613 spec->multiout.dac_nids[i])); 16614 16615 if (i == 2) { 16616 /* Center/LFE */ 16617 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, 16618 "Center", 16619 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0, 16620 HDA_OUTPUT)); 16621 if (err < 0) 16622 return err; 16623 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, 16624 "LFE", 16625 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0, 16626 HDA_OUTPUT)); 16627 if (err < 0) 16628 return err; 16629 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, 16630 "Center", 16631 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2, 16632 HDA_INPUT)); 16633 if (err < 0) 16634 return err; 16635 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, 16636 "LFE", 16637 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2, 16638 HDA_INPUT)); 16639 if (err < 0) 16640 return err; 16641 } else { 16642 const char *pfx; 16643 if (cfg->line_outs == 1 && 16644 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) { 16645 if (!cfg->hp_pins) 16646 pfx = "Speaker"; 16647 else 16648 pfx = "PCM"; 16649 } else 16650 pfx = chname[i]; 16651 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, 16652 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, 16653 HDA_OUTPUT)); 16654 if (err < 0) 16655 return err; 16656 if (cfg->line_outs == 1 && 16657 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) 16658 pfx = "Speaker"; 16659 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx, 16660 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, 16661 HDA_INPUT)); 16662 if (err < 0) 16663 return err; 16664 } 16665 } 16666 return 0; 16667} 16668 16669/* add playback controls for speaker and HP outputs */ 16670/* Based on ALC880 version. But ALC861VD has separate, 16671 * different NIDs for mute/unmute switch and volume control */ 16672static int alc861vd_auto_create_extra_out(struct alc_spec *spec, 16673 hda_nid_t pin, const char *pfx) 16674{ 16675 hda_nid_t nid_v, nid_s; 16676 int err; 16677 16678 if (!pin) 16679 return 0; 16680 16681 if (alc880_is_fixed_pin(pin)) { 16682 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); 16683 /* specify the DAC as the extra output */ 16684 if (!spec->multiout.hp_nid) 16685 spec->multiout.hp_nid = nid_v; 16686 else 16687 spec->multiout.extra_out_nid[0] = nid_v; 16688 /* control HP volume/switch on the output mixer amp */ 16689 nid_v = alc861vd_idx_to_mixer_vol( 16690 alc880_fixed_pin_idx(pin)); 16691 nid_s = alc861vd_idx_to_mixer_switch( 16692 alc880_fixed_pin_idx(pin)); 16693 16694 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, 16695 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT)); 16696 if (err < 0) 16697 return err; 16698 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx, 16699 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT)); 16700 if (err < 0) 16701 return err; 16702 } else if (alc880_is_multi_pin(pin)) { 16703 /* set manual connection */ 16704 /* we have only a switch on HP-out PIN */ 16705 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, 16706 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); 16707 if (err < 0) 16708 return err; 16709 } 16710 return 0; 16711} 16712 16713/* parse the BIOS configuration and set up the alc_spec 16714 * return 1 if successful, 0 if the proper config is not found, 16715 * or a negative error code 16716 * Based on ALC880 version - had to change it to override 16717 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */ 16718static int alc861vd_parse_auto_config(struct hda_codec *codec) 16719{ 16720 struct alc_spec *spec = codec->spec; 16721 int err; 16722 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 }; 16723 16724 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 16725 alc861vd_ignore); 16726 if (err < 0) 16727 return err; 16728 if (!spec->autocfg.line_outs) 16729 return 0; /* can't find valid BIOS pin config */ 16730 16731 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); 16732 if (err < 0) 16733 return err; 16734 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg); 16735 if (err < 0) 16736 return err; 16737 err = alc861vd_auto_create_extra_out(spec, 16738 spec->autocfg.speaker_pins[0], 16739 "Speaker"); 16740 if (err < 0) 16741 return err; 16742 err = alc861vd_auto_create_extra_out(spec, 16743 spec->autocfg.hp_pins[0], 16744 "Headphone"); 16745 if (err < 0) 16746 return err; 16747 err = alc861vd_auto_create_input_ctls(codec, &spec->autocfg); 16748 if (err < 0) 16749 return err; 16750 16751 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 16752 16753 alc_auto_parse_digital(codec); 16754 16755 if (spec->kctls.list) 16756 add_mixer(spec, spec->kctls.list); 16757 16758 add_verb(spec, alc861vd_volume_init_verbs); 16759 16760 spec->num_mux_defs = 1; 16761 spec->input_mux = &spec->private_imux[0]; 16762 16763 err = alc_auto_add_mic_boost(codec); 16764 if (err < 0) 16765 return err; 16766 16767 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); 16768 16769 return 1; 16770} 16771 16772/* additional initialization for auto-configuration model */ 16773static void alc861vd_auto_init(struct hda_codec *codec) 16774{ 16775 struct alc_spec *spec = codec->spec; 16776 alc861vd_auto_init_multi_out(codec); 16777 alc861vd_auto_init_hp_out(codec); 16778 alc861vd_auto_init_analog_input(codec); 16779 alc861vd_auto_init_input_src(codec); 16780 alc_auto_init_digital(codec); 16781 if (spec->unsol_event) 16782 alc_inithook(codec); 16783} 16784 16785enum { 16786 ALC660VD_FIX_ASUS_GPIO1 16787}; 16788 16789/* reset GPIO1 */ 16790static const struct alc_fixup alc861vd_fixups[] = { 16791 [ALC660VD_FIX_ASUS_GPIO1] = { 16792 .verbs = (const struct hda_verb[]) { 16793 {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, 16794 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, 16795 {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, 16796 { } 16797 } 16798 }, 16799}; 16800 16801static struct snd_pci_quirk alc861vd_fixup_tbl[] = { 16802 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1), 16803 {} 16804}; 16805 16806static int patch_alc861vd(struct hda_codec *codec) 16807{ 16808 struct alc_spec *spec; 16809 int err, board_config; 16810 16811 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 16812 if (spec == NULL) 16813 return -ENOMEM; 16814 16815 codec->spec = spec; 16816 16817 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST, 16818 alc861vd_models, 16819 alc861vd_cfg_tbl); 16820 16821 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) { 16822 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 16823 codec->chip_name); 16824 board_config = ALC861VD_AUTO; 16825 } 16826 16827 if (board_config == ALC861VD_AUTO) 16828 alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups, 1); 16829 16830 if (board_config == ALC861VD_AUTO) { 16831 /* automatic parse from the BIOS config */ 16832 err = alc861vd_parse_auto_config(codec); 16833 if (err < 0) { 16834 alc_free(codec); 16835 return err; 16836 } else if (!err) { 16837 printk(KERN_INFO 16838 "hda_codec: Cannot set up configuration " 16839 "from BIOS. Using base mode...\n"); 16840 board_config = ALC861VD_3ST; 16841 } 16842 } 16843 16844 err = snd_hda_attach_beep_device(codec, 0x23); 16845 if (err < 0) { 16846 alc_free(codec); 16847 return err; 16848 } 16849 16850 if (board_config != ALC861VD_AUTO) 16851 setup_preset(codec, &alc861vd_presets[board_config]); 16852 16853 if (codec->vendor_id == 0x10ec0660) { 16854 /* always turn on EAPD */ 16855 add_verb(spec, alc660vd_eapd_verbs); 16856 } 16857 16858 spec->stream_analog_playback = &alc861vd_pcm_analog_playback; 16859 spec->stream_analog_capture = &alc861vd_pcm_analog_capture; 16860 16861 spec->stream_digital_playback = &alc861vd_pcm_digital_playback; 16862 spec->stream_digital_capture = &alc861vd_pcm_digital_capture; 16863 16864 if (!spec->adc_nids) { 16865 spec->adc_nids = alc861vd_adc_nids; 16866 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids); 16867 } 16868 if (!spec->capsrc_nids) 16869 spec->capsrc_nids = alc861vd_capsrc_nids; 16870 16871 set_capture_mixer(codec); 16872 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 16873 16874 spec->vmaster_nid = 0x02; 16875 16876 if (board_config == ALC861VD_AUTO) 16877 alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups, 0); 16878 16879 codec->patch_ops = alc_patch_ops; 16880 16881 if (board_config == ALC861VD_AUTO) 16882 spec->init_hook = alc861vd_auto_init; 16883#ifdef CONFIG_SND_HDA_POWER_SAVE 16884 if (!spec->loopback.amplist) 16885 spec->loopback.amplist = alc861vd_loopbacks; 16886#endif 16887 16888 return 0; 16889} 16890 16891/* 16892 * ALC662 support 16893 * 16894 * ALC662 is almost identical with ALC880 but has cleaner and more flexible 16895 * configuration. Each pin widget can choose any input DACs and a mixer. 16896 * Each ADC is connected from a mixer of all inputs. This makes possible 16897 * 6-channel independent captures. 16898 * 16899 * In addition, an independent DAC for the multi-playback (not used in this 16900 * driver yet). 16901 */ 16902#define ALC662_DIGOUT_NID 0x06 16903#define ALC662_DIGIN_NID 0x0a 16904 16905static hda_nid_t alc662_dac_nids[4] = { 16906 /* front, rear, clfe, rear_surr */ 16907 0x02, 0x03, 0x04 16908}; 16909 16910static hda_nid_t alc272_dac_nids[2] = { 16911 0x02, 0x03 16912}; 16913 16914static hda_nid_t alc662_adc_nids[2] = { 16915 /* ADC1-2 */ 16916 0x09, 0x08 16917}; 16918 16919static hda_nid_t alc272_adc_nids[1] = { 16920 /* ADC1-2 */ 16921 0x08, 16922}; 16923 16924static hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 }; 16925static hda_nid_t alc272_capsrc_nids[1] = { 0x23 }; 16926 16927 16928/* input MUX */ 16929/* FIXME: should be a matrix-type input source selection */ 16930static struct hda_input_mux alc662_capture_source = { 16931 .num_items = 4, 16932 .items = { 16933 { "Mic", 0x0 }, 16934 { "Front Mic", 0x1 }, 16935 { "Line", 0x2 }, 16936 { "CD", 0x4 }, 16937 }, 16938}; 16939 16940static struct hda_input_mux alc662_lenovo_101e_capture_source = { 16941 .num_items = 2, 16942 .items = { 16943 { "Mic", 0x1 }, 16944 { "Line", 0x2 }, 16945 }, 16946}; 16947 16948static struct hda_input_mux alc663_capture_source = { 16949 .num_items = 3, 16950 .items = { 16951 { "Mic", 0x0 }, 16952 { "Front Mic", 0x1 }, 16953 { "Line", 0x2 }, 16954 }, 16955}; 16956 16957#if 0 /* set to 1 for testing other input sources below */ 16958static struct hda_input_mux alc272_nc10_capture_source = { 16959 .num_items = 16, 16960 .items = { 16961 { "Autoselect Mic", 0x0 }, 16962 { "Internal Mic", 0x1 }, 16963 { "In-0x02", 0x2 }, 16964 { "In-0x03", 0x3 }, 16965 { "In-0x04", 0x4 }, 16966 { "In-0x05", 0x5 }, 16967 { "In-0x06", 0x6 }, 16968 { "In-0x07", 0x7 }, 16969 { "In-0x08", 0x8 }, 16970 { "In-0x09", 0x9 }, 16971 { "In-0x0a", 0x0a }, 16972 { "In-0x0b", 0x0b }, 16973 { "In-0x0c", 0x0c }, 16974 { "In-0x0d", 0x0d }, 16975 { "In-0x0e", 0x0e }, 16976 { "In-0x0f", 0x0f }, 16977 }, 16978}; 16979#endif 16980 16981/* 16982 * 2ch mode 16983 */ 16984static struct hda_channel_mode alc662_3ST_2ch_modes[1] = { 16985 { 2, NULL } 16986}; 16987 16988/* 16989 * 2ch mode 16990 */ 16991static struct hda_verb alc662_3ST_ch2_init[] = { 16992 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 16993 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 16994 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 16995 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 16996 { } /* end */ 16997}; 16998 16999/* 17000 * 6ch mode 17001 */ 17002static struct hda_verb alc662_3ST_ch6_init[] = { 17003 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 17004 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 17005 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, 17006 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 17007 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 17008 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 17009 { } /* end */ 17010}; 17011 17012static struct hda_channel_mode alc662_3ST_6ch_modes[2] = { 17013 { 2, alc662_3ST_ch2_init }, 17014 { 6, alc662_3ST_ch6_init }, 17015}; 17016 17017/* 17018 * 2ch mode 17019 */ 17020static struct hda_verb alc662_sixstack_ch6_init[] = { 17021 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 17022 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 17023 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 17024 { } /* end */ 17025}; 17026 17027/* 17028 * 6ch mode 17029 */ 17030static struct hda_verb alc662_sixstack_ch8_init[] = { 17031 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 17032 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 17033 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 17034 { } /* end */ 17035}; 17036 17037static struct hda_channel_mode alc662_5stack_modes[2] = { 17038 { 2, alc662_sixstack_ch6_init }, 17039 { 6, alc662_sixstack_ch8_init }, 17040}; 17041 17042/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 17043 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b 17044 */ 17045 17046static struct snd_kcontrol_new alc662_base_mixer[] = { 17047 /* output mixer control */ 17048 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), 17049 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT), 17050 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT), 17051 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT), 17052 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT), 17053 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT), 17054 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT), 17055 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT), 17056 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 17057 17058 /*Input mixer control */ 17059 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT), 17060 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT), 17061 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT), 17062 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT), 17063 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT), 17064 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT), 17065 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT), 17066 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT), 17067 { } /* end */ 17068}; 17069 17070static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = { 17071 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 17072 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT), 17073 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 17074 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 17075 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 17076 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 17077 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 17078 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17079 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17080 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 17081 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 17082 { } /* end */ 17083}; 17084 17085static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = { 17086 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 17087 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT), 17088 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT), 17089 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT), 17090 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT), 17091 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT), 17092 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT), 17093 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT), 17094 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 17095 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 17096 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 17097 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 17098 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 17099 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17100 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17101 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 17102 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 17103 { } /* end */ 17104}; 17105 17106static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = { 17107 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 17108 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT), 17109 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT), 17110 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT), 17111 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 17112 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 17113 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 17114 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 17115 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 17116 { } /* end */ 17117}; 17118 17119static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = { 17120 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT), 17121 ALC262_HIPPO_MASTER_SWITCH, 17122 17123 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT), 17124 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17125 HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17126 17127 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT), 17128 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 17129 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 17130 { } /* end */ 17131}; 17132 17133static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = { 17134 ALC262_HIPPO_MASTER_SWITCH, 17135 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 17136 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT), 17137 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT), 17138 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT), 17139 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT), 17140 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 17141 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 17142 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17143 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17144 { } /* end */ 17145}; 17146 17147static struct hda_bind_ctls alc663_asus_bind_master_vol = { 17148 .ops = &snd_hda_bind_vol, 17149 .values = { 17150 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), 17151 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT), 17152 0 17153 }, 17154}; 17155 17156static struct hda_bind_ctls alc663_asus_one_bind_switch = { 17157 .ops = &snd_hda_bind_sw, 17158 .values = { 17159 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 17160 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT), 17161 0 17162 }, 17163}; 17164 17165static struct snd_kcontrol_new alc663_m51va_mixer[] = { 17166 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol), 17167 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch), 17168 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17169 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17170 { } /* end */ 17171}; 17172 17173static struct hda_bind_ctls alc663_asus_tree_bind_switch = { 17174 .ops = &snd_hda_bind_sw, 17175 .values = { 17176 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 17177 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT), 17178 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT), 17179 0 17180 }, 17181}; 17182 17183static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = { 17184 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol), 17185 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch), 17186 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17187 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17188 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 17189 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 17190 17191 { } /* end */ 17192}; 17193 17194static struct hda_bind_ctls alc663_asus_four_bind_switch = { 17195 .ops = &snd_hda_bind_sw, 17196 .values = { 17197 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 17198 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT), 17199 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT), 17200 0 17201 }, 17202}; 17203 17204static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = { 17205 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol), 17206 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch), 17207 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17208 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17209 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 17210 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 17211 { } /* end */ 17212}; 17213 17214static struct snd_kcontrol_new alc662_1bjd_mixer[] = { 17215 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 17216 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 17217 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 17218 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17219 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17220 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 17221 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 17222 { } /* end */ 17223}; 17224 17225static struct hda_bind_ctls alc663_asus_two_bind_master_vol = { 17226 .ops = &snd_hda_bind_vol, 17227 .values = { 17228 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), 17229 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT), 17230 0 17231 }, 17232}; 17233 17234static struct hda_bind_ctls alc663_asus_two_bind_switch = { 17235 .ops = &snd_hda_bind_sw, 17236 .values = { 17237 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 17238 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT), 17239 0 17240 }, 17241}; 17242 17243static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = { 17244 HDA_BIND_VOL("Master Playback Volume", 17245 &alc663_asus_two_bind_master_vol), 17246 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch), 17247 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 17248 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT), 17249 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17250 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17251 { } /* end */ 17252}; 17253 17254static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = { 17255 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol), 17256 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch), 17257 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 17258 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 17259 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17260 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17261 { } /* end */ 17262}; 17263 17264static struct snd_kcontrol_new alc663_g71v_mixer[] = { 17265 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 17266 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 17267 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT), 17268 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT), 17269 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT), 17270 17271 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17272 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17273 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 17274 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 17275 { } /* end */ 17276}; 17277 17278static struct snd_kcontrol_new alc663_g50v_mixer[] = { 17279 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 17280 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 17281 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT), 17282 17283 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17284 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17285 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 17286 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 17287 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 17288 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 17289 { } /* end */ 17290}; 17291 17292static struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = { 17293 .ops = &snd_hda_bind_sw, 17294 .values = { 17295 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 17296 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT), 17297 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT), 17298 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT), 17299 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT), 17300 0 17301 }, 17302}; 17303 17304static struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = { 17305 .ops = &snd_hda_bind_sw, 17306 .values = { 17307 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 17308 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT), 17309 0 17310 }, 17311}; 17312 17313static struct snd_kcontrol_new alc663_mode7_mixer[] = { 17314 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch), 17315 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol), 17316 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch), 17317 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 17318 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT), 17319 HDA_CODEC_VOLUME("IntMic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17320 HDA_CODEC_MUTE("IntMic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17321 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 17322 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 17323 { } /* end */ 17324}; 17325 17326static struct snd_kcontrol_new alc663_mode8_mixer[] = { 17327 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch), 17328 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol), 17329 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch), 17330 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x15, 0x0, HDA_OUTPUT), 17331 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT), 17332 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17333 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17334 { } /* end */ 17335}; 17336 17337 17338static struct snd_kcontrol_new alc662_chmode_mixer[] = { 17339 { 17340 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 17341 .name = "Channel Mode", 17342 .info = alc_ch_mode_info, 17343 .get = alc_ch_mode_get, 17344 .put = alc_ch_mode_put, 17345 }, 17346 { } /* end */ 17347}; 17348 17349static struct hda_verb alc662_init_verbs[] = { 17350 /* ADC: mute amp left and right */ 17351 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 17352 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 17353 17354 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 17355 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 17356 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 17357 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 17358 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 17359 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 17360 17361 /* Front Pin: output 0 (0x0c) */ 17362 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 17363 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17364 17365 /* Rear Pin: output 1 (0x0d) */ 17366 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 17367 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17368 17369 /* CLFE Pin: output 2 (0x0e) */ 17370 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 17371 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17372 17373 /* Mic (rear) pin: input vref at 80% */ 17374 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 17375 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 17376 /* Front Mic pin: input vref at 80% */ 17377 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 17378 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 17379 /* Line In pin: input */ 17380 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17381 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 17382 /* Line-2 In: Headphone output (output 0 - 0x0c) */ 17383 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17384 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17385 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 17386 /* CD pin widget for input */ 17387 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17388 17389 /* FIXME: use matrix-type input source selection */ 17390 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 17391 /* Input mixer */ 17392 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 17393 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 17394 17395 /* always trun on EAPD */ 17396 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 17397 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, 17398 17399 { } 17400}; 17401 17402static struct hda_verb alc663_init_verbs[] = { 17403 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 17404 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17405 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 17406 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17407 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 17408 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 17409 { } 17410}; 17411 17412static struct hda_verb alc272_init_verbs[] = { 17413 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17414 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 17415 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 17416 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17417 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 17418 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17419 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 17420 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 17421 { } 17422}; 17423 17424static struct hda_verb alc662_sue_init_verbs[] = { 17425 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT}, 17426 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT}, 17427 {} 17428}; 17429 17430static struct hda_verb alc662_eeepc_sue_init_verbs[] = { 17431 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 17432 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17433 {} 17434}; 17435 17436/* Set Unsolicited Event*/ 17437static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = { 17438 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 17439 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17440 {} 17441}; 17442 17443static struct hda_verb alc663_m51va_init_verbs[] = { 17444 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17445 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17446 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17447 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17448 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ 17449 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 17450 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)}, 17451 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 17452 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17453 {} 17454}; 17455 17456static struct hda_verb alc663_21jd_amic_init_verbs[] = { 17457 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17458 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17459 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ 17460 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 17461 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 17462 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 17463 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17464 {} 17465}; 17466 17467static struct hda_verb alc662_1bjd_amic_init_verbs[] = { 17468 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17469 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17470 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17471 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */ 17472 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 17473 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 17474 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 17475 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17476 {} 17477}; 17478 17479static struct hda_verb alc663_15jd_amic_init_verbs[] = { 17480 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17481 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17482 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ 17483 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 17484 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 17485 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 17486 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17487 {} 17488}; 17489 17490static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = { 17491 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17492 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17493 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17494 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */ 17495 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17496 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17497 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */ 17498 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 17499 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 17500 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 17501 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17502 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17503 {} 17504}; 17505 17506static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = { 17507 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17508 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17509 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17510 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ 17511 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17512 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17513 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ 17514 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 17515 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 17516 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 17517 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17518 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17519 {} 17520}; 17521 17522static struct hda_verb alc663_g71v_init_verbs[] = { 17523 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17524 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */ 17525 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */ 17526 17527 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17528 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17529 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */ 17530 17531 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT}, 17532 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT}, 17533 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT}, 17534 {} 17535}; 17536 17537static struct hda_verb alc663_g50v_init_verbs[] = { 17538 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17539 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17540 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */ 17541 17542 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 17543 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17544 {} 17545}; 17546 17547static struct hda_verb alc662_ecs_init_verbs[] = { 17548 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f}, 17549 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 17550 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 17551 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17552 {} 17553}; 17554 17555static struct hda_verb alc272_dell_zm1_init_verbs[] = { 17556 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17557 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17558 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17559 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17560 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17561 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17562 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ 17563 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 17564 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)}, 17565 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 17566 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17567 {} 17568}; 17569 17570static struct hda_verb alc272_dell_init_verbs[] = { 17571 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17572 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17573 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17574 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17575 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17576 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17577 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ 17578 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 17579 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)}, 17580 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 17581 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17582 {} 17583}; 17584 17585static struct hda_verb alc663_mode7_init_verbs[] = { 17586 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17587 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17588 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 17589 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17590 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17591 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17592 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, 17593 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17594 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17595 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ 17596 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 17597 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)}, 17598 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 17599 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17600 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17601 {} 17602}; 17603 17604static struct hda_verb alc663_mode8_init_verbs[] = { 17605 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17606 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17607 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17608 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 17609 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17610 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 17611 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17612 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17613 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17614 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17615 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ 17616 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 17617 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)}, 17618 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17619 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 17620 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17621 {} 17622}; 17623 17624static struct snd_kcontrol_new alc662_auto_capture_mixer[] = { 17625 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), 17626 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), 17627 { } /* end */ 17628}; 17629 17630static struct snd_kcontrol_new alc272_auto_capture_mixer[] = { 17631 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 17632 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 17633 { } /* end */ 17634}; 17635 17636static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec) 17637{ 17638 unsigned int present; 17639 unsigned char bits; 17640 17641 present = snd_hda_jack_detect(codec, 0x14); 17642 bits = present ? HDA_AMP_MUTE : 0; 17643 17644 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 17645 HDA_AMP_MUTE, bits); 17646} 17647 17648static void alc662_lenovo_101e_all_automute(struct hda_codec *codec) 17649{ 17650 unsigned int present; 17651 unsigned char bits; 17652 17653 present = snd_hda_jack_detect(codec, 0x1b); 17654 bits = present ? HDA_AMP_MUTE : 0; 17655 17656 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 17657 HDA_AMP_MUTE, bits); 17658 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 17659 HDA_AMP_MUTE, bits); 17660} 17661 17662static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec, 17663 unsigned int res) 17664{ 17665 if ((res >> 26) == ALC880_HP_EVENT) 17666 alc662_lenovo_101e_all_automute(codec); 17667 if ((res >> 26) == ALC880_FRONT_EVENT) 17668 alc662_lenovo_101e_ispeaker_automute(codec); 17669} 17670 17671/* unsolicited event for HP jack sensing */ 17672static void alc662_eeepc_unsol_event(struct hda_codec *codec, 17673 unsigned int res) 17674{ 17675 if ((res >> 26) == ALC880_MIC_EVENT) 17676 alc_mic_automute(codec); 17677 else 17678 alc262_hippo_unsol_event(codec, res); 17679} 17680 17681static void alc662_eeepc_setup(struct hda_codec *codec) 17682{ 17683 struct alc_spec *spec = codec->spec; 17684 17685 alc262_hippo1_setup(codec); 17686 spec->ext_mic.pin = 0x18; 17687 spec->ext_mic.mux_idx = 0; 17688 spec->int_mic.pin = 0x19; 17689 spec->int_mic.mux_idx = 1; 17690 spec->auto_mic = 1; 17691} 17692 17693static void alc662_eeepc_inithook(struct hda_codec *codec) 17694{ 17695 alc262_hippo_automute(codec); 17696 alc_mic_automute(codec); 17697} 17698 17699static void alc662_eeepc_ep20_setup(struct hda_codec *codec) 17700{ 17701 struct alc_spec *spec = codec->spec; 17702 17703 spec->autocfg.hp_pins[0] = 0x14; 17704 spec->autocfg.speaker_pins[0] = 0x1b; 17705} 17706 17707#define alc662_eeepc_ep20_inithook alc262_hippo_master_update 17708 17709static void alc663_m51va_speaker_automute(struct hda_codec *codec) 17710{ 17711 unsigned int present; 17712 unsigned char bits; 17713 17714 present = snd_hda_jack_detect(codec, 0x21); 17715 bits = present ? HDA_AMP_MUTE : 0; 17716 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 17717 HDA_AMP_MUTE, bits); 17718 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 17719 HDA_AMP_MUTE, bits); 17720} 17721 17722static void alc663_21jd_two_speaker_automute(struct hda_codec *codec) 17723{ 17724 unsigned int present; 17725 unsigned char bits; 17726 17727 present = snd_hda_jack_detect(codec, 0x21); 17728 bits = present ? HDA_AMP_MUTE : 0; 17729 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 17730 HDA_AMP_MUTE, bits); 17731 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 17732 HDA_AMP_MUTE, bits); 17733 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0, 17734 HDA_AMP_MUTE, bits); 17735 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1, 17736 HDA_AMP_MUTE, bits); 17737} 17738 17739static void alc663_15jd_two_speaker_automute(struct hda_codec *codec) 17740{ 17741 unsigned int present; 17742 unsigned char bits; 17743 17744 present = snd_hda_jack_detect(codec, 0x15); 17745 bits = present ? HDA_AMP_MUTE : 0; 17746 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 17747 HDA_AMP_MUTE, bits); 17748 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 17749 HDA_AMP_MUTE, bits); 17750 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0, 17751 HDA_AMP_MUTE, bits); 17752 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1, 17753 HDA_AMP_MUTE, bits); 17754} 17755 17756static void alc662_f5z_speaker_automute(struct hda_codec *codec) 17757{ 17758 unsigned int present; 17759 unsigned char bits; 17760 17761 present = snd_hda_jack_detect(codec, 0x1b); 17762 bits = present ? 0 : PIN_OUT; 17763 snd_hda_codec_write(codec, 0x14, 0, 17764 AC_VERB_SET_PIN_WIDGET_CONTROL, bits); 17765} 17766 17767static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec) 17768{ 17769 unsigned int present1, present2; 17770 17771 present1 = snd_hda_jack_detect(codec, 0x21); 17772 present2 = snd_hda_jack_detect(codec, 0x15); 17773 17774 if (present1 || present2) { 17775 snd_hda_codec_write_cache(codec, 0x14, 0, 17776 AC_VERB_SET_PIN_WIDGET_CONTROL, 0); 17777 } else { 17778 snd_hda_codec_write_cache(codec, 0x14, 0, 17779 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); 17780 } 17781} 17782 17783static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec) 17784{ 17785 unsigned int present1, present2; 17786 17787 present1 = snd_hda_jack_detect(codec, 0x1b); 17788 present2 = snd_hda_jack_detect(codec, 0x15); 17789 17790 if (present1 || present2) { 17791 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 17792 HDA_AMP_MUTE, HDA_AMP_MUTE); 17793 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 17794 HDA_AMP_MUTE, HDA_AMP_MUTE); 17795 } else { 17796 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 17797 HDA_AMP_MUTE, 0); 17798 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 17799 HDA_AMP_MUTE, 0); 17800 } 17801} 17802 17803static void alc663_two_hp_m7_speaker_automute(struct hda_codec *codec) 17804{ 17805 unsigned int present1, present2; 17806 17807 present1 = snd_hda_codec_read(codec, 0x1b, 0, 17808 AC_VERB_GET_PIN_SENSE, 0) 17809 & AC_PINSENSE_PRESENCE; 17810 present2 = snd_hda_codec_read(codec, 0x21, 0, 17811 AC_VERB_GET_PIN_SENSE, 0) 17812 & AC_PINSENSE_PRESENCE; 17813 17814 if (present1 || present2) { 17815 snd_hda_codec_write_cache(codec, 0x14, 0, 17816 AC_VERB_SET_PIN_WIDGET_CONTROL, 0); 17817 snd_hda_codec_write_cache(codec, 0x17, 0, 17818 AC_VERB_SET_PIN_WIDGET_CONTROL, 0); 17819 } else { 17820 snd_hda_codec_write_cache(codec, 0x14, 0, 17821 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); 17822 snd_hda_codec_write_cache(codec, 0x17, 0, 17823 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); 17824 } 17825} 17826 17827static void alc663_two_hp_m8_speaker_automute(struct hda_codec *codec) 17828{ 17829 unsigned int present1, present2; 17830 17831 present1 = snd_hda_codec_read(codec, 0x21, 0, 17832 AC_VERB_GET_PIN_SENSE, 0) 17833 & AC_PINSENSE_PRESENCE; 17834 present2 = snd_hda_codec_read(codec, 0x15, 0, 17835 AC_VERB_GET_PIN_SENSE, 0) 17836 & AC_PINSENSE_PRESENCE; 17837 17838 if (present1 || present2) { 17839 snd_hda_codec_write_cache(codec, 0x14, 0, 17840 AC_VERB_SET_PIN_WIDGET_CONTROL, 0); 17841 snd_hda_codec_write_cache(codec, 0x17, 0, 17842 AC_VERB_SET_PIN_WIDGET_CONTROL, 0); 17843 } else { 17844 snd_hda_codec_write_cache(codec, 0x14, 0, 17845 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); 17846 snd_hda_codec_write_cache(codec, 0x17, 0, 17847 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); 17848 } 17849} 17850 17851static void alc663_m51va_unsol_event(struct hda_codec *codec, 17852 unsigned int res) 17853{ 17854 switch (res >> 26) { 17855 case ALC880_HP_EVENT: 17856 alc663_m51va_speaker_automute(codec); 17857 break; 17858 case ALC880_MIC_EVENT: 17859 alc_mic_automute(codec); 17860 break; 17861 } 17862} 17863 17864static void alc663_m51va_setup(struct hda_codec *codec) 17865{ 17866 struct alc_spec *spec = codec->spec; 17867 spec->ext_mic.pin = 0x18; 17868 spec->ext_mic.mux_idx = 0; 17869 spec->int_mic.pin = 0x12; 17870 spec->int_mic.mux_idx = 9; 17871 spec->auto_mic = 1; 17872} 17873 17874static void alc663_m51va_inithook(struct hda_codec *codec) 17875{ 17876 alc663_m51va_speaker_automute(codec); 17877 alc_mic_automute(codec); 17878} 17879 17880/* ***************** Mode1 ******************************/ 17881#define alc663_mode1_unsol_event alc663_m51va_unsol_event 17882 17883static void alc663_mode1_setup(struct hda_codec *codec) 17884{ 17885 struct alc_spec *spec = codec->spec; 17886 spec->ext_mic.pin = 0x18; 17887 spec->ext_mic.mux_idx = 0; 17888 spec->int_mic.pin = 0x19; 17889 spec->int_mic.mux_idx = 1; 17890 spec->auto_mic = 1; 17891} 17892 17893#define alc663_mode1_inithook alc663_m51va_inithook 17894 17895/* ***************** Mode2 ******************************/ 17896static void alc662_mode2_unsol_event(struct hda_codec *codec, 17897 unsigned int res) 17898{ 17899 switch (res >> 26) { 17900 case ALC880_HP_EVENT: 17901 alc662_f5z_speaker_automute(codec); 17902 break; 17903 case ALC880_MIC_EVENT: 17904 alc_mic_automute(codec); 17905 break; 17906 } 17907} 17908 17909#define alc662_mode2_setup alc663_mode1_setup 17910 17911static void alc662_mode2_inithook(struct hda_codec *codec) 17912{ 17913 alc662_f5z_speaker_automute(codec); 17914 alc_mic_automute(codec); 17915} 17916/* ***************** Mode3 ******************************/ 17917static void alc663_mode3_unsol_event(struct hda_codec *codec, 17918 unsigned int res) 17919{ 17920 switch (res >> 26) { 17921 case ALC880_HP_EVENT: 17922 alc663_two_hp_m1_speaker_automute(codec); 17923 break; 17924 case ALC880_MIC_EVENT: 17925 alc_mic_automute(codec); 17926 break; 17927 } 17928} 17929 17930#define alc663_mode3_setup alc663_mode1_setup 17931 17932static void alc663_mode3_inithook(struct hda_codec *codec) 17933{ 17934 alc663_two_hp_m1_speaker_automute(codec); 17935 alc_mic_automute(codec); 17936} 17937/* ***************** Mode4 ******************************/ 17938static void alc663_mode4_unsol_event(struct hda_codec *codec, 17939 unsigned int res) 17940{ 17941 switch (res >> 26) { 17942 case ALC880_HP_EVENT: 17943 alc663_21jd_two_speaker_automute(codec); 17944 break; 17945 case ALC880_MIC_EVENT: 17946 alc_mic_automute(codec); 17947 break; 17948 } 17949} 17950 17951#define alc663_mode4_setup alc663_mode1_setup 17952 17953static void alc663_mode4_inithook(struct hda_codec *codec) 17954{ 17955 alc663_21jd_two_speaker_automute(codec); 17956 alc_mic_automute(codec); 17957} 17958/* ***************** Mode5 ******************************/ 17959static void alc663_mode5_unsol_event(struct hda_codec *codec, 17960 unsigned int res) 17961{ 17962 switch (res >> 26) { 17963 case ALC880_HP_EVENT: 17964 alc663_15jd_two_speaker_automute(codec); 17965 break; 17966 case ALC880_MIC_EVENT: 17967 alc_mic_automute(codec); 17968 break; 17969 } 17970} 17971 17972#define alc663_mode5_setup alc663_mode1_setup 17973 17974static void alc663_mode5_inithook(struct hda_codec *codec) 17975{ 17976 alc663_15jd_two_speaker_automute(codec); 17977 alc_mic_automute(codec); 17978} 17979/* ***************** Mode6 ******************************/ 17980static void alc663_mode6_unsol_event(struct hda_codec *codec, 17981 unsigned int res) 17982{ 17983 switch (res >> 26) { 17984 case ALC880_HP_EVENT: 17985 alc663_two_hp_m2_speaker_automute(codec); 17986 break; 17987 case ALC880_MIC_EVENT: 17988 alc_mic_automute(codec); 17989 break; 17990 } 17991} 17992 17993#define alc663_mode6_setup alc663_mode1_setup 17994 17995static void alc663_mode6_inithook(struct hda_codec *codec) 17996{ 17997 alc663_two_hp_m2_speaker_automute(codec); 17998 alc_mic_automute(codec); 17999} 18000 18001/* ***************** Mode7 ******************************/ 18002static void alc663_mode7_unsol_event(struct hda_codec *codec, 18003 unsigned int res) 18004{ 18005 switch (res >> 26) { 18006 case ALC880_HP_EVENT: 18007 alc663_two_hp_m7_speaker_automute(codec); 18008 break; 18009 case ALC880_MIC_EVENT: 18010 alc_mic_automute(codec); 18011 break; 18012 } 18013} 18014 18015#define alc663_mode7_setup alc663_mode1_setup 18016 18017static void alc663_mode7_inithook(struct hda_codec *codec) 18018{ 18019 alc663_two_hp_m7_speaker_automute(codec); 18020 alc_mic_automute(codec); 18021} 18022 18023/* ***************** Mode8 ******************************/ 18024static void alc663_mode8_unsol_event(struct hda_codec *codec, 18025 unsigned int res) 18026{ 18027 switch (res >> 26) { 18028 case ALC880_HP_EVENT: 18029 alc663_two_hp_m8_speaker_automute(codec); 18030 break; 18031 case ALC880_MIC_EVENT: 18032 alc_mic_automute(codec); 18033 break; 18034 } 18035} 18036 18037#define alc663_mode8_setup alc663_m51va_setup 18038 18039static void alc663_mode8_inithook(struct hda_codec *codec) 18040{ 18041 alc663_two_hp_m8_speaker_automute(codec); 18042 alc_mic_automute(codec); 18043} 18044 18045static void alc663_g71v_hp_automute(struct hda_codec *codec) 18046{ 18047 unsigned int present; 18048 unsigned char bits; 18049 18050 present = snd_hda_jack_detect(codec, 0x21); 18051 bits = present ? HDA_AMP_MUTE : 0; 18052 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 18053 HDA_AMP_MUTE, bits); 18054 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 18055 HDA_AMP_MUTE, bits); 18056} 18057 18058static void alc663_g71v_front_automute(struct hda_codec *codec) 18059{ 18060 unsigned int present; 18061 unsigned char bits; 18062 18063 present = snd_hda_jack_detect(codec, 0x15); 18064 bits = present ? HDA_AMP_MUTE : 0; 18065 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 18066 HDA_AMP_MUTE, bits); 18067} 18068 18069static void alc663_g71v_unsol_event(struct hda_codec *codec, 18070 unsigned int res) 18071{ 18072 switch (res >> 26) { 18073 case ALC880_HP_EVENT: 18074 alc663_g71v_hp_automute(codec); 18075 break; 18076 case ALC880_FRONT_EVENT: 18077 alc663_g71v_front_automute(codec); 18078 break; 18079 case ALC880_MIC_EVENT: 18080 alc_mic_automute(codec); 18081 break; 18082 } 18083} 18084 18085#define alc663_g71v_setup alc663_m51va_setup 18086 18087static void alc663_g71v_inithook(struct hda_codec *codec) 18088{ 18089 alc663_g71v_front_automute(codec); 18090 alc663_g71v_hp_automute(codec); 18091 alc_mic_automute(codec); 18092} 18093 18094static void alc663_g50v_unsol_event(struct hda_codec *codec, 18095 unsigned int res) 18096{ 18097 switch (res >> 26) { 18098 case ALC880_HP_EVENT: 18099 alc663_m51va_speaker_automute(codec); 18100 break; 18101 case ALC880_MIC_EVENT: 18102 alc_mic_automute(codec); 18103 break; 18104 } 18105} 18106 18107#define alc663_g50v_setup alc663_m51va_setup 18108 18109static void alc663_g50v_inithook(struct hda_codec *codec) 18110{ 18111 alc663_m51va_speaker_automute(codec); 18112 alc_mic_automute(codec); 18113} 18114 18115static struct snd_kcontrol_new alc662_ecs_mixer[] = { 18116 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT), 18117 ALC262_HIPPO_MASTER_SWITCH, 18118 18119 HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT), 18120 HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT), 18121 HDA_CODEC_MUTE("e-Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT), 18122 18123 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT), 18124 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 18125 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 18126 { } /* end */ 18127}; 18128 18129static struct snd_kcontrol_new alc272_nc10_mixer[] = { 18130 /* Master Playback automatically created from Speaker and Headphone */ 18131 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 18132 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 18133 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 18134 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT), 18135 18136 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 18137 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 18138 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT), 18139 18140 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 18141 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 18142 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 18143 { } /* end */ 18144}; 18145 18146#ifdef CONFIG_SND_HDA_POWER_SAVE 18147#define alc662_loopbacks alc880_loopbacks 18148#endif 18149 18150 18151/* pcm configuration: identical with ALC880 */ 18152#define alc662_pcm_analog_playback alc880_pcm_analog_playback 18153#define alc662_pcm_analog_capture alc880_pcm_analog_capture 18154#define alc662_pcm_digital_playback alc880_pcm_digital_playback 18155#define alc662_pcm_digital_capture alc880_pcm_digital_capture 18156 18157/* 18158 * configuration and preset 18159 */ 18160static const char *alc662_models[ALC662_MODEL_LAST] = { 18161 [ALC662_3ST_2ch_DIG] = "3stack-dig", 18162 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig", 18163 [ALC662_3ST_6ch] = "3stack-6ch", 18164 [ALC662_5ST_DIG] = "6stack-dig", 18165 [ALC662_LENOVO_101E] = "lenovo-101e", 18166 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701", 18167 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20", 18168 [ALC662_ECS] = "ecs", 18169 [ALC663_ASUS_M51VA] = "m51va", 18170 [ALC663_ASUS_G71V] = "g71v", 18171 [ALC663_ASUS_H13] = "h13", 18172 [ALC663_ASUS_G50V] = "g50v", 18173 [ALC663_ASUS_MODE1] = "asus-mode1", 18174 [ALC662_ASUS_MODE2] = "asus-mode2", 18175 [ALC663_ASUS_MODE3] = "asus-mode3", 18176 [ALC663_ASUS_MODE4] = "asus-mode4", 18177 [ALC663_ASUS_MODE5] = "asus-mode5", 18178 [ALC663_ASUS_MODE6] = "asus-mode6", 18179 [ALC663_ASUS_MODE7] = "asus-mode7", 18180 [ALC663_ASUS_MODE8] = "asus-mode8", 18181 [ALC272_DELL] = "dell", 18182 [ALC272_DELL_ZM1] = "dell-zm1", 18183 [ALC272_SAMSUNG_NC10] = "samsung-nc10", 18184 [ALC662_AUTO] = "auto", 18185}; 18186 18187static struct snd_pci_quirk alc662_cfg_tbl[] = { 18188 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS), 18189 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL), 18190 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1), 18191 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1), 18192 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3), 18193 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC663_ASUS_MODE1), 18194 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3), 18195 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1), 18196 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2), 18197 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1), 18198 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC663_ASUS_MODE1), 18199 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC663_ASUS_MODE1), 18200 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2), 18201 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC663_ASUS_MODE7), 18202 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC663_ASUS_MODE7), 18203 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC663_ASUS_MODE8), 18204 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC663_ASUS_MODE3), 18205 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC663_ASUS_MODE1), 18206 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2), 18207 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_ASUS_MODE2), 18208 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC663_ASUS_MODE1), 18209 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2), 18210 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6), 18211 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6), 18212 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2), 18213 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC663_ASUS_MODE1), 18214 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3), 18215 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA), 18216 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2), 18217 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2), 18218 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5), 18219 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6), 18220 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2), 18221 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1), 18222 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2), 18223 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2), 18224 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA), 18225 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/ 18226 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3), 18227 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3), 18228 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1), 18229 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC663_ASUS_MODE1), 18230 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1), 18231 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1), 18232 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1), 18233 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2), 18234 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2), 18235 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1), 18236 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1), 18237 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3), 18238 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1), 18239 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1), 18240 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V), 18241 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/ 18242 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1), 18243 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2), 18244 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA), 18245 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1), 18246 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4), 18247 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG), 18248 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701), 18249 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20), 18250 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS), 18251 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K", 18252 ALC662_3ST_6ch_DIG), 18253 SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO), 18254 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10), 18255 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L", 18256 ALC662_3ST_6ch_DIG), 18257 SND_PCI_QUIRK(0x152d, 0x2304, "Quanta WH1", ALC663_ASUS_H13), 18258 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG), 18259 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA), 18260 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E), 18261 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0", 18262 ALC662_3ST_6ch_DIG), 18263 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x", 18264 ALC663_ASUS_H13), 18265 {} 18266}; 18267 18268static struct alc_config_preset alc662_presets[] = { 18269 [ALC662_3ST_2ch_DIG] = { 18270 .mixers = { alc662_3ST_2ch_mixer }, 18271 .init_verbs = { alc662_init_verbs }, 18272 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18273 .dac_nids = alc662_dac_nids, 18274 .dig_out_nid = ALC662_DIGOUT_NID, 18275 .dig_in_nid = ALC662_DIGIN_NID, 18276 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18277 .channel_mode = alc662_3ST_2ch_modes, 18278 .input_mux = &alc662_capture_source, 18279 }, 18280 [ALC662_3ST_6ch_DIG] = { 18281 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer }, 18282 .init_verbs = { alc662_init_verbs }, 18283 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18284 .dac_nids = alc662_dac_nids, 18285 .dig_out_nid = ALC662_DIGOUT_NID, 18286 .dig_in_nid = ALC662_DIGIN_NID, 18287 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), 18288 .channel_mode = alc662_3ST_6ch_modes, 18289 .need_dac_fix = 1, 18290 .input_mux = &alc662_capture_source, 18291 }, 18292 [ALC662_3ST_6ch] = { 18293 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer }, 18294 .init_verbs = { alc662_init_verbs }, 18295 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18296 .dac_nids = alc662_dac_nids, 18297 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), 18298 .channel_mode = alc662_3ST_6ch_modes, 18299 .need_dac_fix = 1, 18300 .input_mux = &alc662_capture_source, 18301 }, 18302 [ALC662_5ST_DIG] = { 18303 .mixers = { alc662_base_mixer, alc662_chmode_mixer }, 18304 .init_verbs = { alc662_init_verbs }, 18305 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18306 .dac_nids = alc662_dac_nids, 18307 .dig_out_nid = ALC662_DIGOUT_NID, 18308 .dig_in_nid = ALC662_DIGIN_NID, 18309 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes), 18310 .channel_mode = alc662_5stack_modes, 18311 .input_mux = &alc662_capture_source, 18312 }, 18313 [ALC662_LENOVO_101E] = { 18314 .mixers = { alc662_lenovo_101e_mixer }, 18315 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs }, 18316 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18317 .dac_nids = alc662_dac_nids, 18318 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18319 .channel_mode = alc662_3ST_2ch_modes, 18320 .input_mux = &alc662_lenovo_101e_capture_source, 18321 .unsol_event = alc662_lenovo_101e_unsol_event, 18322 .init_hook = alc662_lenovo_101e_all_automute, 18323 }, 18324 [ALC662_ASUS_EEEPC_P701] = { 18325 .mixers = { alc662_eeepc_p701_mixer }, 18326 .init_verbs = { alc662_init_verbs, 18327 alc662_eeepc_sue_init_verbs }, 18328 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18329 .dac_nids = alc662_dac_nids, 18330 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18331 .channel_mode = alc662_3ST_2ch_modes, 18332 .unsol_event = alc662_eeepc_unsol_event, 18333 .setup = alc662_eeepc_setup, 18334 .init_hook = alc662_eeepc_inithook, 18335 }, 18336 [ALC662_ASUS_EEEPC_EP20] = { 18337 .mixers = { alc662_eeepc_ep20_mixer, 18338 alc662_chmode_mixer }, 18339 .init_verbs = { alc662_init_verbs, 18340 alc662_eeepc_ep20_sue_init_verbs }, 18341 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18342 .dac_nids = alc662_dac_nids, 18343 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), 18344 .channel_mode = alc662_3ST_6ch_modes, 18345 .input_mux = &alc662_lenovo_101e_capture_source, 18346 .unsol_event = alc662_eeepc_unsol_event, 18347 .setup = alc662_eeepc_ep20_setup, 18348 .init_hook = alc662_eeepc_ep20_inithook, 18349 }, 18350 [ALC662_ECS] = { 18351 .mixers = { alc662_ecs_mixer }, 18352 .init_verbs = { alc662_init_verbs, 18353 alc662_ecs_init_verbs }, 18354 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18355 .dac_nids = alc662_dac_nids, 18356 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18357 .channel_mode = alc662_3ST_2ch_modes, 18358 .unsol_event = alc662_eeepc_unsol_event, 18359 .setup = alc662_eeepc_setup, 18360 .init_hook = alc662_eeepc_inithook, 18361 }, 18362 [ALC663_ASUS_M51VA] = { 18363 .mixers = { alc663_m51va_mixer }, 18364 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs }, 18365 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18366 .dac_nids = alc662_dac_nids, 18367 .dig_out_nid = ALC662_DIGOUT_NID, 18368 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18369 .channel_mode = alc662_3ST_2ch_modes, 18370 .unsol_event = alc663_m51va_unsol_event, 18371 .setup = alc663_m51va_setup, 18372 .init_hook = alc663_m51va_inithook, 18373 }, 18374 [ALC663_ASUS_G71V] = { 18375 .mixers = { alc663_g71v_mixer }, 18376 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs }, 18377 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18378 .dac_nids = alc662_dac_nids, 18379 .dig_out_nid = ALC662_DIGOUT_NID, 18380 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18381 .channel_mode = alc662_3ST_2ch_modes, 18382 .unsol_event = alc663_g71v_unsol_event, 18383 .setup = alc663_g71v_setup, 18384 .init_hook = alc663_g71v_inithook, 18385 }, 18386 [ALC663_ASUS_H13] = { 18387 .mixers = { alc663_m51va_mixer }, 18388 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs }, 18389 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18390 .dac_nids = alc662_dac_nids, 18391 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18392 .channel_mode = alc662_3ST_2ch_modes, 18393 .unsol_event = alc663_m51va_unsol_event, 18394 .init_hook = alc663_m51va_inithook, 18395 }, 18396 [ALC663_ASUS_G50V] = { 18397 .mixers = { alc663_g50v_mixer }, 18398 .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs }, 18399 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18400 .dac_nids = alc662_dac_nids, 18401 .dig_out_nid = ALC662_DIGOUT_NID, 18402 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), 18403 .channel_mode = alc662_3ST_6ch_modes, 18404 .input_mux = &alc663_capture_source, 18405 .unsol_event = alc663_g50v_unsol_event, 18406 .setup = alc663_g50v_setup, 18407 .init_hook = alc663_g50v_inithook, 18408 }, 18409 [ALC663_ASUS_MODE1] = { 18410 .mixers = { alc663_m51va_mixer }, 18411 .cap_mixer = alc662_auto_capture_mixer, 18412 .init_verbs = { alc662_init_verbs, 18413 alc663_21jd_amic_init_verbs }, 18414 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18415 .hp_nid = 0x03, 18416 .dac_nids = alc662_dac_nids, 18417 .dig_out_nid = ALC662_DIGOUT_NID, 18418 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18419 .channel_mode = alc662_3ST_2ch_modes, 18420 .unsol_event = alc663_mode1_unsol_event, 18421 .setup = alc663_mode1_setup, 18422 .init_hook = alc663_mode1_inithook, 18423 }, 18424 [ALC662_ASUS_MODE2] = { 18425 .mixers = { alc662_1bjd_mixer }, 18426 .cap_mixer = alc662_auto_capture_mixer, 18427 .init_verbs = { alc662_init_verbs, 18428 alc662_1bjd_amic_init_verbs }, 18429 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18430 .dac_nids = alc662_dac_nids, 18431 .dig_out_nid = ALC662_DIGOUT_NID, 18432 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18433 .channel_mode = alc662_3ST_2ch_modes, 18434 .unsol_event = alc662_mode2_unsol_event, 18435 .setup = alc662_mode2_setup, 18436 .init_hook = alc662_mode2_inithook, 18437 }, 18438 [ALC663_ASUS_MODE3] = { 18439 .mixers = { alc663_two_hp_m1_mixer }, 18440 .cap_mixer = alc662_auto_capture_mixer, 18441 .init_verbs = { alc662_init_verbs, 18442 alc663_two_hp_amic_m1_init_verbs }, 18443 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18444 .hp_nid = 0x03, 18445 .dac_nids = alc662_dac_nids, 18446 .dig_out_nid = ALC662_DIGOUT_NID, 18447 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18448 .channel_mode = alc662_3ST_2ch_modes, 18449 .unsol_event = alc663_mode3_unsol_event, 18450 .setup = alc663_mode3_setup, 18451 .init_hook = alc663_mode3_inithook, 18452 }, 18453 [ALC663_ASUS_MODE4] = { 18454 .mixers = { alc663_asus_21jd_clfe_mixer }, 18455 .cap_mixer = alc662_auto_capture_mixer, 18456 .init_verbs = { alc662_init_verbs, 18457 alc663_21jd_amic_init_verbs}, 18458 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18459 .hp_nid = 0x03, 18460 .dac_nids = alc662_dac_nids, 18461 .dig_out_nid = ALC662_DIGOUT_NID, 18462 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18463 .channel_mode = alc662_3ST_2ch_modes, 18464 .unsol_event = alc663_mode4_unsol_event, 18465 .setup = alc663_mode4_setup, 18466 .init_hook = alc663_mode4_inithook, 18467 }, 18468 [ALC663_ASUS_MODE5] = { 18469 .mixers = { alc663_asus_15jd_clfe_mixer }, 18470 .cap_mixer = alc662_auto_capture_mixer, 18471 .init_verbs = { alc662_init_verbs, 18472 alc663_15jd_amic_init_verbs }, 18473 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18474 .hp_nid = 0x03, 18475 .dac_nids = alc662_dac_nids, 18476 .dig_out_nid = ALC662_DIGOUT_NID, 18477 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18478 .channel_mode = alc662_3ST_2ch_modes, 18479 .unsol_event = alc663_mode5_unsol_event, 18480 .setup = alc663_mode5_setup, 18481 .init_hook = alc663_mode5_inithook, 18482 }, 18483 [ALC663_ASUS_MODE6] = { 18484 .mixers = { alc663_two_hp_m2_mixer }, 18485 .cap_mixer = alc662_auto_capture_mixer, 18486 .init_verbs = { alc662_init_verbs, 18487 alc663_two_hp_amic_m2_init_verbs }, 18488 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18489 .hp_nid = 0x03, 18490 .dac_nids = alc662_dac_nids, 18491 .dig_out_nid = ALC662_DIGOUT_NID, 18492 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18493 .channel_mode = alc662_3ST_2ch_modes, 18494 .unsol_event = alc663_mode6_unsol_event, 18495 .setup = alc663_mode6_setup, 18496 .init_hook = alc663_mode6_inithook, 18497 }, 18498 [ALC663_ASUS_MODE7] = { 18499 .mixers = { alc663_mode7_mixer }, 18500 .cap_mixer = alc662_auto_capture_mixer, 18501 .init_verbs = { alc662_init_verbs, 18502 alc663_mode7_init_verbs }, 18503 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18504 .hp_nid = 0x03, 18505 .dac_nids = alc662_dac_nids, 18506 .dig_out_nid = ALC662_DIGOUT_NID, 18507 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18508 .channel_mode = alc662_3ST_2ch_modes, 18509 .unsol_event = alc663_mode7_unsol_event, 18510 .setup = alc663_mode7_setup, 18511 .init_hook = alc663_mode7_inithook, 18512 }, 18513 [ALC663_ASUS_MODE8] = { 18514 .mixers = { alc663_mode8_mixer }, 18515 .cap_mixer = alc662_auto_capture_mixer, 18516 .init_verbs = { alc662_init_verbs, 18517 alc663_mode8_init_verbs }, 18518 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18519 .hp_nid = 0x03, 18520 .dac_nids = alc662_dac_nids, 18521 .dig_out_nid = ALC662_DIGOUT_NID, 18522 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18523 .channel_mode = alc662_3ST_2ch_modes, 18524 .unsol_event = alc663_mode8_unsol_event, 18525 .setup = alc663_mode8_setup, 18526 .init_hook = alc663_mode8_inithook, 18527 }, 18528 [ALC272_DELL] = { 18529 .mixers = { alc663_m51va_mixer }, 18530 .cap_mixer = alc272_auto_capture_mixer, 18531 .init_verbs = { alc662_init_verbs, alc272_dell_init_verbs }, 18532 .num_dacs = ARRAY_SIZE(alc272_dac_nids), 18533 .dac_nids = alc662_dac_nids, 18534 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18535 .adc_nids = alc272_adc_nids, 18536 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids), 18537 .capsrc_nids = alc272_capsrc_nids, 18538 .channel_mode = alc662_3ST_2ch_modes, 18539 .unsol_event = alc663_m51va_unsol_event, 18540 .setup = alc663_m51va_setup, 18541 .init_hook = alc663_m51va_inithook, 18542 }, 18543 [ALC272_DELL_ZM1] = { 18544 .mixers = { alc663_m51va_mixer }, 18545 .cap_mixer = alc662_auto_capture_mixer, 18546 .init_verbs = { alc662_init_verbs, alc272_dell_zm1_init_verbs }, 18547 .num_dacs = ARRAY_SIZE(alc272_dac_nids), 18548 .dac_nids = alc662_dac_nids, 18549 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18550 .adc_nids = alc662_adc_nids, 18551 .num_adc_nids = 1, 18552 .capsrc_nids = alc662_capsrc_nids, 18553 .channel_mode = alc662_3ST_2ch_modes, 18554 .unsol_event = alc663_m51va_unsol_event, 18555 .setup = alc663_m51va_setup, 18556 .init_hook = alc663_m51va_inithook, 18557 }, 18558 [ALC272_SAMSUNG_NC10] = { 18559 .mixers = { alc272_nc10_mixer }, 18560 .init_verbs = { alc662_init_verbs, 18561 alc663_21jd_amic_init_verbs }, 18562 .num_dacs = ARRAY_SIZE(alc272_dac_nids), 18563 .dac_nids = alc272_dac_nids, 18564 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18565 .channel_mode = alc662_3ST_2ch_modes, 18566 /*.input_mux = &alc272_nc10_capture_source,*/ 18567 .unsol_event = alc663_mode4_unsol_event, 18568 .setup = alc663_mode4_setup, 18569 .init_hook = alc663_mode4_inithook, 18570 }, 18571}; 18572 18573 18574/* 18575 * BIOS auto configuration 18576 */ 18577 18578/* convert from MIX nid to DAC */ 18579static inline hda_nid_t alc662_mix_to_dac(hda_nid_t nid) 18580{ 18581 if (nid == 0x0f) 18582 return 0x02; 18583 else if (nid >= 0x0c && nid <= 0x0e) 18584 return nid - 0x0c + 0x02; 18585 else 18586 return 0; 18587} 18588 18589/* get MIX nid connected to the given pin targeted to DAC */ 18590static hda_nid_t alc662_dac_to_mix(struct hda_codec *codec, hda_nid_t pin, 18591 hda_nid_t dac) 18592{ 18593 hda_nid_t mix[4]; 18594 int i, num; 18595 18596 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix)); 18597 for (i = 0; i < num; i++) { 18598 if (alc662_mix_to_dac(mix[i]) == dac) 18599 return mix[i]; 18600 } 18601 return 0; 18602} 18603 18604/* look for an empty DAC slot */ 18605static hda_nid_t alc662_look_for_dac(struct hda_codec *codec, hda_nid_t pin) 18606{ 18607 struct alc_spec *spec = codec->spec; 18608 hda_nid_t srcs[5]; 18609 int i, j, num; 18610 18611 num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs)); 18612 if (num < 0) 18613 return 0; 18614 for (i = 0; i < num; i++) { 18615 hda_nid_t nid = alc662_mix_to_dac(srcs[i]); 18616 if (!nid) 18617 continue; 18618 for (j = 0; j < spec->multiout.num_dacs; j++) 18619 if (spec->multiout.dac_nids[j] == nid) 18620 break; 18621 if (j >= spec->multiout.num_dacs) 18622 return nid; 18623 } 18624 return 0; 18625} 18626 18627/* fill in the dac_nids table from the parsed pin configuration */ 18628static int alc662_auto_fill_dac_nids(struct hda_codec *codec, 18629 const struct auto_pin_cfg *cfg) 18630{ 18631 struct alc_spec *spec = codec->spec; 18632 int i; 18633 hda_nid_t dac; 18634 18635 spec->multiout.dac_nids = spec->private_dac_nids; 18636 for (i = 0; i < cfg->line_outs; i++) { 18637 dac = alc662_look_for_dac(codec, cfg->line_out_pins[i]); 18638 if (!dac) 18639 continue; 18640 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac; 18641 } 18642 return 0; 18643} 18644 18645static inline int alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx, 18646 hda_nid_t nid, unsigned int chs) 18647{ 18648 return add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, 18649 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT)); 18650} 18651 18652static inline int alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx, 18653 hda_nid_t nid, unsigned int chs) 18654{ 18655 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, 18656 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT)); 18657} 18658 18659#define alc662_add_stereo_vol(spec, pfx, nid) \ 18660 alc662_add_vol_ctl(spec, pfx, nid, 3) 18661#define alc662_add_stereo_sw(spec, pfx, nid) \ 18662 alc662_add_sw_ctl(spec, pfx, nid, 3) 18663 18664/* add playback controls from the parsed DAC table */ 18665static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec, 18666 const struct auto_pin_cfg *cfg) 18667{ 18668 struct alc_spec *spec = codec->spec; 18669 static const char *chname[4] = { 18670 "Front", "Surround", NULL /*CLFE*/, "Side" 18671 }; 18672 hda_nid_t nid, mix; 18673 int i, err; 18674 18675 for (i = 0; i < cfg->line_outs; i++) { 18676 nid = spec->multiout.dac_nids[i]; 18677 if (!nid) 18678 continue; 18679 mix = alc662_dac_to_mix(codec, cfg->line_out_pins[i], nid); 18680 if (!mix) 18681 continue; 18682 if (i == 2) { 18683 /* Center/LFE */ 18684 err = alc662_add_vol_ctl(spec, "Center", nid, 1); 18685 if (err < 0) 18686 return err; 18687 err = alc662_add_vol_ctl(spec, "LFE", nid, 2); 18688 if (err < 0) 18689 return err; 18690 err = alc662_add_sw_ctl(spec, "Center", mix, 1); 18691 if (err < 0) 18692 return err; 18693 err = alc662_add_sw_ctl(spec, "LFE", mix, 2); 18694 if (err < 0) 18695 return err; 18696 } else { 18697 const char *pfx; 18698 if (cfg->line_outs == 1 && 18699 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) { 18700 if (cfg->hp_outs) 18701 pfx = "Speaker"; 18702 else 18703 pfx = "PCM"; 18704 } else 18705 pfx = chname[i]; 18706 err = alc662_add_vol_ctl(spec, pfx, nid, 3); 18707 if (err < 0) 18708 return err; 18709 if (cfg->line_outs == 1 && 18710 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) 18711 pfx = "Speaker"; 18712 err = alc662_add_sw_ctl(spec, pfx, mix, 3); 18713 if (err < 0) 18714 return err; 18715 } 18716 } 18717 return 0; 18718} 18719 18720/* add playback controls for speaker and HP outputs */ 18721/* return DAC nid if any new DAC is assigned */ 18722static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin, 18723 const char *pfx) 18724{ 18725 struct alc_spec *spec = codec->spec; 18726 hda_nid_t nid, mix; 18727 int err; 18728 18729 if (!pin) 18730 return 0; 18731 nid = alc662_look_for_dac(codec, pin); 18732 if (!nid) { 18733 /* the corresponding DAC is already occupied */ 18734 if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP)) 18735 return 0; /* no way */ 18736 /* create a switch only */ 18737 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, 18738 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); 18739 } 18740 18741 mix = alc662_dac_to_mix(codec, pin, nid); 18742 if (!mix) 18743 return 0; 18744 err = alc662_add_vol_ctl(spec, pfx, nid, 3); 18745 if (err < 0) 18746 return err; 18747 err = alc662_add_sw_ctl(spec, pfx, mix, 3); 18748 if (err < 0) 18749 return err; 18750 return nid; 18751} 18752 18753/* create playback/capture controls for input pins */ 18754#define alc662_auto_create_input_ctls \ 18755 alc882_auto_create_input_ctls 18756 18757static void alc662_auto_set_output_and_unmute(struct hda_codec *codec, 18758 hda_nid_t nid, int pin_type, 18759 hda_nid_t dac) 18760{ 18761 int i, num; 18762 hda_nid_t srcs[HDA_MAX_CONNECTIONS]; 18763 18764 alc_set_pin_output(codec, nid, pin_type); 18765 /* need the manual connection? */ 18766 num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs)); 18767 if (num <= 1) 18768 return; 18769 for (i = 0; i < num; i++) { 18770 if (alc662_mix_to_dac(srcs[i]) != dac) 18771 continue; 18772 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, i); 18773 return; 18774 } 18775} 18776 18777static void alc662_auto_init_multi_out(struct hda_codec *codec) 18778{ 18779 struct alc_spec *spec = codec->spec; 18780 int pin_type = get_pin_type(spec->autocfg.line_out_type); 18781 int i; 18782 18783 for (i = 0; i <= HDA_SIDE; i++) { 18784 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 18785 if (nid) 18786 alc662_auto_set_output_and_unmute(codec, nid, pin_type, 18787 spec->multiout.dac_nids[i]); 18788 } 18789} 18790 18791static void alc662_auto_init_hp_out(struct hda_codec *codec) 18792{ 18793 struct alc_spec *spec = codec->spec; 18794 hda_nid_t pin; 18795 18796 pin = spec->autocfg.hp_pins[0]; 18797 if (pin) 18798 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 18799 spec->multiout.hp_nid); 18800 pin = spec->autocfg.speaker_pins[0]; 18801 if (pin) 18802 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT, 18803 spec->multiout.extra_out_nid[0]); 18804} 18805 18806#define ALC662_PIN_CD_NID ALC880_PIN_CD_NID 18807 18808static void alc662_auto_init_analog_input(struct hda_codec *codec) 18809{ 18810 struct alc_spec *spec = codec->spec; 18811 struct auto_pin_cfg *cfg = &spec->autocfg; 18812 int i; 18813 18814 for (i = 0; i < cfg->num_inputs; i++) { 18815 hda_nid_t nid = cfg->inputs[i].pin; 18816 if (alc_is_input_pin(codec, nid)) { 18817 alc_set_input_pin(codec, nid, i); 18818 if (nid != ALC662_PIN_CD_NID && 18819 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)) 18820 snd_hda_codec_write(codec, nid, 0, 18821 AC_VERB_SET_AMP_GAIN_MUTE, 18822 AMP_OUT_MUTE); 18823 } 18824 } 18825} 18826 18827#define alc662_auto_init_input_src alc882_auto_init_input_src 18828 18829static int alc662_parse_auto_config(struct hda_codec *codec) 18830{ 18831 struct alc_spec *spec = codec->spec; 18832 int err; 18833 static hda_nid_t alc662_ignore[] = { 0x1d, 0 }; 18834 18835 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 18836 alc662_ignore); 18837 if (err < 0) 18838 return err; 18839 if (!spec->autocfg.line_outs) 18840 return 0; /* can't find valid BIOS pin config */ 18841 18842 err = alc662_auto_fill_dac_nids(codec, &spec->autocfg); 18843 if (err < 0) 18844 return err; 18845 err = alc662_auto_create_multi_out_ctls(codec, &spec->autocfg); 18846 if (err < 0) 18847 return err; 18848 err = alc662_auto_create_extra_out(codec, 18849 spec->autocfg.speaker_pins[0], 18850 "Speaker"); 18851 if (err < 0) 18852 return err; 18853 if (err) 18854 spec->multiout.extra_out_nid[0] = err; 18855 err = alc662_auto_create_extra_out(codec, spec->autocfg.hp_pins[0], 18856 "Headphone"); 18857 if (err < 0) 18858 return err; 18859 if (err) 18860 spec->multiout.hp_nid = err; 18861 err = alc662_auto_create_input_ctls(codec, &spec->autocfg); 18862 if (err < 0) 18863 return err; 18864 18865 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 18866 18867 alc_auto_parse_digital(codec); 18868 18869 if (spec->kctls.list) 18870 add_mixer(spec, spec->kctls.list); 18871 18872 spec->num_mux_defs = 1; 18873 spec->input_mux = &spec->private_imux[0]; 18874 18875 add_verb(spec, alc662_init_verbs); 18876 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 || 18877 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670) 18878 add_verb(spec, alc663_init_verbs); 18879 18880 if (codec->vendor_id == 0x10ec0272) 18881 add_verb(spec, alc272_init_verbs); 18882 18883 err = alc_auto_add_mic_boost(codec); 18884 if (err < 0) 18885 return err; 18886 18887 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 || 18888 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670) 18889 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0x21); 18890 else 18891 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); 18892 18893 return 1; 18894} 18895 18896/* additional initialization for auto-configuration model */ 18897static void alc662_auto_init(struct hda_codec *codec) 18898{ 18899 struct alc_spec *spec = codec->spec; 18900 alc662_auto_init_multi_out(codec); 18901 alc662_auto_init_hp_out(codec); 18902 alc662_auto_init_analog_input(codec); 18903 alc662_auto_init_input_src(codec); 18904 alc_auto_init_digital(codec); 18905 if (spec->unsol_event) 18906 alc_inithook(codec); 18907} 18908 18909static int patch_alc662(struct hda_codec *codec) 18910{ 18911 struct alc_spec *spec; 18912 int err, board_config; 18913 18914 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 18915 if (!spec) 18916 return -ENOMEM; 18917 18918 codec->spec = spec; 18919 18920 alc_auto_parse_customize_define(codec); 18921 18922 alc_fix_pll_init(codec, 0x20, 0x04, 15); 18923 18924 if (alc_read_coef_idx(codec, 0) == 0x8020) 18925 alc_codec_rename(codec, "ALC661"); 18926 else if ((alc_read_coef_idx(codec, 0) & (1 << 14)) && 18927 codec->bus->pci->subsystem_vendor == 0x1025 && 18928 spec->cdefine.platform_type == 1) 18929 alc_codec_rename(codec, "ALC272X"); 18930 18931 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST, 18932 alc662_models, 18933 alc662_cfg_tbl); 18934 if (board_config < 0) { 18935 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 18936 codec->chip_name); 18937 board_config = ALC662_AUTO; 18938 } 18939 18940 if (board_config == ALC662_AUTO) { 18941 /* automatic parse from the BIOS config */ 18942 err = alc662_parse_auto_config(codec); 18943 if (err < 0) { 18944 alc_free(codec); 18945 return err; 18946 } else if (!err) { 18947 printk(KERN_INFO 18948 "hda_codec: Cannot set up configuration " 18949 "from BIOS. Using base mode...\n"); 18950 board_config = ALC662_3ST_2ch_DIG; 18951 } 18952 } 18953 18954 if (has_cdefine_beep(codec)) { 18955 err = snd_hda_attach_beep_device(codec, 0x1); 18956 if (err < 0) { 18957 alc_free(codec); 18958 return err; 18959 } 18960 } 18961 18962 if (board_config != ALC662_AUTO) 18963 setup_preset(codec, &alc662_presets[board_config]); 18964 18965 spec->stream_analog_playback = &alc662_pcm_analog_playback; 18966 spec->stream_analog_capture = &alc662_pcm_analog_capture; 18967 18968 spec->stream_digital_playback = &alc662_pcm_digital_playback; 18969 spec->stream_digital_capture = &alc662_pcm_digital_capture; 18970 18971 if (!spec->adc_nids) { 18972 spec->adc_nids = alc662_adc_nids; 18973 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids); 18974 } 18975 if (!spec->capsrc_nids) 18976 spec->capsrc_nids = alc662_capsrc_nids; 18977 18978 if (!spec->cap_mixer) 18979 set_capture_mixer(codec); 18980 18981 if (has_cdefine_beep(codec)) { 18982 switch (codec->vendor_id) { 18983 case 0x10ec0662: 18984 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 18985 break; 18986 case 0x10ec0272: 18987 case 0x10ec0663: 18988 case 0x10ec0665: 18989 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); 18990 break; 18991 case 0x10ec0273: 18992 set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT); 18993 break; 18994 } 18995 } 18996 spec->vmaster_nid = 0x02; 18997 18998 codec->patch_ops = alc_patch_ops; 18999 if (board_config == ALC662_AUTO) 19000 spec->init_hook = alc662_auto_init; 19001#ifdef CONFIG_SND_HDA_POWER_SAVE 19002 if (!spec->loopback.amplist) 19003 spec->loopback.amplist = alc662_loopbacks; 19004#endif 19005 19006 return 0; 19007} 19008 19009static int patch_alc888(struct hda_codec *codec) 19010{ 19011 if ((alc_read_coef_idx(codec, 0) & 0x00f0)==0x0030){ 19012 kfree(codec->chip_name); 19013 codec->chip_name = kstrdup("ALC888-VD", GFP_KERNEL); 19014 if (!codec->chip_name) { 19015 alc_free(codec); 19016 return -ENOMEM; 19017 } 19018 return patch_alc662(codec); 19019 } 19020 return patch_alc882(codec); 19021} 19022 19023/* 19024 * ALC680 support 19025 */ 19026#define ALC680_DIGIN_NID ALC880_DIGIN_NID 19027#define ALC680_DIGOUT_NID ALC880_DIGOUT_NID 19028#define alc680_modes alc260_modes 19029 19030static hda_nid_t alc680_dac_nids[3] = { 19031 /* Lout1, Lout2, hp */ 19032 0x02, 0x03, 0x04 19033}; 19034 19035static hda_nid_t alc680_adc_nids[3] = { 19036 /* ADC0-2 */ 19037 /* DMIC, MIC, Line-in*/ 19038 0x07, 0x08, 0x09 19039}; 19040 19041/* 19042 * Analog capture ADC cgange 19043 */ 19044static void alc680_rec_autoswitch(struct hda_codec *codec) 19045{ 19046 struct alc_spec *spec = codec->spec; 19047 struct auto_pin_cfg *cfg = &spec->autocfg; 19048 int pin_found = 0; 19049 int type_found = AUTO_PIN_LAST; 19050 hda_nid_t nid; 19051 int i; 19052 19053 for (i = 0; i < cfg->num_inputs; i++) { 19054 nid = cfg->inputs[i].pin; 19055 if (!(snd_hda_query_pin_caps(codec, nid) & 19056 AC_PINCAP_PRES_DETECT)) 19057 continue; 19058 if (snd_hda_jack_detect(codec, nid)) { 19059 if (cfg->inputs[i].type < type_found) { 19060 type_found = cfg->inputs[i].type; 19061 pin_found = nid; 19062 } 19063 } 19064 } 19065 19066 nid = 0x07; 19067 if (pin_found) 19068 snd_hda_get_connections(codec, pin_found, &nid, 1); 19069 19070 if (nid != spec->cur_adc) 19071 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1); 19072 spec->cur_adc = nid; 19073 snd_hda_codec_setup_stream(codec, nid, spec->cur_adc_stream_tag, 0, 19074 spec->cur_adc_format); 19075} 19076 19077static int alc680_capture_pcm_prepare(struct hda_pcm_stream *hinfo, 19078 struct hda_codec *codec, 19079 unsigned int stream_tag, 19080 unsigned int format, 19081 struct snd_pcm_substream *substream) 19082{ 19083 struct alc_spec *spec = codec->spec; 19084 19085 spec->cur_adc = 0x07; 19086 spec->cur_adc_stream_tag = stream_tag; 19087 spec->cur_adc_format = format; 19088 19089 alc680_rec_autoswitch(codec); 19090 return 0; 19091} 19092 19093static int alc680_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, 19094 struct hda_codec *codec, 19095 struct snd_pcm_substream *substream) 19096{ 19097 snd_hda_codec_cleanup_stream(codec, 0x07); 19098 snd_hda_codec_cleanup_stream(codec, 0x08); 19099 snd_hda_codec_cleanup_stream(codec, 0x09); 19100 return 0; 19101} 19102 19103static struct hda_pcm_stream alc680_pcm_analog_auto_capture = { 19104 .substreams = 1, /* can be overridden */ 19105 .channels_min = 2, 19106 .channels_max = 2, 19107 /* NID is set in alc_build_pcms */ 19108 .ops = { 19109 .prepare = alc680_capture_pcm_prepare, 19110 .cleanup = alc680_capture_pcm_cleanup 19111 }, 19112}; 19113 19114static struct snd_kcontrol_new alc680_base_mixer[] = { 19115 /* output mixer control */ 19116 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), 19117 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 19118 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT), 19119 HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT), 19120 HDA_CODEC_VOLUME("Int Mic Boost", 0x12, 0, HDA_INPUT), 19121 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 19122 HDA_CODEC_VOLUME("Line In Boost", 0x19, 0, HDA_INPUT), 19123 { } 19124}; 19125 19126static struct hda_bind_ctls alc680_bind_cap_vol = { 19127 .ops = &snd_hda_bind_vol, 19128 .values = { 19129 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT), 19130 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT), 19131 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT), 19132 0 19133 }, 19134}; 19135 19136static struct hda_bind_ctls alc680_bind_cap_switch = { 19137 .ops = &snd_hda_bind_sw, 19138 .values = { 19139 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT), 19140 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT), 19141 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT), 19142 0 19143 }, 19144}; 19145 19146static struct snd_kcontrol_new alc680_master_capture_mixer[] = { 19147 HDA_BIND_VOL("Capture Volume", &alc680_bind_cap_vol), 19148 HDA_BIND_SW("Capture Switch", &alc680_bind_cap_switch), 19149 { } /* end */ 19150}; 19151 19152/* 19153 * generic initialization of ADC, input mixers and output mixers 19154 */ 19155static struct hda_verb alc680_init_verbs[] = { 19156 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 19157 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 19158 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 19159 19160 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 19161 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 19162 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 19163 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 19164 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 19165 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 19166 19167 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 19168 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 19169 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 19170 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 19171 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 19172 19173 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 19174 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, 19175 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, 19176 19177 { } 19178}; 19179 19180/* toggle speaker-output according to the hp-jack state */ 19181static void alc680_base_setup(struct hda_codec *codec) 19182{ 19183 struct alc_spec *spec = codec->spec; 19184 19185 spec->autocfg.hp_pins[0] = 0x16; 19186 spec->autocfg.speaker_pins[0] = 0x14; 19187 spec->autocfg.speaker_pins[1] = 0x15; 19188 spec->autocfg.num_inputs = 2; 19189 spec->autocfg.inputs[0].pin = 0x18; 19190 spec->autocfg.inputs[0].type = AUTO_PIN_MIC; 19191 spec->autocfg.inputs[1].pin = 0x19; 19192 spec->autocfg.inputs[1].type = AUTO_PIN_LINE; 19193} 19194 19195static void alc680_unsol_event(struct hda_codec *codec, 19196 unsigned int res) 19197{ 19198 if ((res >> 26) == ALC880_HP_EVENT) 19199 alc_automute_amp(codec); 19200 if ((res >> 26) == ALC880_MIC_EVENT) 19201 alc680_rec_autoswitch(codec); 19202} 19203 19204static void alc680_inithook(struct hda_codec *codec) 19205{ 19206 alc_automute_amp(codec); 19207 alc680_rec_autoswitch(codec); 19208} 19209 19210/* create input playback/capture controls for the given pin */ 19211static int alc680_new_analog_output(struct alc_spec *spec, hda_nid_t nid, 19212 const char *ctlname, int idx) 19213{ 19214 hda_nid_t dac; 19215 int err; 19216 19217 switch (nid) { 19218 case 0x14: 19219 dac = 0x02; 19220 break; 19221 case 0x15: 19222 dac = 0x03; 19223 break; 19224 case 0x16: 19225 dac = 0x04; 19226 break; 19227 default: 19228 return 0; 19229 } 19230 if (spec->multiout.dac_nids[0] != dac && 19231 spec->multiout.dac_nids[1] != dac) { 19232 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname, 19233 HDA_COMPOSE_AMP_VAL(dac, 3, idx, 19234 HDA_OUTPUT)); 19235 if (err < 0) 19236 return err; 19237 19238 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname, 19239 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT)); 19240 19241 if (err < 0) 19242 return err; 19243 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac; 19244 } 19245 19246 return 0; 19247} 19248 19249/* add playback controls from the parsed DAC table */ 19250static int alc680_auto_create_multi_out_ctls(struct alc_spec *spec, 19251 const struct auto_pin_cfg *cfg) 19252{ 19253 hda_nid_t nid; 19254 int err; 19255 19256 spec->multiout.dac_nids = spec->private_dac_nids; 19257 19258 nid = cfg->line_out_pins[0]; 19259 if (nid) { 19260 const char *name; 19261 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) 19262 name = "Speaker"; 19263 else 19264 name = "Front"; 19265 err = alc680_new_analog_output(spec, nid, name, 0); 19266 if (err < 0) 19267 return err; 19268 } 19269 19270 nid = cfg->speaker_pins[0]; 19271 if (nid) { 19272 err = alc680_new_analog_output(spec, nid, "Speaker", 0); 19273 if (err < 0) 19274 return err; 19275 } 19276 nid = cfg->hp_pins[0]; 19277 if (nid) { 19278 err = alc680_new_analog_output(spec, nid, "Headphone", 0); 19279 if (err < 0) 19280 return err; 19281 } 19282 19283 return 0; 19284} 19285 19286static void alc680_auto_set_output_and_unmute(struct hda_codec *codec, 19287 hda_nid_t nid, int pin_type) 19288{ 19289 alc_set_pin_output(codec, nid, pin_type); 19290} 19291 19292static void alc680_auto_init_multi_out(struct hda_codec *codec) 19293{ 19294 struct alc_spec *spec = codec->spec; 19295 hda_nid_t nid = spec->autocfg.line_out_pins[0]; 19296 if (nid) { 19297 int pin_type = get_pin_type(spec->autocfg.line_out_type); 19298 alc680_auto_set_output_and_unmute(codec, nid, pin_type); 19299 } 19300} 19301 19302static void alc680_auto_init_hp_out(struct hda_codec *codec) 19303{ 19304 struct alc_spec *spec = codec->spec; 19305 hda_nid_t pin; 19306 19307 pin = spec->autocfg.hp_pins[0]; 19308 if (pin) 19309 alc680_auto_set_output_and_unmute(codec, pin, PIN_HP); 19310 pin = spec->autocfg.speaker_pins[0]; 19311 if (pin) 19312 alc680_auto_set_output_and_unmute(codec, pin, PIN_OUT); 19313} 19314 19315/* pcm configuration: identical with ALC880 */ 19316#define alc680_pcm_analog_playback alc880_pcm_analog_playback 19317#define alc680_pcm_analog_capture alc880_pcm_analog_capture 19318#define alc680_pcm_analog_alt_capture alc880_pcm_analog_alt_capture 19319#define alc680_pcm_digital_playback alc880_pcm_digital_playback 19320#define alc680_pcm_digital_capture alc880_pcm_digital_capture 19321 19322/* 19323 * BIOS auto configuration 19324 */ 19325static int alc680_parse_auto_config(struct hda_codec *codec) 19326{ 19327 struct alc_spec *spec = codec->spec; 19328 int err; 19329 static hda_nid_t alc680_ignore[] = { 0 }; 19330 19331 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 19332 alc680_ignore); 19333 if (err < 0) 19334 return err; 19335 19336 if (!spec->autocfg.line_outs) { 19337 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) { 19338 spec->multiout.max_channels = 2; 19339 spec->no_analog = 1; 19340 goto dig_only; 19341 } 19342 return 0; /* can't find valid BIOS pin config */ 19343 } 19344 err = alc680_auto_create_multi_out_ctls(spec, &spec->autocfg); 19345 if (err < 0) 19346 return err; 19347 19348 spec->multiout.max_channels = 2; 19349 19350 dig_only: 19351 /* digital only support output */ 19352 alc_auto_parse_digital(codec); 19353 if (spec->kctls.list) 19354 add_mixer(spec, spec->kctls.list); 19355 19356 add_verb(spec, alc680_init_verbs); 19357 19358 err = alc_auto_add_mic_boost(codec); 19359 if (err < 0) 19360 return err; 19361 19362 return 1; 19363} 19364 19365#define alc680_auto_init_analog_input alc882_auto_init_analog_input 19366 19367/* init callback for auto-configuration model -- overriding the default init */ 19368static void alc680_auto_init(struct hda_codec *codec) 19369{ 19370 struct alc_spec *spec = codec->spec; 19371 alc680_auto_init_multi_out(codec); 19372 alc680_auto_init_hp_out(codec); 19373 alc680_auto_init_analog_input(codec); 19374 alc_auto_init_digital(codec); 19375 if (spec->unsol_event) 19376 alc_inithook(codec); 19377} 19378 19379/* 19380 * configuration and preset 19381 */ 19382static const char *alc680_models[ALC680_MODEL_LAST] = { 19383 [ALC680_BASE] = "base", 19384 [ALC680_AUTO] = "auto", 19385}; 19386 19387static struct snd_pci_quirk alc680_cfg_tbl[] = { 19388 SND_PCI_QUIRK(0x1043, 0x12f3, "ASUS NX90", ALC680_BASE), 19389 {} 19390}; 19391 19392static struct alc_config_preset alc680_presets[] = { 19393 [ALC680_BASE] = { 19394 .mixers = { alc680_base_mixer }, 19395 .cap_mixer = alc680_master_capture_mixer, 19396 .init_verbs = { alc680_init_verbs }, 19397 .num_dacs = ARRAY_SIZE(alc680_dac_nids), 19398 .dac_nids = alc680_dac_nids, 19399 .dig_out_nid = ALC680_DIGOUT_NID, 19400 .num_channel_mode = ARRAY_SIZE(alc680_modes), 19401 .channel_mode = alc680_modes, 19402 .unsol_event = alc680_unsol_event, 19403 .setup = alc680_base_setup, 19404 .init_hook = alc680_inithook, 19405 19406 }, 19407}; 19408 19409static int patch_alc680(struct hda_codec *codec) 19410{ 19411 struct alc_spec *spec; 19412 int board_config; 19413 int err; 19414 19415 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 19416 if (spec == NULL) 19417 return -ENOMEM; 19418 19419 codec->spec = spec; 19420 19421 board_config = snd_hda_check_board_config(codec, ALC680_MODEL_LAST, 19422 alc680_models, 19423 alc680_cfg_tbl); 19424 19425 if (board_config < 0 || board_config >= ALC680_MODEL_LAST) { 19426 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 19427 codec->chip_name); 19428 board_config = ALC680_AUTO; 19429 } 19430 19431 if (board_config == ALC680_AUTO) { 19432 /* automatic parse from the BIOS config */ 19433 err = alc680_parse_auto_config(codec); 19434 if (err < 0) { 19435 alc_free(codec); 19436 return err; 19437 } else if (!err) { 19438 printk(KERN_INFO 19439 "hda_codec: Cannot set up configuration " 19440 "from BIOS. Using base mode...\n"); 19441 board_config = ALC680_BASE; 19442 } 19443 } 19444 19445 if (board_config != ALC680_AUTO) 19446 setup_preset(codec, &alc680_presets[board_config]); 19447 19448 spec->stream_analog_playback = &alc680_pcm_analog_playback; 19449 spec->stream_analog_capture = &alc680_pcm_analog_auto_capture; 19450 spec->stream_digital_playback = &alc680_pcm_digital_playback; 19451 spec->stream_digital_capture = &alc680_pcm_digital_capture; 19452 19453 if (!spec->adc_nids) { 19454 spec->adc_nids = alc680_adc_nids; 19455 spec->num_adc_nids = ARRAY_SIZE(alc680_adc_nids); 19456 } 19457 19458 if (!spec->cap_mixer) 19459 set_capture_mixer(codec); 19460 19461 spec->vmaster_nid = 0x02; 19462 19463 codec->patch_ops = alc_patch_ops; 19464 if (board_config == ALC680_AUTO) 19465 spec->init_hook = alc680_auto_init; 19466 19467 return 0; 19468} 19469 19470/* 19471 * patch entries 19472 */ 19473static struct hda_codec_preset snd_hda_preset_realtek[] = { 19474 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 }, 19475 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 }, 19476 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 }, 19477 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 }, 19478 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 }, 19479 { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 }, 19480 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 }, 19481 { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 }, 19482 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660", 19483 .patch = patch_alc861 }, 19484 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd }, 19485 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 }, 19486 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd }, 19487 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2", 19488 .patch = patch_alc882 }, 19489 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1", 19490 .patch = patch_alc662 }, 19491 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 }, 19492 { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 }, 19493 { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 }, 19494 { .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 }, 19495 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 }, 19496 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 }, 19497 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 }, 19498 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A", 19499 .patch = patch_alc882 }, 19500 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A", 19501 .patch = patch_alc882 }, 19502 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 }, 19503 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc882 }, 19504 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200", 19505 .patch = patch_alc882 }, 19506 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc888 }, 19507 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 }, 19508 { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 }, 19509 {} /* terminator */ 19510}; 19511 19512MODULE_ALIAS("snd-hda-codec-id:10ec*"); 19513 19514MODULE_LICENSE("GPL"); 19515MODULE_DESCRIPTION("Realtek HD-audio codec"); 19516 19517static struct hda_codec_preset_list realtek_list = { 19518 .preset = snd_hda_preset_realtek, 19519 .owner = THIS_MODULE, 19520}; 19521 19522static int __init patch_realtek_init(void) 19523{ 19524 return snd_hda_add_codec_preset(&realtek_list); 19525} 19526 19527static void __exit patch_realtek_exit(void) 19528{ 19529 snd_hda_delete_codec_preset(&realtek_list); 19530} 19531 19532module_init(patch_realtek_init) 19533module_exit(patch_realtek_exit) 19534