patch_realtek.c revision 5734a07cbb8d4600a74a374c839620ddc62b2cf2
1/* 2 * Universal Interface for Intel High Definition Audio Codec 3 * 4 * HD audio interface patch for ALC 260/880/882 codecs 5 * 6 * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw> 7 * PeiSen Hou <pshou@realtek.com.tw> 8 * Takashi Iwai <tiwai@suse.de> 9 * Jonathan Woithe <jwoithe@physics.adelaide.edu.au> 10 * 11 * This driver is free software; you can redistribute it and/or modify 12 * it under the terms of the GNU General Public License as published by 13 * the Free Software Foundation; either version 2 of the License, or 14 * (at your option) any later version. 15 * 16 * This driver is distributed in the hope that it will be useful, 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 * GNU General Public License for more details. 20 * 21 * You should have received a copy of the GNU General Public License 22 * along with this program; if not, write to the Free Software 23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 24 */ 25 26#include <linux/init.h> 27#include <linux/delay.h> 28#include <linux/slab.h> 29#include <linux/pci.h> 30#include <sound/core.h> 31#include <sound/jack.h> 32#include "hda_codec.h" 33#include "hda_local.h" 34#include "hda_beep.h" 35 36#define ALC880_FRONT_EVENT 0x01 37#define ALC880_DCVOL_EVENT 0x02 38#define ALC880_HP_EVENT 0x04 39#define ALC880_MIC_EVENT 0x08 40 41/* ALC880 board config type */ 42enum { 43 ALC880_3ST, 44 ALC880_3ST_DIG, 45 ALC880_5ST, 46 ALC880_5ST_DIG, 47 ALC880_W810, 48 ALC880_Z71V, 49 ALC880_6ST, 50 ALC880_6ST_DIG, 51 ALC880_F1734, 52 ALC880_ASUS, 53 ALC880_ASUS_DIG, 54 ALC880_ASUS_W1V, 55 ALC880_ASUS_DIG2, 56 ALC880_FUJITSU, 57 ALC880_UNIWILL_DIG, 58 ALC880_UNIWILL, 59 ALC880_UNIWILL_P53, 60 ALC880_CLEVO, 61 ALC880_TCL_S700, 62 ALC880_LG, 63 ALC880_LG_LW, 64 ALC880_MEDION_RIM, 65#ifdef CONFIG_SND_DEBUG 66 ALC880_TEST, 67#endif 68 ALC880_AUTO, 69 ALC880_MODEL_LAST /* last tag */ 70}; 71 72/* ALC260 models */ 73enum { 74 ALC260_BASIC, 75 ALC260_HP, 76 ALC260_HP_DC7600, 77 ALC260_HP_3013, 78 ALC260_FUJITSU_S702X, 79 ALC260_ACER, 80 ALC260_WILL, 81 ALC260_REPLACER_672V, 82 ALC260_FAVORIT100, 83#ifdef CONFIG_SND_DEBUG 84 ALC260_TEST, 85#endif 86 ALC260_AUTO, 87 ALC260_MODEL_LAST /* last tag */ 88}; 89 90/* ALC262 models */ 91enum { 92 ALC262_BASIC, 93 ALC262_HIPPO, 94 ALC262_HIPPO_1, 95 ALC262_FUJITSU, 96 ALC262_HP_BPC, 97 ALC262_HP_BPC_D7000_WL, 98 ALC262_HP_BPC_D7000_WF, 99 ALC262_HP_TC_T5735, 100 ALC262_HP_RP5700, 101 ALC262_BENQ_ED8, 102 ALC262_SONY_ASSAMD, 103 ALC262_BENQ_T31, 104 ALC262_ULTRA, 105 ALC262_LENOVO_3000, 106 ALC262_NEC, 107 ALC262_TOSHIBA_S06, 108 ALC262_TOSHIBA_RX1, 109 ALC262_TYAN, 110 ALC262_AUTO, 111 ALC262_MODEL_LAST /* last tag */ 112}; 113 114/* ALC268 models */ 115enum { 116 ALC267_QUANTA_IL1, 117 ALC268_3ST, 118 ALC268_TOSHIBA, 119 ALC268_ACER, 120 ALC268_ACER_DMIC, 121 ALC268_ACER_ASPIRE_ONE, 122 ALC268_DELL, 123 ALC268_ZEPTO, 124#ifdef CONFIG_SND_DEBUG 125 ALC268_TEST, 126#endif 127 ALC268_AUTO, 128 ALC268_MODEL_LAST /* last tag */ 129}; 130 131/* ALC269 models */ 132enum { 133 ALC269_BASIC, 134 ALC269_QUANTA_FL1, 135 ALC269_AMIC, 136 ALC269_DMIC, 137 ALC269VB_AMIC, 138 ALC269VB_DMIC, 139 ALC269_FUJITSU, 140 ALC269_LIFEBOOK, 141 ALC271_ACER, 142 ALC269_AUTO, 143 ALC269_MODEL_LAST /* last tag */ 144}; 145 146/* ALC861 models */ 147enum { 148 ALC861_3ST, 149 ALC660_3ST, 150 ALC861_3ST_DIG, 151 ALC861_6ST_DIG, 152 ALC861_UNIWILL_M31, 153 ALC861_TOSHIBA, 154 ALC861_ASUS, 155 ALC861_ASUS_LAPTOP, 156 ALC861_AUTO, 157 ALC861_MODEL_LAST, 158}; 159 160/* ALC861-VD models */ 161enum { 162 ALC660VD_3ST, 163 ALC660VD_3ST_DIG, 164 ALC660VD_ASUS_V1S, 165 ALC861VD_3ST, 166 ALC861VD_3ST_DIG, 167 ALC861VD_6ST_DIG, 168 ALC861VD_LENOVO, 169 ALC861VD_DALLAS, 170 ALC861VD_HP, 171 ALC861VD_AUTO, 172 ALC861VD_MODEL_LAST, 173}; 174 175/* ALC662 models */ 176enum { 177 ALC662_3ST_2ch_DIG, 178 ALC662_3ST_6ch_DIG, 179 ALC662_3ST_6ch, 180 ALC662_5ST_DIG, 181 ALC662_LENOVO_101E, 182 ALC662_ASUS_EEEPC_P701, 183 ALC662_ASUS_EEEPC_EP20, 184 ALC663_ASUS_M51VA, 185 ALC663_ASUS_G71V, 186 ALC663_ASUS_H13, 187 ALC663_ASUS_G50V, 188 ALC662_ECS, 189 ALC663_ASUS_MODE1, 190 ALC662_ASUS_MODE2, 191 ALC663_ASUS_MODE3, 192 ALC663_ASUS_MODE4, 193 ALC663_ASUS_MODE5, 194 ALC663_ASUS_MODE6, 195 ALC663_ASUS_MODE7, 196 ALC663_ASUS_MODE8, 197 ALC272_DELL, 198 ALC272_DELL_ZM1, 199 ALC272_SAMSUNG_NC10, 200 ALC662_AUTO, 201 ALC662_MODEL_LAST, 202}; 203 204/* ALC882 models */ 205enum { 206 ALC882_3ST_DIG, 207 ALC882_6ST_DIG, 208 ALC882_ARIMA, 209 ALC882_W2JC, 210 ALC882_TARGA, 211 ALC882_ASUS_A7J, 212 ALC882_ASUS_A7M, 213 ALC885_MACPRO, 214 ALC885_MBA21, 215 ALC885_MBP3, 216 ALC885_MB5, 217 ALC885_MACMINI3, 218 ALC885_IMAC24, 219 ALC885_IMAC91, 220 ALC883_3ST_2ch_DIG, 221 ALC883_3ST_6ch_DIG, 222 ALC883_3ST_6ch, 223 ALC883_6ST_DIG, 224 ALC883_TARGA_DIG, 225 ALC883_TARGA_2ch_DIG, 226 ALC883_TARGA_8ch_DIG, 227 ALC883_ACER, 228 ALC883_ACER_ASPIRE, 229 ALC888_ACER_ASPIRE_4930G, 230 ALC888_ACER_ASPIRE_6530G, 231 ALC888_ACER_ASPIRE_8930G, 232 ALC888_ACER_ASPIRE_7730G, 233 ALC883_MEDION, 234 ALC883_MEDION_WIM2160, 235 ALC883_LAPTOP_EAPD, 236 ALC883_LENOVO_101E_2ch, 237 ALC883_LENOVO_NB0763, 238 ALC888_LENOVO_MS7195_DIG, 239 ALC888_LENOVO_SKY, 240 ALC883_HAIER_W66, 241 ALC888_3ST_HP, 242 ALC888_6ST_DELL, 243 ALC883_MITAC, 244 ALC883_CLEVO_M540R, 245 ALC883_CLEVO_M720, 246 ALC883_FUJITSU_PI2515, 247 ALC888_FUJITSU_XA3530, 248 ALC883_3ST_6ch_INTEL, 249 ALC889A_INTEL, 250 ALC889_INTEL, 251 ALC888_ASUS_M90V, 252 ALC888_ASUS_EEE1601, 253 ALC889A_MB31, 254 ALC1200_ASUS_P5Q, 255 ALC883_SONY_VAIO_TT, 256 ALC882_AUTO, 257 ALC882_MODEL_LAST, 258}; 259 260/* ALC680 models */ 261enum { 262 ALC680_BASE, 263 ALC680_AUTO, 264 ALC680_MODEL_LAST, 265}; 266 267/* for GPIO Poll */ 268#define GPIO_MASK 0x03 269 270/* extra amp-initialization sequence types */ 271enum { 272 ALC_INIT_NONE, 273 ALC_INIT_DEFAULT, 274 ALC_INIT_GPIO1, 275 ALC_INIT_GPIO2, 276 ALC_INIT_GPIO3, 277}; 278 279struct alc_mic_route { 280 hda_nid_t pin; 281 unsigned char mux_idx; 282 unsigned char amix_idx; 283}; 284 285struct alc_jack { 286 hda_nid_t nid; 287 int type; 288 struct snd_jack *jack; 289}; 290 291#define MUX_IDX_UNDEF ((unsigned char)-1) 292 293struct alc_customize_define { 294 unsigned int sku_cfg; 295 unsigned char port_connectivity; 296 unsigned char check_sum; 297 unsigned char customization; 298 unsigned char external_amp; 299 unsigned int enable_pcbeep:1; 300 unsigned int platform_type:1; 301 unsigned int swap:1; 302 unsigned int override:1; 303 unsigned int fixup:1; /* Means that this sku is set by driver, not read from hw */ 304}; 305 306struct alc_fixup; 307 308struct alc_spec { 309 /* codec parameterization */ 310 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */ 311 unsigned int num_mixers; 312 struct snd_kcontrol_new *cap_mixer; /* capture mixer */ 313 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */ 314 315 const struct hda_verb *init_verbs[10]; /* initialization verbs 316 * don't forget NULL 317 * termination! 318 */ 319 unsigned int num_init_verbs; 320 321 char stream_name_analog[32]; /* analog PCM stream */ 322 struct hda_pcm_stream *stream_analog_playback; 323 struct hda_pcm_stream *stream_analog_capture; 324 struct hda_pcm_stream *stream_analog_alt_playback; 325 struct hda_pcm_stream *stream_analog_alt_capture; 326 327 char stream_name_digital[32]; /* digital PCM stream */ 328 struct hda_pcm_stream *stream_digital_playback; 329 struct hda_pcm_stream *stream_digital_capture; 330 331 /* playback */ 332 struct hda_multi_out multiout; /* playback set-up 333 * max_channels, dacs must be set 334 * dig_out_nid and hp_nid are optional 335 */ 336 hda_nid_t alt_dac_nid; 337 hda_nid_t slave_dig_outs[3]; /* optional - for auto-parsing */ 338 int dig_out_type; 339 340 /* capture */ 341 unsigned int num_adc_nids; 342 hda_nid_t *adc_nids; 343 hda_nid_t *capsrc_nids; 344 hda_nid_t dig_in_nid; /* digital-in NID; optional */ 345 346 /* capture setup for dynamic dual-adc switch */ 347 unsigned int cur_adc_idx; 348 hda_nid_t cur_adc; 349 unsigned int cur_adc_stream_tag; 350 unsigned int cur_adc_format; 351 352 /* capture source */ 353 unsigned int num_mux_defs; 354 const struct hda_input_mux *input_mux; 355 unsigned int cur_mux[3]; 356 struct alc_mic_route ext_mic; 357 struct alc_mic_route int_mic; 358 359 /* channel model */ 360 const struct hda_channel_mode *channel_mode; 361 int num_channel_mode; 362 int need_dac_fix; 363 int const_channel_count; 364 int ext_channel_count; 365 366 /* PCM information */ 367 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */ 368 369 /* jack detection */ 370 struct snd_array jacks; 371 372 /* dynamic controls, init_verbs and input_mux */ 373 struct auto_pin_cfg autocfg; 374 struct alc_customize_define cdefine; 375 struct snd_array kctls; 376 struct hda_input_mux private_imux[3]; 377 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; 378 hda_nid_t private_adc_nids[AUTO_CFG_MAX_OUTS]; 379 hda_nid_t private_capsrc_nids[AUTO_CFG_MAX_OUTS]; 380 381 /* hooks */ 382 void (*init_hook)(struct hda_codec *codec); 383 void (*unsol_event)(struct hda_codec *codec, unsigned int res); 384#ifdef CONFIG_SND_HDA_POWER_SAVE 385 void (*power_hook)(struct hda_codec *codec); 386#endif 387 388 /* for pin sensing */ 389 unsigned int sense_updated: 1; 390 unsigned int jack_present: 1; 391 unsigned int master_sw: 1; 392 unsigned int auto_mic:1; 393 394 /* other flags */ 395 unsigned int no_analog :1; /* digital I/O only */ 396 unsigned int dual_adc_switch:1; /* switch ADCs (for ALC275) */ 397 int init_amp; 398 int codec_variant; /* flag for other variants */ 399 400 /* for virtual master */ 401 hda_nid_t vmaster_nid; 402#ifdef CONFIG_SND_HDA_POWER_SAVE 403 struct hda_loopback_check loopback; 404#endif 405 406 /* for PLL fix */ 407 hda_nid_t pll_nid; 408 unsigned int pll_coef_idx, pll_coef_bit; 409 410 /* fix-up list */ 411 int fixup_id; 412 const struct alc_fixup *fixup_list; 413 const char *fixup_name; 414}; 415 416/* 417 * configuration template - to be copied to the spec instance 418 */ 419struct alc_config_preset { 420 struct snd_kcontrol_new *mixers[5]; /* should be identical size 421 * with spec 422 */ 423 struct snd_kcontrol_new *cap_mixer; /* capture mixer */ 424 const struct hda_verb *init_verbs[5]; 425 unsigned int num_dacs; 426 hda_nid_t *dac_nids; 427 hda_nid_t dig_out_nid; /* optional */ 428 hda_nid_t hp_nid; /* optional */ 429 hda_nid_t *slave_dig_outs; 430 unsigned int num_adc_nids; 431 hda_nid_t *adc_nids; 432 hda_nid_t *capsrc_nids; 433 hda_nid_t dig_in_nid; 434 unsigned int num_channel_mode; 435 const struct hda_channel_mode *channel_mode; 436 int need_dac_fix; 437 int const_channel_count; 438 unsigned int num_mux_defs; 439 const struct hda_input_mux *input_mux; 440 void (*unsol_event)(struct hda_codec *, unsigned int); 441 void (*setup)(struct hda_codec *); 442 void (*init_hook)(struct hda_codec *); 443#ifdef CONFIG_SND_HDA_POWER_SAVE 444 struct hda_amp_list *loopbacks; 445 void (*power_hook)(struct hda_codec *codec); 446#endif 447}; 448 449 450/* 451 * input MUX handling 452 */ 453static int alc_mux_enum_info(struct snd_kcontrol *kcontrol, 454 struct snd_ctl_elem_info *uinfo) 455{ 456 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 457 struct alc_spec *spec = codec->spec; 458 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id); 459 if (mux_idx >= spec->num_mux_defs) 460 mux_idx = 0; 461 if (!spec->input_mux[mux_idx].num_items && mux_idx > 0) 462 mux_idx = 0; 463 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo); 464} 465 466static int alc_mux_enum_get(struct snd_kcontrol *kcontrol, 467 struct snd_ctl_elem_value *ucontrol) 468{ 469 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 470 struct alc_spec *spec = codec->spec; 471 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 472 473 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx]; 474 return 0; 475} 476 477static int alc_mux_enum_put(struct snd_kcontrol *kcontrol, 478 struct snd_ctl_elem_value *ucontrol) 479{ 480 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 481 struct alc_spec *spec = codec->spec; 482 const struct hda_input_mux *imux; 483 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 484 unsigned int mux_idx; 485 hda_nid_t nid = spec->capsrc_nids ? 486 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx]; 487 unsigned int type; 488 489 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx; 490 imux = &spec->input_mux[mux_idx]; 491 if (!imux->num_items && mux_idx > 0) 492 imux = &spec->input_mux[0]; 493 494 type = get_wcaps_type(get_wcaps(codec, nid)); 495 if (type == AC_WID_AUD_MIX) { 496 /* Matrix-mixer style (e.g. ALC882) */ 497 unsigned int *cur_val = &spec->cur_mux[adc_idx]; 498 unsigned int i, idx; 499 500 idx = ucontrol->value.enumerated.item[0]; 501 if (idx >= imux->num_items) 502 idx = imux->num_items - 1; 503 if (*cur_val == idx) 504 return 0; 505 for (i = 0; i < imux->num_items; i++) { 506 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE; 507 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 508 imux->items[i].index, 509 HDA_AMP_MUTE, v); 510 } 511 *cur_val = idx; 512 return 1; 513 } else { 514 /* MUX style (e.g. ALC880) */ 515 return snd_hda_input_mux_put(codec, imux, ucontrol, nid, 516 &spec->cur_mux[adc_idx]); 517 } 518} 519 520/* 521 * channel mode setting 522 */ 523static int alc_ch_mode_info(struct snd_kcontrol *kcontrol, 524 struct snd_ctl_elem_info *uinfo) 525{ 526 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 527 struct alc_spec *spec = codec->spec; 528 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode, 529 spec->num_channel_mode); 530} 531 532static int alc_ch_mode_get(struct snd_kcontrol *kcontrol, 533 struct snd_ctl_elem_value *ucontrol) 534{ 535 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 536 struct alc_spec *spec = codec->spec; 537 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode, 538 spec->num_channel_mode, 539 spec->ext_channel_count); 540} 541 542static int alc_ch_mode_put(struct snd_kcontrol *kcontrol, 543 struct snd_ctl_elem_value *ucontrol) 544{ 545 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 546 struct alc_spec *spec = codec->spec; 547 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode, 548 spec->num_channel_mode, 549 &spec->ext_channel_count); 550 if (err >= 0 && !spec->const_channel_count) { 551 spec->multiout.max_channels = spec->ext_channel_count; 552 if (spec->need_dac_fix) 553 spec->multiout.num_dacs = spec->multiout.max_channels / 2; 554 } 555 return err; 556} 557 558/* 559 * Control the mode of pin widget settings via the mixer. "pc" is used 560 * instead of "%" to avoid consequences of accidently treating the % as 561 * being part of a format specifier. Maximum allowed length of a value is 562 * 63 characters plus NULL terminator. 563 * 564 * Note: some retasking pin complexes seem to ignore requests for input 565 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these 566 * are requested. Therefore order this list so that this behaviour will not 567 * cause problems when mixer clients move through the enum sequentially. 568 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of 569 * March 2006. 570 */ 571static char *alc_pin_mode_names[] = { 572 "Mic 50pc bias", "Mic 80pc bias", 573 "Line in", "Line out", "Headphone out", 574}; 575static unsigned char alc_pin_mode_values[] = { 576 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP, 577}; 578/* The control can present all 5 options, or it can limit the options based 579 * in the pin being assumed to be exclusively an input or an output pin. In 580 * addition, "input" pins may or may not process the mic bias option 581 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to 582 * accept requests for bias as of chip versions up to March 2006) and/or 583 * wiring in the computer. 584 */ 585#define ALC_PIN_DIR_IN 0x00 586#define ALC_PIN_DIR_OUT 0x01 587#define ALC_PIN_DIR_INOUT 0x02 588#define ALC_PIN_DIR_IN_NOMICBIAS 0x03 589#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04 590 591/* Info about the pin modes supported by the different pin direction modes. 592 * For each direction the minimum and maximum values are given. 593 */ 594static signed char alc_pin_mode_dir_info[5][2] = { 595 { 0, 2 }, /* ALC_PIN_DIR_IN */ 596 { 3, 4 }, /* ALC_PIN_DIR_OUT */ 597 { 0, 4 }, /* ALC_PIN_DIR_INOUT */ 598 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */ 599 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */ 600}; 601#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0]) 602#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1]) 603#define alc_pin_mode_n_items(_dir) \ 604 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1) 605 606static int alc_pin_mode_info(struct snd_kcontrol *kcontrol, 607 struct snd_ctl_elem_info *uinfo) 608{ 609 unsigned int item_num = uinfo->value.enumerated.item; 610 unsigned char dir = (kcontrol->private_value >> 16) & 0xff; 611 612 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 613 uinfo->count = 1; 614 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir); 615 616 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir)) 617 item_num = alc_pin_mode_min(dir); 618 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]); 619 return 0; 620} 621 622static int alc_pin_mode_get(struct snd_kcontrol *kcontrol, 623 struct snd_ctl_elem_value *ucontrol) 624{ 625 unsigned int i; 626 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 627 hda_nid_t nid = kcontrol->private_value & 0xffff; 628 unsigned char dir = (kcontrol->private_value >> 16) & 0xff; 629 long *valp = ucontrol->value.integer.value; 630 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0, 631 AC_VERB_GET_PIN_WIDGET_CONTROL, 632 0x00); 633 634 /* Find enumerated value for current pinctl setting */ 635 i = alc_pin_mode_min(dir); 636 while (i <= alc_pin_mode_max(dir) && alc_pin_mode_values[i] != pinctl) 637 i++; 638 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir); 639 return 0; 640} 641 642static int alc_pin_mode_put(struct snd_kcontrol *kcontrol, 643 struct snd_ctl_elem_value *ucontrol) 644{ 645 signed int change; 646 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 647 hda_nid_t nid = kcontrol->private_value & 0xffff; 648 unsigned char dir = (kcontrol->private_value >> 16) & 0xff; 649 long val = *ucontrol->value.integer.value; 650 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0, 651 AC_VERB_GET_PIN_WIDGET_CONTROL, 652 0x00); 653 654 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir)) 655 val = alc_pin_mode_min(dir); 656 657 change = pinctl != alc_pin_mode_values[val]; 658 if (change) { 659 /* Set pin mode to that requested */ 660 snd_hda_codec_write_cache(codec, nid, 0, 661 AC_VERB_SET_PIN_WIDGET_CONTROL, 662 alc_pin_mode_values[val]); 663 664 /* Also enable the retasking pin's input/output as required 665 * for the requested pin mode. Enum values of 2 or less are 666 * input modes. 667 * 668 * Dynamically switching the input/output buffers probably 669 * reduces noise slightly (particularly on input) so we'll 670 * do it. However, having both input and output buffers 671 * enabled simultaneously doesn't seem to be problematic if 672 * this turns out to be necessary in the future. 673 */ 674 if (val <= 2) { 675 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, 676 HDA_AMP_MUTE, HDA_AMP_MUTE); 677 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0, 678 HDA_AMP_MUTE, 0); 679 } else { 680 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0, 681 HDA_AMP_MUTE, HDA_AMP_MUTE); 682 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, 683 HDA_AMP_MUTE, 0); 684 } 685 } 686 return change; 687} 688 689#define ALC_PIN_MODE(xname, nid, dir) \ 690 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 691 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \ 692 .info = alc_pin_mode_info, \ 693 .get = alc_pin_mode_get, \ 694 .put = alc_pin_mode_put, \ 695 .private_value = nid | (dir<<16) } 696 697/* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged 698 * together using a mask with more than one bit set. This control is 699 * currently used only by the ALC260 test model. At this stage they are not 700 * needed for any "production" models. 701 */ 702#ifdef CONFIG_SND_DEBUG 703#define alc_gpio_data_info snd_ctl_boolean_mono_info 704 705static int alc_gpio_data_get(struct snd_kcontrol *kcontrol, 706 struct snd_ctl_elem_value *ucontrol) 707{ 708 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 709 hda_nid_t nid = kcontrol->private_value & 0xffff; 710 unsigned char mask = (kcontrol->private_value >> 16) & 0xff; 711 long *valp = ucontrol->value.integer.value; 712 unsigned int val = snd_hda_codec_read(codec, nid, 0, 713 AC_VERB_GET_GPIO_DATA, 0x00); 714 715 *valp = (val & mask) != 0; 716 return 0; 717} 718static int alc_gpio_data_put(struct snd_kcontrol *kcontrol, 719 struct snd_ctl_elem_value *ucontrol) 720{ 721 signed int change; 722 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 723 hda_nid_t nid = kcontrol->private_value & 0xffff; 724 unsigned char mask = (kcontrol->private_value >> 16) & 0xff; 725 long val = *ucontrol->value.integer.value; 726 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0, 727 AC_VERB_GET_GPIO_DATA, 728 0x00); 729 730 /* Set/unset the masked GPIO bit(s) as needed */ 731 change = (val == 0 ? 0 : mask) != (gpio_data & mask); 732 if (val == 0) 733 gpio_data &= ~mask; 734 else 735 gpio_data |= mask; 736 snd_hda_codec_write_cache(codec, nid, 0, 737 AC_VERB_SET_GPIO_DATA, gpio_data); 738 739 return change; 740} 741#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \ 742 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 743 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \ 744 .info = alc_gpio_data_info, \ 745 .get = alc_gpio_data_get, \ 746 .put = alc_gpio_data_put, \ 747 .private_value = nid | (mask<<16) } 748#endif /* CONFIG_SND_DEBUG */ 749 750/* A switch control to allow the enabling of the digital IO pins on the 751 * ALC260. This is incredibly simplistic; the intention of this control is 752 * to provide something in the test model allowing digital outputs to be 753 * identified if present. If models are found which can utilise these 754 * outputs a more complete mixer control can be devised for those models if 755 * necessary. 756 */ 757#ifdef CONFIG_SND_DEBUG 758#define alc_spdif_ctrl_info snd_ctl_boolean_mono_info 759 760static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol, 761 struct snd_ctl_elem_value *ucontrol) 762{ 763 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 764 hda_nid_t nid = kcontrol->private_value & 0xffff; 765 unsigned char mask = (kcontrol->private_value >> 16) & 0xff; 766 long *valp = ucontrol->value.integer.value; 767 unsigned int val = snd_hda_codec_read(codec, nid, 0, 768 AC_VERB_GET_DIGI_CONVERT_1, 0x00); 769 770 *valp = (val & mask) != 0; 771 return 0; 772} 773static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol, 774 struct snd_ctl_elem_value *ucontrol) 775{ 776 signed int change; 777 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 778 hda_nid_t nid = kcontrol->private_value & 0xffff; 779 unsigned char mask = (kcontrol->private_value >> 16) & 0xff; 780 long val = *ucontrol->value.integer.value; 781 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0, 782 AC_VERB_GET_DIGI_CONVERT_1, 783 0x00); 784 785 /* Set/unset the masked control bit(s) as needed */ 786 change = (val == 0 ? 0 : mask) != (ctrl_data & mask); 787 if (val==0) 788 ctrl_data &= ~mask; 789 else 790 ctrl_data |= mask; 791 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, 792 ctrl_data); 793 794 return change; 795} 796#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \ 797 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 798 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \ 799 .info = alc_spdif_ctrl_info, \ 800 .get = alc_spdif_ctrl_get, \ 801 .put = alc_spdif_ctrl_put, \ 802 .private_value = nid | (mask<<16) } 803#endif /* CONFIG_SND_DEBUG */ 804 805/* A switch control to allow the enabling EAPD digital outputs on the ALC26x. 806 * Again, this is only used in the ALC26x test models to help identify when 807 * the EAPD line must be asserted for features to work. 808 */ 809#ifdef CONFIG_SND_DEBUG 810#define alc_eapd_ctrl_info snd_ctl_boolean_mono_info 811 812static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol, 813 struct snd_ctl_elem_value *ucontrol) 814{ 815 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 816 hda_nid_t nid = kcontrol->private_value & 0xffff; 817 unsigned char mask = (kcontrol->private_value >> 16) & 0xff; 818 long *valp = ucontrol->value.integer.value; 819 unsigned int val = snd_hda_codec_read(codec, nid, 0, 820 AC_VERB_GET_EAPD_BTLENABLE, 0x00); 821 822 *valp = (val & mask) != 0; 823 return 0; 824} 825 826static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol, 827 struct snd_ctl_elem_value *ucontrol) 828{ 829 int change; 830 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 831 hda_nid_t nid = kcontrol->private_value & 0xffff; 832 unsigned char mask = (kcontrol->private_value >> 16) & 0xff; 833 long val = *ucontrol->value.integer.value; 834 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0, 835 AC_VERB_GET_EAPD_BTLENABLE, 836 0x00); 837 838 /* Set/unset the masked control bit(s) as needed */ 839 change = (!val ? 0 : mask) != (ctrl_data & mask); 840 if (!val) 841 ctrl_data &= ~mask; 842 else 843 ctrl_data |= mask; 844 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE, 845 ctrl_data); 846 847 return change; 848} 849 850#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \ 851 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 852 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \ 853 .info = alc_eapd_ctrl_info, \ 854 .get = alc_eapd_ctrl_get, \ 855 .put = alc_eapd_ctrl_put, \ 856 .private_value = nid | (mask<<16) } 857#endif /* CONFIG_SND_DEBUG */ 858 859/* 860 * set up the input pin config (depending on the given auto-pin type) 861 */ 862static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid, 863 int auto_pin_type) 864{ 865 unsigned int val = PIN_IN; 866 867 if (auto_pin_type == AUTO_PIN_MIC) { 868 unsigned int pincap; 869 unsigned int oldval; 870 oldval = snd_hda_codec_read(codec, nid, 0, 871 AC_VERB_GET_PIN_WIDGET_CONTROL, 0); 872 pincap = snd_hda_query_pin_caps(codec, nid); 873 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT; 874 /* if the default pin setup is vref50, we give it priority */ 875 if ((pincap & AC_PINCAP_VREF_80) && oldval != PIN_VREF50) 876 val = PIN_VREF80; 877 else if (pincap & AC_PINCAP_VREF_50) 878 val = PIN_VREF50; 879 else if (pincap & AC_PINCAP_VREF_100) 880 val = PIN_VREF100; 881 else if (pincap & AC_PINCAP_VREF_GRD) 882 val = PIN_VREFGRD; 883 } 884 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val); 885} 886 887static void alc_fixup_autocfg_pin_nums(struct hda_codec *codec) 888{ 889 struct alc_spec *spec = codec->spec; 890 struct auto_pin_cfg *cfg = &spec->autocfg; 891 892 if (!cfg->line_outs) { 893 while (cfg->line_outs < AUTO_CFG_MAX_OUTS && 894 cfg->line_out_pins[cfg->line_outs]) 895 cfg->line_outs++; 896 } 897 if (!cfg->speaker_outs) { 898 while (cfg->speaker_outs < AUTO_CFG_MAX_OUTS && 899 cfg->speaker_pins[cfg->speaker_outs]) 900 cfg->speaker_outs++; 901 } 902 if (!cfg->hp_outs) { 903 while (cfg->hp_outs < AUTO_CFG_MAX_OUTS && 904 cfg->hp_pins[cfg->hp_outs]) 905 cfg->hp_outs++; 906 } 907} 908 909/* 910 */ 911static void add_mixer(struct alc_spec *spec, struct snd_kcontrol_new *mix) 912{ 913 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers))) 914 return; 915 spec->mixers[spec->num_mixers++] = mix; 916} 917 918static void add_verb(struct alc_spec *spec, const struct hda_verb *verb) 919{ 920 if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs))) 921 return; 922 spec->init_verbs[spec->num_init_verbs++] = verb; 923} 924 925/* 926 * set up from the preset table 927 */ 928static void setup_preset(struct hda_codec *codec, 929 const struct alc_config_preset *preset) 930{ 931 struct alc_spec *spec = codec->spec; 932 int i; 933 934 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++) 935 add_mixer(spec, preset->mixers[i]); 936 spec->cap_mixer = preset->cap_mixer; 937 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i]; 938 i++) 939 add_verb(spec, preset->init_verbs[i]); 940 941 spec->channel_mode = preset->channel_mode; 942 spec->num_channel_mode = preset->num_channel_mode; 943 spec->need_dac_fix = preset->need_dac_fix; 944 spec->const_channel_count = preset->const_channel_count; 945 946 if (preset->const_channel_count) 947 spec->multiout.max_channels = preset->const_channel_count; 948 else 949 spec->multiout.max_channels = spec->channel_mode[0].channels; 950 spec->ext_channel_count = spec->channel_mode[0].channels; 951 952 spec->multiout.num_dacs = preset->num_dacs; 953 spec->multiout.dac_nids = preset->dac_nids; 954 spec->multiout.dig_out_nid = preset->dig_out_nid; 955 spec->multiout.slave_dig_outs = preset->slave_dig_outs; 956 spec->multiout.hp_nid = preset->hp_nid; 957 958 spec->num_mux_defs = preset->num_mux_defs; 959 if (!spec->num_mux_defs) 960 spec->num_mux_defs = 1; 961 spec->input_mux = preset->input_mux; 962 963 spec->num_adc_nids = preset->num_adc_nids; 964 spec->adc_nids = preset->adc_nids; 965 spec->capsrc_nids = preset->capsrc_nids; 966 spec->dig_in_nid = preset->dig_in_nid; 967 968 spec->unsol_event = preset->unsol_event; 969 spec->init_hook = preset->init_hook; 970#ifdef CONFIG_SND_HDA_POWER_SAVE 971 spec->power_hook = preset->power_hook; 972 spec->loopback.amplist = preset->loopbacks; 973#endif 974 975 if (preset->setup) 976 preset->setup(codec); 977 978 alc_fixup_autocfg_pin_nums(codec); 979} 980 981/* Enable GPIO mask and set output */ 982static struct hda_verb alc_gpio1_init_verbs[] = { 983 {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, 984 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, 985 {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, 986 { } 987}; 988 989static struct hda_verb alc_gpio2_init_verbs[] = { 990 {0x01, AC_VERB_SET_GPIO_MASK, 0x02}, 991 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02}, 992 {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, 993 { } 994}; 995 996static struct hda_verb alc_gpio3_init_verbs[] = { 997 {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, 998 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03}, 999 {0x01, AC_VERB_SET_GPIO_DATA, 0x03}, 1000 { } 1001}; 1002 1003/* 1004 * Fix hardware PLL issue 1005 * On some codecs, the analog PLL gating control must be off while 1006 * the default value is 1. 1007 */ 1008static void alc_fix_pll(struct hda_codec *codec) 1009{ 1010 struct alc_spec *spec = codec->spec; 1011 unsigned int val; 1012 1013 if (!spec->pll_nid) 1014 return; 1015 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX, 1016 spec->pll_coef_idx); 1017 val = snd_hda_codec_read(codec, spec->pll_nid, 0, 1018 AC_VERB_GET_PROC_COEF, 0); 1019 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX, 1020 spec->pll_coef_idx); 1021 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF, 1022 val & ~(1 << spec->pll_coef_bit)); 1023} 1024 1025static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid, 1026 unsigned int coef_idx, unsigned int coef_bit) 1027{ 1028 struct alc_spec *spec = codec->spec; 1029 spec->pll_nid = nid; 1030 spec->pll_coef_idx = coef_idx; 1031 spec->pll_coef_bit = coef_bit; 1032 alc_fix_pll(codec); 1033} 1034 1035#ifdef CONFIG_SND_HDA_INPUT_JACK 1036static void alc_free_jack_priv(struct snd_jack *jack) 1037{ 1038 struct alc_jack *jacks = jack->private_data; 1039 jacks->nid = 0; 1040 jacks->jack = NULL; 1041} 1042 1043static int alc_add_jack(struct hda_codec *codec, 1044 hda_nid_t nid, int type) 1045{ 1046 struct alc_spec *spec; 1047 struct alc_jack *jack; 1048 const char *name; 1049 int err; 1050 1051 spec = codec->spec; 1052 snd_array_init(&spec->jacks, sizeof(*jack), 32); 1053 jack = snd_array_new(&spec->jacks); 1054 if (!jack) 1055 return -ENOMEM; 1056 1057 jack->nid = nid; 1058 jack->type = type; 1059 name = (type == SND_JACK_HEADPHONE) ? "Headphone" : "Mic" ; 1060 1061 err = snd_jack_new(codec->bus->card, name, type, &jack->jack); 1062 if (err < 0) 1063 return err; 1064 jack->jack->private_data = jack; 1065 jack->jack->private_free = alc_free_jack_priv; 1066 return 0; 1067} 1068 1069static void alc_report_jack(struct hda_codec *codec, hda_nid_t nid) 1070{ 1071 struct alc_spec *spec = codec->spec; 1072 struct alc_jack *jacks = spec->jacks.list; 1073 1074 if (jacks) { 1075 int i; 1076 for (i = 0; i < spec->jacks.used; i++) { 1077 if (jacks->nid == nid) { 1078 unsigned int present; 1079 present = snd_hda_jack_detect(codec, nid); 1080 1081 present = (present) ? jacks->type : 0; 1082 1083 snd_jack_report(jacks->jack, present); 1084 } 1085 jacks++; 1086 } 1087 } 1088} 1089 1090static int alc_init_jacks(struct hda_codec *codec) 1091{ 1092 struct alc_spec *spec = codec->spec; 1093 int err; 1094 unsigned int hp_nid = spec->autocfg.hp_pins[0]; 1095 unsigned int mic_nid = spec->ext_mic.pin; 1096 1097 if (hp_nid) { 1098 err = alc_add_jack(codec, hp_nid, SND_JACK_HEADPHONE); 1099 if (err < 0) 1100 return err; 1101 alc_report_jack(codec, hp_nid); 1102 } 1103 1104 if (mic_nid) { 1105 err = alc_add_jack(codec, mic_nid, SND_JACK_MICROPHONE); 1106 if (err < 0) 1107 return err; 1108 alc_report_jack(codec, mic_nid); 1109 } 1110 1111 return 0; 1112} 1113#else 1114static inline void alc_report_jack(struct hda_codec *codec, hda_nid_t nid) 1115{ 1116} 1117 1118static inline int alc_init_jacks(struct hda_codec *codec) 1119{ 1120 return 0; 1121} 1122#endif 1123 1124static void alc_automute_speaker(struct hda_codec *codec, int pinctl) 1125{ 1126 struct alc_spec *spec = codec->spec; 1127 unsigned int mute; 1128 hda_nid_t nid; 1129 int i; 1130 1131 spec->jack_present = 0; 1132 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) { 1133 nid = spec->autocfg.hp_pins[i]; 1134 if (!nid) 1135 break; 1136 if (snd_hda_jack_detect(codec, nid)) { 1137 spec->jack_present = 1; 1138 break; 1139 } 1140 alc_report_jack(codec, spec->autocfg.hp_pins[i]); 1141 } 1142 1143 mute = spec->jack_present ? HDA_AMP_MUTE : 0; 1144 /* Toggle internal speakers muting */ 1145 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) { 1146 nid = spec->autocfg.speaker_pins[i]; 1147 if (!nid) 1148 break; 1149 if (pinctl) { 1150 snd_hda_codec_write(codec, nid, 0, 1151 AC_VERB_SET_PIN_WIDGET_CONTROL, 1152 spec->jack_present ? 0 : PIN_OUT); 1153 } else { 1154 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, 1155 HDA_AMP_MUTE, mute); 1156 } 1157 } 1158} 1159 1160static void alc_automute_pin(struct hda_codec *codec) 1161{ 1162 alc_automute_speaker(codec, 1); 1163} 1164 1165static int get_connection_index(struct hda_codec *codec, hda_nid_t mux, 1166 hda_nid_t nid) 1167{ 1168 hda_nid_t conn[HDA_MAX_NUM_INPUTS]; 1169 int i, nums; 1170 1171 nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn)); 1172 for (i = 0; i < nums; i++) 1173 if (conn[i] == nid) 1174 return i; 1175 return -1; 1176} 1177 1178/* switch the current ADC according to the jack state */ 1179static void alc_dual_mic_adc_auto_switch(struct hda_codec *codec) 1180{ 1181 struct alc_spec *spec = codec->spec; 1182 unsigned int present; 1183 hda_nid_t new_adc; 1184 1185 present = snd_hda_jack_detect(codec, spec->ext_mic.pin); 1186 if (present) 1187 spec->cur_adc_idx = 1; 1188 else 1189 spec->cur_adc_idx = 0; 1190 new_adc = spec->adc_nids[spec->cur_adc_idx]; 1191 if (spec->cur_adc && spec->cur_adc != new_adc) { 1192 /* stream is running, let's swap the current ADC */ 1193 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1); 1194 spec->cur_adc = new_adc; 1195 snd_hda_codec_setup_stream(codec, new_adc, 1196 spec->cur_adc_stream_tag, 0, 1197 spec->cur_adc_format); 1198 } 1199} 1200 1201static void alc_mic_automute(struct hda_codec *codec) 1202{ 1203 struct alc_spec *spec = codec->spec; 1204 struct alc_mic_route *dead, *alive; 1205 unsigned int present, type; 1206 hda_nid_t cap_nid; 1207 1208 if (!spec->auto_mic) 1209 return; 1210 if (!spec->int_mic.pin || !spec->ext_mic.pin) 1211 return; 1212 if (snd_BUG_ON(!spec->adc_nids)) 1213 return; 1214 1215 if (spec->dual_adc_switch) { 1216 alc_dual_mic_adc_auto_switch(codec); 1217 return; 1218 } 1219 1220 cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0]; 1221 1222 present = snd_hda_jack_detect(codec, spec->ext_mic.pin); 1223 if (present) { 1224 alive = &spec->ext_mic; 1225 dead = &spec->int_mic; 1226 } else { 1227 alive = &spec->int_mic; 1228 dead = &spec->ext_mic; 1229 } 1230 1231 type = get_wcaps_type(get_wcaps(codec, cap_nid)); 1232 if (type == AC_WID_AUD_MIX) { 1233 /* Matrix-mixer style (e.g. ALC882) */ 1234 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT, 1235 alive->mux_idx, 1236 HDA_AMP_MUTE, 0); 1237 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT, 1238 dead->mux_idx, 1239 HDA_AMP_MUTE, HDA_AMP_MUTE); 1240 } else { 1241 /* MUX style (e.g. ALC880) */ 1242 snd_hda_codec_write_cache(codec, cap_nid, 0, 1243 AC_VERB_SET_CONNECT_SEL, 1244 alive->mux_idx); 1245 } 1246 alc_report_jack(codec, spec->ext_mic.pin); 1247 1248 /* FIXME: analog mixer */ 1249} 1250 1251/* unsolicited event for HP jack sensing */ 1252static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res) 1253{ 1254 if (codec->vendor_id == 0x10ec0880) 1255 res >>= 28; 1256 else 1257 res >>= 26; 1258 switch (res) { 1259 case ALC880_HP_EVENT: 1260 alc_automute_pin(codec); 1261 break; 1262 case ALC880_MIC_EVENT: 1263 alc_mic_automute(codec); 1264 break; 1265 } 1266} 1267 1268static void alc_inithook(struct hda_codec *codec) 1269{ 1270 alc_automute_pin(codec); 1271 alc_mic_automute(codec); 1272} 1273 1274/* additional initialization for ALC888 variants */ 1275static void alc888_coef_init(struct hda_codec *codec) 1276{ 1277 unsigned int tmp; 1278 1279 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0); 1280 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0); 1281 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7); 1282 if ((tmp & 0xf0) == 0x20) 1283 /* alc888S-VC */ 1284 snd_hda_codec_read(codec, 0x20, 0, 1285 AC_VERB_SET_PROC_COEF, 0x830); 1286 else 1287 /* alc888-VB */ 1288 snd_hda_codec_read(codec, 0x20, 0, 1289 AC_VERB_SET_PROC_COEF, 0x3030); 1290} 1291 1292static void alc889_coef_init(struct hda_codec *codec) 1293{ 1294 unsigned int tmp; 1295 1296 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7); 1297 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0); 1298 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7); 1299 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, tmp|0x2010); 1300} 1301 1302/* turn on/off EAPD control (only if available) */ 1303static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on) 1304{ 1305 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN) 1306 return; 1307 if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD) 1308 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE, 1309 on ? 2 : 0); 1310} 1311 1312static void alc_auto_init_amp(struct hda_codec *codec, int type) 1313{ 1314 unsigned int tmp; 1315 1316 switch (type) { 1317 case ALC_INIT_GPIO1: 1318 snd_hda_sequence_write(codec, alc_gpio1_init_verbs); 1319 break; 1320 case ALC_INIT_GPIO2: 1321 snd_hda_sequence_write(codec, alc_gpio2_init_verbs); 1322 break; 1323 case ALC_INIT_GPIO3: 1324 snd_hda_sequence_write(codec, alc_gpio3_init_verbs); 1325 break; 1326 case ALC_INIT_DEFAULT: 1327 switch (codec->vendor_id) { 1328 case 0x10ec0260: 1329 set_eapd(codec, 0x0f, 1); 1330 set_eapd(codec, 0x10, 1); 1331 break; 1332 case 0x10ec0262: 1333 case 0x10ec0267: 1334 case 0x10ec0268: 1335 case 0x10ec0269: 1336 case 0x10ec0270: 1337 case 0x10ec0272: 1338 case 0x10ec0660: 1339 case 0x10ec0662: 1340 case 0x10ec0663: 1341 case 0x10ec0862: 1342 case 0x10ec0889: 1343 set_eapd(codec, 0x14, 1); 1344 set_eapd(codec, 0x15, 1); 1345 break; 1346 } 1347 switch (codec->vendor_id) { 1348 case 0x10ec0260: 1349 snd_hda_codec_write(codec, 0x1a, 0, 1350 AC_VERB_SET_COEF_INDEX, 7); 1351 tmp = snd_hda_codec_read(codec, 0x1a, 0, 1352 AC_VERB_GET_PROC_COEF, 0); 1353 snd_hda_codec_write(codec, 0x1a, 0, 1354 AC_VERB_SET_COEF_INDEX, 7); 1355 snd_hda_codec_write(codec, 0x1a, 0, 1356 AC_VERB_SET_PROC_COEF, 1357 tmp | 0x2010); 1358 break; 1359 case 0x10ec0262: 1360 case 0x10ec0880: 1361 case 0x10ec0882: 1362 case 0x10ec0883: 1363 case 0x10ec0885: 1364 case 0x10ec0887: 1365 case 0x10ec0889: 1366 alc889_coef_init(codec); 1367 break; 1368 case 0x10ec0888: 1369 alc888_coef_init(codec); 1370 break; 1371#if 0 /* XXX: This may cause the silent output on speaker on some machines */ 1372 case 0x10ec0267: 1373 case 0x10ec0268: 1374 snd_hda_codec_write(codec, 0x20, 0, 1375 AC_VERB_SET_COEF_INDEX, 7); 1376 tmp = snd_hda_codec_read(codec, 0x20, 0, 1377 AC_VERB_GET_PROC_COEF, 0); 1378 snd_hda_codec_write(codec, 0x20, 0, 1379 AC_VERB_SET_COEF_INDEX, 7); 1380 snd_hda_codec_write(codec, 0x20, 0, 1381 AC_VERB_SET_PROC_COEF, 1382 tmp | 0x3000); 1383 break; 1384#endif /* XXX */ 1385 } 1386 break; 1387 } 1388} 1389 1390static void alc_init_auto_hp(struct hda_codec *codec) 1391{ 1392 struct alc_spec *spec = codec->spec; 1393 struct auto_pin_cfg *cfg = &spec->autocfg; 1394 int i; 1395 1396 if (!cfg->hp_pins[0]) { 1397 if (cfg->line_out_type != AUTO_PIN_HP_OUT) 1398 return; 1399 } 1400 1401 if (!cfg->speaker_pins[0]) { 1402 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) 1403 return; 1404 memcpy(cfg->speaker_pins, cfg->line_out_pins, 1405 sizeof(cfg->speaker_pins)); 1406 cfg->speaker_outs = cfg->line_outs; 1407 } 1408 1409 if (!cfg->hp_pins[0]) { 1410 memcpy(cfg->hp_pins, cfg->line_out_pins, 1411 sizeof(cfg->hp_pins)); 1412 cfg->hp_outs = cfg->line_outs; 1413 } 1414 1415 for (i = 0; i < cfg->hp_outs; i++) { 1416 snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n", 1417 cfg->hp_pins[i]); 1418 snd_hda_codec_write_cache(codec, cfg->hp_pins[i], 0, 1419 AC_VERB_SET_UNSOLICITED_ENABLE, 1420 AC_USRSP_EN | ALC880_HP_EVENT); 1421 } 1422 spec->unsol_event = alc_sku_unsol_event; 1423} 1424 1425static void alc_init_auto_mic(struct hda_codec *codec) 1426{ 1427 struct alc_spec *spec = codec->spec; 1428 struct auto_pin_cfg *cfg = &spec->autocfg; 1429 hda_nid_t fixed, ext; 1430 int i; 1431 1432 /* there must be only two mic inputs exclusively */ 1433 for (i = 0; i < cfg->num_inputs; i++) 1434 if (cfg->inputs[i].type >= AUTO_PIN_LINE_IN) 1435 return; 1436 1437 fixed = ext = 0; 1438 for (i = 0; i < cfg->num_inputs; i++) { 1439 hda_nid_t nid = cfg->inputs[i].pin; 1440 unsigned int defcfg; 1441 defcfg = snd_hda_codec_get_pincfg(codec, nid); 1442 switch (snd_hda_get_input_pin_attr(defcfg)) { 1443 case INPUT_PIN_ATTR_INT: 1444 if (fixed) 1445 return; /* already occupied */ 1446 fixed = nid; 1447 break; 1448 case INPUT_PIN_ATTR_UNUSED: 1449 return; /* invalid entry */ 1450 default: 1451 if (ext) 1452 return; /* already occupied */ 1453 ext = nid; 1454 break; 1455 } 1456 } 1457 if (!ext || !fixed) 1458 return; 1459 if (!(get_wcaps(codec, ext) & AC_WCAP_UNSOL_CAP)) 1460 return; /* no unsol support */ 1461 snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x\n", 1462 ext, fixed); 1463 spec->ext_mic.pin = ext; 1464 spec->int_mic.pin = fixed; 1465 spec->ext_mic.mux_idx = MUX_IDX_UNDEF; /* set later */ 1466 spec->int_mic.mux_idx = MUX_IDX_UNDEF; /* set later */ 1467 spec->auto_mic = 1; 1468 snd_hda_codec_write_cache(codec, spec->ext_mic.pin, 0, 1469 AC_VERB_SET_UNSOLICITED_ENABLE, 1470 AC_USRSP_EN | ALC880_MIC_EVENT); 1471 spec->unsol_event = alc_sku_unsol_event; 1472} 1473 1474/* Could be any non-zero and even value. When used as fixup, tells 1475 * the driver to ignore any present sku defines. 1476 */ 1477#define ALC_FIXUP_SKU_IGNORE (2) 1478 1479static int alc_auto_parse_customize_define(struct hda_codec *codec) 1480{ 1481 unsigned int ass, tmp, i; 1482 unsigned nid = 0; 1483 struct alc_spec *spec = codec->spec; 1484 1485 spec->cdefine.enable_pcbeep = 1; /* assume always enabled */ 1486 1487 if (spec->cdefine.fixup) { 1488 ass = spec->cdefine.sku_cfg; 1489 if (ass == ALC_FIXUP_SKU_IGNORE) 1490 return -1; 1491 goto do_sku; 1492 } 1493 1494 ass = codec->subsystem_id & 0xffff; 1495 if (ass != codec->bus->pci->subsystem_device && (ass & 1)) 1496 goto do_sku; 1497 1498 nid = 0x1d; 1499 if (codec->vendor_id == 0x10ec0260) 1500 nid = 0x17; 1501 ass = snd_hda_codec_get_pincfg(codec, nid); 1502 1503 if (!(ass & 1)) { 1504 printk(KERN_INFO "hda_codec: %s: SKU not ready 0x%08x\n", 1505 codec->chip_name, ass); 1506 return -1; 1507 } 1508 1509 /* check sum */ 1510 tmp = 0; 1511 for (i = 1; i < 16; i++) { 1512 if ((ass >> i) & 1) 1513 tmp++; 1514 } 1515 if (((ass >> 16) & 0xf) != tmp) 1516 return -1; 1517 1518 spec->cdefine.port_connectivity = ass >> 30; 1519 spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20; 1520 spec->cdefine.check_sum = (ass >> 16) & 0xf; 1521 spec->cdefine.customization = ass >> 8; 1522do_sku: 1523 spec->cdefine.sku_cfg = ass; 1524 spec->cdefine.external_amp = (ass & 0x38) >> 3; 1525 spec->cdefine.platform_type = (ass & 0x4) >> 2; 1526 spec->cdefine.swap = (ass & 0x2) >> 1; 1527 spec->cdefine.override = ass & 0x1; 1528 1529 snd_printd("SKU: Nid=0x%x sku_cfg=0x%08x\n", 1530 nid, spec->cdefine.sku_cfg); 1531 snd_printd("SKU: port_connectivity=0x%x\n", 1532 spec->cdefine.port_connectivity); 1533 snd_printd("SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep); 1534 snd_printd("SKU: check_sum=0x%08x\n", spec->cdefine.check_sum); 1535 snd_printd("SKU: customization=0x%08x\n", spec->cdefine.customization); 1536 snd_printd("SKU: external_amp=0x%x\n", spec->cdefine.external_amp); 1537 snd_printd("SKU: platform_type=0x%x\n", spec->cdefine.platform_type); 1538 snd_printd("SKU: swap=0x%x\n", spec->cdefine.swap); 1539 snd_printd("SKU: override=0x%x\n", spec->cdefine.override); 1540 1541 return 0; 1542} 1543 1544/* check subsystem ID and set up device-specific initialization; 1545 * return 1 if initialized, 0 if invalid SSID 1546 */ 1547/* 32-bit subsystem ID for BIOS loading in HD Audio codec. 1548 * 31 ~ 16 : Manufacture ID 1549 * 15 ~ 8 : SKU ID 1550 * 7 ~ 0 : Assembly ID 1551 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36 1552 */ 1553static int alc_subsystem_id(struct hda_codec *codec, 1554 hda_nid_t porta, hda_nid_t porte, 1555 hda_nid_t portd, hda_nid_t porti) 1556{ 1557 unsigned int ass, tmp, i; 1558 unsigned nid; 1559 struct alc_spec *spec = codec->spec; 1560 1561 if (spec->cdefine.fixup) { 1562 ass = spec->cdefine.sku_cfg; 1563 if (ass == ALC_FIXUP_SKU_IGNORE) 1564 return 0; 1565 goto do_sku; 1566 } 1567 1568 ass = codec->subsystem_id & 0xffff; 1569 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1)) 1570 goto do_sku; 1571 1572 /* invalid SSID, check the special NID pin defcfg instead */ 1573 /* 1574 * 31~30 : port connectivity 1575 * 29~21 : reserve 1576 * 20 : PCBEEP input 1577 * 19~16 : Check sum (15:1) 1578 * 15~1 : Custom 1579 * 0 : override 1580 */ 1581 nid = 0x1d; 1582 if (codec->vendor_id == 0x10ec0260) 1583 nid = 0x17; 1584 ass = snd_hda_codec_get_pincfg(codec, nid); 1585 snd_printd("realtek: No valid SSID, " 1586 "checking pincfg 0x%08x for NID 0x%x\n", 1587 ass, nid); 1588 if (!(ass & 1)) 1589 return 0; 1590 if ((ass >> 30) != 1) /* no physical connection */ 1591 return 0; 1592 1593 /* check sum */ 1594 tmp = 0; 1595 for (i = 1; i < 16; i++) { 1596 if ((ass >> i) & 1) 1597 tmp++; 1598 } 1599 if (((ass >> 16) & 0xf) != tmp) 1600 return 0; 1601do_sku: 1602 snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n", 1603 ass & 0xffff, codec->vendor_id); 1604 /* 1605 * 0 : override 1606 * 1 : Swap Jack 1607 * 2 : 0 --> Desktop, 1 --> Laptop 1608 * 3~5 : External Amplifier control 1609 * 7~6 : Reserved 1610 */ 1611 tmp = (ass & 0x38) >> 3; /* external Amp control */ 1612 switch (tmp) { 1613 case 1: 1614 spec->init_amp = ALC_INIT_GPIO1; 1615 break; 1616 case 3: 1617 spec->init_amp = ALC_INIT_GPIO2; 1618 break; 1619 case 7: 1620 spec->init_amp = ALC_INIT_GPIO3; 1621 break; 1622 case 5: 1623 default: 1624 spec->init_amp = ALC_INIT_DEFAULT; 1625 break; 1626 } 1627 1628 /* is laptop or Desktop and enable the function "Mute internal speaker 1629 * when the external headphone out jack is plugged" 1630 */ 1631 if (!(ass & 0x8000)) 1632 return 1; 1633 /* 1634 * 10~8 : Jack location 1635 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered 1636 * 14~13: Resvered 1637 * 15 : 1 --> enable the function "Mute internal speaker 1638 * when the external headphone out jack is plugged" 1639 */ 1640 if (!spec->autocfg.hp_pins[0]) { 1641 hda_nid_t nid; 1642 tmp = (ass >> 11) & 0x3; /* HP to chassis */ 1643 if (tmp == 0) 1644 nid = porta; 1645 else if (tmp == 1) 1646 nid = porte; 1647 else if (tmp == 2) 1648 nid = portd; 1649 else if (tmp == 3) 1650 nid = porti; 1651 else 1652 return 1; 1653 for (i = 0; i < spec->autocfg.line_outs; i++) 1654 if (spec->autocfg.line_out_pins[i] == nid) 1655 return 1; 1656 spec->autocfg.hp_pins[0] = nid; 1657 } 1658 1659 alc_init_auto_hp(codec); 1660 alc_init_auto_mic(codec); 1661 return 1; 1662} 1663 1664static void alc_ssid_check(struct hda_codec *codec, 1665 hda_nid_t porta, hda_nid_t porte, 1666 hda_nid_t portd, hda_nid_t porti) 1667{ 1668 if (!alc_subsystem_id(codec, porta, porte, portd, porti)) { 1669 struct alc_spec *spec = codec->spec; 1670 snd_printd("realtek: " 1671 "Enable default setup for auto mode as fallback\n"); 1672 spec->init_amp = ALC_INIT_DEFAULT; 1673 alc_init_auto_hp(codec); 1674 alc_init_auto_mic(codec); 1675 } 1676} 1677 1678/* 1679 * Fix-up pin default configurations and add default verbs 1680 */ 1681 1682struct alc_pincfg { 1683 hda_nid_t nid; 1684 u32 val; 1685}; 1686 1687struct alc_model_fixup { 1688 const int id; 1689 const char *name; 1690}; 1691 1692struct alc_fixup { 1693 int type; 1694 bool chained; 1695 int chain_id; 1696 union { 1697 unsigned int sku; 1698 const struct alc_pincfg *pins; 1699 const struct hda_verb *verbs; 1700 void (*func)(struct hda_codec *codec, 1701 const struct alc_fixup *fix, 1702 int action); 1703 } v; 1704}; 1705 1706enum { 1707 ALC_FIXUP_INVALID, 1708 ALC_FIXUP_SKU, 1709 ALC_FIXUP_PINS, 1710 ALC_FIXUP_VERBS, 1711 ALC_FIXUP_FUNC, 1712}; 1713 1714enum { 1715 ALC_FIXUP_ACT_PRE_PROBE, 1716 ALC_FIXUP_ACT_PROBE, 1717 ALC_FIXUP_ACT_INIT, 1718}; 1719 1720static void alc_apply_fixup(struct hda_codec *codec, int action) 1721{ 1722 struct alc_spec *spec = codec->spec; 1723 int id = spec->fixup_id; 1724 const char *modelname = spec->fixup_name; 1725 int depth = 0; 1726 1727 if (!spec->fixup_list) 1728 return; 1729 1730 while (id >= 0) { 1731 const struct alc_fixup *fix = spec->fixup_list + id; 1732 const struct alc_pincfg *cfg; 1733 1734 switch (fix->type) { 1735 case ALC_FIXUP_SKU: 1736 if (action != ALC_FIXUP_ACT_PRE_PROBE || !fix->v.sku) 1737 break;; 1738 snd_printdd(KERN_INFO "hda_codec: %s: " 1739 "Apply sku override for %s\n", 1740 codec->chip_name, modelname); 1741 spec->cdefine.sku_cfg = fix->v.sku; 1742 spec->cdefine.fixup = 1; 1743 break; 1744 case ALC_FIXUP_PINS: 1745 cfg = fix->v.pins; 1746 if (action != ALC_FIXUP_ACT_PRE_PROBE || !cfg) 1747 break; 1748 snd_printdd(KERN_INFO "hda_codec: %s: " 1749 "Apply pincfg for %s\n", 1750 codec->chip_name, modelname); 1751 for (; cfg->nid; cfg++) 1752 snd_hda_codec_set_pincfg(codec, cfg->nid, 1753 cfg->val); 1754 break; 1755 case ALC_FIXUP_VERBS: 1756 if (action != ALC_FIXUP_ACT_PROBE || !fix->v.verbs) 1757 break; 1758 snd_printdd(KERN_INFO "hda_codec: %s: " 1759 "Apply fix-verbs for %s\n", 1760 codec->chip_name, modelname); 1761 add_verb(codec->spec, fix->v.verbs); 1762 break; 1763 case ALC_FIXUP_FUNC: 1764 if (!fix->v.func) 1765 break; 1766 snd_printdd(KERN_INFO "hda_codec: %s: " 1767 "Apply fix-func for %s\n", 1768 codec->chip_name, modelname); 1769 fix->v.func(codec, fix, action); 1770 break; 1771 default: 1772 snd_printk(KERN_ERR "hda_codec: %s: " 1773 "Invalid fixup type %d\n", 1774 codec->chip_name, fix->type); 1775 break; 1776 } 1777 if (!fix[id].chained) 1778 break; 1779 if (++depth > 10) 1780 break; 1781 id = fix[id].chain_id; 1782 } 1783} 1784 1785static void alc_pick_fixup(struct hda_codec *codec, 1786 const struct alc_model_fixup *models, 1787 const struct snd_pci_quirk *quirk, 1788 const struct alc_fixup *fixlist) 1789{ 1790 struct alc_spec *spec = codec->spec; 1791 int id = -1; 1792 const char *name = NULL; 1793 1794 if (codec->modelname && models) { 1795 while (models->name) { 1796 if (!strcmp(codec->modelname, models->name)) { 1797 id = models->id; 1798 name = models->name; 1799 break; 1800 } 1801 models++; 1802 } 1803 } 1804 if (id < 0) { 1805 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk); 1806 if (quirk) { 1807 id = quirk->value; 1808#ifdef CONFIG_SND_DEBUG_VERBOSE 1809 name = quirk->name; 1810#endif 1811 } 1812 } 1813 1814 spec->fixup_id = id; 1815 if (id >= 0) { 1816 spec->fixup_list = fixlist; 1817 spec->fixup_name = name; 1818 } 1819} 1820 1821static int alc_read_coef_idx(struct hda_codec *codec, 1822 unsigned int coef_idx) 1823{ 1824 unsigned int val; 1825 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 1826 coef_idx); 1827 val = snd_hda_codec_read(codec, 0x20, 0, 1828 AC_VERB_GET_PROC_COEF, 0); 1829 return val; 1830} 1831 1832static void alc_write_coef_idx(struct hda_codec *codec, unsigned int coef_idx, 1833 unsigned int coef_val) 1834{ 1835 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 1836 coef_idx); 1837 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, 1838 coef_val); 1839} 1840 1841/* set right pin controls for digital I/O */ 1842static void alc_auto_init_digital(struct hda_codec *codec) 1843{ 1844 struct alc_spec *spec = codec->spec; 1845 int i; 1846 hda_nid_t pin; 1847 1848 for (i = 0; i < spec->autocfg.dig_outs; i++) { 1849 pin = spec->autocfg.dig_out_pins[i]; 1850 if (pin) { 1851 snd_hda_codec_write(codec, pin, 0, 1852 AC_VERB_SET_PIN_WIDGET_CONTROL, 1853 PIN_OUT); 1854 } 1855 } 1856 pin = spec->autocfg.dig_in_pin; 1857 if (pin) 1858 snd_hda_codec_write(codec, pin, 0, 1859 AC_VERB_SET_PIN_WIDGET_CONTROL, 1860 PIN_IN); 1861} 1862 1863/* parse digital I/Os and set up NIDs in BIOS auto-parse mode */ 1864static void alc_auto_parse_digital(struct hda_codec *codec) 1865{ 1866 struct alc_spec *spec = codec->spec; 1867 int i, err; 1868 hda_nid_t dig_nid; 1869 1870 /* support multiple SPDIFs; the secondary is set up as a slave */ 1871 for (i = 0; i < spec->autocfg.dig_outs; i++) { 1872 err = snd_hda_get_connections(codec, 1873 spec->autocfg.dig_out_pins[i], 1874 &dig_nid, 1); 1875 if (err < 0) 1876 continue; 1877 if (!i) { 1878 spec->multiout.dig_out_nid = dig_nid; 1879 spec->dig_out_type = spec->autocfg.dig_out_type[0]; 1880 } else { 1881 spec->multiout.slave_dig_outs = spec->slave_dig_outs; 1882 if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1) 1883 break; 1884 spec->slave_dig_outs[i - 1] = dig_nid; 1885 } 1886 } 1887 1888 if (spec->autocfg.dig_in_pin) { 1889 dig_nid = codec->start_nid; 1890 for (i = 0; i < codec->num_nodes; i++, dig_nid++) { 1891 unsigned int wcaps = get_wcaps(codec, dig_nid); 1892 if (get_wcaps_type(wcaps) != AC_WID_AUD_IN) 1893 continue; 1894 if (!(wcaps & AC_WCAP_DIGITAL)) 1895 continue; 1896 if (!(wcaps & AC_WCAP_CONN_LIST)) 1897 continue; 1898 err = get_connection_index(codec, dig_nid, 1899 spec->autocfg.dig_in_pin); 1900 if (err >= 0) { 1901 spec->dig_in_nid = dig_nid; 1902 break; 1903 } 1904 } 1905 } 1906} 1907 1908/* 1909 * ALC888 1910 */ 1911 1912/* 1913 * 2ch mode 1914 */ 1915static struct hda_verb alc888_4ST_ch2_intel_init[] = { 1916/* Mic-in jack as mic in */ 1917 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 1918 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 1919/* Line-in jack as Line in */ 1920 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 1921 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 1922/* Line-Out as Front */ 1923 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00}, 1924 { } /* end */ 1925}; 1926 1927/* 1928 * 4ch mode 1929 */ 1930static struct hda_verb alc888_4ST_ch4_intel_init[] = { 1931/* Mic-in jack as mic in */ 1932 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 1933 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 1934/* Line-in jack as Surround */ 1935 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 1936 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 1937/* Line-Out as Front */ 1938 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00}, 1939 { } /* end */ 1940}; 1941 1942/* 1943 * 6ch mode 1944 */ 1945static struct hda_verb alc888_4ST_ch6_intel_init[] = { 1946/* Mic-in jack as CLFE */ 1947 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 1948 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 1949/* Line-in jack as Surround */ 1950 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 1951 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 1952/* Line-Out as CLFE (workaround because Mic-in is not loud enough) */ 1953 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, 1954 { } /* end */ 1955}; 1956 1957/* 1958 * 8ch mode 1959 */ 1960static struct hda_verb alc888_4ST_ch8_intel_init[] = { 1961/* Mic-in jack as CLFE */ 1962 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 1963 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 1964/* Line-in jack as Surround */ 1965 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 1966 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 1967/* Line-Out as Side */ 1968 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, 1969 { } /* end */ 1970}; 1971 1972static struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = { 1973 { 2, alc888_4ST_ch2_intel_init }, 1974 { 4, alc888_4ST_ch4_intel_init }, 1975 { 6, alc888_4ST_ch6_intel_init }, 1976 { 8, alc888_4ST_ch8_intel_init }, 1977}; 1978 1979/* 1980 * ALC888 Fujitsu Siemens Amillo xa3530 1981 */ 1982 1983static struct hda_verb alc888_fujitsu_xa3530_verbs[] = { 1984/* Front Mic: set to PIN_IN (empty by default) */ 1985 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1986/* Connect Internal HP to Front */ 1987 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1988 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1989 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 1990/* Connect Bass HP to Front */ 1991 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1992 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1993 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 1994/* Connect Line-Out side jack (SPDIF) to Side */ 1995 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1996 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1997 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, 1998/* Connect Mic jack to CLFE */ 1999 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2000 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2001 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, 2002/* Connect Line-in jack to Surround */ 2003 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2004 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2005 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, 2006/* Connect HP out jack to Front */ 2007 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2008 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2009 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 2010/* Enable unsolicited event for HP jack and Line-out jack */ 2011 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 2012 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 2013 {} 2014}; 2015 2016static void alc_automute_amp(struct hda_codec *codec) 2017{ 2018 alc_automute_speaker(codec, 0); 2019} 2020 2021static void alc_automute_amp_unsol_event(struct hda_codec *codec, 2022 unsigned int res) 2023{ 2024 if (codec->vendor_id == 0x10ec0880) 2025 res >>= 28; 2026 else 2027 res >>= 26; 2028 if (res == ALC880_HP_EVENT) 2029 alc_automute_amp(codec); 2030} 2031 2032static void alc889_automute_setup(struct hda_codec *codec) 2033{ 2034 struct alc_spec *spec = codec->spec; 2035 2036 spec->autocfg.hp_pins[0] = 0x15; 2037 spec->autocfg.speaker_pins[0] = 0x14; 2038 spec->autocfg.speaker_pins[1] = 0x16; 2039 spec->autocfg.speaker_pins[2] = 0x17; 2040 spec->autocfg.speaker_pins[3] = 0x19; 2041 spec->autocfg.speaker_pins[4] = 0x1a; 2042} 2043 2044static void alc889_intel_init_hook(struct hda_codec *codec) 2045{ 2046 alc889_coef_init(codec); 2047 alc_automute_amp(codec); 2048} 2049 2050static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec) 2051{ 2052 struct alc_spec *spec = codec->spec; 2053 2054 spec->autocfg.hp_pins[0] = 0x17; /* line-out */ 2055 spec->autocfg.hp_pins[1] = 0x1b; /* hp */ 2056 spec->autocfg.speaker_pins[0] = 0x14; /* speaker */ 2057 spec->autocfg.speaker_pins[1] = 0x15; /* bass */ 2058} 2059 2060/* 2061 * ALC888 Acer Aspire 4930G model 2062 */ 2063 2064static struct hda_verb alc888_acer_aspire_4930g_verbs[] = { 2065/* Front Mic: set to PIN_IN (empty by default) */ 2066 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2067/* Unselect Front Mic by default in input mixer 3 */ 2068 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)}, 2069/* Enable unsolicited event for HP jack */ 2070 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 2071/* Connect Internal HP to front */ 2072 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2073 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2074 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 2075/* Connect HP out to front */ 2076 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2077 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2078 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 2079 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, 2080 { } 2081}; 2082 2083/* 2084 * ALC888 Acer Aspire 6530G model 2085 */ 2086 2087static struct hda_verb alc888_acer_aspire_6530g_verbs[] = { 2088/* Route to built-in subwoofer as well as speakers */ 2089 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 2090 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 2091 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 2092 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 2093/* Bias voltage on for external mic port */ 2094 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80}, 2095/* Front Mic: set to PIN_IN (empty by default) */ 2096 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2097/* Unselect Front Mic by default in input mixer 3 */ 2098 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)}, 2099/* Enable unsolicited event for HP jack */ 2100 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 2101/* Enable speaker output */ 2102 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2103 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2104 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 2105/* Enable headphone output */ 2106 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP}, 2107 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2108 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 2109 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, 2110 { } 2111}; 2112 2113/* 2114 *ALC888 Acer Aspire 7730G model 2115 */ 2116 2117static struct hda_verb alc888_acer_aspire_7730G_verbs[] = { 2118/* Bias voltage on for external mic port */ 2119 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80}, 2120/* Front Mic: set to PIN_IN (empty by default) */ 2121 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2122/* Unselect Front Mic by default in input mixer 3 */ 2123 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)}, 2124/* Enable unsolicited event for HP jack */ 2125 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 2126/* Enable speaker output */ 2127 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2128 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2129 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 2130/* Enable headphone output */ 2131 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP}, 2132 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2133 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 2134 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, 2135/*Enable internal subwoofer */ 2136 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2137 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2138 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02}, 2139 {0x17, AC_VERB_SET_EAPD_BTLENABLE, 2}, 2140 { } 2141}; 2142 2143/* 2144 * ALC889 Acer Aspire 8930G model 2145 */ 2146 2147static struct hda_verb alc889_acer_aspire_8930g_verbs[] = { 2148/* Front Mic: set to PIN_IN (empty by default) */ 2149 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2150/* Unselect Front Mic by default in input mixer 3 */ 2151 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)}, 2152/* Enable unsolicited event for HP jack */ 2153 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 2154/* Connect Internal Front to Front */ 2155 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2156 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2157 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 2158/* Connect Internal Rear to Rear */ 2159 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2160 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2161 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, 2162/* Connect Internal CLFE to CLFE */ 2163 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2164 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2165 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, 2166/* Connect HP out to Front */ 2167 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP}, 2168 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2169 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 2170/* Enable all DACs */ 2171/* DAC DISABLE/MUTE 1? */ 2172/* setting bits 1-5 disables DAC nids 0x02-0x06 apparently. Init=0x38 */ 2173 {0x20, AC_VERB_SET_COEF_INDEX, 0x03}, 2174 {0x20, AC_VERB_SET_PROC_COEF, 0x0000}, 2175/* DAC DISABLE/MUTE 2? */ 2176/* some bit here disables the other DACs. Init=0x4900 */ 2177 {0x20, AC_VERB_SET_COEF_INDEX, 0x08}, 2178 {0x20, AC_VERB_SET_PROC_COEF, 0x0000}, 2179/* DMIC fix 2180 * This laptop has a stereo digital microphone. The mics are only 1cm apart 2181 * which makes the stereo useless. However, either the mic or the ALC889 2182 * makes the signal become a difference/sum signal instead of standard 2183 * stereo, which is annoying. So instead we flip this bit which makes the 2184 * codec replicate the sum signal to both channels, turning it into a 2185 * normal mono mic. 2186 */ 2187/* DMIC_CONTROL? Init value = 0x0001 */ 2188 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b}, 2189 {0x20, AC_VERB_SET_PROC_COEF, 0x0003}, 2190 { } 2191}; 2192 2193static struct hda_input_mux alc888_2_capture_sources[2] = { 2194 /* Front mic only available on one ADC */ 2195 { 2196 .num_items = 4, 2197 .items = { 2198 { "Mic", 0x0 }, 2199 { "Line", 0x2 }, 2200 { "CD", 0x4 }, 2201 { "Front Mic", 0xb }, 2202 }, 2203 }, 2204 { 2205 .num_items = 3, 2206 .items = { 2207 { "Mic", 0x0 }, 2208 { "Line", 0x2 }, 2209 { "CD", 0x4 }, 2210 }, 2211 } 2212}; 2213 2214static struct hda_input_mux alc888_acer_aspire_6530_sources[2] = { 2215 /* Interal mic only available on one ADC */ 2216 { 2217 .num_items = 5, 2218 .items = { 2219 { "Mic", 0x0 }, 2220 { "Line In", 0x2 }, 2221 { "CD", 0x4 }, 2222 { "Input Mix", 0xa }, 2223 { "Internal Mic", 0xb }, 2224 }, 2225 }, 2226 { 2227 .num_items = 4, 2228 .items = { 2229 { "Mic", 0x0 }, 2230 { "Line In", 0x2 }, 2231 { "CD", 0x4 }, 2232 { "Input Mix", 0xa }, 2233 }, 2234 } 2235}; 2236 2237static struct hda_input_mux alc889_capture_sources[3] = { 2238 /* Digital mic only available on first "ADC" */ 2239 { 2240 .num_items = 5, 2241 .items = { 2242 { "Mic", 0x0 }, 2243 { "Line", 0x2 }, 2244 { "CD", 0x4 }, 2245 { "Front Mic", 0xb }, 2246 { "Input Mix", 0xa }, 2247 }, 2248 }, 2249 { 2250 .num_items = 4, 2251 .items = { 2252 { "Mic", 0x0 }, 2253 { "Line", 0x2 }, 2254 { "CD", 0x4 }, 2255 { "Input Mix", 0xa }, 2256 }, 2257 }, 2258 { 2259 .num_items = 4, 2260 .items = { 2261 { "Mic", 0x0 }, 2262 { "Line", 0x2 }, 2263 { "CD", 0x4 }, 2264 { "Input Mix", 0xa }, 2265 }, 2266 } 2267}; 2268 2269static struct snd_kcontrol_new alc888_base_mixer[] = { 2270 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2271 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 2272 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2273 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 2274 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, 2275 HDA_OUTPUT), 2276 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 2277 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 2278 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 2279 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 2280 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 2281 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 2282 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 2283 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 2284 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 2285 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 2286 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 2287 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 2288 { } /* end */ 2289}; 2290 2291static struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = { 2292 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2293 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 2294 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2295 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 2296 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, 2297 HDA_OUTPUT), 2298 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 2299 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 2300 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 2301 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 2302 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 2303 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 2304 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 2305 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 2306 { } /* end */ 2307}; 2308 2309 2310static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec) 2311{ 2312 struct alc_spec *spec = codec->spec; 2313 2314 spec->autocfg.hp_pins[0] = 0x15; 2315 spec->autocfg.speaker_pins[0] = 0x14; 2316 spec->autocfg.speaker_pins[1] = 0x16; 2317 spec->autocfg.speaker_pins[2] = 0x17; 2318} 2319 2320static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec) 2321{ 2322 struct alc_spec *spec = codec->spec; 2323 2324 spec->autocfg.hp_pins[0] = 0x15; 2325 spec->autocfg.speaker_pins[0] = 0x14; 2326 spec->autocfg.speaker_pins[1] = 0x16; 2327 spec->autocfg.speaker_pins[2] = 0x17; 2328} 2329 2330static void alc888_acer_aspire_7730g_setup(struct hda_codec *codec) 2331{ 2332 struct alc_spec *spec = codec->spec; 2333 2334 spec->autocfg.hp_pins[0] = 0x15; 2335 spec->autocfg.speaker_pins[0] = 0x14; 2336 spec->autocfg.speaker_pins[1] = 0x16; 2337 spec->autocfg.speaker_pins[2] = 0x17; 2338} 2339 2340static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec) 2341{ 2342 struct alc_spec *spec = codec->spec; 2343 2344 spec->autocfg.hp_pins[0] = 0x15; 2345 spec->autocfg.speaker_pins[0] = 0x14; 2346 spec->autocfg.speaker_pins[1] = 0x16; 2347 spec->autocfg.speaker_pins[2] = 0x1b; 2348} 2349 2350/* 2351 * ALC880 3-stack model 2352 * 2353 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e) 2354 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18, 2355 * F-Mic = 0x1b, HP = 0x19 2356 */ 2357 2358static hda_nid_t alc880_dac_nids[4] = { 2359 /* front, rear, clfe, rear_surr */ 2360 0x02, 0x05, 0x04, 0x03 2361}; 2362 2363static hda_nid_t alc880_adc_nids[3] = { 2364 /* ADC0-2 */ 2365 0x07, 0x08, 0x09, 2366}; 2367 2368/* The datasheet says the node 0x07 is connected from inputs, 2369 * but it shows zero connection in the real implementation on some devices. 2370 * Note: this is a 915GAV bug, fixed on 915GLV 2371 */ 2372static hda_nid_t alc880_adc_nids_alt[2] = { 2373 /* ADC1-2 */ 2374 0x08, 0x09, 2375}; 2376 2377#define ALC880_DIGOUT_NID 0x06 2378#define ALC880_DIGIN_NID 0x0a 2379 2380static struct hda_input_mux alc880_capture_source = { 2381 .num_items = 4, 2382 .items = { 2383 { "Mic", 0x0 }, 2384 { "Front Mic", 0x3 }, 2385 { "Line", 0x2 }, 2386 { "CD", 0x4 }, 2387 }, 2388}; 2389 2390/* channel source setting (2/6 channel selection for 3-stack) */ 2391/* 2ch mode */ 2392static struct hda_verb alc880_threestack_ch2_init[] = { 2393 /* set line-in to input, mute it */ 2394 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 2395 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 2396 /* set mic-in to input vref 80%, mute it */ 2397 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 2398 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 2399 { } /* end */ 2400}; 2401 2402/* 6ch mode */ 2403static struct hda_verb alc880_threestack_ch6_init[] = { 2404 /* set line-in to output, unmute it */ 2405 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 2406 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 2407 /* set mic-in to output, unmute it */ 2408 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 2409 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 2410 { } /* end */ 2411}; 2412 2413static struct hda_channel_mode alc880_threestack_modes[2] = { 2414 { 2, alc880_threestack_ch2_init }, 2415 { 6, alc880_threestack_ch6_init }, 2416}; 2417 2418static struct snd_kcontrol_new alc880_three_stack_mixer[] = { 2419 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2420 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 2421 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 2422 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT), 2423 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 2424 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 2425 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 2426 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 2427 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 2428 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 2429 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 2430 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 2431 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 2432 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 2433 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT), 2434 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT), 2435 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT), 2436 { 2437 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2438 .name = "Channel Mode", 2439 .info = alc_ch_mode_info, 2440 .get = alc_ch_mode_get, 2441 .put = alc_ch_mode_put, 2442 }, 2443 { } /* end */ 2444}; 2445 2446/* capture mixer elements */ 2447static int alc_cap_vol_info(struct snd_kcontrol *kcontrol, 2448 struct snd_ctl_elem_info *uinfo) 2449{ 2450 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2451 struct alc_spec *spec = codec->spec; 2452 int err; 2453 2454 mutex_lock(&codec->control_mutex); 2455 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0, 2456 HDA_INPUT); 2457 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo); 2458 mutex_unlock(&codec->control_mutex); 2459 return err; 2460} 2461 2462static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag, 2463 unsigned int size, unsigned int __user *tlv) 2464{ 2465 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2466 struct alc_spec *spec = codec->spec; 2467 int err; 2468 2469 mutex_lock(&codec->control_mutex); 2470 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0, 2471 HDA_INPUT); 2472 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv); 2473 mutex_unlock(&codec->control_mutex); 2474 return err; 2475} 2476 2477typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol, 2478 struct snd_ctl_elem_value *ucontrol); 2479 2480static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol, 2481 struct snd_ctl_elem_value *ucontrol, 2482 getput_call_t func) 2483{ 2484 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2485 struct alc_spec *spec = codec->spec; 2486 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 2487 int err; 2488 2489 mutex_lock(&codec->control_mutex); 2490 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx], 2491 3, 0, HDA_INPUT); 2492 err = func(kcontrol, ucontrol); 2493 mutex_unlock(&codec->control_mutex); 2494 return err; 2495} 2496 2497static int alc_cap_vol_get(struct snd_kcontrol *kcontrol, 2498 struct snd_ctl_elem_value *ucontrol) 2499{ 2500 return alc_cap_getput_caller(kcontrol, ucontrol, 2501 snd_hda_mixer_amp_volume_get); 2502} 2503 2504static int alc_cap_vol_put(struct snd_kcontrol *kcontrol, 2505 struct snd_ctl_elem_value *ucontrol) 2506{ 2507 return alc_cap_getput_caller(kcontrol, ucontrol, 2508 snd_hda_mixer_amp_volume_put); 2509} 2510 2511/* capture mixer elements */ 2512#define alc_cap_sw_info snd_ctl_boolean_stereo_info 2513 2514static int alc_cap_sw_get(struct snd_kcontrol *kcontrol, 2515 struct snd_ctl_elem_value *ucontrol) 2516{ 2517 return alc_cap_getput_caller(kcontrol, ucontrol, 2518 snd_hda_mixer_amp_switch_get); 2519} 2520 2521static int alc_cap_sw_put(struct snd_kcontrol *kcontrol, 2522 struct snd_ctl_elem_value *ucontrol) 2523{ 2524 return alc_cap_getput_caller(kcontrol, ucontrol, 2525 snd_hda_mixer_amp_switch_put); 2526} 2527 2528#define _DEFINE_CAPMIX(num) \ 2529 { \ 2530 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 2531 .name = "Capture Switch", \ 2532 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \ 2533 .count = num, \ 2534 .info = alc_cap_sw_info, \ 2535 .get = alc_cap_sw_get, \ 2536 .put = alc_cap_sw_put, \ 2537 }, \ 2538 { \ 2539 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 2540 .name = "Capture Volume", \ 2541 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \ 2542 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \ 2543 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \ 2544 .count = num, \ 2545 .info = alc_cap_vol_info, \ 2546 .get = alc_cap_vol_get, \ 2547 .put = alc_cap_vol_put, \ 2548 .tlv = { .c = alc_cap_vol_tlv }, \ 2549 } 2550 2551#define _DEFINE_CAPSRC(num) \ 2552 { \ 2553 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 2554 /* .name = "Capture Source", */ \ 2555 .name = "Input Source", \ 2556 .count = num, \ 2557 .info = alc_mux_enum_info, \ 2558 .get = alc_mux_enum_get, \ 2559 .put = alc_mux_enum_put, \ 2560 } 2561 2562#define DEFINE_CAPMIX(num) \ 2563static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \ 2564 _DEFINE_CAPMIX(num), \ 2565 _DEFINE_CAPSRC(num), \ 2566 { } /* end */ \ 2567} 2568 2569#define DEFINE_CAPMIX_NOSRC(num) \ 2570static struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \ 2571 _DEFINE_CAPMIX(num), \ 2572 { } /* end */ \ 2573} 2574 2575/* up to three ADCs */ 2576DEFINE_CAPMIX(1); 2577DEFINE_CAPMIX(2); 2578DEFINE_CAPMIX(3); 2579DEFINE_CAPMIX_NOSRC(1); 2580DEFINE_CAPMIX_NOSRC(2); 2581DEFINE_CAPMIX_NOSRC(3); 2582 2583/* 2584 * ALC880 5-stack model 2585 * 2586 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d), 2587 * Side = 0x02 (0xd) 2588 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16 2589 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19 2590 */ 2591 2592/* additional mixers to alc880_three_stack_mixer */ 2593static struct snd_kcontrol_new alc880_five_stack_mixer[] = { 2594 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2595 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT), 2596 { } /* end */ 2597}; 2598 2599/* channel source setting (6/8 channel selection for 5-stack) */ 2600/* 6ch mode */ 2601static struct hda_verb alc880_fivestack_ch6_init[] = { 2602 /* set line-in to input, mute it */ 2603 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 2604 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 2605 { } /* end */ 2606}; 2607 2608/* 8ch mode */ 2609static struct hda_verb alc880_fivestack_ch8_init[] = { 2610 /* set line-in to output, unmute it */ 2611 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 2612 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 2613 { } /* end */ 2614}; 2615 2616static struct hda_channel_mode alc880_fivestack_modes[2] = { 2617 { 6, alc880_fivestack_ch6_init }, 2618 { 8, alc880_fivestack_ch8_init }, 2619}; 2620 2621 2622/* 2623 * ALC880 6-stack model 2624 * 2625 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e), 2626 * Side = 0x05 (0x0f) 2627 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17, 2628 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b 2629 */ 2630 2631static hda_nid_t alc880_6st_dac_nids[4] = { 2632 /* front, rear, clfe, rear_surr */ 2633 0x02, 0x03, 0x04, 0x05 2634}; 2635 2636static struct hda_input_mux alc880_6stack_capture_source = { 2637 .num_items = 4, 2638 .items = { 2639 { "Mic", 0x0 }, 2640 { "Front Mic", 0x1 }, 2641 { "Line", 0x2 }, 2642 { "CD", 0x4 }, 2643 }, 2644}; 2645 2646/* fixed 8-channels */ 2647static struct hda_channel_mode alc880_sixstack_modes[1] = { 2648 { 8, NULL }, 2649}; 2650 2651static struct snd_kcontrol_new alc880_six_stack_mixer[] = { 2652 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2653 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 2654 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2655 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 2656 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 2657 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 2658 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 2659 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 2660 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 2661 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 2662 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 2663 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 2664 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 2665 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 2666 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 2667 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 2668 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 2669 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 2670 { 2671 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2672 .name = "Channel Mode", 2673 .info = alc_ch_mode_info, 2674 .get = alc_ch_mode_get, 2675 .put = alc_ch_mode_put, 2676 }, 2677 { } /* end */ 2678}; 2679 2680 2681/* 2682 * ALC880 W810 model 2683 * 2684 * W810 has rear IO for: 2685 * Front (DAC 02) 2686 * Surround (DAC 03) 2687 * Center/LFE (DAC 04) 2688 * Digital out (06) 2689 * 2690 * The system also has a pair of internal speakers, and a headphone jack. 2691 * These are both connected to Line2 on the codec, hence to DAC 02. 2692 * 2693 * There is a variable resistor to control the speaker or headphone 2694 * volume. This is a hardware-only device without a software API. 2695 * 2696 * Plugging headphones in will disable the internal speakers. This is 2697 * implemented in hardware, not via the driver using jack sense. In 2698 * a similar fashion, plugging into the rear socket marked "front" will 2699 * disable both the speakers and headphones. 2700 * 2701 * For input, there's a microphone jack, and an "audio in" jack. 2702 * These may not do anything useful with this driver yet, because I 2703 * haven't setup any initialization verbs for these yet... 2704 */ 2705 2706static hda_nid_t alc880_w810_dac_nids[3] = { 2707 /* front, rear/surround, clfe */ 2708 0x02, 0x03, 0x04 2709}; 2710 2711/* fixed 6 channels */ 2712static struct hda_channel_mode alc880_w810_modes[1] = { 2713 { 6, NULL } 2714}; 2715 2716/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */ 2717static struct snd_kcontrol_new alc880_w810_base_mixer[] = { 2718 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2719 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 2720 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2721 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 2722 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 2723 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 2724 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 2725 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 2726 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 2727 { } /* end */ 2728}; 2729 2730 2731/* 2732 * Z710V model 2733 * 2734 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d) 2735 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?), 2736 * Line = 0x1a 2737 */ 2738 2739static hda_nid_t alc880_z71v_dac_nids[1] = { 2740 0x02 2741}; 2742#define ALC880_Z71V_HP_DAC 0x03 2743 2744/* fixed 2 channels */ 2745static struct hda_channel_mode alc880_2_jack_modes[1] = { 2746 { 2, NULL } 2747}; 2748 2749static struct snd_kcontrol_new alc880_z71v_mixer[] = { 2750 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2751 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 2752 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2753 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT), 2754 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 2755 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 2756 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 2757 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 2758 { } /* end */ 2759}; 2760 2761 2762/* 2763 * ALC880 F1734 model 2764 * 2765 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d) 2766 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18 2767 */ 2768 2769static hda_nid_t alc880_f1734_dac_nids[1] = { 2770 0x03 2771}; 2772#define ALC880_F1734_HP_DAC 0x02 2773 2774static struct snd_kcontrol_new alc880_f1734_mixer[] = { 2775 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2776 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), 2777 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2778 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 2779 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 2780 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 2781 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 2782 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 2783 { } /* end */ 2784}; 2785 2786static struct hda_input_mux alc880_f1734_capture_source = { 2787 .num_items = 2, 2788 .items = { 2789 { "Mic", 0x1 }, 2790 { "CD", 0x4 }, 2791 }, 2792}; 2793 2794 2795/* 2796 * ALC880 ASUS model 2797 * 2798 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e) 2799 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16, 2800 * Mic = 0x18, Line = 0x1a 2801 */ 2802 2803#define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */ 2804#define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */ 2805 2806static struct snd_kcontrol_new alc880_asus_mixer[] = { 2807 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2808 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 2809 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2810 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 2811 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 2812 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 2813 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 2814 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 2815 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 2816 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 2817 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 2818 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 2819 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 2820 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 2821 { 2822 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2823 .name = "Channel Mode", 2824 .info = alc_ch_mode_info, 2825 .get = alc_ch_mode_get, 2826 .put = alc_ch_mode_put, 2827 }, 2828 { } /* end */ 2829}; 2830 2831/* 2832 * ALC880 ASUS W1V model 2833 * 2834 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e) 2835 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16, 2836 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b 2837 */ 2838 2839/* additional mixers to alc880_asus_mixer */ 2840static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = { 2841 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT), 2842 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT), 2843 { } /* end */ 2844}; 2845 2846/* TCL S700 */ 2847static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = { 2848 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2849 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 2850 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 2851 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT), 2852 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT), 2853 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT), 2854 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT), 2855 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 2856 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 2857 { } /* end */ 2858}; 2859 2860/* Uniwill */ 2861static struct snd_kcontrol_new alc880_uniwill_mixer[] = { 2862 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2863 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), 2864 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2865 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 2866 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 2867 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 2868 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 2869 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 2870 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 2871 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 2872 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 2873 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 2874 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 2875 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 2876 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 2877 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 2878 { 2879 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2880 .name = "Channel Mode", 2881 .info = alc_ch_mode_info, 2882 .get = alc_ch_mode_get, 2883 .put = alc_ch_mode_put, 2884 }, 2885 { } /* end */ 2886}; 2887 2888static struct snd_kcontrol_new alc880_fujitsu_mixer[] = { 2889 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2890 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), 2891 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2892 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 2893 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 2894 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 2895 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 2896 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 2897 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 2898 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 2899 { } /* end */ 2900}; 2901 2902static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = { 2903 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2904 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), 2905 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2906 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 2907 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 2908 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 2909 { } /* end */ 2910}; 2911 2912/* 2913 * virtual master controls 2914 */ 2915 2916/* 2917 * slave controls for virtual master 2918 */ 2919static const char * const alc_slave_vols[] = { 2920 "Front Playback Volume", 2921 "Surround Playback Volume", 2922 "Center Playback Volume", 2923 "LFE Playback Volume", 2924 "Side Playback Volume", 2925 "Headphone Playback Volume", 2926 "Speaker Playback Volume", 2927 "Mono Playback Volume", 2928 "Line-Out Playback Volume", 2929 "PCM Playback Volume", 2930 NULL, 2931}; 2932 2933static const char * const alc_slave_sws[] = { 2934 "Front Playback Switch", 2935 "Surround Playback Switch", 2936 "Center Playback Switch", 2937 "LFE Playback Switch", 2938 "Side Playback Switch", 2939 "Headphone Playback Switch", 2940 "Speaker Playback Switch", 2941 "Mono Playback Switch", 2942 "IEC958 Playback Switch", 2943 "Line-Out Playback Switch", 2944 "PCM Playback Switch", 2945 NULL, 2946}; 2947 2948/* 2949 * build control elements 2950 */ 2951 2952#define NID_MAPPING (-1) 2953 2954#define SUBDEV_SPEAKER_ (0 << 6) 2955#define SUBDEV_HP_ (1 << 6) 2956#define SUBDEV_LINE_ (2 << 6) 2957#define SUBDEV_SPEAKER(x) (SUBDEV_SPEAKER_ | ((x) & 0x3f)) 2958#define SUBDEV_HP(x) (SUBDEV_HP_ | ((x) & 0x3f)) 2959#define SUBDEV_LINE(x) (SUBDEV_LINE_ | ((x) & 0x3f)) 2960 2961static void alc_free_kctls(struct hda_codec *codec); 2962 2963#ifdef CONFIG_SND_HDA_INPUT_BEEP 2964/* additional beep mixers; the actual parameters are overwritten at build */ 2965static struct snd_kcontrol_new alc_beep_mixer[] = { 2966 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT), 2967 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT), 2968 { } /* end */ 2969}; 2970#endif 2971 2972static int alc_build_controls(struct hda_codec *codec) 2973{ 2974 struct alc_spec *spec = codec->spec; 2975 struct snd_kcontrol *kctl = NULL; 2976 struct snd_kcontrol_new *knew; 2977 int i, j, err; 2978 unsigned int u; 2979 hda_nid_t nid; 2980 2981 for (i = 0; i < spec->num_mixers; i++) { 2982 err = snd_hda_add_new_ctls(codec, spec->mixers[i]); 2983 if (err < 0) 2984 return err; 2985 } 2986 if (spec->cap_mixer) { 2987 err = snd_hda_add_new_ctls(codec, spec->cap_mixer); 2988 if (err < 0) 2989 return err; 2990 } 2991 if (spec->multiout.dig_out_nid) { 2992 err = snd_hda_create_spdif_out_ctls(codec, 2993 spec->multiout.dig_out_nid); 2994 if (err < 0) 2995 return err; 2996 if (!spec->no_analog) { 2997 err = snd_hda_create_spdif_share_sw(codec, 2998 &spec->multiout); 2999 if (err < 0) 3000 return err; 3001 spec->multiout.share_spdif = 1; 3002 } 3003 } 3004 if (spec->dig_in_nid) { 3005 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid); 3006 if (err < 0) 3007 return err; 3008 } 3009 3010#ifdef CONFIG_SND_HDA_INPUT_BEEP 3011 /* create beep controls if needed */ 3012 if (spec->beep_amp) { 3013 struct snd_kcontrol_new *knew; 3014 for (knew = alc_beep_mixer; knew->name; knew++) { 3015 struct snd_kcontrol *kctl; 3016 kctl = snd_ctl_new1(knew, codec); 3017 if (!kctl) 3018 return -ENOMEM; 3019 kctl->private_value = spec->beep_amp; 3020 err = snd_hda_ctl_add(codec, 0, kctl); 3021 if (err < 0) 3022 return err; 3023 } 3024 } 3025#endif 3026 3027 /* if we have no master control, let's create it */ 3028 if (!spec->no_analog && 3029 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) { 3030 unsigned int vmaster_tlv[4]; 3031 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid, 3032 HDA_OUTPUT, vmaster_tlv); 3033 err = snd_hda_add_vmaster(codec, "Master Playback Volume", 3034 vmaster_tlv, alc_slave_vols); 3035 if (err < 0) 3036 return err; 3037 } 3038 if (!spec->no_analog && 3039 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) { 3040 err = snd_hda_add_vmaster(codec, "Master Playback Switch", 3041 NULL, alc_slave_sws); 3042 if (err < 0) 3043 return err; 3044 } 3045 3046 /* assign Capture Source enums to NID */ 3047 if (spec->capsrc_nids || spec->adc_nids) { 3048 kctl = snd_hda_find_mixer_ctl(codec, "Capture Source"); 3049 if (!kctl) 3050 kctl = snd_hda_find_mixer_ctl(codec, "Input Source"); 3051 for (i = 0; kctl && i < kctl->count; i++) { 3052 hda_nid_t *nids = spec->capsrc_nids; 3053 if (!nids) 3054 nids = spec->adc_nids; 3055 err = snd_hda_add_nid(codec, kctl, i, nids[i]); 3056 if (err < 0) 3057 return err; 3058 } 3059 } 3060 if (spec->cap_mixer) { 3061 const char *kname = kctl ? kctl->id.name : NULL; 3062 for (knew = spec->cap_mixer; knew->name; knew++) { 3063 if (kname && strcmp(knew->name, kname) == 0) 3064 continue; 3065 kctl = snd_hda_find_mixer_ctl(codec, knew->name); 3066 for (i = 0; kctl && i < kctl->count; i++) { 3067 err = snd_hda_add_nid(codec, kctl, i, 3068 spec->adc_nids[i]); 3069 if (err < 0) 3070 return err; 3071 } 3072 } 3073 } 3074 3075 /* other nid->control mapping */ 3076 for (i = 0; i < spec->num_mixers; i++) { 3077 for (knew = spec->mixers[i]; knew->name; knew++) { 3078 if (knew->iface != NID_MAPPING) 3079 continue; 3080 kctl = snd_hda_find_mixer_ctl(codec, knew->name); 3081 if (kctl == NULL) 3082 continue; 3083 u = knew->subdevice; 3084 for (j = 0; j < 4; j++, u >>= 8) { 3085 nid = u & 0x3f; 3086 if (nid == 0) 3087 continue; 3088 switch (u & 0xc0) { 3089 case SUBDEV_SPEAKER_: 3090 nid = spec->autocfg.speaker_pins[nid]; 3091 break; 3092 case SUBDEV_LINE_: 3093 nid = spec->autocfg.line_out_pins[nid]; 3094 break; 3095 case SUBDEV_HP_: 3096 nid = spec->autocfg.hp_pins[nid]; 3097 break; 3098 default: 3099 continue; 3100 } 3101 err = snd_hda_add_nid(codec, kctl, 0, nid); 3102 if (err < 0) 3103 return err; 3104 } 3105 u = knew->private_value; 3106 for (j = 0; j < 4; j++, u >>= 8) { 3107 nid = u & 0xff; 3108 if (nid == 0) 3109 continue; 3110 err = snd_hda_add_nid(codec, kctl, 0, nid); 3111 if (err < 0) 3112 return err; 3113 } 3114 } 3115 } 3116 3117 alc_free_kctls(codec); /* no longer needed */ 3118 3119 return 0; 3120} 3121 3122 3123/* 3124 * initialize the codec volumes, etc 3125 */ 3126 3127/* 3128 * generic initialization of ADC, input mixers and output mixers 3129 */ 3130static struct hda_verb alc880_volume_init_verbs[] = { 3131 /* 3132 * Unmute ADC0-2 and set the default input to mic-in 3133 */ 3134 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 3135 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3136 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 3137 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3138 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 3139 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3140 3141 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 3142 * mixer widget 3143 * Note: PASD motherboards uses the Line In 2 as the input for front 3144 * panel mic (mic 2) 3145 */ 3146 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 3147 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3148 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 3149 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 3150 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 3151 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 3152 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, 3153 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, 3154 3155 /* 3156 * Set up output mixers (0x0c - 0x0f) 3157 */ 3158 /* set vol=0 to output mixers */ 3159 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3160 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3161 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3162 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3163 /* set up input amps for analog loopback */ 3164 /* Amp Indices: DAC = 0, mixer = 1 */ 3165 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3166 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 3167 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3168 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 3169 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3170 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 3171 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3172 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 3173 3174 { } 3175}; 3176 3177/* 3178 * 3-stack pin configuration: 3179 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b 3180 */ 3181static struct hda_verb alc880_pin_3stack_init_verbs[] = { 3182 /* 3183 * preset connection lists of input pins 3184 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround 3185 */ 3186 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ 3187 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 3188 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */ 3189 3190 /* 3191 * Set pin mode and muting 3192 */ 3193 /* set front pin widgets 0x14 for output */ 3194 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3195 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3196 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 3197 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3198 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3199 /* Mic2 (as headphone out) for HP output */ 3200 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3201 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3202 /* Line In pin widget for input */ 3203 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3204 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3205 /* Line2 (as front mic) pin widget for input and vref at 80% */ 3206 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3207 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3208 /* CD pin widget for input */ 3209 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3210 3211 { } 3212}; 3213 3214/* 3215 * 5-stack pin configuration: 3216 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19, 3217 * line-in/side = 0x1a, f-mic = 0x1b 3218 */ 3219static struct hda_verb alc880_pin_5stack_init_verbs[] = { 3220 /* 3221 * preset connection lists of input pins 3222 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround 3223 */ 3224 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 3225 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */ 3226 3227 /* 3228 * Set pin mode and muting 3229 */ 3230 /* set pin widgets 0x14-0x17 for output */ 3231 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3232 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3233 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3234 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3235 /* unmute pins for output (no gain on this amp) */ 3236 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3237 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3238 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3239 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3240 3241 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 3242 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3243 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3244 /* Mic2 (as headphone out) for HP output */ 3245 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3246 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3247 /* Line In pin widget for input */ 3248 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3249 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3250 /* Line2 (as front mic) pin widget for input and vref at 80% */ 3251 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3252 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3253 /* CD pin widget for input */ 3254 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3255 3256 { } 3257}; 3258 3259/* 3260 * W810 pin configuration: 3261 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b 3262 */ 3263static struct hda_verb alc880_pin_w810_init_verbs[] = { 3264 /* hphone/speaker input selector: front DAC */ 3265 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0}, 3266 3267 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3268 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3269 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3270 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3271 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3272 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3273 3274 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3275 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3276 3277 { } 3278}; 3279 3280/* 3281 * Z71V pin configuration: 3282 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?) 3283 */ 3284static struct hda_verb alc880_pin_z71v_init_verbs[] = { 3285 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3286 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3287 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3288 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3289 3290 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3291 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3292 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3293 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3294 3295 { } 3296}; 3297 3298/* 3299 * 6-stack pin configuration: 3300 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18, 3301 * f-mic = 0x19, line = 0x1a, HP = 0x1b 3302 */ 3303static struct hda_verb alc880_pin_6stack_init_verbs[] = { 3304 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 3305 3306 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3307 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3308 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3309 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3310 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3311 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3312 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3313 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3314 3315 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3316 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3317 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3318 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3319 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3320 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3321 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3322 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3323 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3324 3325 { } 3326}; 3327 3328/* 3329 * Uniwill pin configuration: 3330 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19, 3331 * line = 0x1a 3332 */ 3333static struct hda_verb alc880_uniwill_init_verbs[] = { 3334 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 3335 3336 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3337 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3338 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3339 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3340 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3341 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3342 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3343 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3344 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 3345 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 3346 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 3347 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 3348 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 3349 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 3350 3351 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3352 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3353 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3354 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3355 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3356 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3357 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */ 3358 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */ 3359 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3360 3361 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 3362 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 3363 3364 { } 3365}; 3366 3367/* 3368* Uniwill P53 3369* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19, 3370 */ 3371static struct hda_verb alc880_uniwill_p53_init_verbs[] = { 3372 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 3373 3374 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3375 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3376 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3377 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3378 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3379 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3380 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 3381 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 3382 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 3383 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 3384 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 3385 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 3386 3387 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3388 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3389 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3390 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3391 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3392 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3393 3394 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 3395 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT}, 3396 3397 { } 3398}; 3399 3400static struct hda_verb alc880_beep_init_verbs[] = { 3401 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) }, 3402 { } 3403}; 3404 3405/* auto-toggle front mic */ 3406static void alc88x_simple_mic_automute(struct hda_codec *codec) 3407{ 3408 unsigned int present; 3409 unsigned char bits; 3410 3411 present = snd_hda_jack_detect(codec, 0x18); 3412 bits = present ? HDA_AMP_MUTE : 0; 3413 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits); 3414} 3415 3416static void alc880_uniwill_setup(struct hda_codec *codec) 3417{ 3418 struct alc_spec *spec = codec->spec; 3419 3420 spec->autocfg.hp_pins[0] = 0x14; 3421 spec->autocfg.speaker_pins[0] = 0x15; 3422 spec->autocfg.speaker_pins[0] = 0x16; 3423} 3424 3425static void alc880_uniwill_init_hook(struct hda_codec *codec) 3426{ 3427 alc_automute_amp(codec); 3428 alc88x_simple_mic_automute(codec); 3429} 3430 3431static void alc880_uniwill_unsol_event(struct hda_codec *codec, 3432 unsigned int res) 3433{ 3434 /* Looks like the unsol event is incompatible with the standard 3435 * definition. 4bit tag is placed at 28 bit! 3436 */ 3437 switch (res >> 28) { 3438 case ALC880_MIC_EVENT: 3439 alc88x_simple_mic_automute(codec); 3440 break; 3441 default: 3442 alc_automute_amp_unsol_event(codec, res); 3443 break; 3444 } 3445} 3446 3447static void alc880_uniwill_p53_setup(struct hda_codec *codec) 3448{ 3449 struct alc_spec *spec = codec->spec; 3450 3451 spec->autocfg.hp_pins[0] = 0x14; 3452 spec->autocfg.speaker_pins[0] = 0x15; 3453} 3454 3455static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec) 3456{ 3457 unsigned int present; 3458 3459 present = snd_hda_codec_read(codec, 0x21, 0, 3460 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0); 3461 present &= HDA_AMP_VOLMASK; 3462 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0, 3463 HDA_AMP_VOLMASK, present); 3464 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0, 3465 HDA_AMP_VOLMASK, present); 3466} 3467 3468static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec, 3469 unsigned int res) 3470{ 3471 /* Looks like the unsol event is incompatible with the standard 3472 * definition. 4bit tag is placed at 28 bit! 3473 */ 3474 if ((res >> 28) == ALC880_DCVOL_EVENT) 3475 alc880_uniwill_p53_dcvol_automute(codec); 3476 else 3477 alc_automute_amp_unsol_event(codec, res); 3478} 3479 3480/* 3481 * F1734 pin configuration: 3482 * HP = 0x14, speaker-out = 0x15, mic = 0x18 3483 */ 3484static struct hda_verb alc880_pin_f1734_init_verbs[] = { 3485 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01}, 3486 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, 3487 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, 3488 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, 3489 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, 3490 3491 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3492 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3493 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3494 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3495 3496 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3497 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3498 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, 3499 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3500 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3501 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3502 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3503 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3504 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3505 3506 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT}, 3507 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT}, 3508 3509 { } 3510}; 3511 3512/* 3513 * ASUS pin configuration: 3514 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a 3515 */ 3516static struct hda_verb alc880_pin_asus_init_verbs[] = { 3517 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, 3518 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, 3519 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, 3520 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, 3521 3522 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3523 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3524 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3525 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3526 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3527 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3528 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3529 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3530 3531 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3532 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3533 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3534 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3535 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3536 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3537 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3538 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3539 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3540 3541 { } 3542}; 3543 3544/* Enable GPIO mask and set output */ 3545#define alc880_gpio1_init_verbs alc_gpio1_init_verbs 3546#define alc880_gpio2_init_verbs alc_gpio2_init_verbs 3547#define alc880_gpio3_init_verbs alc_gpio3_init_verbs 3548 3549/* Clevo m520g init */ 3550static struct hda_verb alc880_pin_clevo_init_verbs[] = { 3551 /* headphone output */ 3552 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01}, 3553 /* line-out */ 3554 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3555 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3556 /* Line-in */ 3557 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3558 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3559 /* CD */ 3560 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3561 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3562 /* Mic1 (rear panel) */ 3563 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3564 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3565 /* Mic2 (front panel) */ 3566 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3567 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3568 /* headphone */ 3569 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3570 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3571 /* change to EAPD mode */ 3572 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 3573 {0x20, AC_VERB_SET_PROC_COEF, 0x3060}, 3574 3575 { } 3576}; 3577 3578static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = { 3579 /* change to EAPD mode */ 3580 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 3581 {0x20, AC_VERB_SET_PROC_COEF, 0x3060}, 3582 3583 /* Headphone output */ 3584 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3585 /* Front output*/ 3586 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3587 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 3588 3589 /* Line In pin widget for input */ 3590 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3591 /* CD pin widget for input */ 3592 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3593 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 3594 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3595 3596 /* change to EAPD mode */ 3597 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 3598 {0x20, AC_VERB_SET_PROC_COEF, 0x3070}, 3599 3600 { } 3601}; 3602 3603/* 3604 * LG m1 express dual 3605 * 3606 * Pin assignment: 3607 * Rear Line-In/Out (blue): 0x14 3608 * Build-in Mic-In: 0x15 3609 * Speaker-out: 0x17 3610 * HP-Out (green): 0x1b 3611 * Mic-In/Out (red): 0x19 3612 * SPDIF-Out: 0x1e 3613 */ 3614 3615/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */ 3616static hda_nid_t alc880_lg_dac_nids[3] = { 3617 0x05, 0x02, 0x03 3618}; 3619 3620/* seems analog CD is not working */ 3621static struct hda_input_mux alc880_lg_capture_source = { 3622 .num_items = 3, 3623 .items = { 3624 { "Mic", 0x1 }, 3625 { "Line", 0x5 }, 3626 { "Internal Mic", 0x6 }, 3627 }, 3628}; 3629 3630/* 2,4,6 channel modes */ 3631static struct hda_verb alc880_lg_ch2_init[] = { 3632 /* set line-in and mic-in to input */ 3633 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 3634 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 3635 { } 3636}; 3637 3638static struct hda_verb alc880_lg_ch4_init[] = { 3639 /* set line-in to out and mic-in to input */ 3640 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, 3641 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 3642 { } 3643}; 3644 3645static struct hda_verb alc880_lg_ch6_init[] = { 3646 /* set line-in and mic-in to output */ 3647 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, 3648 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, 3649 { } 3650}; 3651 3652static struct hda_channel_mode alc880_lg_ch_modes[3] = { 3653 { 2, alc880_lg_ch2_init }, 3654 { 4, alc880_lg_ch4_init }, 3655 { 6, alc880_lg_ch6_init }, 3656}; 3657 3658static struct snd_kcontrol_new alc880_lg_mixer[] = { 3659 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 3660 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT), 3661 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 3662 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT), 3663 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT), 3664 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT), 3665 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT), 3666 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT), 3667 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 3668 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 3669 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT), 3670 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT), 3671 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT), 3672 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT), 3673 { 3674 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 3675 .name = "Channel Mode", 3676 .info = alc_ch_mode_info, 3677 .get = alc_ch_mode_get, 3678 .put = alc_ch_mode_put, 3679 }, 3680 { } /* end */ 3681}; 3682 3683static struct hda_verb alc880_lg_init_verbs[] = { 3684 /* set capture source to mic-in */ 3685 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 3686 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 3687 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 3688 /* mute all amp mixer inputs */ 3689 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)}, 3690 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, 3691 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, 3692 /* line-in to input */ 3693 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3694 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3695 /* built-in mic */ 3696 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3697 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3698 /* speaker-out */ 3699 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3700 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3701 /* mic-in to input */ 3702 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01}, 3703 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3704 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3705 /* HP-out */ 3706 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03}, 3707 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3708 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3709 /* jack sense */ 3710 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 3711 { } 3712}; 3713 3714/* toggle speaker-output according to the hp-jack state */ 3715static void alc880_lg_setup(struct hda_codec *codec) 3716{ 3717 struct alc_spec *spec = codec->spec; 3718 3719 spec->autocfg.hp_pins[0] = 0x1b; 3720 spec->autocfg.speaker_pins[0] = 0x17; 3721} 3722 3723/* 3724 * LG LW20 3725 * 3726 * Pin assignment: 3727 * Speaker-out: 0x14 3728 * Mic-In: 0x18 3729 * Built-in Mic-In: 0x19 3730 * Line-In: 0x1b 3731 * HP-Out: 0x1a 3732 * SPDIF-Out: 0x1e 3733 */ 3734 3735static struct hda_input_mux alc880_lg_lw_capture_source = { 3736 .num_items = 3, 3737 .items = { 3738 { "Mic", 0x0 }, 3739 { "Internal Mic", 0x1 }, 3740 { "Line In", 0x2 }, 3741 }, 3742}; 3743 3744#define alc880_lg_lw_modes alc880_threestack_modes 3745 3746static struct snd_kcontrol_new alc880_lg_lw_mixer[] = { 3747 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 3748 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 3749 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 3750 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT), 3751 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 3752 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 3753 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 3754 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 3755 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 3756 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 3757 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 3758 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 3759 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 3760 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 3761 { 3762 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 3763 .name = "Channel Mode", 3764 .info = alc_ch_mode_info, 3765 .get = alc_ch_mode_get, 3766 .put = alc_ch_mode_put, 3767 }, 3768 { } /* end */ 3769}; 3770 3771static struct hda_verb alc880_lg_lw_init_verbs[] = { 3772 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 3773 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ 3774 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */ 3775 3776 /* set capture source to mic-in */ 3777 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3778 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3779 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3780 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, 3781 /* speaker-out */ 3782 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3783 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3784 /* HP-out */ 3785 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3786 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3787 /* mic-in to input */ 3788 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3789 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3790 /* built-in mic */ 3791 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3792 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3793 /* jack sense */ 3794 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 3795 { } 3796}; 3797 3798/* toggle speaker-output according to the hp-jack state */ 3799static void alc880_lg_lw_setup(struct hda_codec *codec) 3800{ 3801 struct alc_spec *spec = codec->spec; 3802 3803 spec->autocfg.hp_pins[0] = 0x1b; 3804 spec->autocfg.speaker_pins[0] = 0x14; 3805} 3806 3807static struct snd_kcontrol_new alc880_medion_rim_mixer[] = { 3808 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 3809 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT), 3810 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 3811 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 3812 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 3813 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT), 3814 { } /* end */ 3815}; 3816 3817static struct hda_input_mux alc880_medion_rim_capture_source = { 3818 .num_items = 2, 3819 .items = { 3820 { "Mic", 0x0 }, 3821 { "Internal Mic", 0x1 }, 3822 }, 3823}; 3824 3825static struct hda_verb alc880_medion_rim_init_verbs[] = { 3826 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 3827 3828 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3829 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3830 3831 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 3832 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3833 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3834 /* Mic2 (as headphone out) for HP output */ 3835 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3836 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3837 /* Internal Speaker */ 3838 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3839 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3840 3841 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 3842 {0x20, AC_VERB_SET_PROC_COEF, 0x3060}, 3843 3844 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 3845 { } 3846}; 3847 3848/* toggle speaker-output according to the hp-jack state */ 3849static void alc880_medion_rim_automute(struct hda_codec *codec) 3850{ 3851 struct alc_spec *spec = codec->spec; 3852 alc_automute_amp(codec); 3853 /* toggle EAPD */ 3854 if (spec->jack_present) 3855 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0); 3856 else 3857 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2); 3858} 3859 3860static void alc880_medion_rim_unsol_event(struct hda_codec *codec, 3861 unsigned int res) 3862{ 3863 /* Looks like the unsol event is incompatible with the standard 3864 * definition. 4bit tag is placed at 28 bit! 3865 */ 3866 if ((res >> 28) == ALC880_HP_EVENT) 3867 alc880_medion_rim_automute(codec); 3868} 3869 3870static void alc880_medion_rim_setup(struct hda_codec *codec) 3871{ 3872 struct alc_spec *spec = codec->spec; 3873 3874 spec->autocfg.hp_pins[0] = 0x14; 3875 spec->autocfg.speaker_pins[0] = 0x1b; 3876} 3877 3878#ifdef CONFIG_SND_HDA_POWER_SAVE 3879static struct hda_amp_list alc880_loopbacks[] = { 3880 { 0x0b, HDA_INPUT, 0 }, 3881 { 0x0b, HDA_INPUT, 1 }, 3882 { 0x0b, HDA_INPUT, 2 }, 3883 { 0x0b, HDA_INPUT, 3 }, 3884 { 0x0b, HDA_INPUT, 4 }, 3885 { } /* end */ 3886}; 3887 3888static struct hda_amp_list alc880_lg_loopbacks[] = { 3889 { 0x0b, HDA_INPUT, 1 }, 3890 { 0x0b, HDA_INPUT, 6 }, 3891 { 0x0b, HDA_INPUT, 7 }, 3892 { } /* end */ 3893}; 3894#endif 3895 3896/* 3897 * Common callbacks 3898 */ 3899 3900static int alc_init(struct hda_codec *codec) 3901{ 3902 struct alc_spec *spec = codec->spec; 3903 unsigned int i; 3904 3905 alc_fix_pll(codec); 3906 alc_auto_init_amp(codec, spec->init_amp); 3907 3908 for (i = 0; i < spec->num_init_verbs; i++) 3909 snd_hda_sequence_write(codec, spec->init_verbs[i]); 3910 3911 if (spec->init_hook) 3912 spec->init_hook(codec); 3913 3914 alc_apply_fixup(codec, ALC_FIXUP_ACT_INIT); 3915 3916 hda_call_check_power_status(codec, 0x01); 3917 return 0; 3918} 3919 3920static void alc_unsol_event(struct hda_codec *codec, unsigned int res) 3921{ 3922 struct alc_spec *spec = codec->spec; 3923 3924 if (spec->unsol_event) 3925 spec->unsol_event(codec, res); 3926} 3927 3928#ifdef CONFIG_SND_HDA_POWER_SAVE 3929static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid) 3930{ 3931 struct alc_spec *spec = codec->spec; 3932 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid); 3933} 3934#endif 3935 3936/* 3937 * Analog playback callbacks 3938 */ 3939static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo, 3940 struct hda_codec *codec, 3941 struct snd_pcm_substream *substream) 3942{ 3943 struct alc_spec *spec = codec->spec; 3944 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream, 3945 hinfo); 3946} 3947 3948static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo, 3949 struct hda_codec *codec, 3950 unsigned int stream_tag, 3951 unsigned int format, 3952 struct snd_pcm_substream *substream) 3953{ 3954 struct alc_spec *spec = codec->spec; 3955 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, 3956 stream_tag, format, substream); 3957} 3958 3959static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, 3960 struct hda_codec *codec, 3961 struct snd_pcm_substream *substream) 3962{ 3963 struct alc_spec *spec = codec->spec; 3964 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); 3965} 3966 3967/* 3968 * Digital out 3969 */ 3970static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo, 3971 struct hda_codec *codec, 3972 struct snd_pcm_substream *substream) 3973{ 3974 struct alc_spec *spec = codec->spec; 3975 return snd_hda_multi_out_dig_open(codec, &spec->multiout); 3976} 3977 3978static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, 3979 struct hda_codec *codec, 3980 unsigned int stream_tag, 3981 unsigned int format, 3982 struct snd_pcm_substream *substream) 3983{ 3984 struct alc_spec *spec = codec->spec; 3985 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, 3986 stream_tag, format, substream); 3987} 3988 3989static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, 3990 struct hda_codec *codec, 3991 struct snd_pcm_substream *substream) 3992{ 3993 struct alc_spec *spec = codec->spec; 3994 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout); 3995} 3996 3997static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, 3998 struct hda_codec *codec, 3999 struct snd_pcm_substream *substream) 4000{ 4001 struct alc_spec *spec = codec->spec; 4002 return snd_hda_multi_out_dig_close(codec, &spec->multiout); 4003} 4004 4005/* 4006 * Analog capture 4007 */ 4008static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo, 4009 struct hda_codec *codec, 4010 unsigned int stream_tag, 4011 unsigned int format, 4012 struct snd_pcm_substream *substream) 4013{ 4014 struct alc_spec *spec = codec->spec; 4015 4016 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1], 4017 stream_tag, 0, format); 4018 return 0; 4019} 4020 4021static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, 4022 struct hda_codec *codec, 4023 struct snd_pcm_substream *substream) 4024{ 4025 struct alc_spec *spec = codec->spec; 4026 4027 snd_hda_codec_cleanup_stream(codec, 4028 spec->adc_nids[substream->number + 1]); 4029 return 0; 4030} 4031 4032/* analog capture with dynamic dual-adc changes */ 4033static int dualmic_capture_pcm_prepare(struct hda_pcm_stream *hinfo, 4034 struct hda_codec *codec, 4035 unsigned int stream_tag, 4036 unsigned int format, 4037 struct snd_pcm_substream *substream) 4038{ 4039 struct alc_spec *spec = codec->spec; 4040 spec->cur_adc = spec->adc_nids[spec->cur_adc_idx]; 4041 spec->cur_adc_stream_tag = stream_tag; 4042 spec->cur_adc_format = format; 4043 snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format); 4044 return 0; 4045} 4046 4047static int dualmic_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, 4048 struct hda_codec *codec, 4049 struct snd_pcm_substream *substream) 4050{ 4051 struct alc_spec *spec = codec->spec; 4052 snd_hda_codec_cleanup_stream(codec, spec->cur_adc); 4053 spec->cur_adc = 0; 4054 return 0; 4055} 4056 4057static struct hda_pcm_stream dualmic_pcm_analog_capture = { 4058 .substreams = 1, 4059 .channels_min = 2, 4060 .channels_max = 2, 4061 .nid = 0, /* fill later */ 4062 .ops = { 4063 .prepare = dualmic_capture_pcm_prepare, 4064 .cleanup = dualmic_capture_pcm_cleanup 4065 }, 4066}; 4067 4068/* 4069 */ 4070static struct hda_pcm_stream alc880_pcm_analog_playback = { 4071 .substreams = 1, 4072 .channels_min = 2, 4073 .channels_max = 8, 4074 /* NID is set in alc_build_pcms */ 4075 .ops = { 4076 .open = alc880_playback_pcm_open, 4077 .prepare = alc880_playback_pcm_prepare, 4078 .cleanup = alc880_playback_pcm_cleanup 4079 }, 4080}; 4081 4082static struct hda_pcm_stream alc880_pcm_analog_capture = { 4083 .substreams = 1, 4084 .channels_min = 2, 4085 .channels_max = 2, 4086 /* NID is set in alc_build_pcms */ 4087}; 4088 4089static struct hda_pcm_stream alc880_pcm_analog_alt_playback = { 4090 .substreams = 1, 4091 .channels_min = 2, 4092 .channels_max = 2, 4093 /* NID is set in alc_build_pcms */ 4094}; 4095 4096static struct hda_pcm_stream alc880_pcm_analog_alt_capture = { 4097 .substreams = 2, /* can be overridden */ 4098 .channels_min = 2, 4099 .channels_max = 2, 4100 /* NID is set in alc_build_pcms */ 4101 .ops = { 4102 .prepare = alc880_alt_capture_pcm_prepare, 4103 .cleanup = alc880_alt_capture_pcm_cleanup 4104 }, 4105}; 4106 4107static struct hda_pcm_stream alc880_pcm_digital_playback = { 4108 .substreams = 1, 4109 .channels_min = 2, 4110 .channels_max = 2, 4111 /* NID is set in alc_build_pcms */ 4112 .ops = { 4113 .open = alc880_dig_playback_pcm_open, 4114 .close = alc880_dig_playback_pcm_close, 4115 .prepare = alc880_dig_playback_pcm_prepare, 4116 .cleanup = alc880_dig_playback_pcm_cleanup 4117 }, 4118}; 4119 4120static struct hda_pcm_stream alc880_pcm_digital_capture = { 4121 .substreams = 1, 4122 .channels_min = 2, 4123 .channels_max = 2, 4124 /* NID is set in alc_build_pcms */ 4125}; 4126 4127/* Used by alc_build_pcms to flag that a PCM has no playback stream */ 4128static struct hda_pcm_stream alc_pcm_null_stream = { 4129 .substreams = 0, 4130 .channels_min = 0, 4131 .channels_max = 0, 4132}; 4133 4134static int alc_build_pcms(struct hda_codec *codec) 4135{ 4136 struct alc_spec *spec = codec->spec; 4137 struct hda_pcm *info = spec->pcm_rec; 4138 int i; 4139 4140 codec->num_pcms = 1; 4141 codec->pcm_info = info; 4142 4143 if (spec->no_analog) 4144 goto skip_analog; 4145 4146 snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog), 4147 "%s Analog", codec->chip_name); 4148 info->name = spec->stream_name_analog; 4149 4150 if (spec->stream_analog_playback) { 4151 if (snd_BUG_ON(!spec->multiout.dac_nids)) 4152 return -EINVAL; 4153 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback); 4154 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0]; 4155 } 4156 if (spec->stream_analog_capture) { 4157 if (snd_BUG_ON(!spec->adc_nids)) 4158 return -EINVAL; 4159 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture); 4160 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0]; 4161 } 4162 4163 if (spec->channel_mode) { 4164 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0; 4165 for (i = 0; i < spec->num_channel_mode; i++) { 4166 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) { 4167 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels; 4168 } 4169 } 4170 } 4171 4172 skip_analog: 4173 /* SPDIF for stream index #1 */ 4174 if (spec->multiout.dig_out_nid || spec->dig_in_nid) { 4175 snprintf(spec->stream_name_digital, 4176 sizeof(spec->stream_name_digital), 4177 "%s Digital", codec->chip_name); 4178 codec->num_pcms = 2; 4179 codec->slave_dig_outs = spec->multiout.slave_dig_outs; 4180 info = spec->pcm_rec + 1; 4181 info->name = spec->stream_name_digital; 4182 if (spec->dig_out_type) 4183 info->pcm_type = spec->dig_out_type; 4184 else 4185 info->pcm_type = HDA_PCM_TYPE_SPDIF; 4186 if (spec->multiout.dig_out_nid && 4187 spec->stream_digital_playback) { 4188 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback); 4189 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid; 4190 } 4191 if (spec->dig_in_nid && 4192 spec->stream_digital_capture) { 4193 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture); 4194 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid; 4195 } 4196 /* FIXME: do we need this for all Realtek codec models? */ 4197 codec->spdif_status_reset = 1; 4198 } 4199 4200 if (spec->no_analog) 4201 return 0; 4202 4203 /* If the use of more than one ADC is requested for the current 4204 * model, configure a second analog capture-only PCM. 4205 */ 4206 /* Additional Analaog capture for index #2 */ 4207 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) || 4208 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) { 4209 codec->num_pcms = 3; 4210 info = spec->pcm_rec + 2; 4211 info->name = spec->stream_name_analog; 4212 if (spec->alt_dac_nid) { 4213 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = 4214 *spec->stream_analog_alt_playback; 4215 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 4216 spec->alt_dac_nid; 4217 } else { 4218 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = 4219 alc_pcm_null_stream; 4220 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0; 4221 } 4222 if (spec->num_adc_nids > 1) { 4223 info->stream[SNDRV_PCM_STREAM_CAPTURE] = 4224 *spec->stream_analog_alt_capture; 4225 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 4226 spec->adc_nids[1]; 4227 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = 4228 spec->num_adc_nids - 1; 4229 } else { 4230 info->stream[SNDRV_PCM_STREAM_CAPTURE] = 4231 alc_pcm_null_stream; 4232 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0; 4233 } 4234 } 4235 4236 return 0; 4237} 4238 4239static inline void alc_shutup(struct hda_codec *codec) 4240{ 4241 snd_hda_shutup_pins(codec); 4242} 4243 4244static void alc_free_kctls(struct hda_codec *codec) 4245{ 4246 struct alc_spec *spec = codec->spec; 4247 4248 if (spec->kctls.list) { 4249 struct snd_kcontrol_new *kctl = spec->kctls.list; 4250 int i; 4251 for (i = 0; i < spec->kctls.used; i++) 4252 kfree(kctl[i].name); 4253 } 4254 snd_array_free(&spec->kctls); 4255} 4256 4257static void alc_free(struct hda_codec *codec) 4258{ 4259 struct alc_spec *spec = codec->spec; 4260 4261 if (!spec) 4262 return; 4263 4264 alc_shutup(codec); 4265 alc_free_kctls(codec); 4266 kfree(spec); 4267 snd_hda_detach_beep_device(codec); 4268} 4269 4270#ifdef CONFIG_SND_HDA_POWER_SAVE 4271static void alc_power_eapd(struct hda_codec *codec) 4272{ 4273 /* We currently only handle front, HP */ 4274 switch (codec->vendor_id) { 4275 case 0x10ec0260: 4276 set_eapd(codec, 0x0f, 0); 4277 set_eapd(codec, 0x10, 0); 4278 break; 4279 case 0x10ec0262: 4280 case 0x10ec0267: 4281 case 0x10ec0268: 4282 case 0x10ec0269: 4283 case 0x10ec0270: 4284 case 0x10ec0272: 4285 case 0x10ec0660: 4286 case 0x10ec0662: 4287 case 0x10ec0663: 4288 case 0x10ec0862: 4289 case 0x10ec0889: 4290 set_eapd(codec, 0x14, 0); 4291 set_eapd(codec, 0x15, 0); 4292 break; 4293 } 4294} 4295 4296static int alc_suspend(struct hda_codec *codec, pm_message_t state) 4297{ 4298 struct alc_spec *spec = codec->spec; 4299 alc_shutup(codec); 4300 if (spec && spec->power_hook) 4301 spec->power_hook(codec); 4302 return 0; 4303} 4304#endif 4305 4306#ifdef SND_HDA_NEEDS_RESUME 4307static int alc_resume(struct hda_codec *codec) 4308{ 4309 codec->patch_ops.init(codec); 4310 snd_hda_codec_resume_amp(codec); 4311 snd_hda_codec_resume_cache(codec); 4312 hda_call_check_power_status(codec, 0x01); 4313 return 0; 4314} 4315#endif 4316 4317/* 4318 */ 4319static struct hda_codec_ops alc_patch_ops = { 4320 .build_controls = alc_build_controls, 4321 .build_pcms = alc_build_pcms, 4322 .init = alc_init, 4323 .free = alc_free, 4324 .unsol_event = alc_unsol_event, 4325#ifdef SND_HDA_NEEDS_RESUME 4326 .resume = alc_resume, 4327#endif 4328#ifdef CONFIG_SND_HDA_POWER_SAVE 4329 .suspend = alc_suspend, 4330 .check_power_status = alc_check_power_status, 4331#endif 4332 .reboot_notify = alc_shutup, 4333}; 4334 4335/* replace the codec chip_name with the given string */ 4336static int alc_codec_rename(struct hda_codec *codec, const char *name) 4337{ 4338 kfree(codec->chip_name); 4339 codec->chip_name = kstrdup(name, GFP_KERNEL); 4340 if (!codec->chip_name) { 4341 alc_free(codec); 4342 return -ENOMEM; 4343 } 4344 return 0; 4345} 4346 4347/* 4348 * Test configuration for debugging 4349 * 4350 * Almost all inputs/outputs are enabled. I/O pins can be configured via 4351 * enum controls. 4352 */ 4353#ifdef CONFIG_SND_DEBUG 4354static hda_nid_t alc880_test_dac_nids[4] = { 4355 0x02, 0x03, 0x04, 0x05 4356}; 4357 4358static struct hda_input_mux alc880_test_capture_source = { 4359 .num_items = 7, 4360 .items = { 4361 { "In-1", 0x0 }, 4362 { "In-2", 0x1 }, 4363 { "In-3", 0x2 }, 4364 { "In-4", 0x3 }, 4365 { "CD", 0x4 }, 4366 { "Front", 0x5 }, 4367 { "Surround", 0x6 }, 4368 }, 4369}; 4370 4371static struct hda_channel_mode alc880_test_modes[4] = { 4372 { 2, NULL }, 4373 { 4, NULL }, 4374 { 6, NULL }, 4375 { 8, NULL }, 4376}; 4377 4378static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol, 4379 struct snd_ctl_elem_info *uinfo) 4380{ 4381 static char *texts[] = { 4382 "N/A", "Line Out", "HP Out", 4383 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%" 4384 }; 4385 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 4386 uinfo->count = 1; 4387 uinfo->value.enumerated.items = 8; 4388 if (uinfo->value.enumerated.item >= 8) 4389 uinfo->value.enumerated.item = 7; 4390 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); 4391 return 0; 4392} 4393 4394static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol, 4395 struct snd_ctl_elem_value *ucontrol) 4396{ 4397 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 4398 hda_nid_t nid = (hda_nid_t)kcontrol->private_value; 4399 unsigned int pin_ctl, item = 0; 4400 4401 pin_ctl = snd_hda_codec_read(codec, nid, 0, 4402 AC_VERB_GET_PIN_WIDGET_CONTROL, 0); 4403 if (pin_ctl & AC_PINCTL_OUT_EN) { 4404 if (pin_ctl & AC_PINCTL_HP_EN) 4405 item = 2; 4406 else 4407 item = 1; 4408 } else if (pin_ctl & AC_PINCTL_IN_EN) { 4409 switch (pin_ctl & AC_PINCTL_VREFEN) { 4410 case AC_PINCTL_VREF_HIZ: item = 3; break; 4411 case AC_PINCTL_VREF_50: item = 4; break; 4412 case AC_PINCTL_VREF_GRD: item = 5; break; 4413 case AC_PINCTL_VREF_80: item = 6; break; 4414 case AC_PINCTL_VREF_100: item = 7; break; 4415 } 4416 } 4417 ucontrol->value.enumerated.item[0] = item; 4418 return 0; 4419} 4420 4421static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol, 4422 struct snd_ctl_elem_value *ucontrol) 4423{ 4424 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 4425 hda_nid_t nid = (hda_nid_t)kcontrol->private_value; 4426 static unsigned int ctls[] = { 4427 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN, 4428 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ, 4429 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50, 4430 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD, 4431 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80, 4432 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100, 4433 }; 4434 unsigned int old_ctl, new_ctl; 4435 4436 old_ctl = snd_hda_codec_read(codec, nid, 0, 4437 AC_VERB_GET_PIN_WIDGET_CONTROL, 0); 4438 new_ctl = ctls[ucontrol->value.enumerated.item[0]]; 4439 if (old_ctl != new_ctl) { 4440 int val; 4441 snd_hda_codec_write_cache(codec, nid, 0, 4442 AC_VERB_SET_PIN_WIDGET_CONTROL, 4443 new_ctl); 4444 val = ucontrol->value.enumerated.item[0] >= 3 ? 4445 HDA_AMP_MUTE : 0; 4446 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, 4447 HDA_AMP_MUTE, val); 4448 return 1; 4449 } 4450 return 0; 4451} 4452 4453static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol, 4454 struct snd_ctl_elem_info *uinfo) 4455{ 4456 static char *texts[] = { 4457 "Front", "Surround", "CLFE", "Side" 4458 }; 4459 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 4460 uinfo->count = 1; 4461 uinfo->value.enumerated.items = 4; 4462 if (uinfo->value.enumerated.item >= 4) 4463 uinfo->value.enumerated.item = 3; 4464 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); 4465 return 0; 4466} 4467 4468static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol, 4469 struct snd_ctl_elem_value *ucontrol) 4470{ 4471 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 4472 hda_nid_t nid = (hda_nid_t)kcontrol->private_value; 4473 unsigned int sel; 4474 4475 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0); 4476 ucontrol->value.enumerated.item[0] = sel & 3; 4477 return 0; 4478} 4479 4480static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol, 4481 struct snd_ctl_elem_value *ucontrol) 4482{ 4483 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 4484 hda_nid_t nid = (hda_nid_t)kcontrol->private_value; 4485 unsigned int sel; 4486 4487 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3; 4488 if (ucontrol->value.enumerated.item[0] != sel) { 4489 sel = ucontrol->value.enumerated.item[0] & 3; 4490 snd_hda_codec_write_cache(codec, nid, 0, 4491 AC_VERB_SET_CONNECT_SEL, sel); 4492 return 1; 4493 } 4494 return 0; 4495} 4496 4497#define PIN_CTL_TEST(xname,nid) { \ 4498 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 4499 .name = xname, \ 4500 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \ 4501 .info = alc_test_pin_ctl_info, \ 4502 .get = alc_test_pin_ctl_get, \ 4503 .put = alc_test_pin_ctl_put, \ 4504 .private_value = nid \ 4505 } 4506 4507#define PIN_SRC_TEST(xname,nid) { \ 4508 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 4509 .name = xname, \ 4510 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \ 4511 .info = alc_test_pin_src_info, \ 4512 .get = alc_test_pin_src_get, \ 4513 .put = alc_test_pin_src_put, \ 4514 .private_value = nid \ 4515 } 4516 4517static struct snd_kcontrol_new alc880_test_mixer[] = { 4518 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 4519 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 4520 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT), 4521 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 4522 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 4523 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 4524 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT), 4525 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 4526 PIN_CTL_TEST("Front Pin Mode", 0x14), 4527 PIN_CTL_TEST("Surround Pin Mode", 0x15), 4528 PIN_CTL_TEST("CLFE Pin Mode", 0x16), 4529 PIN_CTL_TEST("Side Pin Mode", 0x17), 4530 PIN_CTL_TEST("In-1 Pin Mode", 0x18), 4531 PIN_CTL_TEST("In-2 Pin Mode", 0x19), 4532 PIN_CTL_TEST("In-3 Pin Mode", 0x1a), 4533 PIN_CTL_TEST("In-4 Pin Mode", 0x1b), 4534 PIN_SRC_TEST("In-1 Pin Source", 0x18), 4535 PIN_SRC_TEST("In-2 Pin Source", 0x19), 4536 PIN_SRC_TEST("In-3 Pin Source", 0x1a), 4537 PIN_SRC_TEST("In-4 Pin Source", 0x1b), 4538 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT), 4539 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT), 4540 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT), 4541 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT), 4542 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT), 4543 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT), 4544 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT), 4545 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT), 4546 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT), 4547 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT), 4548 { 4549 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 4550 .name = "Channel Mode", 4551 .info = alc_ch_mode_info, 4552 .get = alc_ch_mode_get, 4553 .put = alc_ch_mode_put, 4554 }, 4555 { } /* end */ 4556}; 4557 4558static struct hda_verb alc880_test_init_verbs[] = { 4559 /* Unmute inputs of 0x0c - 0x0f */ 4560 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4561 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4562 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4563 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4564 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4565 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4566 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4567 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4568 /* Vol output for 0x0c-0x0f */ 4569 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4570 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4571 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4572 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4573 /* Set output pins 0x14-0x17 */ 4574 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4575 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4576 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4577 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4578 /* Unmute output pins 0x14-0x17 */ 4579 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4580 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4581 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4582 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4583 /* Set input pins 0x18-0x1c */ 4584 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 4585 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 4586 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 4587 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 4588 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 4589 /* Mute input pins 0x18-0x1b */ 4590 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 4591 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 4592 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 4593 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 4594 /* ADC set up */ 4595 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4596 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 4597 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4598 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 4599 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4600 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 4601 /* Analog input/passthru */ 4602 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4603 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4604 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 4605 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 4606 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 4607 { } 4608}; 4609#endif 4610 4611/* 4612 */ 4613 4614static const char * const alc880_models[ALC880_MODEL_LAST] = { 4615 [ALC880_3ST] = "3stack", 4616 [ALC880_TCL_S700] = "tcl", 4617 [ALC880_3ST_DIG] = "3stack-digout", 4618 [ALC880_CLEVO] = "clevo", 4619 [ALC880_5ST] = "5stack", 4620 [ALC880_5ST_DIG] = "5stack-digout", 4621 [ALC880_W810] = "w810", 4622 [ALC880_Z71V] = "z71v", 4623 [ALC880_6ST] = "6stack", 4624 [ALC880_6ST_DIG] = "6stack-digout", 4625 [ALC880_ASUS] = "asus", 4626 [ALC880_ASUS_W1V] = "asus-w1v", 4627 [ALC880_ASUS_DIG] = "asus-dig", 4628 [ALC880_ASUS_DIG2] = "asus-dig2", 4629 [ALC880_UNIWILL_DIG] = "uniwill", 4630 [ALC880_UNIWILL_P53] = "uniwill-p53", 4631 [ALC880_FUJITSU] = "fujitsu", 4632 [ALC880_F1734] = "F1734", 4633 [ALC880_LG] = "lg", 4634 [ALC880_LG_LW] = "lg-lw", 4635 [ALC880_MEDION_RIM] = "medion", 4636#ifdef CONFIG_SND_DEBUG 4637 [ALC880_TEST] = "test", 4638#endif 4639 [ALC880_AUTO] = "auto", 4640}; 4641 4642static struct snd_pci_quirk alc880_cfg_tbl[] = { 4643 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810), 4644 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG), 4645 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST), 4646 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG), 4647 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG), 4648 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG), 4649 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG), 4650 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG), 4651 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST), 4652 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG), 4653 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST), 4654 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V), 4655 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG), 4656 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG), 4657 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG), 4658 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG), 4659 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG), 4660 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V), 4661 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */ 4662 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG), 4663 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG), 4664 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG), 4665 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG), 4666 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST), 4667 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST), 4668 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */ 4669 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST), 4670 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST), 4671 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST), 4672 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST), 4673 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST), 4674 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG), 4675 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG), 4676 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG), 4677 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG), 4678 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO), 4679 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO), 4680 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2), 4681 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG), 4682 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG), 4683 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734), 4684 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL), 4685 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53), 4686 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810), 4687 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM), 4688 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG), 4689 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG), 4690 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734), 4691 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU), 4692 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_F1734), 4693 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU), 4694 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW), 4695 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG), 4696 SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_LG), 4697 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG), 4698 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW), 4699 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700), 4700 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */ 4701 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG), 4702 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG), 4703 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG), 4704 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG), 4705 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG), 4706 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG), 4707 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG), 4708 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG), 4709 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG), 4710 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG), 4711 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG), 4712 /* default Intel */ 4713 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST), 4714 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG), 4715 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG), 4716 {} 4717}; 4718 4719/* 4720 * ALC880 codec presets 4721 */ 4722static struct alc_config_preset alc880_presets[] = { 4723 [ALC880_3ST] = { 4724 .mixers = { alc880_three_stack_mixer }, 4725 .init_verbs = { alc880_volume_init_verbs, 4726 alc880_pin_3stack_init_verbs }, 4727 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 4728 .dac_nids = alc880_dac_nids, 4729 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), 4730 .channel_mode = alc880_threestack_modes, 4731 .need_dac_fix = 1, 4732 .input_mux = &alc880_capture_source, 4733 }, 4734 [ALC880_3ST_DIG] = { 4735 .mixers = { alc880_three_stack_mixer }, 4736 .init_verbs = { alc880_volume_init_verbs, 4737 alc880_pin_3stack_init_verbs }, 4738 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 4739 .dac_nids = alc880_dac_nids, 4740 .dig_out_nid = ALC880_DIGOUT_NID, 4741 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), 4742 .channel_mode = alc880_threestack_modes, 4743 .need_dac_fix = 1, 4744 .input_mux = &alc880_capture_source, 4745 }, 4746 [ALC880_TCL_S700] = { 4747 .mixers = { alc880_tcl_s700_mixer }, 4748 .init_verbs = { alc880_volume_init_verbs, 4749 alc880_pin_tcl_S700_init_verbs, 4750 alc880_gpio2_init_verbs }, 4751 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 4752 .dac_nids = alc880_dac_nids, 4753 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */ 4754 .num_adc_nids = 1, /* single ADC */ 4755 .hp_nid = 0x03, 4756 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), 4757 .channel_mode = alc880_2_jack_modes, 4758 .input_mux = &alc880_capture_source, 4759 }, 4760 [ALC880_5ST] = { 4761 .mixers = { alc880_three_stack_mixer, 4762 alc880_five_stack_mixer}, 4763 .init_verbs = { alc880_volume_init_verbs, 4764 alc880_pin_5stack_init_verbs }, 4765 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 4766 .dac_nids = alc880_dac_nids, 4767 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes), 4768 .channel_mode = alc880_fivestack_modes, 4769 .input_mux = &alc880_capture_source, 4770 }, 4771 [ALC880_5ST_DIG] = { 4772 .mixers = { alc880_three_stack_mixer, 4773 alc880_five_stack_mixer }, 4774 .init_verbs = { alc880_volume_init_verbs, 4775 alc880_pin_5stack_init_verbs }, 4776 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 4777 .dac_nids = alc880_dac_nids, 4778 .dig_out_nid = ALC880_DIGOUT_NID, 4779 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes), 4780 .channel_mode = alc880_fivestack_modes, 4781 .input_mux = &alc880_capture_source, 4782 }, 4783 [ALC880_6ST] = { 4784 .mixers = { alc880_six_stack_mixer }, 4785 .init_verbs = { alc880_volume_init_verbs, 4786 alc880_pin_6stack_init_verbs }, 4787 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids), 4788 .dac_nids = alc880_6st_dac_nids, 4789 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes), 4790 .channel_mode = alc880_sixstack_modes, 4791 .input_mux = &alc880_6stack_capture_source, 4792 }, 4793 [ALC880_6ST_DIG] = { 4794 .mixers = { alc880_six_stack_mixer }, 4795 .init_verbs = { alc880_volume_init_verbs, 4796 alc880_pin_6stack_init_verbs }, 4797 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids), 4798 .dac_nids = alc880_6st_dac_nids, 4799 .dig_out_nid = ALC880_DIGOUT_NID, 4800 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes), 4801 .channel_mode = alc880_sixstack_modes, 4802 .input_mux = &alc880_6stack_capture_source, 4803 }, 4804 [ALC880_W810] = { 4805 .mixers = { alc880_w810_base_mixer }, 4806 .init_verbs = { alc880_volume_init_verbs, 4807 alc880_pin_w810_init_verbs, 4808 alc880_gpio2_init_verbs }, 4809 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids), 4810 .dac_nids = alc880_w810_dac_nids, 4811 .dig_out_nid = ALC880_DIGOUT_NID, 4812 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes), 4813 .channel_mode = alc880_w810_modes, 4814 .input_mux = &alc880_capture_source, 4815 }, 4816 [ALC880_Z71V] = { 4817 .mixers = { alc880_z71v_mixer }, 4818 .init_verbs = { alc880_volume_init_verbs, 4819 alc880_pin_z71v_init_verbs }, 4820 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids), 4821 .dac_nids = alc880_z71v_dac_nids, 4822 .dig_out_nid = ALC880_DIGOUT_NID, 4823 .hp_nid = 0x03, 4824 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), 4825 .channel_mode = alc880_2_jack_modes, 4826 .input_mux = &alc880_capture_source, 4827 }, 4828 [ALC880_F1734] = { 4829 .mixers = { alc880_f1734_mixer }, 4830 .init_verbs = { alc880_volume_init_verbs, 4831 alc880_pin_f1734_init_verbs }, 4832 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids), 4833 .dac_nids = alc880_f1734_dac_nids, 4834 .hp_nid = 0x02, 4835 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), 4836 .channel_mode = alc880_2_jack_modes, 4837 .input_mux = &alc880_f1734_capture_source, 4838 .unsol_event = alc880_uniwill_p53_unsol_event, 4839 .setup = alc880_uniwill_p53_setup, 4840 .init_hook = alc_automute_amp, 4841 }, 4842 [ALC880_ASUS] = { 4843 .mixers = { alc880_asus_mixer }, 4844 .init_verbs = { alc880_volume_init_verbs, 4845 alc880_pin_asus_init_verbs, 4846 alc880_gpio1_init_verbs }, 4847 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 4848 .dac_nids = alc880_asus_dac_nids, 4849 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), 4850 .channel_mode = alc880_asus_modes, 4851 .need_dac_fix = 1, 4852 .input_mux = &alc880_capture_source, 4853 }, 4854 [ALC880_ASUS_DIG] = { 4855 .mixers = { alc880_asus_mixer }, 4856 .init_verbs = { alc880_volume_init_verbs, 4857 alc880_pin_asus_init_verbs, 4858 alc880_gpio1_init_verbs }, 4859 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 4860 .dac_nids = alc880_asus_dac_nids, 4861 .dig_out_nid = ALC880_DIGOUT_NID, 4862 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), 4863 .channel_mode = alc880_asus_modes, 4864 .need_dac_fix = 1, 4865 .input_mux = &alc880_capture_source, 4866 }, 4867 [ALC880_ASUS_DIG2] = { 4868 .mixers = { alc880_asus_mixer }, 4869 .init_verbs = { alc880_volume_init_verbs, 4870 alc880_pin_asus_init_verbs, 4871 alc880_gpio2_init_verbs }, /* use GPIO2 */ 4872 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 4873 .dac_nids = alc880_asus_dac_nids, 4874 .dig_out_nid = ALC880_DIGOUT_NID, 4875 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), 4876 .channel_mode = alc880_asus_modes, 4877 .need_dac_fix = 1, 4878 .input_mux = &alc880_capture_source, 4879 }, 4880 [ALC880_ASUS_W1V] = { 4881 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer }, 4882 .init_verbs = { alc880_volume_init_verbs, 4883 alc880_pin_asus_init_verbs, 4884 alc880_gpio1_init_verbs }, 4885 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 4886 .dac_nids = alc880_asus_dac_nids, 4887 .dig_out_nid = ALC880_DIGOUT_NID, 4888 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), 4889 .channel_mode = alc880_asus_modes, 4890 .need_dac_fix = 1, 4891 .input_mux = &alc880_capture_source, 4892 }, 4893 [ALC880_UNIWILL_DIG] = { 4894 .mixers = { alc880_asus_mixer }, 4895 .init_verbs = { alc880_volume_init_verbs, 4896 alc880_pin_asus_init_verbs }, 4897 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 4898 .dac_nids = alc880_asus_dac_nids, 4899 .dig_out_nid = ALC880_DIGOUT_NID, 4900 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), 4901 .channel_mode = alc880_asus_modes, 4902 .need_dac_fix = 1, 4903 .input_mux = &alc880_capture_source, 4904 }, 4905 [ALC880_UNIWILL] = { 4906 .mixers = { alc880_uniwill_mixer }, 4907 .init_verbs = { alc880_volume_init_verbs, 4908 alc880_uniwill_init_verbs }, 4909 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 4910 .dac_nids = alc880_asus_dac_nids, 4911 .dig_out_nid = ALC880_DIGOUT_NID, 4912 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), 4913 .channel_mode = alc880_threestack_modes, 4914 .need_dac_fix = 1, 4915 .input_mux = &alc880_capture_source, 4916 .unsol_event = alc880_uniwill_unsol_event, 4917 .setup = alc880_uniwill_setup, 4918 .init_hook = alc880_uniwill_init_hook, 4919 }, 4920 [ALC880_UNIWILL_P53] = { 4921 .mixers = { alc880_uniwill_p53_mixer }, 4922 .init_verbs = { alc880_volume_init_verbs, 4923 alc880_uniwill_p53_init_verbs }, 4924 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 4925 .dac_nids = alc880_asus_dac_nids, 4926 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes), 4927 .channel_mode = alc880_threestack_modes, 4928 .input_mux = &alc880_capture_source, 4929 .unsol_event = alc880_uniwill_p53_unsol_event, 4930 .setup = alc880_uniwill_p53_setup, 4931 .init_hook = alc_automute_amp, 4932 }, 4933 [ALC880_FUJITSU] = { 4934 .mixers = { alc880_fujitsu_mixer }, 4935 .init_verbs = { alc880_volume_init_verbs, 4936 alc880_uniwill_p53_init_verbs, 4937 alc880_beep_init_verbs }, 4938 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 4939 .dac_nids = alc880_dac_nids, 4940 .dig_out_nid = ALC880_DIGOUT_NID, 4941 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), 4942 .channel_mode = alc880_2_jack_modes, 4943 .input_mux = &alc880_capture_source, 4944 .unsol_event = alc880_uniwill_p53_unsol_event, 4945 .setup = alc880_uniwill_p53_setup, 4946 .init_hook = alc_automute_amp, 4947 }, 4948 [ALC880_CLEVO] = { 4949 .mixers = { alc880_three_stack_mixer }, 4950 .init_verbs = { alc880_volume_init_verbs, 4951 alc880_pin_clevo_init_verbs }, 4952 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 4953 .dac_nids = alc880_dac_nids, 4954 .hp_nid = 0x03, 4955 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), 4956 .channel_mode = alc880_threestack_modes, 4957 .need_dac_fix = 1, 4958 .input_mux = &alc880_capture_source, 4959 }, 4960 [ALC880_LG] = { 4961 .mixers = { alc880_lg_mixer }, 4962 .init_verbs = { alc880_volume_init_verbs, 4963 alc880_lg_init_verbs }, 4964 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids), 4965 .dac_nids = alc880_lg_dac_nids, 4966 .dig_out_nid = ALC880_DIGOUT_NID, 4967 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes), 4968 .channel_mode = alc880_lg_ch_modes, 4969 .need_dac_fix = 1, 4970 .input_mux = &alc880_lg_capture_source, 4971 .unsol_event = alc_automute_amp_unsol_event, 4972 .setup = alc880_lg_setup, 4973 .init_hook = alc_automute_amp, 4974#ifdef CONFIG_SND_HDA_POWER_SAVE 4975 .loopbacks = alc880_lg_loopbacks, 4976#endif 4977 }, 4978 [ALC880_LG_LW] = { 4979 .mixers = { alc880_lg_lw_mixer }, 4980 .init_verbs = { alc880_volume_init_verbs, 4981 alc880_lg_lw_init_verbs }, 4982 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 4983 .dac_nids = alc880_dac_nids, 4984 .dig_out_nid = ALC880_DIGOUT_NID, 4985 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes), 4986 .channel_mode = alc880_lg_lw_modes, 4987 .input_mux = &alc880_lg_lw_capture_source, 4988 .unsol_event = alc_automute_amp_unsol_event, 4989 .setup = alc880_lg_lw_setup, 4990 .init_hook = alc_automute_amp, 4991 }, 4992 [ALC880_MEDION_RIM] = { 4993 .mixers = { alc880_medion_rim_mixer }, 4994 .init_verbs = { alc880_volume_init_verbs, 4995 alc880_medion_rim_init_verbs, 4996 alc_gpio2_init_verbs }, 4997 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 4998 .dac_nids = alc880_dac_nids, 4999 .dig_out_nid = ALC880_DIGOUT_NID, 5000 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), 5001 .channel_mode = alc880_2_jack_modes, 5002 .input_mux = &alc880_medion_rim_capture_source, 5003 .unsol_event = alc880_medion_rim_unsol_event, 5004 .setup = alc880_medion_rim_setup, 5005 .init_hook = alc880_medion_rim_automute, 5006 }, 5007#ifdef CONFIG_SND_DEBUG 5008 [ALC880_TEST] = { 5009 .mixers = { alc880_test_mixer }, 5010 .init_verbs = { alc880_test_init_verbs }, 5011 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids), 5012 .dac_nids = alc880_test_dac_nids, 5013 .dig_out_nid = ALC880_DIGOUT_NID, 5014 .num_channel_mode = ARRAY_SIZE(alc880_test_modes), 5015 .channel_mode = alc880_test_modes, 5016 .input_mux = &alc880_test_capture_source, 5017 }, 5018#endif 5019}; 5020 5021/* 5022 * Automatic parse of I/O pins from the BIOS configuration 5023 */ 5024 5025enum { 5026 ALC_CTL_WIDGET_VOL, 5027 ALC_CTL_WIDGET_MUTE, 5028 ALC_CTL_BIND_MUTE, 5029}; 5030static struct snd_kcontrol_new alc880_control_templates[] = { 5031 HDA_CODEC_VOLUME(NULL, 0, 0, 0), 5032 HDA_CODEC_MUTE(NULL, 0, 0, 0), 5033 HDA_BIND_MUTE(NULL, 0, 0, 0), 5034}; 5035 5036/* add dynamic controls */ 5037static int add_control(struct alc_spec *spec, int type, const char *name, 5038 int cidx, unsigned long val) 5039{ 5040 struct snd_kcontrol_new *knew; 5041 5042 snd_array_init(&spec->kctls, sizeof(*knew), 32); 5043 knew = snd_array_new(&spec->kctls); 5044 if (!knew) 5045 return -ENOMEM; 5046 *knew = alc880_control_templates[type]; 5047 knew->name = kstrdup(name, GFP_KERNEL); 5048 if (!knew->name) 5049 return -ENOMEM; 5050 knew->index = cidx; 5051 if (get_amp_nid_(val)) 5052 knew->subdevice = HDA_SUBDEV_AMP_FLAG; 5053 knew->private_value = val; 5054 return 0; 5055} 5056 5057static int add_control_with_pfx(struct alc_spec *spec, int type, 5058 const char *pfx, const char *dir, 5059 const char *sfx, int cidx, unsigned long val) 5060{ 5061 char name[32]; 5062 snprintf(name, sizeof(name), "%s %s %s", pfx, dir, sfx); 5063 return add_control(spec, type, name, cidx, val); 5064} 5065 5066#define add_pb_vol_ctrl(spec, type, pfx, val) \ 5067 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", 0, val) 5068#define add_pb_sw_ctrl(spec, type, pfx, val) \ 5069 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", 0, val) 5070#define __add_pb_vol_ctrl(spec, type, pfx, cidx, val) \ 5071 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", cidx, val) 5072#define __add_pb_sw_ctrl(spec, type, pfx, cidx, val) \ 5073 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", cidx, val) 5074 5075#define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17) 5076#define alc880_fixed_pin_idx(nid) ((nid) - 0x14) 5077#define alc880_is_multi_pin(nid) ((nid) >= 0x18) 5078#define alc880_multi_pin_idx(nid) ((nid) - 0x18) 5079#define alc880_idx_to_dac(nid) ((nid) + 0x02) 5080#define alc880_dac_to_idx(nid) ((nid) - 0x02) 5081#define alc880_idx_to_mixer(nid) ((nid) + 0x0c) 5082#define alc880_idx_to_selector(nid) ((nid) + 0x10) 5083#define ALC880_PIN_CD_NID 0x1c 5084 5085/* fill in the dac_nids table from the parsed pin configuration */ 5086static int alc880_auto_fill_dac_nids(struct alc_spec *spec, 5087 const struct auto_pin_cfg *cfg) 5088{ 5089 hda_nid_t nid; 5090 int assigned[4]; 5091 int i, j; 5092 5093 memset(assigned, 0, sizeof(assigned)); 5094 spec->multiout.dac_nids = spec->private_dac_nids; 5095 5096 /* check the pins hardwired to audio widget */ 5097 for (i = 0; i < cfg->line_outs; i++) { 5098 nid = cfg->line_out_pins[i]; 5099 if (alc880_is_fixed_pin(nid)) { 5100 int idx = alc880_fixed_pin_idx(nid); 5101 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx); 5102 assigned[idx] = 1; 5103 } 5104 } 5105 /* left pins can be connect to any audio widget */ 5106 for (i = 0; i < cfg->line_outs; i++) { 5107 nid = cfg->line_out_pins[i]; 5108 if (alc880_is_fixed_pin(nid)) 5109 continue; 5110 /* search for an empty channel */ 5111 for (j = 0; j < cfg->line_outs; j++) { 5112 if (!assigned[j]) { 5113 spec->multiout.dac_nids[i] = 5114 alc880_idx_to_dac(j); 5115 assigned[j] = 1; 5116 break; 5117 } 5118 } 5119 } 5120 spec->multiout.num_dacs = cfg->line_outs; 5121 return 0; 5122} 5123 5124static const char *alc_get_line_out_pfx(const struct auto_pin_cfg *cfg, 5125 bool can_be_master) 5126{ 5127 if (!cfg->hp_outs && !cfg->speaker_outs && can_be_master) 5128 return "Master"; 5129 5130 switch (cfg->line_out_type) { 5131 case AUTO_PIN_SPEAKER_OUT: 5132 return "Speaker"; 5133 case AUTO_PIN_HP_OUT: 5134 return "Headphone"; 5135 default: 5136 if (cfg->line_outs == 1) 5137 return "PCM"; 5138 break; 5139 } 5140 return NULL; 5141} 5142 5143/* add playback controls from the parsed DAC table */ 5144static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec, 5145 const struct auto_pin_cfg *cfg) 5146{ 5147 static const char * const chname[4] = { 5148 "Front", "Surround", NULL /*CLFE*/, "Side" 5149 }; 5150 const char *pfx = alc_get_line_out_pfx(cfg, false); 5151 hda_nid_t nid; 5152 int i, err; 5153 5154 for (i = 0; i < cfg->line_outs; i++) { 5155 if (!spec->multiout.dac_nids[i]) 5156 continue; 5157 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i])); 5158 if (!pfx && i == 2) { 5159 /* Center/LFE */ 5160 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, 5161 "Center", 5162 HDA_COMPOSE_AMP_VAL(nid, 1, 0, 5163 HDA_OUTPUT)); 5164 if (err < 0) 5165 return err; 5166 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, 5167 "LFE", 5168 HDA_COMPOSE_AMP_VAL(nid, 2, 0, 5169 HDA_OUTPUT)); 5170 if (err < 0) 5171 return err; 5172 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, 5173 "Center", 5174 HDA_COMPOSE_AMP_VAL(nid, 1, 2, 5175 HDA_INPUT)); 5176 if (err < 0) 5177 return err; 5178 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, 5179 "LFE", 5180 HDA_COMPOSE_AMP_VAL(nid, 2, 2, 5181 HDA_INPUT)); 5182 if (err < 0) 5183 return err; 5184 } else { 5185 const char *name = pfx; 5186 if (!name) 5187 name = chname[i]; 5188 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, 5189 name, i, 5190 HDA_COMPOSE_AMP_VAL(nid, 3, 0, 5191 HDA_OUTPUT)); 5192 if (err < 0) 5193 return err; 5194 err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, 5195 name, i, 5196 HDA_COMPOSE_AMP_VAL(nid, 3, 2, 5197 HDA_INPUT)); 5198 if (err < 0) 5199 return err; 5200 } 5201 } 5202 return 0; 5203} 5204 5205/* add playback controls for speaker and HP outputs */ 5206static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin, 5207 const char *pfx) 5208{ 5209 hda_nid_t nid; 5210 int err; 5211 5212 if (!pin) 5213 return 0; 5214 5215 if (alc880_is_fixed_pin(pin)) { 5216 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); 5217 /* specify the DAC as the extra output */ 5218 if (!spec->multiout.hp_nid) 5219 spec->multiout.hp_nid = nid; 5220 else 5221 spec->multiout.extra_out_nid[0] = nid; 5222 /* control HP volume/switch on the output mixer amp */ 5223 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin)); 5224 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, 5225 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); 5226 if (err < 0) 5227 return err; 5228 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx, 5229 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT)); 5230 if (err < 0) 5231 return err; 5232 } else if (alc880_is_multi_pin(pin)) { 5233 /* set manual connection */ 5234 /* we have only a switch on HP-out PIN */ 5235 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, 5236 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); 5237 if (err < 0) 5238 return err; 5239 } 5240 return 0; 5241} 5242 5243/* create input playback/capture controls for the given pin */ 5244static int new_analog_input(struct alc_spec *spec, hda_nid_t pin, 5245 const char *ctlname, int ctlidx, 5246 int idx, hda_nid_t mix_nid) 5247{ 5248 int err; 5249 5250 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname, ctlidx, 5251 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT)); 5252 if (err < 0) 5253 return err; 5254 err = __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname, ctlidx, 5255 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT)); 5256 if (err < 0) 5257 return err; 5258 return 0; 5259} 5260 5261static int alc_is_input_pin(struct hda_codec *codec, hda_nid_t nid) 5262{ 5263 unsigned int pincap = snd_hda_query_pin_caps(codec, nid); 5264 return (pincap & AC_PINCAP_IN) != 0; 5265} 5266 5267/* create playback/capture controls for input pins */ 5268static int alc_auto_create_input_ctls(struct hda_codec *codec, 5269 const struct auto_pin_cfg *cfg, 5270 hda_nid_t mixer, 5271 hda_nid_t cap1, hda_nid_t cap2) 5272{ 5273 struct alc_spec *spec = codec->spec; 5274 struct hda_input_mux *imux = &spec->private_imux[0]; 5275 int i, err, idx, type_idx = 0; 5276 const char *prev_label = NULL; 5277 5278 for (i = 0; i < cfg->num_inputs; i++) { 5279 hda_nid_t pin; 5280 const char *label; 5281 5282 pin = cfg->inputs[i].pin; 5283 if (!alc_is_input_pin(codec, pin)) 5284 continue; 5285 5286 label = hda_get_autocfg_input_label(codec, cfg, i); 5287 if (prev_label && !strcmp(label, prev_label)) 5288 type_idx++; 5289 else 5290 type_idx = 0; 5291 prev_label = label; 5292 5293 if (mixer) { 5294 idx = get_connection_index(codec, mixer, pin); 5295 if (idx >= 0) { 5296 err = new_analog_input(spec, pin, 5297 label, type_idx, 5298 idx, mixer); 5299 if (err < 0) 5300 return err; 5301 } 5302 } 5303 5304 if (!cap1) 5305 continue; 5306 idx = get_connection_index(codec, cap1, pin); 5307 if (idx < 0 && cap2) 5308 idx = get_connection_index(codec, cap2, pin); 5309 if (idx >= 0) 5310 snd_hda_add_imux_item(imux, label, idx, NULL); 5311 } 5312 return 0; 5313} 5314 5315static int alc880_auto_create_input_ctls(struct hda_codec *codec, 5316 const struct auto_pin_cfg *cfg) 5317{ 5318 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x08, 0x09); 5319} 5320 5321static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid, 5322 unsigned int pin_type) 5323{ 5324 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 5325 pin_type); 5326 /* unmute pin */ 5327 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, 5328 AMP_OUT_UNMUTE); 5329} 5330 5331static void alc880_auto_set_output_and_unmute(struct hda_codec *codec, 5332 hda_nid_t nid, int pin_type, 5333 int dac_idx) 5334{ 5335 alc_set_pin_output(codec, nid, pin_type); 5336 /* need the manual connection? */ 5337 if (alc880_is_multi_pin(nid)) { 5338 struct alc_spec *spec = codec->spec; 5339 int idx = alc880_multi_pin_idx(nid); 5340 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0, 5341 AC_VERB_SET_CONNECT_SEL, 5342 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx])); 5343 } 5344} 5345 5346static int get_pin_type(int line_out_type) 5347{ 5348 if (line_out_type == AUTO_PIN_HP_OUT) 5349 return PIN_HP; 5350 else 5351 return PIN_OUT; 5352} 5353 5354static void alc880_auto_init_multi_out(struct hda_codec *codec) 5355{ 5356 struct alc_spec *spec = codec->spec; 5357 int i; 5358 5359 for (i = 0; i < spec->autocfg.line_outs; i++) { 5360 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 5361 int pin_type = get_pin_type(spec->autocfg.line_out_type); 5362 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i); 5363 } 5364} 5365 5366static void alc880_auto_init_extra_out(struct hda_codec *codec) 5367{ 5368 struct alc_spec *spec = codec->spec; 5369 hda_nid_t pin; 5370 5371 pin = spec->autocfg.speaker_pins[0]; 5372 if (pin) /* connect to front */ 5373 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0); 5374 pin = spec->autocfg.hp_pins[0]; 5375 if (pin) /* connect to front */ 5376 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); 5377} 5378 5379static void alc880_auto_init_analog_input(struct hda_codec *codec) 5380{ 5381 struct alc_spec *spec = codec->spec; 5382 struct auto_pin_cfg *cfg = &spec->autocfg; 5383 int i; 5384 5385 for (i = 0; i < cfg->num_inputs; i++) { 5386 hda_nid_t nid = cfg->inputs[i].pin; 5387 if (alc_is_input_pin(codec, nid)) { 5388 alc_set_input_pin(codec, nid, cfg->inputs[i].type); 5389 if (nid != ALC880_PIN_CD_NID && 5390 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)) 5391 snd_hda_codec_write(codec, nid, 0, 5392 AC_VERB_SET_AMP_GAIN_MUTE, 5393 AMP_OUT_MUTE); 5394 } 5395 } 5396} 5397 5398static void alc880_auto_init_input_src(struct hda_codec *codec) 5399{ 5400 struct alc_spec *spec = codec->spec; 5401 int c; 5402 5403 for (c = 0; c < spec->num_adc_nids; c++) { 5404 unsigned int mux_idx; 5405 const struct hda_input_mux *imux; 5406 mux_idx = c >= spec->num_mux_defs ? 0 : c; 5407 imux = &spec->input_mux[mux_idx]; 5408 if (!imux->num_items && mux_idx > 0) 5409 imux = &spec->input_mux[0]; 5410 if (imux) 5411 snd_hda_codec_write(codec, spec->adc_nids[c], 0, 5412 AC_VERB_SET_CONNECT_SEL, 5413 imux->items[0].index); 5414 } 5415} 5416 5417/* parse the BIOS configuration and set up the alc_spec */ 5418/* return 1 if successful, 0 if the proper config is not found, 5419 * or a negative error code 5420 */ 5421static int alc880_parse_auto_config(struct hda_codec *codec) 5422{ 5423 struct alc_spec *spec = codec->spec; 5424 int err; 5425 static hda_nid_t alc880_ignore[] = { 0x1d, 0 }; 5426 5427 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 5428 alc880_ignore); 5429 if (err < 0) 5430 return err; 5431 if (!spec->autocfg.line_outs) 5432 return 0; /* can't find valid BIOS pin config */ 5433 5434 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); 5435 if (err < 0) 5436 return err; 5437 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg); 5438 if (err < 0) 5439 return err; 5440 err = alc880_auto_create_extra_out(spec, 5441 spec->autocfg.speaker_pins[0], 5442 "Speaker"); 5443 if (err < 0) 5444 return err; 5445 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0], 5446 "Headphone"); 5447 if (err < 0) 5448 return err; 5449 err = alc880_auto_create_input_ctls(codec, &spec->autocfg); 5450 if (err < 0) 5451 return err; 5452 5453 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 5454 5455 alc_auto_parse_digital(codec); 5456 5457 if (spec->kctls.list) 5458 add_mixer(spec, spec->kctls.list); 5459 5460 add_verb(spec, alc880_volume_init_verbs); 5461 5462 spec->num_mux_defs = 1; 5463 spec->input_mux = &spec->private_imux[0]; 5464 5465 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); 5466 5467 return 1; 5468} 5469 5470/* additional initialization for auto-configuration model */ 5471static void alc880_auto_init(struct hda_codec *codec) 5472{ 5473 struct alc_spec *spec = codec->spec; 5474 alc880_auto_init_multi_out(codec); 5475 alc880_auto_init_extra_out(codec); 5476 alc880_auto_init_analog_input(codec); 5477 alc880_auto_init_input_src(codec); 5478 alc_auto_init_digital(codec); 5479 if (spec->unsol_event) 5480 alc_inithook(codec); 5481} 5482 5483/* check the ADC/MUX contains all input pins; some ADC/MUX contains only 5484 * one of two digital mic pins, e.g. on ALC272 5485 */ 5486static void fixup_automic_adc(struct hda_codec *codec) 5487{ 5488 struct alc_spec *spec = codec->spec; 5489 int i; 5490 5491 for (i = 0; i < spec->num_adc_nids; i++) { 5492 hda_nid_t cap = spec->capsrc_nids ? 5493 spec->capsrc_nids[i] : spec->adc_nids[i]; 5494 int iidx, eidx; 5495 5496 iidx = get_connection_index(codec, cap, spec->int_mic.pin); 5497 if (iidx < 0) 5498 continue; 5499 eidx = get_connection_index(codec, cap, spec->ext_mic.pin); 5500 if (eidx < 0) 5501 continue; 5502 spec->int_mic.mux_idx = iidx; 5503 spec->ext_mic.mux_idx = eidx; 5504 if (spec->capsrc_nids) 5505 spec->capsrc_nids += i; 5506 spec->adc_nids += i; 5507 spec->num_adc_nids = 1; 5508 return; 5509 } 5510 snd_printd(KERN_INFO "hda_codec: %s: " 5511 "No ADC/MUX containing both 0x%x and 0x%x pins\n", 5512 codec->chip_name, spec->int_mic.pin, spec->ext_mic.pin); 5513 spec->auto_mic = 0; /* disable auto-mic to be sure */ 5514} 5515 5516/* select or unmute the given capsrc route */ 5517static void select_or_unmute_capsrc(struct hda_codec *codec, hda_nid_t cap, 5518 int idx) 5519{ 5520 if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) { 5521 snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx, 5522 HDA_AMP_MUTE, 0); 5523 } else { 5524 snd_hda_codec_write_cache(codec, cap, 0, 5525 AC_VERB_SET_CONNECT_SEL, idx); 5526 } 5527} 5528 5529/* set the default connection to that pin */ 5530static int init_capsrc_for_pin(struct hda_codec *codec, hda_nid_t pin) 5531{ 5532 struct alc_spec *spec = codec->spec; 5533 int i; 5534 5535 for (i = 0; i < spec->num_adc_nids; i++) { 5536 hda_nid_t cap = spec->capsrc_nids ? 5537 spec->capsrc_nids[i] : spec->adc_nids[i]; 5538 int idx; 5539 5540 idx = get_connection_index(codec, cap, pin); 5541 if (idx < 0) 5542 continue; 5543 select_or_unmute_capsrc(codec, cap, idx); 5544 return i; /* return the found index */ 5545 } 5546 return -1; /* not found */ 5547} 5548 5549/* choose the ADC/MUX containing the input pin and initialize the setup */ 5550static void fixup_single_adc(struct hda_codec *codec) 5551{ 5552 struct alc_spec *spec = codec->spec; 5553 struct auto_pin_cfg *cfg = &spec->autocfg; 5554 int i; 5555 5556 /* search for the input pin; there must be only one */ 5557 if (cfg->num_inputs != 1) 5558 return; 5559 i = init_capsrc_for_pin(codec, cfg->inputs[0].pin); 5560 if (i >= 0) { 5561 /* use only this ADC */ 5562 if (spec->capsrc_nids) 5563 spec->capsrc_nids += i; 5564 spec->adc_nids += i; 5565 spec->num_adc_nids = 1; 5566 } 5567} 5568 5569/* initialize dual adcs */ 5570static void fixup_dual_adc_switch(struct hda_codec *codec) 5571{ 5572 struct alc_spec *spec = codec->spec; 5573 init_capsrc_for_pin(codec, spec->ext_mic.pin); 5574 init_capsrc_for_pin(codec, spec->int_mic.pin); 5575} 5576 5577static void set_capture_mixer(struct hda_codec *codec) 5578{ 5579 struct alc_spec *spec = codec->spec; 5580 static struct snd_kcontrol_new *caps[2][3] = { 5581 { alc_capture_mixer_nosrc1, 5582 alc_capture_mixer_nosrc2, 5583 alc_capture_mixer_nosrc3 }, 5584 { alc_capture_mixer1, 5585 alc_capture_mixer2, 5586 alc_capture_mixer3 }, 5587 }; 5588 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) { 5589 int mux = 0; 5590 int num_adcs = spec->num_adc_nids; 5591 if (spec->dual_adc_switch) 5592 fixup_dual_adc_switch(codec); 5593 else if (spec->auto_mic) 5594 fixup_automic_adc(codec); 5595 else if (spec->input_mux) { 5596 if (spec->input_mux->num_items > 1) 5597 mux = 1; 5598 else if (spec->input_mux->num_items == 1) 5599 fixup_single_adc(codec); 5600 } 5601 if (spec->dual_adc_switch) 5602 num_adcs = 1; 5603 spec->cap_mixer = caps[mux][num_adcs - 1]; 5604 } 5605} 5606 5607/* fill adc_nids (and capsrc_nids) containing all active input pins */ 5608static void fillup_priv_adc_nids(struct hda_codec *codec, hda_nid_t *nids, 5609 int num_nids) 5610{ 5611 struct alc_spec *spec = codec->spec; 5612 struct auto_pin_cfg *cfg = &spec->autocfg; 5613 int n; 5614 hda_nid_t fallback_adc = 0, fallback_cap = 0; 5615 5616 for (n = 0; n < num_nids; n++) { 5617 hda_nid_t adc, cap; 5618 hda_nid_t conn[HDA_MAX_NUM_INPUTS]; 5619 int nconns, i, j; 5620 5621 adc = nids[n]; 5622 if (get_wcaps_type(get_wcaps(codec, adc)) != AC_WID_AUD_IN) 5623 continue; 5624 cap = adc; 5625 nconns = snd_hda_get_connections(codec, cap, conn, 5626 ARRAY_SIZE(conn)); 5627 if (nconns == 1) { 5628 cap = conn[0]; 5629 nconns = snd_hda_get_connections(codec, cap, conn, 5630 ARRAY_SIZE(conn)); 5631 } 5632 if (nconns <= 0) 5633 continue; 5634 if (!fallback_adc) { 5635 fallback_adc = adc; 5636 fallback_cap = cap; 5637 } 5638 for (i = 0; i < cfg->num_inputs; i++) { 5639 hda_nid_t nid = cfg->inputs[i].pin; 5640 for (j = 0; j < nconns; j++) { 5641 if (conn[j] == nid) 5642 break; 5643 } 5644 if (j >= nconns) 5645 break; 5646 } 5647 if (i >= cfg->num_inputs) { 5648 int num_adcs = spec->num_adc_nids; 5649 spec->private_adc_nids[num_adcs] = adc; 5650 spec->private_capsrc_nids[num_adcs] = cap; 5651 spec->num_adc_nids++; 5652 spec->adc_nids = spec->private_adc_nids; 5653 if (adc != cap) 5654 spec->capsrc_nids = spec->private_capsrc_nids; 5655 } 5656 } 5657 if (!spec->num_adc_nids) { 5658 printk(KERN_WARNING "hda_codec: %s: no valid ADC found;" 5659 " using fallback 0x%x\n", 5660 codec->chip_name, fallback_adc); 5661 spec->private_adc_nids[0] = fallback_adc; 5662 spec->adc_nids = spec->private_adc_nids; 5663 if (fallback_adc != fallback_cap) { 5664 spec->private_capsrc_nids[0] = fallback_cap; 5665 spec->capsrc_nids = spec->private_adc_nids; 5666 } 5667 } 5668} 5669 5670#ifdef CONFIG_SND_HDA_INPUT_BEEP 5671#define set_beep_amp(spec, nid, idx, dir) \ 5672 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir)) 5673 5674static struct snd_pci_quirk beep_white_list[] = { 5675 SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1), 5676 SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1), 5677 SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1), 5678 {} 5679}; 5680 5681static inline int has_cdefine_beep(struct hda_codec *codec) 5682{ 5683 struct alc_spec *spec = codec->spec; 5684 const struct snd_pci_quirk *q; 5685 q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list); 5686 if (q) 5687 return q->value; 5688 return spec->cdefine.enable_pcbeep; 5689} 5690#else 5691#define set_beep_amp(spec, nid, idx, dir) /* NOP */ 5692#define has_cdefine_beep(codec) 0 5693#endif 5694 5695/* 5696 * OK, here we have finally the patch for ALC880 5697 */ 5698 5699static int patch_alc880(struct hda_codec *codec) 5700{ 5701 struct alc_spec *spec; 5702 int board_config; 5703 int err; 5704 5705 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 5706 if (spec == NULL) 5707 return -ENOMEM; 5708 5709 codec->spec = spec; 5710 5711 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST, 5712 alc880_models, 5713 alc880_cfg_tbl); 5714 if (board_config < 0) { 5715 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 5716 codec->chip_name); 5717 board_config = ALC880_AUTO; 5718 } 5719 5720 if (board_config == ALC880_AUTO) { 5721 /* automatic parse from the BIOS config */ 5722 err = alc880_parse_auto_config(codec); 5723 if (err < 0) { 5724 alc_free(codec); 5725 return err; 5726 } else if (!err) { 5727 printk(KERN_INFO 5728 "hda_codec: Cannot set up configuration " 5729 "from BIOS. Using 3-stack mode...\n"); 5730 board_config = ALC880_3ST; 5731 } 5732 } 5733 5734 err = snd_hda_attach_beep_device(codec, 0x1); 5735 if (err < 0) { 5736 alc_free(codec); 5737 return err; 5738 } 5739 5740 if (board_config != ALC880_AUTO) 5741 setup_preset(codec, &alc880_presets[board_config]); 5742 5743 spec->stream_analog_playback = &alc880_pcm_analog_playback; 5744 spec->stream_analog_capture = &alc880_pcm_analog_capture; 5745 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture; 5746 5747 spec->stream_digital_playback = &alc880_pcm_digital_playback; 5748 spec->stream_digital_capture = &alc880_pcm_digital_capture; 5749 5750 if (!spec->adc_nids && spec->input_mux) { 5751 /* check whether NID 0x07 is valid */ 5752 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]); 5753 /* get type */ 5754 wcap = get_wcaps_type(wcap); 5755 if (wcap != AC_WID_AUD_IN) { 5756 spec->adc_nids = alc880_adc_nids_alt; 5757 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt); 5758 } else { 5759 spec->adc_nids = alc880_adc_nids; 5760 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids); 5761 } 5762 } 5763 set_capture_mixer(codec); 5764 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 5765 5766 spec->vmaster_nid = 0x0c; 5767 5768 codec->patch_ops = alc_patch_ops; 5769 if (board_config == ALC880_AUTO) 5770 spec->init_hook = alc880_auto_init; 5771#ifdef CONFIG_SND_HDA_POWER_SAVE 5772 if (!spec->loopback.amplist) 5773 spec->loopback.amplist = alc880_loopbacks; 5774#endif 5775 5776 return 0; 5777} 5778 5779 5780/* 5781 * ALC260 support 5782 */ 5783 5784static hda_nid_t alc260_dac_nids[1] = { 5785 /* front */ 5786 0x02, 5787}; 5788 5789static hda_nid_t alc260_adc_nids[1] = { 5790 /* ADC0 */ 5791 0x04, 5792}; 5793 5794static hda_nid_t alc260_adc_nids_alt[1] = { 5795 /* ADC1 */ 5796 0x05, 5797}; 5798 5799/* NIDs used when simultaneous access to both ADCs makes sense. Note that 5800 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC. 5801 */ 5802static hda_nid_t alc260_dual_adc_nids[2] = { 5803 /* ADC0, ADC1 */ 5804 0x04, 0x05 5805}; 5806 5807#define ALC260_DIGOUT_NID 0x03 5808#define ALC260_DIGIN_NID 0x06 5809 5810static struct hda_input_mux alc260_capture_source = { 5811 .num_items = 4, 5812 .items = { 5813 { "Mic", 0x0 }, 5814 { "Front Mic", 0x1 }, 5815 { "Line", 0x2 }, 5816 { "CD", 0x4 }, 5817 }, 5818}; 5819 5820/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack, 5821 * headphone jack and the internal CD lines since these are the only pins at 5822 * which audio can appear. For flexibility, also allow the option of 5823 * recording the mixer output on the second ADC (ADC0 doesn't have a 5824 * connection to the mixer output). 5825 */ 5826static struct hda_input_mux alc260_fujitsu_capture_sources[2] = { 5827 { 5828 .num_items = 3, 5829 .items = { 5830 { "Mic/Line", 0x0 }, 5831 { "CD", 0x4 }, 5832 { "Headphone", 0x2 }, 5833 }, 5834 }, 5835 { 5836 .num_items = 4, 5837 .items = { 5838 { "Mic/Line", 0x0 }, 5839 { "CD", 0x4 }, 5840 { "Headphone", 0x2 }, 5841 { "Mixer", 0x5 }, 5842 }, 5843 }, 5844 5845}; 5846 5847/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to 5848 * the Fujitsu S702x, but jacks are marked differently. 5849 */ 5850static struct hda_input_mux alc260_acer_capture_sources[2] = { 5851 { 5852 .num_items = 4, 5853 .items = { 5854 { "Mic", 0x0 }, 5855 { "Line", 0x2 }, 5856 { "CD", 0x4 }, 5857 { "Headphone", 0x5 }, 5858 }, 5859 }, 5860 { 5861 .num_items = 5, 5862 .items = { 5863 { "Mic", 0x0 }, 5864 { "Line", 0x2 }, 5865 { "CD", 0x4 }, 5866 { "Headphone", 0x6 }, 5867 { "Mixer", 0x5 }, 5868 }, 5869 }, 5870}; 5871 5872/* Maxdata Favorit 100XS */ 5873static struct hda_input_mux alc260_favorit100_capture_sources[2] = { 5874 { 5875 .num_items = 2, 5876 .items = { 5877 { "Line/Mic", 0x0 }, 5878 { "CD", 0x4 }, 5879 }, 5880 }, 5881 { 5882 .num_items = 3, 5883 .items = { 5884 { "Line/Mic", 0x0 }, 5885 { "CD", 0x4 }, 5886 { "Mixer", 0x5 }, 5887 }, 5888 }, 5889}; 5890 5891/* 5892 * This is just place-holder, so there's something for alc_build_pcms to look 5893 * at when it calculates the maximum number of channels. ALC260 has no mixer 5894 * element which allows changing the channel mode, so the verb list is 5895 * never used. 5896 */ 5897static struct hda_channel_mode alc260_modes[1] = { 5898 { 2, NULL }, 5899}; 5900 5901 5902/* Mixer combinations 5903 * 5904 * basic: base_output + input + pc_beep + capture 5905 * HP: base_output + input + capture_alt 5906 * HP_3013: hp_3013 + input + capture 5907 * fujitsu: fujitsu + capture 5908 * acer: acer + capture 5909 */ 5910 5911static struct snd_kcontrol_new alc260_base_output_mixer[] = { 5912 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT), 5913 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT), 5914 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT), 5915 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT), 5916 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), 5917 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT), 5918 { } /* end */ 5919}; 5920 5921static struct snd_kcontrol_new alc260_input_mixer[] = { 5922 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), 5923 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), 5924 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), 5925 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT), 5926 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), 5927 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT), 5928 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT), 5929 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT), 5930 { } /* end */ 5931}; 5932 5933/* update HP, line and mono out pins according to the master switch */ 5934static void alc260_hp_master_update(struct hda_codec *codec, 5935 hda_nid_t hp, hda_nid_t line, 5936 hda_nid_t mono) 5937{ 5938 struct alc_spec *spec = codec->spec; 5939 unsigned int val = spec->master_sw ? PIN_HP : 0; 5940 /* change HP and line-out pins */ 5941 snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 5942 val); 5943 snd_hda_codec_write(codec, line, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 5944 val); 5945 /* mono (speaker) depending on the HP jack sense */ 5946 val = (val && !spec->jack_present) ? PIN_OUT : 0; 5947 snd_hda_codec_write(codec, mono, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 5948 val); 5949} 5950 5951static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol, 5952 struct snd_ctl_elem_value *ucontrol) 5953{ 5954 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 5955 struct alc_spec *spec = codec->spec; 5956 *ucontrol->value.integer.value = spec->master_sw; 5957 return 0; 5958} 5959 5960static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol, 5961 struct snd_ctl_elem_value *ucontrol) 5962{ 5963 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 5964 struct alc_spec *spec = codec->spec; 5965 int val = !!*ucontrol->value.integer.value; 5966 hda_nid_t hp, line, mono; 5967 5968 if (val == spec->master_sw) 5969 return 0; 5970 spec->master_sw = val; 5971 hp = (kcontrol->private_value >> 16) & 0xff; 5972 line = (kcontrol->private_value >> 8) & 0xff; 5973 mono = kcontrol->private_value & 0xff; 5974 alc260_hp_master_update(codec, hp, line, mono); 5975 return 1; 5976} 5977 5978static struct snd_kcontrol_new alc260_hp_output_mixer[] = { 5979 { 5980 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 5981 .name = "Master Playback Switch", 5982 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11, 5983 .info = snd_ctl_boolean_mono_info, 5984 .get = alc260_hp_master_sw_get, 5985 .put = alc260_hp_master_sw_put, 5986 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11 5987 }, 5988 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT), 5989 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT), 5990 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT), 5991 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT), 5992 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, 5993 HDA_OUTPUT), 5994 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT), 5995 { } /* end */ 5996}; 5997 5998static struct hda_verb alc260_hp_unsol_verbs[] = { 5999 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 6000 {}, 6001}; 6002 6003static void alc260_hp_automute(struct hda_codec *codec) 6004{ 6005 struct alc_spec *spec = codec->spec; 6006 6007 spec->jack_present = snd_hda_jack_detect(codec, 0x10); 6008 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11); 6009} 6010 6011static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res) 6012{ 6013 if ((res >> 26) == ALC880_HP_EVENT) 6014 alc260_hp_automute(codec); 6015} 6016 6017static struct snd_kcontrol_new alc260_hp_3013_mixer[] = { 6018 { 6019 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 6020 .name = "Master Playback Switch", 6021 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11, 6022 .info = snd_ctl_boolean_mono_info, 6023 .get = alc260_hp_master_sw_get, 6024 .put = alc260_hp_master_sw_put, 6025 .private_value = (0x15 << 16) | (0x10 << 8) | 0x11 6026 }, 6027 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT), 6028 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT), 6029 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT), 6030 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT), 6031 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT), 6032 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 6033 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), 6034 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT), 6035 { } /* end */ 6036}; 6037 6038static struct hda_bind_ctls alc260_dc7600_bind_master_vol = { 6039 .ops = &snd_hda_bind_vol, 6040 .values = { 6041 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT), 6042 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT), 6043 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT), 6044 0 6045 }, 6046}; 6047 6048static struct hda_bind_ctls alc260_dc7600_bind_switch = { 6049 .ops = &snd_hda_bind_sw, 6050 .values = { 6051 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT), 6052 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT), 6053 0 6054 }, 6055}; 6056 6057static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = { 6058 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol), 6059 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch), 6060 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT), 6061 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT), 6062 { } /* end */ 6063}; 6064 6065static struct hda_verb alc260_hp_3013_unsol_verbs[] = { 6066 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 6067 {}, 6068}; 6069 6070static void alc260_hp_3013_automute(struct hda_codec *codec) 6071{ 6072 struct alc_spec *spec = codec->spec; 6073 6074 spec->jack_present = snd_hda_jack_detect(codec, 0x15); 6075 alc260_hp_master_update(codec, 0x15, 0x10, 0x11); 6076} 6077 6078static void alc260_hp_3013_unsol_event(struct hda_codec *codec, 6079 unsigned int res) 6080{ 6081 if ((res >> 26) == ALC880_HP_EVENT) 6082 alc260_hp_3013_automute(codec); 6083} 6084 6085static void alc260_hp_3012_automute(struct hda_codec *codec) 6086{ 6087 unsigned int bits = snd_hda_jack_detect(codec, 0x10) ? 0 : PIN_OUT; 6088 6089 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 6090 bits); 6091 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 6092 bits); 6093 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 6094 bits); 6095} 6096 6097static void alc260_hp_3012_unsol_event(struct hda_codec *codec, 6098 unsigned int res) 6099{ 6100 if ((res >> 26) == ALC880_HP_EVENT) 6101 alc260_hp_3012_automute(codec); 6102} 6103 6104/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12, 6105 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10. 6106 */ 6107static struct snd_kcontrol_new alc260_fujitsu_mixer[] = { 6108 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT), 6109 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT), 6110 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT), 6111 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), 6112 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), 6113 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT), 6114 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT), 6115 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN), 6116 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT), 6117 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT), 6118 { } /* end */ 6119}; 6120 6121/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current 6122 * versions of the ALC260 don't act on requests to enable mic bias from NID 6123 * 0x0f (used to drive the headphone jack in these laptops). The ALC260 6124 * datasheet doesn't mention this restriction. At this stage it's not clear 6125 * whether this behaviour is intentional or is a hardware bug in chip 6126 * revisions available in early 2006. Therefore for now allow the 6127 * "Headphone Jack Mode" control to span all choices, but if it turns out 6128 * that the lack of mic bias for this NID is intentional we could change the 6129 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS. 6130 * 6131 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006 6132 * don't appear to make the mic bias available from the "line" jack, even 6133 * though the NID used for this jack (0x14) can supply it. The theory is 6134 * that perhaps Acer have included blocking capacitors between the ALC260 6135 * and the output jack. If this turns out to be the case for all such 6136 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT 6137 * to ALC_PIN_DIR_INOUT_NOMICBIAS. 6138 * 6139 * The C20x Tablet series have a mono internal speaker which is controlled 6140 * via the chip's Mono sum widget and pin complex, so include the necessary 6141 * controls for such models. On models without a "mono speaker" the control 6142 * won't do anything. 6143 */ 6144static struct snd_kcontrol_new alc260_acer_mixer[] = { 6145 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), 6146 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT), 6147 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT), 6148 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, 6149 HDA_OUTPUT), 6150 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, 6151 HDA_INPUT), 6152 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), 6153 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), 6154 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), 6155 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT), 6156 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN), 6157 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), 6158 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT), 6159 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT), 6160 { } /* end */ 6161}; 6162 6163/* Maxdata Favorit 100XS: one output and one input (0x12) jack 6164 */ 6165static struct snd_kcontrol_new alc260_favorit100_mixer[] = { 6166 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), 6167 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT), 6168 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT), 6169 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT), 6170 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT), 6171 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN), 6172 { } /* end */ 6173}; 6174 6175/* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12, 6176 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17. 6177 */ 6178static struct snd_kcontrol_new alc260_will_mixer[] = { 6179 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), 6180 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT), 6181 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), 6182 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT), 6183 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN), 6184 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), 6185 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT), 6186 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT), 6187 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), 6188 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), 6189 { } /* end */ 6190}; 6191 6192/* Replacer 672V ALC260 pin usage: Mic jack = 0x12, 6193 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f. 6194 */ 6195static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = { 6196 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), 6197 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT), 6198 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), 6199 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT), 6200 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN), 6201 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT), 6202 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT), 6203 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), 6204 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT), 6205 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT), 6206 { } /* end */ 6207}; 6208 6209/* 6210 * initialization verbs 6211 */ 6212static struct hda_verb alc260_init_verbs[] = { 6213 /* Line In pin widget for input */ 6214 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 6215 /* CD pin widget for input */ 6216 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 6217 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 6218 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 6219 /* Mic2 (front panel) pin widget for input and vref at 80% */ 6220 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 6221 /* LINE-2 is used for line-out in rear */ 6222 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6223 /* select line-out */ 6224 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00}, 6225 /* LINE-OUT pin */ 6226 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6227 /* enable HP */ 6228 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6229 /* enable Mono */ 6230 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6231 /* mute capture amp left and right */ 6232 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6233 /* set connection select to line in (default select for this ADC) */ 6234 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02}, 6235 /* mute capture amp left and right */ 6236 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6237 /* set connection select to line in (default select for this ADC) */ 6238 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02}, 6239 /* set vol=0 Line-Out mixer amp left and right */ 6240 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6241 /* unmute pin widget amp left and right (no gain on this amp) */ 6242 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6243 /* set vol=0 HP mixer amp left and right */ 6244 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6245 /* unmute pin widget amp left and right (no gain on this amp) */ 6246 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6247 /* set vol=0 Mono mixer amp left and right */ 6248 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6249 /* unmute pin widget amp left and right (no gain on this amp) */ 6250 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6251 /* unmute LINE-2 out pin */ 6252 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6253 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & 6254 * Line In 2 = 0x03 6255 */ 6256 /* mute analog inputs */ 6257 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6258 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6259 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 6260 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 6261 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 6262 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */ 6263 /* mute Front out path */ 6264 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6265 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6266 /* mute Headphone out path */ 6267 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6268 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6269 /* mute Mono out path */ 6270 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6271 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6272 { } 6273}; 6274 6275#if 0 /* should be identical with alc260_init_verbs? */ 6276static struct hda_verb alc260_hp_init_verbs[] = { 6277 /* Headphone and output */ 6278 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 6279 /* mono output */ 6280 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 6281 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 6282 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 6283 /* Mic2 (front panel) pin widget for input and vref at 80% */ 6284 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 6285 /* Line In pin widget for input */ 6286 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 6287 /* Line-2 pin widget for output */ 6288 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 6289 /* CD pin widget for input */ 6290 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 6291 /* unmute amp left and right */ 6292 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000}, 6293 /* set connection select to line in (default select for this ADC) */ 6294 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02}, 6295 /* unmute Line-Out mixer amp left and right (volume = 0) */ 6296 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 6297 /* mute pin widget amp left and right (no gain on this amp) */ 6298 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 6299 /* unmute HP mixer amp left and right (volume = 0) */ 6300 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 6301 /* mute pin widget amp left and right (no gain on this amp) */ 6302 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 6303 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & 6304 * Line In 2 = 0x03 6305 */ 6306 /* mute analog inputs */ 6307 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6308 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6309 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 6310 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 6311 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 6312 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */ 6313 /* Unmute Front out path */ 6314 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 6315 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 6316 /* Unmute Headphone out path */ 6317 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 6318 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 6319 /* Unmute Mono out path */ 6320 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 6321 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 6322 { } 6323}; 6324#endif 6325 6326static struct hda_verb alc260_hp_3013_init_verbs[] = { 6327 /* Line out and output */ 6328 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 6329 /* mono output */ 6330 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 6331 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 6332 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 6333 /* Mic2 (front panel) pin widget for input and vref at 80% */ 6334 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 6335 /* Line In pin widget for input */ 6336 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 6337 /* Headphone pin widget for output */ 6338 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 6339 /* CD pin widget for input */ 6340 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 6341 /* unmute amp left and right */ 6342 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000}, 6343 /* set connection select to line in (default select for this ADC) */ 6344 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02}, 6345 /* unmute Line-Out mixer amp left and right (volume = 0) */ 6346 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 6347 /* mute pin widget amp left and right (no gain on this amp) */ 6348 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 6349 /* unmute HP mixer amp left and right (volume = 0) */ 6350 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 6351 /* mute pin widget amp left and right (no gain on this amp) */ 6352 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 6353 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & 6354 * Line In 2 = 0x03 6355 */ 6356 /* mute analog inputs */ 6357 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6358 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6359 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 6360 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 6361 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 6362 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */ 6363 /* Unmute Front out path */ 6364 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 6365 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 6366 /* Unmute Headphone out path */ 6367 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 6368 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 6369 /* Unmute Mono out path */ 6370 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 6371 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 6372 { } 6373}; 6374 6375/* Initialisation sequence for ALC260 as configured in Fujitsu S702x 6376 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD 6377 * audio = 0x16, internal speaker = 0x10. 6378 */ 6379static struct hda_verb alc260_fujitsu_init_verbs[] = { 6380 /* Disable all GPIOs */ 6381 {0x01, AC_VERB_SET_GPIO_MASK, 0}, 6382 /* Internal speaker is connected to headphone pin */ 6383 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6384 /* Headphone/Line-out jack connects to Line1 pin; make it an output */ 6385 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6386 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */ 6387 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 6388 /* Ensure all other unused pins are disabled and muted. */ 6389 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6390 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6391 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6392 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6393 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6394 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6395 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6396 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6397 6398 /* Disable digital (SPDIF) pins */ 6399 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0}, 6400 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0}, 6401 6402 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus 6403 * when acting as an output. 6404 */ 6405 {0x0d, AC_VERB_SET_CONNECT_SEL, 0}, 6406 6407 /* Start with output sum widgets muted and their output gains at min */ 6408 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6409 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6410 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6411 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6412 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6413 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6414 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6415 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6416 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6417 6418 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */ 6419 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6420 /* Unmute Line1 pin widget output buffer since it starts as an output. 6421 * If the pin mode is changed by the user the pin mode control will 6422 * take care of enabling the pin's input/output buffers as needed. 6423 * Therefore there's no need to enable the input buffer at this 6424 * stage. 6425 */ 6426 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6427 /* Unmute input buffer of pin widget used for Line-in (no equiv 6428 * mixer ctrl) 6429 */ 6430 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6431 6432 /* Mute capture amp left and right */ 6433 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6434 /* Set ADC connection select to match default mixer setting - line 6435 * in (on mic1 pin) 6436 */ 6437 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, 6438 6439 /* Do the same for the second ADC: mute capture input amp and 6440 * set ADC connection to line in (on mic1 pin) 6441 */ 6442 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6443 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, 6444 6445 /* Mute all inputs to mixer widget (even unconnected ones) */ 6446 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */ 6447 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */ 6448 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */ 6449 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */ 6450 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */ 6451 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */ 6452 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */ 6453 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */ 6454 6455 { } 6456}; 6457 6458/* Initialisation sequence for ALC260 as configured in Acer TravelMate and 6459 * similar laptops (adapted from Fujitsu init verbs). 6460 */ 6461static struct hda_verb alc260_acer_init_verbs[] = { 6462 /* On TravelMate laptops, GPIO 0 enables the internal speaker and 6463 * the headphone jack. Turn this on and rely on the standard mute 6464 * methods whenever the user wants to turn these outputs off. 6465 */ 6466 {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, 6467 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, 6468 {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, 6469 /* Internal speaker/Headphone jack is connected to Line-out pin */ 6470 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6471 /* Internal microphone/Mic jack is connected to Mic1 pin */ 6472 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, 6473 /* Line In jack is connected to Line1 pin */ 6474 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 6475 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */ 6476 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6477 /* Ensure all other unused pins are disabled and muted. */ 6478 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6479 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6480 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6481 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6482 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6483 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6484 /* Disable digital (SPDIF) pins */ 6485 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0}, 6486 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0}, 6487 6488 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum 6489 * bus when acting as outputs. 6490 */ 6491 {0x0b, AC_VERB_SET_CONNECT_SEL, 0}, 6492 {0x0d, AC_VERB_SET_CONNECT_SEL, 0}, 6493 6494 /* Start with output sum widgets muted and their output gains at min */ 6495 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6496 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6497 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6498 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6499 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6500 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6501 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6502 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6503 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6504 6505 /* Unmute Line-out pin widget amp left and right 6506 * (no equiv mixer ctrl) 6507 */ 6508 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6509 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */ 6510 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6511 /* Unmute Mic1 and Line1 pin widget input buffers since they start as 6512 * inputs. If the pin mode is changed by the user the pin mode control 6513 * will take care of enabling the pin's input/output buffers as needed. 6514 * Therefore there's no need to enable the input buffer at this 6515 * stage. 6516 */ 6517 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6518 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6519 6520 /* Mute capture amp left and right */ 6521 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6522 /* Set ADC connection select to match default mixer setting - mic 6523 * (on mic1 pin) 6524 */ 6525 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, 6526 6527 /* Do similar with the second ADC: mute capture input amp and 6528 * set ADC connection to mic to match ALSA's default state. 6529 */ 6530 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6531 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, 6532 6533 /* Mute all inputs to mixer widget (even unconnected ones) */ 6534 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */ 6535 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */ 6536 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */ 6537 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */ 6538 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */ 6539 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */ 6540 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */ 6541 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */ 6542 6543 { } 6544}; 6545 6546/* Initialisation sequence for Maxdata Favorit 100XS 6547 * (adapted from Acer init verbs). 6548 */ 6549static struct hda_verb alc260_favorit100_init_verbs[] = { 6550 /* GPIO 0 enables the output jack. 6551 * Turn this on and rely on the standard mute 6552 * methods whenever the user wants to turn these outputs off. 6553 */ 6554 {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, 6555 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, 6556 {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, 6557 /* Line/Mic input jack is connected to Mic1 pin */ 6558 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, 6559 /* Ensure all other unused pins are disabled and muted. */ 6560 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6561 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6562 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6563 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6564 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6565 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6566 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6567 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6568 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6569 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6570 /* Disable digital (SPDIF) pins */ 6571 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0}, 6572 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0}, 6573 6574 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum 6575 * bus when acting as outputs. 6576 */ 6577 {0x0b, AC_VERB_SET_CONNECT_SEL, 0}, 6578 {0x0d, AC_VERB_SET_CONNECT_SEL, 0}, 6579 6580 /* Start with output sum widgets muted and their output gains at min */ 6581 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6582 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6583 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6584 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6585 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6586 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6587 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6588 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6589 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6590 6591 /* Unmute Line-out pin widget amp left and right 6592 * (no equiv mixer ctrl) 6593 */ 6594 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6595 /* Unmute Mic1 and Line1 pin widget input buffers since they start as 6596 * inputs. If the pin mode is changed by the user the pin mode control 6597 * will take care of enabling the pin's input/output buffers as needed. 6598 * Therefore there's no need to enable the input buffer at this 6599 * stage. 6600 */ 6601 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6602 6603 /* Mute capture amp left and right */ 6604 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6605 /* Set ADC connection select to match default mixer setting - mic 6606 * (on mic1 pin) 6607 */ 6608 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, 6609 6610 /* Do similar with the second ADC: mute capture input amp and 6611 * set ADC connection to mic to match ALSA's default state. 6612 */ 6613 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6614 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, 6615 6616 /* Mute all inputs to mixer widget (even unconnected ones) */ 6617 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */ 6618 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */ 6619 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */ 6620 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */ 6621 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */ 6622 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */ 6623 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */ 6624 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */ 6625 6626 { } 6627}; 6628 6629static struct hda_verb alc260_will_verbs[] = { 6630 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6631 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00}, 6632 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00}, 6633 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02}, 6634 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07}, 6635 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040}, 6636 {} 6637}; 6638 6639static struct hda_verb alc260_replacer_672v_verbs[] = { 6640 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02}, 6641 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07}, 6642 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050}, 6643 6644 {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, 6645 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, 6646 {0x01, AC_VERB_SET_GPIO_DATA, 0x00}, 6647 6648 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 6649 {} 6650}; 6651 6652/* toggle speaker-output according to the hp-jack state */ 6653static void alc260_replacer_672v_automute(struct hda_codec *codec) 6654{ 6655 unsigned int present; 6656 6657 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */ 6658 present = snd_hda_jack_detect(codec, 0x0f); 6659 if (present) { 6660 snd_hda_codec_write_cache(codec, 0x01, 0, 6661 AC_VERB_SET_GPIO_DATA, 1); 6662 snd_hda_codec_write_cache(codec, 0x0f, 0, 6663 AC_VERB_SET_PIN_WIDGET_CONTROL, 6664 PIN_HP); 6665 } else { 6666 snd_hda_codec_write_cache(codec, 0x01, 0, 6667 AC_VERB_SET_GPIO_DATA, 0); 6668 snd_hda_codec_write_cache(codec, 0x0f, 0, 6669 AC_VERB_SET_PIN_WIDGET_CONTROL, 6670 PIN_OUT); 6671 } 6672} 6673 6674static void alc260_replacer_672v_unsol_event(struct hda_codec *codec, 6675 unsigned int res) 6676{ 6677 if ((res >> 26) == ALC880_HP_EVENT) 6678 alc260_replacer_672v_automute(codec); 6679} 6680 6681static struct hda_verb alc260_hp_dc7600_verbs[] = { 6682 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01}, 6683 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 6684 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6685 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6686 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6687 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6688 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 6689 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 6690 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 6691 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 6692 {} 6693}; 6694 6695/* Test configuration for debugging, modelled after the ALC880 test 6696 * configuration. 6697 */ 6698#ifdef CONFIG_SND_DEBUG 6699static hda_nid_t alc260_test_dac_nids[1] = { 6700 0x02, 6701}; 6702static hda_nid_t alc260_test_adc_nids[2] = { 6703 0x04, 0x05, 6704}; 6705/* For testing the ALC260, each input MUX needs its own definition since 6706 * the signal assignments are different. This assumes that the first ADC 6707 * is NID 0x04. 6708 */ 6709static struct hda_input_mux alc260_test_capture_sources[2] = { 6710 { 6711 .num_items = 7, 6712 .items = { 6713 { "MIC1 pin", 0x0 }, 6714 { "MIC2 pin", 0x1 }, 6715 { "LINE1 pin", 0x2 }, 6716 { "LINE2 pin", 0x3 }, 6717 { "CD pin", 0x4 }, 6718 { "LINE-OUT pin", 0x5 }, 6719 { "HP-OUT pin", 0x6 }, 6720 }, 6721 }, 6722 { 6723 .num_items = 8, 6724 .items = { 6725 { "MIC1 pin", 0x0 }, 6726 { "MIC2 pin", 0x1 }, 6727 { "LINE1 pin", 0x2 }, 6728 { "LINE2 pin", 0x3 }, 6729 { "CD pin", 0x4 }, 6730 { "Mixer", 0x5 }, 6731 { "LINE-OUT pin", 0x6 }, 6732 { "HP-OUT pin", 0x7 }, 6733 }, 6734 }, 6735}; 6736static struct snd_kcontrol_new alc260_test_mixer[] = { 6737 /* Output driver widgets */ 6738 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), 6739 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT), 6740 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT), 6741 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT), 6742 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT), 6743 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT), 6744 6745 /* Modes for retasking pin widgets 6746 * Note: the ALC260 doesn't seem to act on requests to enable mic 6747 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't 6748 * mention this restriction. At this stage it's not clear whether 6749 * this behaviour is intentional or is a hardware bug in chip 6750 * revisions available at least up until early 2006. Therefore for 6751 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all 6752 * choices, but if it turns out that the lack of mic bias for these 6753 * NIDs is intentional we could change their modes from 6754 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS. 6755 */ 6756 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT), 6757 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT), 6758 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT), 6759 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT), 6760 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT), 6761 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT), 6762 6763 /* Loopback mixer controls */ 6764 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT), 6765 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT), 6766 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT), 6767 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT), 6768 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT), 6769 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT), 6770 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT), 6771 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT), 6772 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), 6773 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), 6774 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT), 6775 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT), 6776 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT), 6777 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT), 6778 6779 /* Controls for GPIO pins, assuming they are configured as outputs */ 6780 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01), 6781 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02), 6782 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04), 6783 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08), 6784 6785 /* Switches to allow the digital IO pins to be enabled. The datasheet 6786 * is ambigious as to which NID is which; testing on laptops which 6787 * make this output available should provide clarification. 6788 */ 6789 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01), 6790 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01), 6791 6792 /* A switch allowing EAPD to be enabled. Some laptops seem to use 6793 * this output to turn on an external amplifier. 6794 */ 6795 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02), 6796 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02), 6797 6798 { } /* end */ 6799}; 6800static struct hda_verb alc260_test_init_verbs[] = { 6801 /* Enable all GPIOs as outputs with an initial value of 0 */ 6802 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f}, 6803 {0x01, AC_VERB_SET_GPIO_DATA, 0x00}, 6804 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f}, 6805 6806 /* Enable retasking pins as output, initially without power amp */ 6807 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6808 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6809 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6810 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6811 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6812 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6813 6814 /* Disable digital (SPDIF) pins initially, but users can enable 6815 * them via a mixer switch. In the case of SPDIF-out, this initverb 6816 * payload also sets the generation to 0, output to be in "consumer" 6817 * PCM format, copyright asserted, no pre-emphasis and no validity 6818 * control. 6819 */ 6820 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0}, 6821 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0}, 6822 6823 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the 6824 * OUT1 sum bus when acting as an output. 6825 */ 6826 {0x0b, AC_VERB_SET_CONNECT_SEL, 0}, 6827 {0x0c, AC_VERB_SET_CONNECT_SEL, 0}, 6828 {0x0d, AC_VERB_SET_CONNECT_SEL, 0}, 6829 {0x0e, AC_VERB_SET_CONNECT_SEL, 0}, 6830 6831 /* Start with output sum widgets muted and their output gains at min */ 6832 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6833 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6834 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6835 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6836 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6837 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6838 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6839 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6840 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6841 6842 /* Unmute retasking pin widget output buffers since the default 6843 * state appears to be output. As the pin mode is changed by the 6844 * user the pin mode control will take care of enabling the pin's 6845 * input/output buffers as needed. 6846 */ 6847 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6848 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6849 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6850 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6851 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6852 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6853 /* Also unmute the mono-out pin widget */ 6854 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6855 6856 /* Mute capture amp left and right */ 6857 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6858 /* Set ADC connection select to match default mixer setting (mic1 6859 * pin) 6860 */ 6861 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, 6862 6863 /* Do the same for the second ADC: mute capture input amp and 6864 * set ADC connection to mic1 pin 6865 */ 6866 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6867 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, 6868 6869 /* Mute all inputs to mixer widget (even unconnected ones) */ 6870 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */ 6871 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */ 6872 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */ 6873 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */ 6874 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */ 6875 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */ 6876 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */ 6877 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */ 6878 6879 { } 6880}; 6881#endif 6882 6883#define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback 6884#define alc260_pcm_analog_capture alc880_pcm_analog_capture 6885 6886#define alc260_pcm_digital_playback alc880_pcm_digital_playback 6887#define alc260_pcm_digital_capture alc880_pcm_digital_capture 6888 6889/* 6890 * for BIOS auto-configuration 6891 */ 6892 6893static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid, 6894 const char *pfx, int *vol_bits) 6895{ 6896 hda_nid_t nid_vol; 6897 unsigned long vol_val, sw_val; 6898 int err; 6899 6900 if (nid >= 0x0f && nid < 0x11) { 6901 nid_vol = nid - 0x7; 6902 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT); 6903 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT); 6904 } else if (nid == 0x11) { 6905 nid_vol = nid - 0x7; 6906 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT); 6907 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT); 6908 } else if (nid >= 0x12 && nid <= 0x15) { 6909 nid_vol = 0x08; 6910 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT); 6911 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT); 6912 } else 6913 return 0; /* N/A */ 6914 6915 if (!(*vol_bits & (1 << nid_vol))) { 6916 /* first control for the volume widget */ 6917 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, vol_val); 6918 if (err < 0) 6919 return err; 6920 *vol_bits |= (1 << nid_vol); 6921 } 6922 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, sw_val); 6923 if (err < 0) 6924 return err; 6925 return 1; 6926} 6927 6928/* add playback controls from the parsed DAC table */ 6929static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec, 6930 const struct auto_pin_cfg *cfg) 6931{ 6932 hda_nid_t nid; 6933 int err; 6934 int vols = 0; 6935 6936 spec->multiout.num_dacs = 1; 6937 spec->multiout.dac_nids = spec->private_dac_nids; 6938 spec->multiout.dac_nids[0] = 0x02; 6939 6940 nid = cfg->line_out_pins[0]; 6941 if (nid) { 6942 const char *pfx; 6943 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0]) 6944 pfx = "Master"; 6945 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) 6946 pfx = "Speaker"; 6947 else 6948 pfx = "Front"; 6949 err = alc260_add_playback_controls(spec, nid, pfx, &vols); 6950 if (err < 0) 6951 return err; 6952 } 6953 6954 nid = cfg->speaker_pins[0]; 6955 if (nid) { 6956 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols); 6957 if (err < 0) 6958 return err; 6959 } 6960 6961 nid = cfg->hp_pins[0]; 6962 if (nid) { 6963 err = alc260_add_playback_controls(spec, nid, "Headphone", 6964 &vols); 6965 if (err < 0) 6966 return err; 6967 } 6968 return 0; 6969} 6970 6971/* create playback/capture controls for input pins */ 6972static int alc260_auto_create_input_ctls(struct hda_codec *codec, 6973 const struct auto_pin_cfg *cfg) 6974{ 6975 return alc_auto_create_input_ctls(codec, cfg, 0x07, 0x04, 0x05); 6976} 6977 6978static void alc260_auto_set_output_and_unmute(struct hda_codec *codec, 6979 hda_nid_t nid, int pin_type, 6980 int sel_idx) 6981{ 6982 alc_set_pin_output(codec, nid, pin_type); 6983 /* need the manual connection? */ 6984 if (nid >= 0x12) { 6985 int idx = nid - 0x12; 6986 snd_hda_codec_write(codec, idx + 0x0b, 0, 6987 AC_VERB_SET_CONNECT_SEL, sel_idx); 6988 } 6989} 6990 6991static void alc260_auto_init_multi_out(struct hda_codec *codec) 6992{ 6993 struct alc_spec *spec = codec->spec; 6994 hda_nid_t nid; 6995 6996 nid = spec->autocfg.line_out_pins[0]; 6997 if (nid) { 6998 int pin_type = get_pin_type(spec->autocfg.line_out_type); 6999 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0); 7000 } 7001 7002 nid = spec->autocfg.speaker_pins[0]; 7003 if (nid) 7004 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0); 7005 7006 nid = spec->autocfg.hp_pins[0]; 7007 if (nid) 7008 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0); 7009} 7010 7011#define ALC260_PIN_CD_NID 0x16 7012static void alc260_auto_init_analog_input(struct hda_codec *codec) 7013{ 7014 struct alc_spec *spec = codec->spec; 7015 struct auto_pin_cfg *cfg = &spec->autocfg; 7016 int i; 7017 7018 for (i = 0; i < cfg->num_inputs; i++) { 7019 hda_nid_t nid = cfg->inputs[i].pin; 7020 if (nid >= 0x12) { 7021 alc_set_input_pin(codec, nid, cfg->inputs[i].type); 7022 if (nid != ALC260_PIN_CD_NID && 7023 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)) 7024 snd_hda_codec_write(codec, nid, 0, 7025 AC_VERB_SET_AMP_GAIN_MUTE, 7026 AMP_OUT_MUTE); 7027 } 7028 } 7029} 7030 7031#define alc260_auto_init_input_src alc880_auto_init_input_src 7032 7033/* 7034 * generic initialization of ADC, input mixers and output mixers 7035 */ 7036static struct hda_verb alc260_volume_init_verbs[] = { 7037 /* 7038 * Unmute ADC0-1 and set the default input to mic-in 7039 */ 7040 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, 7041 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7042 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, 7043 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7044 7045 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 7046 * mixer widget 7047 * Note: PASD motherboards uses the Line In 2 as the input for 7048 * front panel mic (mic 2) 7049 */ 7050 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 7051 /* mute analog inputs */ 7052 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7053 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7054 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 7055 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 7056 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 7057 7058 /* 7059 * Set up output mixers (0x08 - 0x0a) 7060 */ 7061 /* set vol=0 to output mixers */ 7062 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 7063 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 7064 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 7065 /* set up input amps for analog loopback */ 7066 /* Amp Indices: DAC = 0, mixer = 1 */ 7067 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7068 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 7069 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7070 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 7071 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7072 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 7073 7074 { } 7075}; 7076 7077static int alc260_parse_auto_config(struct hda_codec *codec) 7078{ 7079 struct alc_spec *spec = codec->spec; 7080 int err; 7081 static hda_nid_t alc260_ignore[] = { 0x17, 0 }; 7082 7083 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 7084 alc260_ignore); 7085 if (err < 0) 7086 return err; 7087 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg); 7088 if (err < 0) 7089 return err; 7090 if (!spec->kctls.list) 7091 return 0; /* can't find valid BIOS pin config */ 7092 err = alc260_auto_create_input_ctls(codec, &spec->autocfg); 7093 if (err < 0) 7094 return err; 7095 7096 spec->multiout.max_channels = 2; 7097 7098 if (spec->autocfg.dig_outs) 7099 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID; 7100 if (spec->kctls.list) 7101 add_mixer(spec, spec->kctls.list); 7102 7103 add_verb(spec, alc260_volume_init_verbs); 7104 7105 spec->num_mux_defs = 1; 7106 spec->input_mux = &spec->private_imux[0]; 7107 7108 alc_ssid_check(codec, 0x10, 0x15, 0x0f, 0); 7109 7110 return 1; 7111} 7112 7113/* additional initialization for auto-configuration model */ 7114static void alc260_auto_init(struct hda_codec *codec) 7115{ 7116 struct alc_spec *spec = codec->spec; 7117 alc260_auto_init_multi_out(codec); 7118 alc260_auto_init_analog_input(codec); 7119 alc260_auto_init_input_src(codec); 7120 alc_auto_init_digital(codec); 7121 if (spec->unsol_event) 7122 alc_inithook(codec); 7123} 7124 7125#ifdef CONFIG_SND_HDA_POWER_SAVE 7126static struct hda_amp_list alc260_loopbacks[] = { 7127 { 0x07, HDA_INPUT, 0 }, 7128 { 0x07, HDA_INPUT, 1 }, 7129 { 0x07, HDA_INPUT, 2 }, 7130 { 0x07, HDA_INPUT, 3 }, 7131 { 0x07, HDA_INPUT, 4 }, 7132 { } /* end */ 7133}; 7134#endif 7135 7136/* 7137 * Pin config fixes 7138 */ 7139enum { 7140 PINFIX_HP_DC5750, 7141}; 7142 7143static const struct alc_fixup alc260_fixups[] = { 7144 [PINFIX_HP_DC5750] = { 7145 .type = ALC_FIXUP_PINS, 7146 .v.pins = (const struct alc_pincfg[]) { 7147 { 0x11, 0x90130110 }, /* speaker */ 7148 { } 7149 } 7150 }, 7151}; 7152 7153static struct snd_pci_quirk alc260_fixup_tbl[] = { 7154 SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", PINFIX_HP_DC5750), 7155 {} 7156}; 7157 7158/* 7159 * ALC260 configurations 7160 */ 7161static const char * const alc260_models[ALC260_MODEL_LAST] = { 7162 [ALC260_BASIC] = "basic", 7163 [ALC260_HP] = "hp", 7164 [ALC260_HP_3013] = "hp-3013", 7165 [ALC260_HP_DC7600] = "hp-dc7600", 7166 [ALC260_FUJITSU_S702X] = "fujitsu", 7167 [ALC260_ACER] = "acer", 7168 [ALC260_WILL] = "will", 7169 [ALC260_REPLACER_672V] = "replacer", 7170 [ALC260_FAVORIT100] = "favorit100", 7171#ifdef CONFIG_SND_DEBUG 7172 [ALC260_TEST] = "test", 7173#endif 7174 [ALC260_AUTO] = "auto", 7175}; 7176 7177static struct snd_pci_quirk alc260_cfg_tbl[] = { 7178 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER), 7179 SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL), 7180 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER), 7181 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100), 7182 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013), 7183 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_AUTO), /* no quirk */ 7184 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013), 7185 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013), 7186 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600), 7187 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013), 7188 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP), 7189 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP), 7190 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP), 7191 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC), 7192 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC), 7193 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC), 7194 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X), 7195 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC), 7196 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V), 7197 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL), 7198 {} 7199}; 7200 7201static struct alc_config_preset alc260_presets[] = { 7202 [ALC260_BASIC] = { 7203 .mixers = { alc260_base_output_mixer, 7204 alc260_input_mixer }, 7205 .init_verbs = { alc260_init_verbs }, 7206 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 7207 .dac_nids = alc260_dac_nids, 7208 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids), 7209 .adc_nids = alc260_dual_adc_nids, 7210 .num_channel_mode = ARRAY_SIZE(alc260_modes), 7211 .channel_mode = alc260_modes, 7212 .input_mux = &alc260_capture_source, 7213 }, 7214 [ALC260_HP] = { 7215 .mixers = { alc260_hp_output_mixer, 7216 alc260_input_mixer }, 7217 .init_verbs = { alc260_init_verbs, 7218 alc260_hp_unsol_verbs }, 7219 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 7220 .dac_nids = alc260_dac_nids, 7221 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt), 7222 .adc_nids = alc260_adc_nids_alt, 7223 .num_channel_mode = ARRAY_SIZE(alc260_modes), 7224 .channel_mode = alc260_modes, 7225 .input_mux = &alc260_capture_source, 7226 .unsol_event = alc260_hp_unsol_event, 7227 .init_hook = alc260_hp_automute, 7228 }, 7229 [ALC260_HP_DC7600] = { 7230 .mixers = { alc260_hp_dc7600_mixer, 7231 alc260_input_mixer }, 7232 .init_verbs = { alc260_init_verbs, 7233 alc260_hp_dc7600_verbs }, 7234 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 7235 .dac_nids = alc260_dac_nids, 7236 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt), 7237 .adc_nids = alc260_adc_nids_alt, 7238 .num_channel_mode = ARRAY_SIZE(alc260_modes), 7239 .channel_mode = alc260_modes, 7240 .input_mux = &alc260_capture_source, 7241 .unsol_event = alc260_hp_3012_unsol_event, 7242 .init_hook = alc260_hp_3012_automute, 7243 }, 7244 [ALC260_HP_3013] = { 7245 .mixers = { alc260_hp_3013_mixer, 7246 alc260_input_mixer }, 7247 .init_verbs = { alc260_hp_3013_init_verbs, 7248 alc260_hp_3013_unsol_verbs }, 7249 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 7250 .dac_nids = alc260_dac_nids, 7251 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt), 7252 .adc_nids = alc260_adc_nids_alt, 7253 .num_channel_mode = ARRAY_SIZE(alc260_modes), 7254 .channel_mode = alc260_modes, 7255 .input_mux = &alc260_capture_source, 7256 .unsol_event = alc260_hp_3013_unsol_event, 7257 .init_hook = alc260_hp_3013_automute, 7258 }, 7259 [ALC260_FUJITSU_S702X] = { 7260 .mixers = { alc260_fujitsu_mixer }, 7261 .init_verbs = { alc260_fujitsu_init_verbs }, 7262 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 7263 .dac_nids = alc260_dac_nids, 7264 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids), 7265 .adc_nids = alc260_dual_adc_nids, 7266 .num_channel_mode = ARRAY_SIZE(alc260_modes), 7267 .channel_mode = alc260_modes, 7268 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources), 7269 .input_mux = alc260_fujitsu_capture_sources, 7270 }, 7271 [ALC260_ACER] = { 7272 .mixers = { alc260_acer_mixer }, 7273 .init_verbs = { alc260_acer_init_verbs }, 7274 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 7275 .dac_nids = alc260_dac_nids, 7276 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids), 7277 .adc_nids = alc260_dual_adc_nids, 7278 .num_channel_mode = ARRAY_SIZE(alc260_modes), 7279 .channel_mode = alc260_modes, 7280 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources), 7281 .input_mux = alc260_acer_capture_sources, 7282 }, 7283 [ALC260_FAVORIT100] = { 7284 .mixers = { alc260_favorit100_mixer }, 7285 .init_verbs = { alc260_favorit100_init_verbs }, 7286 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 7287 .dac_nids = alc260_dac_nids, 7288 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids), 7289 .adc_nids = alc260_dual_adc_nids, 7290 .num_channel_mode = ARRAY_SIZE(alc260_modes), 7291 .channel_mode = alc260_modes, 7292 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources), 7293 .input_mux = alc260_favorit100_capture_sources, 7294 }, 7295 [ALC260_WILL] = { 7296 .mixers = { alc260_will_mixer }, 7297 .init_verbs = { alc260_init_verbs, alc260_will_verbs }, 7298 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 7299 .dac_nids = alc260_dac_nids, 7300 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids), 7301 .adc_nids = alc260_adc_nids, 7302 .dig_out_nid = ALC260_DIGOUT_NID, 7303 .num_channel_mode = ARRAY_SIZE(alc260_modes), 7304 .channel_mode = alc260_modes, 7305 .input_mux = &alc260_capture_source, 7306 }, 7307 [ALC260_REPLACER_672V] = { 7308 .mixers = { alc260_replacer_672v_mixer }, 7309 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs }, 7310 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 7311 .dac_nids = alc260_dac_nids, 7312 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids), 7313 .adc_nids = alc260_adc_nids, 7314 .dig_out_nid = ALC260_DIGOUT_NID, 7315 .num_channel_mode = ARRAY_SIZE(alc260_modes), 7316 .channel_mode = alc260_modes, 7317 .input_mux = &alc260_capture_source, 7318 .unsol_event = alc260_replacer_672v_unsol_event, 7319 .init_hook = alc260_replacer_672v_automute, 7320 }, 7321#ifdef CONFIG_SND_DEBUG 7322 [ALC260_TEST] = { 7323 .mixers = { alc260_test_mixer }, 7324 .init_verbs = { alc260_test_init_verbs }, 7325 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids), 7326 .dac_nids = alc260_test_dac_nids, 7327 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids), 7328 .adc_nids = alc260_test_adc_nids, 7329 .num_channel_mode = ARRAY_SIZE(alc260_modes), 7330 .channel_mode = alc260_modes, 7331 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources), 7332 .input_mux = alc260_test_capture_sources, 7333 }, 7334#endif 7335}; 7336 7337static int patch_alc260(struct hda_codec *codec) 7338{ 7339 struct alc_spec *spec; 7340 int err, board_config; 7341 7342 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 7343 if (spec == NULL) 7344 return -ENOMEM; 7345 7346 codec->spec = spec; 7347 7348 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST, 7349 alc260_models, 7350 alc260_cfg_tbl); 7351 if (board_config < 0) { 7352 snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 7353 codec->chip_name); 7354 board_config = ALC260_AUTO; 7355 } 7356 7357 if (board_config == ALC260_AUTO) { 7358 alc_pick_fixup(codec, NULL, alc260_fixup_tbl, alc260_fixups); 7359 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); 7360 } 7361 7362 if (board_config == ALC260_AUTO) { 7363 /* automatic parse from the BIOS config */ 7364 err = alc260_parse_auto_config(codec); 7365 if (err < 0) { 7366 alc_free(codec); 7367 return err; 7368 } else if (!err) { 7369 printk(KERN_INFO 7370 "hda_codec: Cannot set up configuration " 7371 "from BIOS. Using base mode...\n"); 7372 board_config = ALC260_BASIC; 7373 } 7374 } 7375 7376 err = snd_hda_attach_beep_device(codec, 0x1); 7377 if (err < 0) { 7378 alc_free(codec); 7379 return err; 7380 } 7381 7382 if (board_config != ALC260_AUTO) 7383 setup_preset(codec, &alc260_presets[board_config]); 7384 7385 spec->stream_analog_playback = &alc260_pcm_analog_playback; 7386 spec->stream_analog_capture = &alc260_pcm_analog_capture; 7387 spec->stream_analog_alt_capture = &alc260_pcm_analog_capture; 7388 7389 spec->stream_digital_playback = &alc260_pcm_digital_playback; 7390 spec->stream_digital_capture = &alc260_pcm_digital_capture; 7391 7392 if (!spec->adc_nids && spec->input_mux) { 7393 /* check whether NID 0x04 is valid */ 7394 unsigned int wcap = get_wcaps(codec, 0x04); 7395 wcap = get_wcaps_type(wcap); 7396 /* get type */ 7397 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) { 7398 spec->adc_nids = alc260_adc_nids_alt; 7399 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt); 7400 } else { 7401 spec->adc_nids = alc260_adc_nids; 7402 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids); 7403 } 7404 } 7405 set_capture_mixer(codec); 7406 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT); 7407 7408 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); 7409 7410 spec->vmaster_nid = 0x08; 7411 7412 codec->patch_ops = alc_patch_ops; 7413 if (board_config == ALC260_AUTO) 7414 spec->init_hook = alc260_auto_init; 7415#ifdef CONFIG_SND_HDA_POWER_SAVE 7416 if (!spec->loopback.amplist) 7417 spec->loopback.amplist = alc260_loopbacks; 7418#endif 7419 7420 return 0; 7421} 7422 7423 7424/* 7425 * ALC882/883/885/888/889 support 7426 * 7427 * ALC882 is almost identical with ALC880 but has cleaner and more flexible 7428 * configuration. Each pin widget can choose any input DACs and a mixer. 7429 * Each ADC is connected from a mixer of all inputs. This makes possible 7430 * 6-channel independent captures. 7431 * 7432 * In addition, an independent DAC for the multi-playback (not used in this 7433 * driver yet). 7434 */ 7435#define ALC882_DIGOUT_NID 0x06 7436#define ALC882_DIGIN_NID 0x0a 7437#define ALC883_DIGOUT_NID ALC882_DIGOUT_NID 7438#define ALC883_DIGIN_NID ALC882_DIGIN_NID 7439#define ALC1200_DIGOUT_NID 0x10 7440 7441 7442static struct hda_channel_mode alc882_ch_modes[1] = { 7443 { 8, NULL } 7444}; 7445 7446/* DACs */ 7447static hda_nid_t alc882_dac_nids[4] = { 7448 /* front, rear, clfe, rear_surr */ 7449 0x02, 0x03, 0x04, 0x05 7450}; 7451#define alc883_dac_nids alc882_dac_nids 7452 7453/* ADCs */ 7454#define alc882_adc_nids alc880_adc_nids 7455#define alc882_adc_nids_alt alc880_adc_nids_alt 7456#define alc883_adc_nids alc882_adc_nids_alt 7457static hda_nid_t alc883_adc_nids_alt[1] = { 0x08 }; 7458static hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 }; 7459#define alc889_adc_nids alc880_adc_nids 7460 7461static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 }; 7462static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 }; 7463#define alc883_capsrc_nids alc882_capsrc_nids_alt 7464static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 }; 7465#define alc889_capsrc_nids alc882_capsrc_nids 7466 7467/* input MUX */ 7468/* FIXME: should be a matrix-type input source selection */ 7469 7470static struct hda_input_mux alc882_capture_source = { 7471 .num_items = 4, 7472 .items = { 7473 { "Mic", 0x0 }, 7474 { "Front Mic", 0x1 }, 7475 { "Line", 0x2 }, 7476 { "CD", 0x4 }, 7477 }, 7478}; 7479 7480#define alc883_capture_source alc882_capture_source 7481 7482static struct hda_input_mux alc889_capture_source = { 7483 .num_items = 3, 7484 .items = { 7485 { "Front Mic", 0x0 }, 7486 { "Mic", 0x3 }, 7487 { "Line", 0x2 }, 7488 }, 7489}; 7490 7491static struct hda_input_mux mb5_capture_source = { 7492 .num_items = 3, 7493 .items = { 7494 { "Mic", 0x1 }, 7495 { "Line", 0x7 }, 7496 { "CD", 0x4 }, 7497 }, 7498}; 7499 7500static struct hda_input_mux macmini3_capture_source = { 7501 .num_items = 2, 7502 .items = { 7503 { "Line", 0x2 }, 7504 { "CD", 0x4 }, 7505 }, 7506}; 7507 7508static struct hda_input_mux alc883_3stack_6ch_intel = { 7509 .num_items = 4, 7510 .items = { 7511 { "Mic", 0x1 }, 7512 { "Front Mic", 0x0 }, 7513 { "Line", 0x2 }, 7514 { "CD", 0x4 }, 7515 }, 7516}; 7517 7518static struct hda_input_mux alc883_lenovo_101e_capture_source = { 7519 .num_items = 2, 7520 .items = { 7521 { "Mic", 0x1 }, 7522 { "Line", 0x2 }, 7523 }, 7524}; 7525 7526static struct hda_input_mux alc883_lenovo_nb0763_capture_source = { 7527 .num_items = 4, 7528 .items = { 7529 { "Mic", 0x0 }, 7530 { "Internal Mic", 0x1 }, 7531 { "Line", 0x2 }, 7532 { "CD", 0x4 }, 7533 }, 7534}; 7535 7536static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = { 7537 .num_items = 2, 7538 .items = { 7539 { "Mic", 0x0 }, 7540 { "Internal Mic", 0x1 }, 7541 }, 7542}; 7543 7544static struct hda_input_mux alc883_lenovo_sky_capture_source = { 7545 .num_items = 3, 7546 .items = { 7547 { "Mic", 0x0 }, 7548 { "Front Mic", 0x1 }, 7549 { "Line", 0x4 }, 7550 }, 7551}; 7552 7553static struct hda_input_mux alc883_asus_eee1601_capture_source = { 7554 .num_items = 2, 7555 .items = { 7556 { "Mic", 0x0 }, 7557 { "Line", 0x2 }, 7558 }, 7559}; 7560 7561static struct hda_input_mux alc889A_mb31_capture_source = { 7562 .num_items = 2, 7563 .items = { 7564 { "Mic", 0x0 }, 7565 /* Front Mic (0x01) unused */ 7566 { "Line", 0x2 }, 7567 /* Line 2 (0x03) unused */ 7568 /* CD (0x04) unused? */ 7569 }, 7570}; 7571 7572static struct hda_input_mux alc889A_imac91_capture_source = { 7573 .num_items = 2, 7574 .items = { 7575 { "Mic", 0x01 }, 7576 { "Line", 0x2 }, /* Not sure! */ 7577 }, 7578}; 7579 7580/* 7581 * 2ch mode 7582 */ 7583static struct hda_channel_mode alc883_3ST_2ch_modes[1] = { 7584 { 2, NULL } 7585}; 7586 7587/* 7588 * 2ch mode 7589 */ 7590static struct hda_verb alc882_3ST_ch2_init[] = { 7591 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 7592 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7593 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 7594 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7595 { } /* end */ 7596}; 7597 7598/* 7599 * 4ch mode 7600 */ 7601static struct hda_verb alc882_3ST_ch4_init[] = { 7602 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 7603 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7604 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7605 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7606 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7607 { } /* end */ 7608}; 7609 7610/* 7611 * 6ch mode 7612 */ 7613static struct hda_verb alc882_3ST_ch6_init[] = { 7614 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7615 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7616 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, 7617 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7618 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7619 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7620 { } /* end */ 7621}; 7622 7623static struct hda_channel_mode alc882_3ST_6ch_modes[3] = { 7624 { 2, alc882_3ST_ch2_init }, 7625 { 4, alc882_3ST_ch4_init }, 7626 { 6, alc882_3ST_ch6_init }, 7627}; 7628 7629#define alc883_3ST_6ch_modes alc882_3ST_6ch_modes 7630 7631/* 7632 * 2ch mode 7633 */ 7634static struct hda_verb alc883_3ST_ch2_clevo_init[] = { 7635 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, 7636 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 7637 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7638 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 7639 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7640 { } /* end */ 7641}; 7642 7643/* 7644 * 4ch mode 7645 */ 7646static struct hda_verb alc883_3ST_ch4_clevo_init[] = { 7647 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7648 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 7649 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7650 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7651 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7652 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7653 { } /* end */ 7654}; 7655 7656/* 7657 * 6ch mode 7658 */ 7659static struct hda_verb alc883_3ST_ch6_clevo_init[] = { 7660 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7661 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7662 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7663 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, 7664 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7665 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7666 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7667 { } /* end */ 7668}; 7669 7670static struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = { 7671 { 2, alc883_3ST_ch2_clevo_init }, 7672 { 4, alc883_3ST_ch4_clevo_init }, 7673 { 6, alc883_3ST_ch6_clevo_init }, 7674}; 7675 7676 7677/* 7678 * 6ch mode 7679 */ 7680static struct hda_verb alc882_sixstack_ch6_init[] = { 7681 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 7682 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7683 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7684 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7685 { } /* end */ 7686}; 7687 7688/* 7689 * 8ch mode 7690 */ 7691static struct hda_verb alc882_sixstack_ch8_init[] = { 7692 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7693 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7694 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7695 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7696 { } /* end */ 7697}; 7698 7699static struct hda_channel_mode alc882_sixstack_modes[2] = { 7700 { 6, alc882_sixstack_ch6_init }, 7701 { 8, alc882_sixstack_ch8_init }, 7702}; 7703 7704 7705/* Macbook Air 2,1 */ 7706 7707static struct hda_channel_mode alc885_mba21_ch_modes[1] = { 7708 { 2, NULL }, 7709}; 7710 7711/* 7712 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic 7713 */ 7714 7715/* 7716 * 2ch mode 7717 */ 7718static struct hda_verb alc885_mbp_ch2_init[] = { 7719 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 7720 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7721 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7722 { } /* end */ 7723}; 7724 7725/* 7726 * 4ch mode 7727 */ 7728static struct hda_verb alc885_mbp_ch4_init[] = { 7729 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7730 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7731 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7732 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7733 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 7734 { } /* end */ 7735}; 7736 7737static struct hda_channel_mode alc885_mbp_4ch_modes[2] = { 7738 { 2, alc885_mbp_ch2_init }, 7739 { 4, alc885_mbp_ch4_init }, 7740}; 7741 7742/* 7743 * 2ch 7744 * Speakers/Woofer/HP = Front 7745 * LineIn = Input 7746 */ 7747static struct hda_verb alc885_mb5_ch2_init[] = { 7748 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 7749 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 7750 { } /* end */ 7751}; 7752 7753/* 7754 * 6ch mode 7755 * Speakers/HP = Front 7756 * Woofer = LFE 7757 * LineIn = Surround 7758 */ 7759static struct hda_verb alc885_mb5_ch6_init[] = { 7760 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 7761 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7762 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 7763 { } /* end */ 7764}; 7765 7766static struct hda_channel_mode alc885_mb5_6ch_modes[2] = { 7767 { 2, alc885_mb5_ch2_init }, 7768 { 6, alc885_mb5_ch6_init }, 7769}; 7770 7771#define alc885_macmini3_6ch_modes alc885_mb5_6ch_modes 7772 7773/* 7774 * 2ch mode 7775 */ 7776static struct hda_verb alc883_4ST_ch2_init[] = { 7777 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7778 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7779 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 7780 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7781 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 7782 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7783 { } /* end */ 7784}; 7785 7786/* 7787 * 4ch mode 7788 */ 7789static struct hda_verb alc883_4ST_ch4_init[] = { 7790 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7791 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7792 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 7793 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7794 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7795 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7796 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7797 { } /* end */ 7798}; 7799 7800/* 7801 * 6ch mode 7802 */ 7803static struct hda_verb alc883_4ST_ch6_init[] = { 7804 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7805 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7806 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7807 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7808 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, 7809 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7810 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7811 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7812 { } /* end */ 7813}; 7814 7815/* 7816 * 8ch mode 7817 */ 7818static struct hda_verb alc883_4ST_ch8_init[] = { 7819 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7820 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7821 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 }, 7822 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7823 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7824 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, 7825 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7826 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7827 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7828 { } /* end */ 7829}; 7830 7831static struct hda_channel_mode alc883_4ST_8ch_modes[4] = { 7832 { 2, alc883_4ST_ch2_init }, 7833 { 4, alc883_4ST_ch4_init }, 7834 { 6, alc883_4ST_ch6_init }, 7835 { 8, alc883_4ST_ch8_init }, 7836}; 7837 7838 7839/* 7840 * 2ch mode 7841 */ 7842static struct hda_verb alc883_3ST_ch2_intel_init[] = { 7843 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 7844 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7845 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 7846 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7847 { } /* end */ 7848}; 7849 7850/* 7851 * 4ch mode 7852 */ 7853static struct hda_verb alc883_3ST_ch4_intel_init[] = { 7854 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 7855 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7856 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7857 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7858 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7859 { } /* end */ 7860}; 7861 7862/* 7863 * 6ch mode 7864 */ 7865static struct hda_verb alc883_3ST_ch6_intel_init[] = { 7866 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7867 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7868 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 }, 7869 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7870 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7871 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7872 { } /* end */ 7873}; 7874 7875static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = { 7876 { 2, alc883_3ST_ch2_intel_init }, 7877 { 4, alc883_3ST_ch4_intel_init }, 7878 { 6, alc883_3ST_ch6_intel_init }, 7879}; 7880 7881/* 7882 * 2ch mode 7883 */ 7884static struct hda_verb alc889_ch2_intel_init[] = { 7885 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 }, 7886 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 }, 7887 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 }, 7888 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00 }, 7889 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 7890 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7891 { } /* end */ 7892}; 7893 7894/* 7895 * 6ch mode 7896 */ 7897static struct hda_verb alc889_ch6_intel_init[] = { 7898 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 }, 7899 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7900 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 }, 7901 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 }, 7902 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 7903 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7904 { } /* end */ 7905}; 7906 7907/* 7908 * 8ch mode 7909 */ 7910static struct hda_verb alc889_ch8_intel_init[] = { 7911 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 }, 7912 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7913 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 }, 7914 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 }, 7915 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x03 }, 7916 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7917 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7918 { } /* end */ 7919}; 7920 7921static struct hda_channel_mode alc889_8ch_intel_modes[3] = { 7922 { 2, alc889_ch2_intel_init }, 7923 { 6, alc889_ch6_intel_init }, 7924 { 8, alc889_ch8_intel_init }, 7925}; 7926 7927/* 7928 * 6ch mode 7929 */ 7930static struct hda_verb alc883_sixstack_ch6_init[] = { 7931 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 7932 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7933 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7934 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7935 { } /* end */ 7936}; 7937 7938/* 7939 * 8ch mode 7940 */ 7941static struct hda_verb alc883_sixstack_ch8_init[] = { 7942 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7943 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7944 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7945 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7946 { } /* end */ 7947}; 7948 7949static struct hda_channel_mode alc883_sixstack_modes[2] = { 7950 { 6, alc883_sixstack_ch6_init }, 7951 { 8, alc883_sixstack_ch8_init }, 7952}; 7953 7954 7955/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 7956 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b 7957 */ 7958static struct snd_kcontrol_new alc882_base_mixer[] = { 7959 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7960 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 7961 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 7962 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 7963 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 7964 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 7965 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 7966 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 7967 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 7968 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 7969 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 7970 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 7971 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 7972 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 7973 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 7974 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7975 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 7976 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7977 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 7978 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), 7979 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 7980 { } /* end */ 7981}; 7982 7983/* Macbook Air 2,1 same control for HP and internal Speaker */ 7984 7985static struct snd_kcontrol_new alc885_mba21_mixer[] = { 7986 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 7987 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT), 7988 { } 7989}; 7990 7991 7992static struct snd_kcontrol_new alc885_mbp3_mixer[] = { 7993 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 7994 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT), 7995 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT), 7996 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0e, 0x02, HDA_INPUT), 7997 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT), 7998 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 7999 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8000 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT), 8001 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT), 8002 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT), 8003 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT), 8004 { } /* end */ 8005}; 8006 8007static struct snd_kcontrol_new alc885_mb5_mixer[] = { 8008 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 8009 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT), 8010 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT), 8011 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT), 8012 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT), 8013 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT), 8014 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT), 8015 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT), 8016 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT), 8017 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT), 8018 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 8019 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 8020 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT), 8021 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0x00, HDA_INPUT), 8022 { } /* end */ 8023}; 8024 8025static struct snd_kcontrol_new alc885_macmini3_mixer[] = { 8026 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 8027 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT), 8028 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT), 8029 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT), 8030 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT), 8031 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT), 8032 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT), 8033 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT), 8034 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT), 8035 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT), 8036 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT), 8037 { } /* end */ 8038}; 8039 8040static struct snd_kcontrol_new alc885_imac91_mixer[] = { 8041 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 8042 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT), 8043 { } /* end */ 8044}; 8045 8046 8047static struct snd_kcontrol_new alc882_w2jc_mixer[] = { 8048 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8049 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8050 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 8051 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 8052 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8053 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8054 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8055 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 8056 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8057 { } /* end */ 8058}; 8059 8060static struct snd_kcontrol_new alc882_targa_mixer[] = { 8061 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8062 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8063 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 8064 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 8065 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 8066 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8067 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8068 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8069 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8070 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 8071 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8072 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8073 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), 8074 { } /* end */ 8075}; 8076 8077/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ??? 8078 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c 8079 */ 8080static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = { 8081 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8082 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 8083 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 8084 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT), 8085 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 8086 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 8087 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8088 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8089 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT), 8090 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT), 8091 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8092 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8093 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 8094 { } /* end */ 8095}; 8096 8097static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = { 8098 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8099 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8100 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 8101 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 8102 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 8103 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8104 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8105 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8106 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 8107 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8108 { } /* end */ 8109}; 8110 8111static struct snd_kcontrol_new alc882_chmode_mixer[] = { 8112 { 8113 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 8114 .name = "Channel Mode", 8115 .info = alc_ch_mode_info, 8116 .get = alc_ch_mode_get, 8117 .put = alc_ch_mode_put, 8118 }, 8119 { } /* end */ 8120}; 8121 8122static struct hda_verb alc882_base_init_verbs[] = { 8123 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 8124 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8125 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8126 /* Rear mixer */ 8127 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8128 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8129 /* CLFE mixer */ 8130 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8131 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8132 /* Side mixer */ 8133 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8134 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8135 8136 /* Front Pin: output 0 (0x0c) */ 8137 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8138 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8139 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 8140 /* Rear Pin: output 1 (0x0d) */ 8141 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8142 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8143 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 8144 /* CLFE Pin: output 2 (0x0e) */ 8145 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8146 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8147 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, 8148 /* Side Pin: output 3 (0x0f) */ 8149 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8150 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8151 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, 8152 /* Mic (rear) pin: input vref at 80% */ 8153 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 8154 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8155 /* Front Mic pin: input vref at 80% */ 8156 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 8157 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8158 /* Line In pin: input */ 8159 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 8160 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8161 /* Line-2 In: Headphone output (output 0 - 0x0c) */ 8162 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8163 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8164 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 8165 /* CD pin widget for input */ 8166 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 8167 8168 /* FIXME: use matrix-type input source selection */ 8169 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 8170 /* Input mixer2 */ 8171 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8172 /* Input mixer3 */ 8173 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8174 /* ADC2: mute amp left and right */ 8175 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8176 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 8177 /* ADC3: mute amp left and right */ 8178 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8179 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 8180 8181 { } 8182}; 8183 8184static struct hda_verb alc882_adc1_init_verbs[] = { 8185 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 8186 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8187 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8188 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 8189 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8190 /* ADC1: mute amp left and right */ 8191 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8192 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 8193 { } 8194}; 8195 8196static struct hda_verb alc882_eapd_verbs[] = { 8197 /* change to EAPD mode */ 8198 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 8199 {0x20, AC_VERB_SET_PROC_COEF, 0x3060}, 8200 { } 8201}; 8202 8203static struct hda_verb alc889_eapd_verbs[] = { 8204 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 8205 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, 8206 { } 8207}; 8208 8209static struct hda_verb alc_hp15_unsol_verbs[] = { 8210 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 8211 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8212 {} 8213}; 8214 8215static struct hda_verb alc885_init_verbs[] = { 8216 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 8217 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8218 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8219 /* Rear mixer */ 8220 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8221 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8222 /* CLFE mixer */ 8223 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8224 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8225 /* Side mixer */ 8226 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8227 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8228 8229 /* Front HP Pin: output 0 (0x0c) */ 8230 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8231 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8232 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 8233 /* Front Pin: output 0 (0x0c) */ 8234 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8235 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8236 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 8237 /* Rear Pin: output 1 (0x0d) */ 8238 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8239 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8240 {0x19, AC_VERB_SET_CONNECT_SEL, 0x01}, 8241 /* CLFE Pin: output 2 (0x0e) */ 8242 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8243 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8244 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, 8245 /* Side Pin: output 3 (0x0f) */ 8246 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8247 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8248 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, 8249 /* Mic (rear) pin: input vref at 80% */ 8250 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 8251 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8252 /* Front Mic pin: input vref at 80% */ 8253 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 8254 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8255 /* Line In pin: input */ 8256 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 8257 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8258 8259 /* Mixer elements: 0x18, , 0x1a, 0x1b */ 8260 /* Input mixer1 */ 8261 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8262 /* Input mixer2 */ 8263 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8264 /* Input mixer3 */ 8265 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8266 /* ADC2: mute amp left and right */ 8267 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8268 /* ADC3: mute amp left and right */ 8269 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8270 8271 { } 8272}; 8273 8274static struct hda_verb alc885_init_input_verbs[] = { 8275 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8276 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 8277 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 8278 { } 8279}; 8280 8281 8282/* Unmute Selector 24h and set the default input to front mic */ 8283static struct hda_verb alc889_init_input_verbs[] = { 8284 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00}, 8285 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8286 { } 8287}; 8288 8289 8290#define alc883_init_verbs alc882_base_init_verbs 8291 8292/* Mac Pro test */ 8293static struct snd_kcontrol_new alc882_macpro_mixer[] = { 8294 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8295 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8296 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT), 8297 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT), 8298 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT), 8299 /* FIXME: this looks suspicious... 8300 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x02, HDA_INPUT), 8301 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x02, HDA_INPUT), 8302 */ 8303 { } /* end */ 8304}; 8305 8306static struct hda_verb alc882_macpro_init_verbs[] = { 8307 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 8308 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8309 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8310 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8311 /* Front Pin: output 0 (0x0c) */ 8312 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8313 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8314 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 8315 /* Front Mic pin: input vref at 80% */ 8316 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 8317 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8318 /* Speaker: output */ 8319 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8320 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8321 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04}, 8322 /* Headphone output (output 0 - 0x0c) */ 8323 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8324 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8325 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00}, 8326 8327 /* FIXME: use matrix-type input source selection */ 8328 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 8329 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 8330 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8331 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8332 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 8333 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8334 /* Input mixer2 */ 8335 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8336 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8337 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 8338 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8339 /* Input mixer3 */ 8340 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8341 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8342 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 8343 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8344 /* ADC1: mute amp left and right */ 8345 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8346 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 8347 /* ADC2: mute amp left and right */ 8348 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8349 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 8350 /* ADC3: mute amp left and right */ 8351 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8352 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 8353 8354 { } 8355}; 8356 8357/* Macbook 5,1 */ 8358static struct hda_verb alc885_mb5_init_verbs[] = { 8359 /* DACs */ 8360 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8361 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8362 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8363 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8364 /* Front mixer */ 8365 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8366 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8367 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8368 /* Surround mixer */ 8369 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8370 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8371 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8372 /* LFE mixer */ 8373 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8374 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8375 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8376 /* HP mixer */ 8377 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8378 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8379 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8380 /* Front Pin (0x0c) */ 8381 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01}, 8382 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8383 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00}, 8384 /* LFE Pin (0x0e) */ 8385 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01}, 8386 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8387 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, 8388 /* HP Pin (0x0f) */ 8389 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8390 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8391 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03}, 8392 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 8393 /* Front Mic pin: input vref at 80% */ 8394 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 8395 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8396 /* Line In pin */ 8397 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 8398 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8399 8400 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0x1)}, 8401 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x7)}, 8402 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x4)}, 8403 { } 8404}; 8405 8406/* Macmini 3,1 */ 8407static struct hda_verb alc885_macmini3_init_verbs[] = { 8408 /* DACs */ 8409 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8410 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8411 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8412 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8413 /* Front mixer */ 8414 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8415 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8416 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8417 /* Surround mixer */ 8418 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8419 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8420 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8421 /* LFE mixer */ 8422 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8423 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8424 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8425 /* HP mixer */ 8426 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8427 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8428 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8429 /* Front Pin (0x0c) */ 8430 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01}, 8431 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8432 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00}, 8433 /* LFE Pin (0x0e) */ 8434 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01}, 8435 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8436 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, 8437 /* HP Pin (0x0f) */ 8438 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8439 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8440 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03}, 8441 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 8442 /* Line In pin */ 8443 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 8444 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8445 8446 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8447 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8448 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 8449 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8450 { } 8451}; 8452 8453 8454static struct hda_verb alc885_mba21_init_verbs[] = { 8455 /*Internal and HP Speaker Mixer*/ 8456 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8457 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8458 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8459 /*Internal Speaker Pin (0x0c)*/ 8460 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) }, 8461 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8462 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00}, 8463 /* HP Pin: output 0 (0x0e) */ 8464 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, 8465 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8466 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 8467 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)}, 8468 /* Line in (is hp when jack connected)*/ 8469 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50}, 8470 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8471 8472 { } 8473 }; 8474 8475 8476/* Macbook Pro rev3 */ 8477static struct hda_verb alc885_mbp3_init_verbs[] = { 8478 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 8479 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8480 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8481 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8482 /* Rear mixer */ 8483 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8484 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8485 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8486 /* HP mixer */ 8487 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8488 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8489 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8490 /* Front Pin: output 0 (0x0c) */ 8491 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8492 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8493 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 8494 /* HP Pin: output 0 (0x0e) */ 8495 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, 8496 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8497 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02}, 8498 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 8499 /* Mic (rear) pin: input vref at 80% */ 8500 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 8501 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8502 /* Front Mic pin: input vref at 80% */ 8503 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 8504 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8505 /* Line In pin: use output 1 when in LineOut mode */ 8506 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 8507 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8508 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, 8509 8510 /* FIXME: use matrix-type input source selection */ 8511 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 8512 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 8513 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8514 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8515 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 8516 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8517 /* Input mixer2 */ 8518 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8519 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8520 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 8521 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8522 /* Input mixer3 */ 8523 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8524 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8525 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 8526 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8527 /* ADC1: mute amp left and right */ 8528 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8529 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 8530 /* ADC2: mute amp left and right */ 8531 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8532 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 8533 /* ADC3: mute amp left and right */ 8534 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8535 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 8536 8537 { } 8538}; 8539 8540/* iMac 9,1 */ 8541static struct hda_verb alc885_imac91_init_verbs[] = { 8542 /* Internal Speaker Pin (0x0c) */ 8543 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) }, 8544 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8545 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00}, 8546 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) }, 8547 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8548 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00}, 8549 /* HP Pin: Rear */ 8550 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8551 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8552 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 8553 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)}, 8554 /* Line in Rear */ 8555 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50}, 8556 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8557 /* Front Mic pin: input vref at 80% */ 8558 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 8559 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8560 /* Rear mixer */ 8561 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8562 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8563 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8564 /* Line-Out mixer: unmute input/output amp left and right (volume = 0) */ 8565 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8566 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8567 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8568 /* 0x24 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */ 8569 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8570 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8571 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 8572 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8573 /* 0x23 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */ 8574 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8575 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8576 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 8577 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8578 /* 0x22 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */ 8579 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8580 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8581 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 8582 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8583 /* 0x07 [Audio Input] wcaps 0x10011b: Stereo Amp-In */ 8584 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8585 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 8586 /* 0x08 [Audio Input] wcaps 0x10011b: Stereo Amp-In */ 8587 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8588 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 8589 /* 0x09 [Audio Input] wcaps 0x10011b: Stereo Amp-In */ 8590 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8591 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 8592 { } 8593}; 8594 8595/* iMac 24 mixer. */ 8596static struct snd_kcontrol_new alc885_imac24_mixer[] = { 8597 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 8598 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT), 8599 { } /* end */ 8600}; 8601 8602/* iMac 24 init verbs. */ 8603static struct hda_verb alc885_imac24_init_verbs[] = { 8604 /* Internal speakers: output 0 (0x0c) */ 8605 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8606 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8607 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00}, 8608 /* Internal speakers: output 0 (0x0c) */ 8609 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8610 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8611 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00}, 8612 /* Headphone: output 0 (0x0c) */ 8613 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8614 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8615 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 8616 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 8617 /* Front Mic: input vref at 80% */ 8618 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 8619 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8620 { } 8621}; 8622 8623/* Toggle speaker-output according to the hp-jack state */ 8624static void alc885_imac24_setup(struct hda_codec *codec) 8625{ 8626 struct alc_spec *spec = codec->spec; 8627 8628 spec->autocfg.hp_pins[0] = 0x14; 8629 spec->autocfg.speaker_pins[0] = 0x18; 8630 spec->autocfg.speaker_pins[1] = 0x1a; 8631} 8632 8633#define alc885_mb5_setup alc885_imac24_setup 8634#define alc885_macmini3_setup alc885_imac24_setup 8635 8636/* Macbook Air 2,1 */ 8637static void alc885_mba21_setup(struct hda_codec *codec) 8638{ 8639 struct alc_spec *spec = codec->spec; 8640 8641 spec->autocfg.hp_pins[0] = 0x14; 8642 spec->autocfg.speaker_pins[0] = 0x18; 8643} 8644 8645 8646 8647static void alc885_mbp3_setup(struct hda_codec *codec) 8648{ 8649 struct alc_spec *spec = codec->spec; 8650 8651 spec->autocfg.hp_pins[0] = 0x15; 8652 spec->autocfg.speaker_pins[0] = 0x14; 8653} 8654 8655static void alc885_imac91_setup(struct hda_codec *codec) 8656{ 8657 struct alc_spec *spec = codec->spec; 8658 8659 spec->autocfg.hp_pins[0] = 0x14; 8660 spec->autocfg.speaker_pins[0] = 0x18; 8661 spec->autocfg.speaker_pins[1] = 0x1a; 8662} 8663 8664static struct hda_verb alc882_targa_verbs[] = { 8665 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8666 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8667 8668 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8669 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8670 8671 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ 8672 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */ 8673 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 8674 8675 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 8676 { } /* end */ 8677}; 8678 8679/* toggle speaker-output according to the hp-jack state */ 8680static void alc882_targa_automute(struct hda_codec *codec) 8681{ 8682 struct alc_spec *spec = codec->spec; 8683 alc_automute_amp(codec); 8684 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA, 8685 spec->jack_present ? 1 : 3); 8686} 8687 8688static void alc882_targa_setup(struct hda_codec *codec) 8689{ 8690 struct alc_spec *spec = codec->spec; 8691 8692 spec->autocfg.hp_pins[0] = 0x14; 8693 spec->autocfg.speaker_pins[0] = 0x1b; 8694} 8695 8696static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res) 8697{ 8698 if ((res >> 26) == ALC880_HP_EVENT) 8699 alc882_targa_automute(codec); 8700} 8701 8702static struct hda_verb alc882_asus_a7j_verbs[] = { 8703 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8704 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8705 8706 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8707 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8708 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8709 8710 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */ 8711 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 8712 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */ 8713 8714 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ 8715 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */ 8716 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 8717 { } /* end */ 8718}; 8719 8720static struct hda_verb alc882_asus_a7m_verbs[] = { 8721 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8722 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8723 8724 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8725 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8726 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8727 8728 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */ 8729 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 8730 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */ 8731 8732 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ 8733 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */ 8734 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 8735 { } /* end */ 8736}; 8737 8738static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted) 8739{ 8740 unsigned int gpiostate, gpiomask, gpiodir; 8741 8742 gpiostate = snd_hda_codec_read(codec, codec->afg, 0, 8743 AC_VERB_GET_GPIO_DATA, 0); 8744 8745 if (!muted) 8746 gpiostate |= (1 << pin); 8747 else 8748 gpiostate &= ~(1 << pin); 8749 8750 gpiomask = snd_hda_codec_read(codec, codec->afg, 0, 8751 AC_VERB_GET_GPIO_MASK, 0); 8752 gpiomask |= (1 << pin); 8753 8754 gpiodir = snd_hda_codec_read(codec, codec->afg, 0, 8755 AC_VERB_GET_GPIO_DIRECTION, 0); 8756 gpiodir |= (1 << pin); 8757 8758 8759 snd_hda_codec_write(codec, codec->afg, 0, 8760 AC_VERB_SET_GPIO_MASK, gpiomask); 8761 snd_hda_codec_write(codec, codec->afg, 0, 8762 AC_VERB_SET_GPIO_DIRECTION, gpiodir); 8763 8764 msleep(1); 8765 8766 snd_hda_codec_write(codec, codec->afg, 0, 8767 AC_VERB_SET_GPIO_DATA, gpiostate); 8768} 8769 8770/* set up GPIO at initialization */ 8771static void alc885_macpro_init_hook(struct hda_codec *codec) 8772{ 8773 alc882_gpio_mute(codec, 0, 0); 8774 alc882_gpio_mute(codec, 1, 0); 8775} 8776 8777/* set up GPIO and update auto-muting at initialization */ 8778static void alc885_imac24_init_hook(struct hda_codec *codec) 8779{ 8780 alc885_macpro_init_hook(codec); 8781 alc_automute_amp(codec); 8782} 8783 8784/* 8785 * generic initialization of ADC, input mixers and output mixers 8786 */ 8787static struct hda_verb alc883_auto_init_verbs[] = { 8788 /* 8789 * Unmute ADC0-2 and set the default input to mic-in 8790 */ 8791 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 8792 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8793 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 8794 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8795 8796 /* 8797 * Set up output mixers (0x0c - 0x0f) 8798 */ 8799 /* set vol=0 to output mixers */ 8800 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8801 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8802 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8803 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8804 /* set up input amps for analog loopback */ 8805 /* Amp Indices: DAC = 0, mixer = 1 */ 8806 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8807 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8808 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8809 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8810 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8811 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8812 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8813 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8814 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8815 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8816 8817 /* FIXME: use matrix-type input source selection */ 8818 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 8819 /* Input mixer2 */ 8820 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8821 /* Input mixer3 */ 8822 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8823 { } 8824}; 8825 8826/* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */ 8827static struct hda_verb alc889A_mb31_ch2_init[] = { 8828 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */ 8829 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */ 8830 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */ 8831 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */ 8832 { } /* end */ 8833}; 8834 8835/* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */ 8836static struct hda_verb alc889A_mb31_ch4_init[] = { 8837 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */ 8838 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */ 8839 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */ 8840 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */ 8841 { } /* end */ 8842}; 8843 8844/* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */ 8845static struct hda_verb alc889A_mb31_ch5_init[] = { 8846 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */ 8847 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */ 8848 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */ 8849 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */ 8850 { } /* end */ 8851}; 8852 8853/* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */ 8854static struct hda_verb alc889A_mb31_ch6_init[] = { 8855 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */ 8856 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */ 8857 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */ 8858 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */ 8859 { } /* end */ 8860}; 8861 8862static struct hda_channel_mode alc889A_mb31_6ch_modes[4] = { 8863 { 2, alc889A_mb31_ch2_init }, 8864 { 4, alc889A_mb31_ch4_init }, 8865 { 5, alc889A_mb31_ch5_init }, 8866 { 6, alc889A_mb31_ch6_init }, 8867}; 8868 8869static struct hda_verb alc883_medion_eapd_verbs[] = { 8870 /* eanable EAPD on medion laptop */ 8871 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 8872 {0x20, AC_VERB_SET_PROC_COEF, 0x3070}, 8873 { } 8874}; 8875 8876#define alc883_base_mixer alc882_base_mixer 8877 8878static struct snd_kcontrol_new alc883_mitac_mixer[] = { 8879 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8880 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8881 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 8882 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 8883 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 8884 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 8885 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 8886 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8887 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 8888 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8889 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8890 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), 8891 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8892 { } /* end */ 8893}; 8894 8895static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = { 8896 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8897 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), 8898 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 8899 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 8900 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8901 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 8902 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8903 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8904 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), 8905 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8906 { } /* end */ 8907}; 8908 8909static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = { 8910 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8911 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), 8912 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 8913 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 8914 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8915 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 8916 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8917 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8918 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), 8919 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8920 { } /* end */ 8921}; 8922 8923static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = { 8924 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8925 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8926 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 8927 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 8928 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 8929 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8930 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8931 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8932 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 8933 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8934 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8935 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), 8936 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8937 { } /* end */ 8938}; 8939 8940static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = { 8941 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8942 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8943 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 8944 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 8945 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 8946 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 8947 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 8948 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 8949 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 8950 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 8951 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 8952 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8953 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8954 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8955 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 8956 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8957 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8958 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), 8959 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8960 { } /* end */ 8961}; 8962 8963static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = { 8964 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8965 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8966 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 8967 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 8968 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, 8969 HDA_OUTPUT), 8970 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 8971 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 8972 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 8973 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 8974 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 8975 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 8976 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8977 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8978 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8979 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT), 8980 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8981 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8982 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT), 8983 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8984 { } /* end */ 8985}; 8986 8987static struct snd_kcontrol_new alc885_8ch_intel_mixer[] = { 8988 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8989 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8990 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 8991 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 8992 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, 8993 HDA_OUTPUT), 8994 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 8995 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 8996 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 8997 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 8998 HDA_BIND_MUTE("Speaker Playback Switch", 0x0f, 2, HDA_INPUT), 8999 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 9000 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 9001 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 9002 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT), 9003 HDA_CODEC_VOLUME("Mic Boost Volume", 0x1b, 0, HDA_INPUT), 9004 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT), 9005 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9006 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT), 9007 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9008 { } /* end */ 9009}; 9010 9011static struct snd_kcontrol_new alc883_fivestack_mixer[] = { 9012 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9013 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 9014 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 9015 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 9016 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 9017 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 9018 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 9019 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 9020 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 9021 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 9022 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 9023 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 9024 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 9025 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9026 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 9027 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9028 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 9029 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), 9030 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 9031 { } /* end */ 9032}; 9033 9034static struct snd_kcontrol_new alc883_targa_mixer[] = { 9035 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9036 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 9037 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 9038 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 9039 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 9040 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 9041 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 9042 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 9043 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 9044 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 9045 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 9046 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 9047 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 9048 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 9049 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9050 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 9051 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9052 { } /* end */ 9053}; 9054 9055static struct snd_kcontrol_new alc883_targa_2ch_mixer[] = { 9056 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9057 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 9058 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 9059 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 9060 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 9061 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 9062 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9063 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 9064 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9065 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 9066 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), 9067 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 9068 { } /* end */ 9069}; 9070 9071static struct snd_kcontrol_new alc883_targa_8ch_mixer[] = { 9072 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 9073 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 9074 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 9075 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), 9076 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 9077 { } /* end */ 9078}; 9079 9080static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = { 9081 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9082 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 9083 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 9084 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 9085 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 9086 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 9087 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 9088 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 9089 { } /* end */ 9090}; 9091 9092static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = { 9093 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9094 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT), 9095 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 9096 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 9097 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 9098 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9099 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9100 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 9101 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 9102 { } /* end */ 9103}; 9104 9105static struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = { 9106 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9107 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 9108 HDA_CODEC_MUTE("Speaker Playback Switch", 0x15, 0x0, HDA_OUTPUT), 9109 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT), 9110 HDA_CODEC_VOLUME("Line Playback Volume", 0x08, 0x0, HDA_INPUT), 9111 HDA_CODEC_MUTE("Line Playback Switch", 0x08, 0x0, HDA_INPUT), 9112 { } /* end */ 9113}; 9114 9115static struct hda_verb alc883_medion_wim2160_verbs[] = { 9116 /* Unmute front mixer */ 9117 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9118 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9119 9120 /* Set speaker pin to front mixer */ 9121 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9122 9123 /* Init headphone pin */ 9124 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9125 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9126 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00}, 9127 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9128 9129 { } /* end */ 9130}; 9131 9132/* toggle speaker-output according to the hp-jack state */ 9133static void alc883_medion_wim2160_setup(struct hda_codec *codec) 9134{ 9135 struct alc_spec *spec = codec->spec; 9136 9137 spec->autocfg.hp_pins[0] = 0x1a; 9138 spec->autocfg.speaker_pins[0] = 0x15; 9139} 9140 9141static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = { 9142 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9143 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 9144 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 9145 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 9146 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 9147 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9148 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 9149 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9150 { } /* end */ 9151}; 9152 9153static struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = { 9154 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9155 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 9156 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 9157 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 9158 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 9159 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 9160 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9161 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 9162 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9163 { } /* end */ 9164}; 9165 9166static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = { 9167 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9168 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 9169 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT), 9170 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT), 9171 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 9172 0x0d, 1, 0x0, HDA_OUTPUT), 9173 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT), 9174 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT), 9175 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT), 9176 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 9177 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 9178 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 9179 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 9180 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 9181 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 9182 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9183 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 9184 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9185 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 9186 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), 9187 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 9188 { } /* end */ 9189}; 9190 9191static struct snd_kcontrol_new alc889A_mb31_mixer[] = { 9192 /* Output mixers */ 9193 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 9194 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT), 9195 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT), 9196 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT), 9197 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00, 9198 HDA_OUTPUT), 9199 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT), 9200 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT), 9201 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT), 9202 /* Output switches */ 9203 HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT), 9204 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT), 9205 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT), 9206 /* Boost mixers */ 9207 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT), 9208 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT), 9209 /* Input mixers */ 9210 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT), 9211 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT), 9212 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 9213 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 9214 { } /* end */ 9215}; 9216 9217static struct snd_kcontrol_new alc883_vaiott_mixer[] = { 9218 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9219 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 9220 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 9221 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 9222 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT), 9223 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 9224 { } /* end */ 9225}; 9226 9227static struct hda_bind_ctls alc883_bind_cap_vol = { 9228 .ops = &snd_hda_bind_vol, 9229 .values = { 9230 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT), 9231 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT), 9232 0 9233 }, 9234}; 9235 9236static struct hda_bind_ctls alc883_bind_cap_switch = { 9237 .ops = &snd_hda_bind_sw, 9238 .values = { 9239 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT), 9240 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT), 9241 0 9242 }, 9243}; 9244 9245static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = { 9246 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9247 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 9248 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 9249 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 9250 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 9251 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9252 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 9253 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9254 { } /* end */ 9255}; 9256 9257static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = { 9258 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol), 9259 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch), 9260 { 9261 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 9262 /* .name = "Capture Source", */ 9263 .name = "Input Source", 9264 .count = 1, 9265 .info = alc_mux_enum_info, 9266 .get = alc_mux_enum_get, 9267 .put = alc_mux_enum_put, 9268 }, 9269 { } /* end */ 9270}; 9271 9272static struct snd_kcontrol_new alc883_chmode_mixer[] = { 9273 { 9274 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 9275 .name = "Channel Mode", 9276 .info = alc_ch_mode_info, 9277 .get = alc_ch_mode_get, 9278 .put = alc_ch_mode_put, 9279 }, 9280 { } /* end */ 9281}; 9282 9283/* toggle speaker-output according to the hp-jack state */ 9284static void alc883_mitac_setup(struct hda_codec *codec) 9285{ 9286 struct alc_spec *spec = codec->spec; 9287 9288 spec->autocfg.hp_pins[0] = 0x15; 9289 spec->autocfg.speaker_pins[0] = 0x14; 9290 spec->autocfg.speaker_pins[1] = 0x17; 9291} 9292 9293static struct hda_verb alc883_mitac_verbs[] = { 9294 /* HP */ 9295 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9296 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9297 /* Subwoofer */ 9298 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02}, 9299 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9300 9301 /* enable unsolicited event */ 9302 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9303 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */ 9304 9305 { } /* end */ 9306}; 9307 9308static struct hda_verb alc883_clevo_m540r_verbs[] = { 9309 /* HP */ 9310 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9311 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9312 /* Int speaker */ 9313 /*{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},*/ 9314 9315 /* enable unsolicited event */ 9316 /* 9317 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9318 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, 9319 */ 9320 9321 { } /* end */ 9322}; 9323 9324static struct hda_verb alc883_clevo_m720_verbs[] = { 9325 /* HP */ 9326 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9327 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9328 /* Int speaker */ 9329 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01}, 9330 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9331 9332 /* enable unsolicited event */ 9333 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9334 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, 9335 9336 { } /* end */ 9337}; 9338 9339static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = { 9340 /* HP */ 9341 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 9342 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9343 /* Subwoofer */ 9344 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 9345 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9346 9347 /* enable unsolicited event */ 9348 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9349 9350 { } /* end */ 9351}; 9352 9353static struct hda_verb alc883_targa_verbs[] = { 9354 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9355 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9356 9357 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9358 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9359 9360/* Connect Line-Out side jack (SPDIF) to Side */ 9361 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9362 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9363 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, 9364/* Connect Mic jack to CLFE */ 9365 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9366 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9367 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, 9368/* Connect Line-in jack to Surround */ 9369 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9370 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9371 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, 9372/* Connect HP out jack to Front */ 9373 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9374 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9375 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 9376 9377 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9378 9379 { } /* end */ 9380}; 9381 9382static struct hda_verb alc883_lenovo_101e_verbs[] = { 9383 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9384 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN}, 9385 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN}, 9386 { } /* end */ 9387}; 9388 9389static struct hda_verb alc883_lenovo_nb0763_verbs[] = { 9390 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9391 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9392 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9393 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9394 { } /* end */ 9395}; 9396 9397static struct hda_verb alc888_lenovo_ms7195_verbs[] = { 9398 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9399 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9400 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9401 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN}, 9402 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9403 { } /* end */ 9404}; 9405 9406static struct hda_verb alc883_haier_w66_verbs[] = { 9407 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9408 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9409 9410 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9411 9412 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 9413 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9414 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9415 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9416 { } /* end */ 9417}; 9418 9419static struct hda_verb alc888_lenovo_sky_verbs[] = { 9420 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9421 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9422 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9423 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9424 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9425 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9426 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00}, 9427 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9428 { } /* end */ 9429}; 9430 9431static struct hda_verb alc888_6st_dell_verbs[] = { 9432 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9433 { } 9434}; 9435 9436static struct hda_verb alc883_vaiott_verbs[] = { 9437 /* HP */ 9438 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9439 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9440 9441 /* enable unsolicited event */ 9442 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9443 9444 { } /* end */ 9445}; 9446 9447static void alc888_3st_hp_setup(struct hda_codec *codec) 9448{ 9449 struct alc_spec *spec = codec->spec; 9450 9451 spec->autocfg.hp_pins[0] = 0x1b; 9452 spec->autocfg.speaker_pins[0] = 0x14; 9453 spec->autocfg.speaker_pins[1] = 0x16; 9454 spec->autocfg.speaker_pins[2] = 0x18; 9455} 9456 9457static struct hda_verb alc888_3st_hp_verbs[] = { 9458 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */ 9459 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */ 9460 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */ 9461 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9462 { } /* end */ 9463}; 9464 9465/* 9466 * 2ch mode 9467 */ 9468static struct hda_verb alc888_3st_hp_2ch_init[] = { 9469 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 9470 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 9471 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 9472 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 9473 { } /* end */ 9474}; 9475 9476/* 9477 * 4ch mode 9478 */ 9479static struct hda_verb alc888_3st_hp_4ch_init[] = { 9480 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 9481 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 9482 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 9483 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 9484 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 }, 9485 { } /* end */ 9486}; 9487 9488/* 9489 * 6ch mode 9490 */ 9491static struct hda_verb alc888_3st_hp_6ch_init[] = { 9492 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 9493 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 9494 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, 9495 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 9496 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 9497 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 }, 9498 { } /* end */ 9499}; 9500 9501static struct hda_channel_mode alc888_3st_hp_modes[3] = { 9502 { 2, alc888_3st_hp_2ch_init }, 9503 { 4, alc888_3st_hp_4ch_init }, 9504 { 6, alc888_3st_hp_6ch_init }, 9505}; 9506 9507/* toggle front-jack and RCA according to the hp-jack state */ 9508static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec) 9509{ 9510 unsigned int present = snd_hda_jack_detect(codec, 0x1b); 9511 9512 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 9513 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 9514 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 9515 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 9516} 9517 9518/* toggle RCA according to the front-jack state */ 9519static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec) 9520{ 9521 unsigned int present = snd_hda_jack_detect(codec, 0x14); 9522 9523 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 9524 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 9525} 9526 9527static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec, 9528 unsigned int res) 9529{ 9530 if ((res >> 26) == ALC880_HP_EVENT) 9531 alc888_lenovo_ms7195_front_automute(codec); 9532 if ((res >> 26) == ALC880_FRONT_EVENT) 9533 alc888_lenovo_ms7195_rca_automute(codec); 9534} 9535 9536/* toggle speaker-output according to the hp-jack state */ 9537static void alc883_lenovo_nb0763_setup(struct hda_codec *codec) 9538{ 9539 struct alc_spec *spec = codec->spec; 9540 9541 spec->autocfg.hp_pins[0] = 0x14; 9542 spec->autocfg.speaker_pins[0] = 0x15; 9543} 9544 9545/* toggle speaker-output according to the hp-jack state */ 9546#define alc883_targa_init_hook alc882_targa_init_hook 9547#define alc883_targa_unsol_event alc882_targa_unsol_event 9548 9549static void alc883_clevo_m720_setup(struct hda_codec *codec) 9550{ 9551 struct alc_spec *spec = codec->spec; 9552 9553 spec->autocfg.hp_pins[0] = 0x15; 9554 spec->autocfg.speaker_pins[0] = 0x14; 9555} 9556 9557static void alc883_clevo_m720_init_hook(struct hda_codec *codec) 9558{ 9559 alc_automute_amp(codec); 9560 alc88x_simple_mic_automute(codec); 9561} 9562 9563static void alc883_clevo_m720_unsol_event(struct hda_codec *codec, 9564 unsigned int res) 9565{ 9566 switch (res >> 26) { 9567 case ALC880_MIC_EVENT: 9568 alc88x_simple_mic_automute(codec); 9569 break; 9570 default: 9571 alc_automute_amp_unsol_event(codec, res); 9572 break; 9573 } 9574} 9575 9576/* toggle speaker-output according to the hp-jack state */ 9577static void alc883_2ch_fujitsu_pi2515_setup(struct hda_codec *codec) 9578{ 9579 struct alc_spec *spec = codec->spec; 9580 9581 spec->autocfg.hp_pins[0] = 0x14; 9582 spec->autocfg.speaker_pins[0] = 0x15; 9583} 9584 9585static void alc883_haier_w66_setup(struct hda_codec *codec) 9586{ 9587 struct alc_spec *spec = codec->spec; 9588 9589 spec->autocfg.hp_pins[0] = 0x1b; 9590 spec->autocfg.speaker_pins[0] = 0x14; 9591} 9592 9593static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec) 9594{ 9595 int bits = snd_hda_jack_detect(codec, 0x14) ? HDA_AMP_MUTE : 0; 9596 9597 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 9598 HDA_AMP_MUTE, bits); 9599} 9600 9601static void alc883_lenovo_101e_all_automute(struct hda_codec *codec) 9602{ 9603 int bits = snd_hda_jack_detect(codec, 0x1b) ? HDA_AMP_MUTE : 0; 9604 9605 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 9606 HDA_AMP_MUTE, bits); 9607 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 9608 HDA_AMP_MUTE, bits); 9609} 9610 9611static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec, 9612 unsigned int res) 9613{ 9614 if ((res >> 26) == ALC880_HP_EVENT) 9615 alc883_lenovo_101e_all_automute(codec); 9616 if ((res >> 26) == ALC880_FRONT_EVENT) 9617 alc883_lenovo_101e_ispeaker_automute(codec); 9618} 9619 9620/* toggle speaker-output according to the hp-jack state */ 9621static void alc883_acer_aspire_setup(struct hda_codec *codec) 9622{ 9623 struct alc_spec *spec = codec->spec; 9624 9625 spec->autocfg.hp_pins[0] = 0x14; 9626 spec->autocfg.speaker_pins[0] = 0x15; 9627 spec->autocfg.speaker_pins[1] = 0x16; 9628} 9629 9630static struct hda_verb alc883_acer_eapd_verbs[] = { 9631 /* HP Pin: output 0 (0x0c) */ 9632 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9633 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9634 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 9635 /* Front Pin: output 0 (0x0c) */ 9636 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9637 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9638 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9639 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, 9640 /* eanable EAPD on medion laptop */ 9641 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 9642 {0x20, AC_VERB_SET_PROC_COEF, 0x3050}, 9643 /* enable unsolicited event */ 9644 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9645 { } 9646}; 9647 9648static void alc888_6st_dell_setup(struct hda_codec *codec) 9649{ 9650 struct alc_spec *spec = codec->spec; 9651 9652 spec->autocfg.hp_pins[0] = 0x1b; 9653 spec->autocfg.speaker_pins[0] = 0x14; 9654 spec->autocfg.speaker_pins[1] = 0x15; 9655 spec->autocfg.speaker_pins[2] = 0x16; 9656 spec->autocfg.speaker_pins[3] = 0x17; 9657} 9658 9659static void alc888_lenovo_sky_setup(struct hda_codec *codec) 9660{ 9661 struct alc_spec *spec = codec->spec; 9662 9663 spec->autocfg.hp_pins[0] = 0x1b; 9664 spec->autocfg.speaker_pins[0] = 0x14; 9665 spec->autocfg.speaker_pins[1] = 0x15; 9666 spec->autocfg.speaker_pins[2] = 0x16; 9667 spec->autocfg.speaker_pins[3] = 0x17; 9668 spec->autocfg.speaker_pins[4] = 0x1a; 9669} 9670 9671static void alc883_vaiott_setup(struct hda_codec *codec) 9672{ 9673 struct alc_spec *spec = codec->spec; 9674 9675 spec->autocfg.hp_pins[0] = 0x15; 9676 spec->autocfg.speaker_pins[0] = 0x14; 9677 spec->autocfg.speaker_pins[1] = 0x17; 9678} 9679 9680static struct hda_verb alc888_asus_m90v_verbs[] = { 9681 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 9682 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 9683 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9684 /* enable unsolicited event */ 9685 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9686 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, 9687 { } /* end */ 9688}; 9689 9690static void alc883_mode2_setup(struct hda_codec *codec) 9691{ 9692 struct alc_spec *spec = codec->spec; 9693 9694 spec->autocfg.hp_pins[0] = 0x1b; 9695 spec->autocfg.speaker_pins[0] = 0x14; 9696 spec->autocfg.speaker_pins[1] = 0x15; 9697 spec->autocfg.speaker_pins[2] = 0x16; 9698 spec->ext_mic.pin = 0x18; 9699 spec->int_mic.pin = 0x19; 9700 spec->ext_mic.mux_idx = 0; 9701 spec->int_mic.mux_idx = 1; 9702 spec->auto_mic = 1; 9703} 9704 9705static struct hda_verb alc888_asus_eee1601_verbs[] = { 9706 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9707 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9708 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 9709 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9710 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 9711 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b}, 9712 {0x20, AC_VERB_SET_PROC_COEF, 0x0838}, 9713 /* enable unsolicited event */ 9714 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9715 { } /* end */ 9716}; 9717 9718static void alc883_eee1601_inithook(struct hda_codec *codec) 9719{ 9720 struct alc_spec *spec = codec->spec; 9721 9722 spec->autocfg.hp_pins[0] = 0x14; 9723 spec->autocfg.speaker_pins[0] = 0x1b; 9724 alc_automute_pin(codec); 9725} 9726 9727static struct hda_verb alc889A_mb31_verbs[] = { 9728 /* Init rear pin (used as headphone output) */ 9729 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */ 9730 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */ 9731 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9732 /* Init line pin (used as output in 4ch and 6ch mode) */ 9733 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */ 9734 /* Init line 2 pin (used as headphone out by default) */ 9735 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */ 9736 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */ 9737 { } /* end */ 9738}; 9739 9740/* Mute speakers according to the headphone jack state */ 9741static void alc889A_mb31_automute(struct hda_codec *codec) 9742{ 9743 unsigned int present; 9744 9745 /* Mute only in 2ch or 4ch mode */ 9746 if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0) 9747 == 0x00) { 9748 present = snd_hda_jack_detect(codec, 0x15); 9749 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 9750 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 9751 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0, 9752 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 9753 } 9754} 9755 9756static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res) 9757{ 9758 if ((res >> 26) == ALC880_HP_EVENT) 9759 alc889A_mb31_automute(codec); 9760} 9761 9762 9763#ifdef CONFIG_SND_HDA_POWER_SAVE 9764#define alc882_loopbacks alc880_loopbacks 9765#endif 9766 9767/* pcm configuration: identical with ALC880 */ 9768#define alc882_pcm_analog_playback alc880_pcm_analog_playback 9769#define alc882_pcm_analog_capture alc880_pcm_analog_capture 9770#define alc882_pcm_digital_playback alc880_pcm_digital_playback 9771#define alc882_pcm_digital_capture alc880_pcm_digital_capture 9772 9773static hda_nid_t alc883_slave_dig_outs[] = { 9774 ALC1200_DIGOUT_NID, 0, 9775}; 9776 9777static hda_nid_t alc1200_slave_dig_outs[] = { 9778 ALC883_DIGOUT_NID, 0, 9779}; 9780 9781/* 9782 * configuration and preset 9783 */ 9784static const char * const alc882_models[ALC882_MODEL_LAST] = { 9785 [ALC882_3ST_DIG] = "3stack-dig", 9786 [ALC882_6ST_DIG] = "6stack-dig", 9787 [ALC882_ARIMA] = "arima", 9788 [ALC882_W2JC] = "w2jc", 9789 [ALC882_TARGA] = "targa", 9790 [ALC882_ASUS_A7J] = "asus-a7j", 9791 [ALC882_ASUS_A7M] = "asus-a7m", 9792 [ALC885_MACPRO] = "macpro", 9793 [ALC885_MB5] = "mb5", 9794 [ALC885_MACMINI3] = "macmini3", 9795 [ALC885_MBA21] = "mba21", 9796 [ALC885_MBP3] = "mbp3", 9797 [ALC885_IMAC24] = "imac24", 9798 [ALC885_IMAC91] = "imac91", 9799 [ALC883_3ST_2ch_DIG] = "3stack-2ch-dig", 9800 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig", 9801 [ALC883_3ST_6ch] = "3stack-6ch", 9802 [ALC883_6ST_DIG] = "alc883-6stack-dig", 9803 [ALC883_TARGA_DIG] = "targa-dig", 9804 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig", 9805 [ALC883_TARGA_8ch_DIG] = "targa-8ch-dig", 9806 [ALC883_ACER] = "acer", 9807 [ALC883_ACER_ASPIRE] = "acer-aspire", 9808 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g", 9809 [ALC888_ACER_ASPIRE_6530G] = "acer-aspire-6530g", 9810 [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g", 9811 [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g", 9812 [ALC883_MEDION] = "medion", 9813 [ALC883_MEDION_WIM2160] = "medion-wim2160", 9814 [ALC883_LAPTOP_EAPD] = "laptop-eapd", 9815 [ALC883_LENOVO_101E_2ch] = "lenovo-101e", 9816 [ALC883_LENOVO_NB0763] = "lenovo-nb0763", 9817 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig", 9818 [ALC888_LENOVO_SKY] = "lenovo-sky", 9819 [ALC883_HAIER_W66] = "haier-w66", 9820 [ALC888_3ST_HP] = "3stack-hp", 9821 [ALC888_6ST_DELL] = "6stack-dell", 9822 [ALC883_MITAC] = "mitac", 9823 [ALC883_CLEVO_M540R] = "clevo-m540r", 9824 [ALC883_CLEVO_M720] = "clevo-m720", 9825 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515", 9826 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530", 9827 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel", 9828 [ALC889A_INTEL] = "intel-alc889a", 9829 [ALC889_INTEL] = "intel-x58", 9830 [ALC1200_ASUS_P5Q] = "asus-p5q", 9831 [ALC889A_MB31] = "mb31", 9832 [ALC883_SONY_VAIO_TT] = "sony-vaio-tt", 9833 [ALC882_AUTO] = "auto", 9834}; 9835 9836static struct snd_pci_quirk alc882_cfg_tbl[] = { 9837 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG), 9838 9839 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE), 9840 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE), 9841 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE), 9842 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE), 9843 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE), 9844 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE), 9845 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G", 9846 ALC888_ACER_ASPIRE_4930G), 9847 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G", 9848 ALC888_ACER_ASPIRE_4930G), 9849 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G", 9850 ALC888_ACER_ASPIRE_8930G), 9851 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G", 9852 ALC888_ACER_ASPIRE_8930G), 9853 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC882_AUTO), 9854 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC882_AUTO), 9855 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G", 9856 ALC888_ACER_ASPIRE_6530G), 9857 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G", 9858 ALC888_ACER_ASPIRE_6530G), 9859 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G", 9860 ALC888_ACER_ASPIRE_7730G), 9861 /* default Acer -- disabled as it causes more problems. 9862 * model=auto should work fine now 9863 */ 9864 /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */ 9865 9866 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL), 9867 9868 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG), 9869 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP), 9870 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP), 9871 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG), 9872 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP), 9873 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP), 9874 9875 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J), 9876 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J), 9877 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M), 9878 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V), 9879 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC), 9880 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG), 9881 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG), 9882 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG), 9883 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG), 9884 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q), 9885 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601), 9886 9887 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT), 9888 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG), 9889 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG), 9890 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC), 9891 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC), 9892 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD), 9893 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL), 9894 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch), 9895 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG), 9896 9897 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG), 9898 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG), 9899 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG), 9900 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */ 9901 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC882_AUTO), 9902 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG), 9903 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG), 9904 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG), 9905 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG), 9906 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG), 9907 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG), 9908 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG), 9909 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG), 9910 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG), 9911 SND_PCI_QUIRK(0x1462, 0x42cd, "MSI", ALC883_TARGA_DIG), 9912 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG), 9913 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG), 9914 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG), 9915 SND_PCI_QUIRK(0x1462, 0x4570, "MSI Wind Top AE2220", ALC883_TARGA_DIG), 9916 SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG), 9917 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG), 9918 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG), 9919 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG), 9920 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG), 9921 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG), 9922 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG), 9923 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG), 9924 SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG), 9925 SND_PCI_QUIRK(0x1462, 0x7437, "MSI NetOn AP1900", ALC883_TARGA_DIG), 9926 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG), 9927 SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG), 9928 9929 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG), 9930 SND_PCI_QUIRK(0x1558, 0x0571, "Clevo laptop M570U", ALC883_3ST_6ch_DIG), 9931 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720), 9932 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720), 9933 SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R), 9934 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD), 9935 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch), 9936 /* SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), */ 9937 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION), 9938 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx", 9939 ALC883_FUJITSU_PI2515), 9940 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx", 9941 ALC888_FUJITSU_XA3530), 9942 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch), 9943 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763), 9944 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763), 9945 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763), 9946 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY), 9947 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG), 9948 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG), 9949 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66), 9950 9951 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL), 9952 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL), 9953 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC), 9954 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL), 9955 SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL), 9956 SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL), 9957 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC882_6ST_DIG), 9958 9959 {} 9960}; 9961 9962/* codec SSID table for Intel Mac */ 9963static struct snd_pci_quirk alc882_ssid_cfg_tbl[] = { 9964 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3), 9965 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3), 9966 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3), 9967 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_MACPRO), 9968 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24), 9969 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24), 9970 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3), 9971 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889A_MB31), 9972 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_ASUS_A7M), 9973 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC885_MBP3), 9974 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC885_MBA21), 9975 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31), 9976 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3), 9977 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24), 9978 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC885_IMAC91), 9979 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5), 9980 SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC885_MB5), 9981 /* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2, 9982 * so apparently no perfect solution yet 9983 */ 9984 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5), 9985 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5), 9986 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC885_MACMINI3), 9987 {} /* terminator */ 9988}; 9989 9990static struct alc_config_preset alc882_presets[] = { 9991 [ALC882_3ST_DIG] = { 9992 .mixers = { alc882_base_mixer }, 9993 .init_verbs = { alc882_base_init_verbs, 9994 alc882_adc1_init_verbs }, 9995 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 9996 .dac_nids = alc882_dac_nids, 9997 .dig_out_nid = ALC882_DIGOUT_NID, 9998 .dig_in_nid = ALC882_DIGIN_NID, 9999 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes), 10000 .channel_mode = alc882_ch_modes, 10001 .need_dac_fix = 1, 10002 .input_mux = &alc882_capture_source, 10003 }, 10004 [ALC882_6ST_DIG] = { 10005 .mixers = { alc882_base_mixer, alc882_chmode_mixer }, 10006 .init_verbs = { alc882_base_init_verbs, 10007 alc882_adc1_init_verbs }, 10008 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 10009 .dac_nids = alc882_dac_nids, 10010 .dig_out_nid = ALC882_DIGOUT_NID, 10011 .dig_in_nid = ALC882_DIGIN_NID, 10012 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes), 10013 .channel_mode = alc882_sixstack_modes, 10014 .input_mux = &alc882_capture_source, 10015 }, 10016 [ALC882_ARIMA] = { 10017 .mixers = { alc882_base_mixer, alc882_chmode_mixer }, 10018 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs, 10019 alc882_eapd_verbs }, 10020 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 10021 .dac_nids = alc882_dac_nids, 10022 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes), 10023 .channel_mode = alc882_sixstack_modes, 10024 .input_mux = &alc882_capture_source, 10025 }, 10026 [ALC882_W2JC] = { 10027 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer }, 10028 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs, 10029 alc882_eapd_verbs, alc880_gpio1_init_verbs }, 10030 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 10031 .dac_nids = alc882_dac_nids, 10032 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), 10033 .channel_mode = alc880_threestack_modes, 10034 .need_dac_fix = 1, 10035 .input_mux = &alc882_capture_source, 10036 .dig_out_nid = ALC882_DIGOUT_NID, 10037 }, 10038 [ALC885_MBA21] = { 10039 .mixers = { alc885_mba21_mixer }, 10040 .init_verbs = { alc885_mba21_init_verbs, alc880_gpio1_init_verbs }, 10041 .num_dacs = 2, 10042 .dac_nids = alc882_dac_nids, 10043 .channel_mode = alc885_mba21_ch_modes, 10044 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes), 10045 .input_mux = &alc882_capture_source, 10046 .unsol_event = alc_automute_amp_unsol_event, 10047 .setup = alc885_mba21_setup, 10048 .init_hook = alc_automute_amp, 10049 }, 10050 [ALC885_MBP3] = { 10051 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer }, 10052 .init_verbs = { alc885_mbp3_init_verbs, 10053 alc880_gpio1_init_verbs }, 10054 .num_dacs = 2, 10055 .dac_nids = alc882_dac_nids, 10056 .hp_nid = 0x04, 10057 .channel_mode = alc885_mbp_4ch_modes, 10058 .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes), 10059 .input_mux = &alc882_capture_source, 10060 .dig_out_nid = ALC882_DIGOUT_NID, 10061 .dig_in_nid = ALC882_DIGIN_NID, 10062 .unsol_event = alc_automute_amp_unsol_event, 10063 .setup = alc885_mbp3_setup, 10064 .init_hook = alc_automute_amp, 10065 }, 10066 [ALC885_MB5] = { 10067 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer }, 10068 .init_verbs = { alc885_mb5_init_verbs, 10069 alc880_gpio1_init_verbs }, 10070 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 10071 .dac_nids = alc882_dac_nids, 10072 .channel_mode = alc885_mb5_6ch_modes, 10073 .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes), 10074 .input_mux = &mb5_capture_source, 10075 .dig_out_nid = ALC882_DIGOUT_NID, 10076 .dig_in_nid = ALC882_DIGIN_NID, 10077 .unsol_event = alc_automute_amp_unsol_event, 10078 .setup = alc885_mb5_setup, 10079 .init_hook = alc_automute_amp, 10080 }, 10081 [ALC885_MACMINI3] = { 10082 .mixers = { alc885_macmini3_mixer, alc882_chmode_mixer }, 10083 .init_verbs = { alc885_macmini3_init_verbs, 10084 alc880_gpio1_init_verbs }, 10085 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 10086 .dac_nids = alc882_dac_nids, 10087 .channel_mode = alc885_macmini3_6ch_modes, 10088 .num_channel_mode = ARRAY_SIZE(alc885_macmini3_6ch_modes), 10089 .input_mux = &macmini3_capture_source, 10090 .dig_out_nid = ALC882_DIGOUT_NID, 10091 .dig_in_nid = ALC882_DIGIN_NID, 10092 .unsol_event = alc_automute_amp_unsol_event, 10093 .setup = alc885_macmini3_setup, 10094 .init_hook = alc_automute_amp, 10095 }, 10096 [ALC885_MACPRO] = { 10097 .mixers = { alc882_macpro_mixer }, 10098 .init_verbs = { alc882_macpro_init_verbs }, 10099 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 10100 .dac_nids = alc882_dac_nids, 10101 .dig_out_nid = ALC882_DIGOUT_NID, 10102 .dig_in_nid = ALC882_DIGIN_NID, 10103 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes), 10104 .channel_mode = alc882_ch_modes, 10105 .input_mux = &alc882_capture_source, 10106 .init_hook = alc885_macpro_init_hook, 10107 }, 10108 [ALC885_IMAC24] = { 10109 .mixers = { alc885_imac24_mixer }, 10110 .init_verbs = { alc885_imac24_init_verbs }, 10111 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 10112 .dac_nids = alc882_dac_nids, 10113 .dig_out_nid = ALC882_DIGOUT_NID, 10114 .dig_in_nid = ALC882_DIGIN_NID, 10115 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes), 10116 .channel_mode = alc882_ch_modes, 10117 .input_mux = &alc882_capture_source, 10118 .unsol_event = alc_automute_amp_unsol_event, 10119 .setup = alc885_imac24_setup, 10120 .init_hook = alc885_imac24_init_hook, 10121 }, 10122 [ALC885_IMAC91] = { 10123 .mixers = {alc885_imac91_mixer}, 10124 .init_verbs = { alc885_imac91_init_verbs, 10125 alc880_gpio1_init_verbs }, 10126 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 10127 .dac_nids = alc882_dac_nids, 10128 .channel_mode = alc885_mba21_ch_modes, 10129 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes), 10130 .input_mux = &alc889A_imac91_capture_source, 10131 .dig_out_nid = ALC882_DIGOUT_NID, 10132 .dig_in_nid = ALC882_DIGIN_NID, 10133 .unsol_event = alc_automute_amp_unsol_event, 10134 .setup = alc885_imac91_setup, 10135 .init_hook = alc_automute_amp, 10136 }, 10137 [ALC882_TARGA] = { 10138 .mixers = { alc882_targa_mixer, alc882_chmode_mixer }, 10139 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs, 10140 alc880_gpio3_init_verbs, alc882_targa_verbs}, 10141 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 10142 .dac_nids = alc882_dac_nids, 10143 .dig_out_nid = ALC882_DIGOUT_NID, 10144 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids), 10145 .adc_nids = alc882_adc_nids, 10146 .capsrc_nids = alc882_capsrc_nids, 10147 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes), 10148 .channel_mode = alc882_3ST_6ch_modes, 10149 .need_dac_fix = 1, 10150 .input_mux = &alc882_capture_source, 10151 .unsol_event = alc882_targa_unsol_event, 10152 .setup = alc882_targa_setup, 10153 .init_hook = alc882_targa_automute, 10154 }, 10155 [ALC882_ASUS_A7J] = { 10156 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer }, 10157 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs, 10158 alc882_asus_a7j_verbs}, 10159 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 10160 .dac_nids = alc882_dac_nids, 10161 .dig_out_nid = ALC882_DIGOUT_NID, 10162 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids), 10163 .adc_nids = alc882_adc_nids, 10164 .capsrc_nids = alc882_capsrc_nids, 10165 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes), 10166 .channel_mode = alc882_3ST_6ch_modes, 10167 .need_dac_fix = 1, 10168 .input_mux = &alc882_capture_source, 10169 }, 10170 [ALC882_ASUS_A7M] = { 10171 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer }, 10172 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs, 10173 alc882_eapd_verbs, alc880_gpio1_init_verbs, 10174 alc882_asus_a7m_verbs }, 10175 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 10176 .dac_nids = alc882_dac_nids, 10177 .dig_out_nid = ALC882_DIGOUT_NID, 10178 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), 10179 .channel_mode = alc880_threestack_modes, 10180 .need_dac_fix = 1, 10181 .input_mux = &alc882_capture_source, 10182 }, 10183 [ALC883_3ST_2ch_DIG] = { 10184 .mixers = { alc883_3ST_2ch_mixer }, 10185 .init_verbs = { alc883_init_verbs }, 10186 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10187 .dac_nids = alc883_dac_nids, 10188 .dig_out_nid = ALC883_DIGOUT_NID, 10189 .dig_in_nid = ALC883_DIGIN_NID, 10190 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10191 .channel_mode = alc883_3ST_2ch_modes, 10192 .input_mux = &alc883_capture_source, 10193 }, 10194 [ALC883_3ST_6ch_DIG] = { 10195 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, 10196 .init_verbs = { alc883_init_verbs }, 10197 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10198 .dac_nids = alc883_dac_nids, 10199 .dig_out_nid = ALC883_DIGOUT_NID, 10200 .dig_in_nid = ALC883_DIGIN_NID, 10201 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 10202 .channel_mode = alc883_3ST_6ch_modes, 10203 .need_dac_fix = 1, 10204 .input_mux = &alc883_capture_source, 10205 }, 10206 [ALC883_3ST_6ch] = { 10207 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, 10208 .init_verbs = { alc883_init_verbs }, 10209 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10210 .dac_nids = alc883_dac_nids, 10211 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 10212 .channel_mode = alc883_3ST_6ch_modes, 10213 .need_dac_fix = 1, 10214 .input_mux = &alc883_capture_source, 10215 }, 10216 [ALC883_3ST_6ch_INTEL] = { 10217 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer }, 10218 .init_verbs = { alc883_init_verbs }, 10219 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10220 .dac_nids = alc883_dac_nids, 10221 .dig_out_nid = ALC883_DIGOUT_NID, 10222 .dig_in_nid = ALC883_DIGIN_NID, 10223 .slave_dig_outs = alc883_slave_dig_outs, 10224 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes), 10225 .channel_mode = alc883_3ST_6ch_intel_modes, 10226 .need_dac_fix = 1, 10227 .input_mux = &alc883_3stack_6ch_intel, 10228 }, 10229 [ALC889A_INTEL] = { 10230 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer }, 10231 .init_verbs = { alc885_init_verbs, alc885_init_input_verbs, 10232 alc_hp15_unsol_verbs }, 10233 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10234 .dac_nids = alc883_dac_nids, 10235 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids), 10236 .adc_nids = alc889_adc_nids, 10237 .dig_out_nid = ALC883_DIGOUT_NID, 10238 .dig_in_nid = ALC883_DIGIN_NID, 10239 .slave_dig_outs = alc883_slave_dig_outs, 10240 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes), 10241 .channel_mode = alc889_8ch_intel_modes, 10242 .capsrc_nids = alc889_capsrc_nids, 10243 .input_mux = &alc889_capture_source, 10244 .setup = alc889_automute_setup, 10245 .init_hook = alc_automute_amp, 10246 .unsol_event = alc_automute_amp_unsol_event, 10247 .need_dac_fix = 1, 10248 }, 10249 [ALC889_INTEL] = { 10250 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer }, 10251 .init_verbs = { alc885_init_verbs, alc889_init_input_verbs, 10252 alc889_eapd_verbs, alc_hp15_unsol_verbs}, 10253 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10254 .dac_nids = alc883_dac_nids, 10255 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids), 10256 .adc_nids = alc889_adc_nids, 10257 .dig_out_nid = ALC883_DIGOUT_NID, 10258 .dig_in_nid = ALC883_DIGIN_NID, 10259 .slave_dig_outs = alc883_slave_dig_outs, 10260 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes), 10261 .channel_mode = alc889_8ch_intel_modes, 10262 .capsrc_nids = alc889_capsrc_nids, 10263 .input_mux = &alc889_capture_source, 10264 .setup = alc889_automute_setup, 10265 .init_hook = alc889_intel_init_hook, 10266 .unsol_event = alc_automute_amp_unsol_event, 10267 .need_dac_fix = 1, 10268 }, 10269 [ALC883_6ST_DIG] = { 10270 .mixers = { alc883_base_mixer, alc883_chmode_mixer }, 10271 .init_verbs = { alc883_init_verbs }, 10272 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10273 .dac_nids = alc883_dac_nids, 10274 .dig_out_nid = ALC883_DIGOUT_NID, 10275 .dig_in_nid = ALC883_DIGIN_NID, 10276 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), 10277 .channel_mode = alc883_sixstack_modes, 10278 .input_mux = &alc883_capture_source, 10279 }, 10280 [ALC883_TARGA_DIG] = { 10281 .mixers = { alc883_targa_mixer, alc883_chmode_mixer }, 10282 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs, 10283 alc883_targa_verbs}, 10284 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10285 .dac_nids = alc883_dac_nids, 10286 .dig_out_nid = ALC883_DIGOUT_NID, 10287 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 10288 .channel_mode = alc883_3ST_6ch_modes, 10289 .need_dac_fix = 1, 10290 .input_mux = &alc883_capture_source, 10291 .unsol_event = alc883_targa_unsol_event, 10292 .setup = alc882_targa_setup, 10293 .init_hook = alc882_targa_automute, 10294 }, 10295 [ALC883_TARGA_2ch_DIG] = { 10296 .mixers = { alc883_targa_2ch_mixer}, 10297 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs, 10298 alc883_targa_verbs}, 10299 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10300 .dac_nids = alc883_dac_nids, 10301 .adc_nids = alc883_adc_nids_alt, 10302 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt), 10303 .capsrc_nids = alc883_capsrc_nids, 10304 .dig_out_nid = ALC883_DIGOUT_NID, 10305 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10306 .channel_mode = alc883_3ST_2ch_modes, 10307 .input_mux = &alc883_capture_source, 10308 .unsol_event = alc883_targa_unsol_event, 10309 .setup = alc882_targa_setup, 10310 .init_hook = alc882_targa_automute, 10311 }, 10312 [ALC883_TARGA_8ch_DIG] = { 10313 .mixers = { alc883_targa_mixer, alc883_targa_8ch_mixer, 10314 alc883_chmode_mixer }, 10315 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs, 10316 alc883_targa_verbs }, 10317 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10318 .dac_nids = alc883_dac_nids, 10319 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev), 10320 .adc_nids = alc883_adc_nids_rev, 10321 .capsrc_nids = alc883_capsrc_nids_rev, 10322 .dig_out_nid = ALC883_DIGOUT_NID, 10323 .dig_in_nid = ALC883_DIGIN_NID, 10324 .num_channel_mode = ARRAY_SIZE(alc883_4ST_8ch_modes), 10325 .channel_mode = alc883_4ST_8ch_modes, 10326 .need_dac_fix = 1, 10327 .input_mux = &alc883_capture_source, 10328 .unsol_event = alc883_targa_unsol_event, 10329 .setup = alc882_targa_setup, 10330 .init_hook = alc882_targa_automute, 10331 }, 10332 [ALC883_ACER] = { 10333 .mixers = { alc883_base_mixer }, 10334 /* On TravelMate laptops, GPIO 0 enables the internal speaker 10335 * and the headphone jack. Turn this on and rely on the 10336 * standard mute methods whenever the user wants to turn 10337 * these outputs off. 10338 */ 10339 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs }, 10340 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10341 .dac_nids = alc883_dac_nids, 10342 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10343 .channel_mode = alc883_3ST_2ch_modes, 10344 .input_mux = &alc883_capture_source, 10345 }, 10346 [ALC883_ACER_ASPIRE] = { 10347 .mixers = { alc883_acer_aspire_mixer }, 10348 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs }, 10349 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10350 .dac_nids = alc883_dac_nids, 10351 .dig_out_nid = ALC883_DIGOUT_NID, 10352 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10353 .channel_mode = alc883_3ST_2ch_modes, 10354 .input_mux = &alc883_capture_source, 10355 .unsol_event = alc_automute_amp_unsol_event, 10356 .setup = alc883_acer_aspire_setup, 10357 .init_hook = alc_automute_amp, 10358 }, 10359 [ALC888_ACER_ASPIRE_4930G] = { 10360 .mixers = { alc888_base_mixer, 10361 alc883_chmode_mixer }, 10362 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs, 10363 alc888_acer_aspire_4930g_verbs }, 10364 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10365 .dac_nids = alc883_dac_nids, 10366 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev), 10367 .adc_nids = alc883_adc_nids_rev, 10368 .capsrc_nids = alc883_capsrc_nids_rev, 10369 .dig_out_nid = ALC883_DIGOUT_NID, 10370 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 10371 .channel_mode = alc883_3ST_6ch_modes, 10372 .need_dac_fix = 1, 10373 .const_channel_count = 6, 10374 .num_mux_defs = 10375 ARRAY_SIZE(alc888_2_capture_sources), 10376 .input_mux = alc888_2_capture_sources, 10377 .unsol_event = alc_automute_amp_unsol_event, 10378 .setup = alc888_acer_aspire_4930g_setup, 10379 .init_hook = alc_automute_amp, 10380 }, 10381 [ALC888_ACER_ASPIRE_6530G] = { 10382 .mixers = { alc888_acer_aspire_6530_mixer }, 10383 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs, 10384 alc888_acer_aspire_6530g_verbs }, 10385 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10386 .dac_nids = alc883_dac_nids, 10387 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev), 10388 .adc_nids = alc883_adc_nids_rev, 10389 .capsrc_nids = alc883_capsrc_nids_rev, 10390 .dig_out_nid = ALC883_DIGOUT_NID, 10391 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10392 .channel_mode = alc883_3ST_2ch_modes, 10393 .num_mux_defs = 10394 ARRAY_SIZE(alc888_2_capture_sources), 10395 .input_mux = alc888_acer_aspire_6530_sources, 10396 .unsol_event = alc_automute_amp_unsol_event, 10397 .setup = alc888_acer_aspire_6530g_setup, 10398 .init_hook = alc_automute_amp, 10399 }, 10400 [ALC888_ACER_ASPIRE_8930G] = { 10401 .mixers = { alc889_acer_aspire_8930g_mixer, 10402 alc883_chmode_mixer }, 10403 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs, 10404 alc889_acer_aspire_8930g_verbs, 10405 alc889_eapd_verbs}, 10406 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10407 .dac_nids = alc883_dac_nids, 10408 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids), 10409 .adc_nids = alc889_adc_nids, 10410 .capsrc_nids = alc889_capsrc_nids, 10411 .dig_out_nid = ALC883_DIGOUT_NID, 10412 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 10413 .channel_mode = alc883_3ST_6ch_modes, 10414 .need_dac_fix = 1, 10415 .const_channel_count = 6, 10416 .num_mux_defs = 10417 ARRAY_SIZE(alc889_capture_sources), 10418 .input_mux = alc889_capture_sources, 10419 .unsol_event = alc_automute_amp_unsol_event, 10420 .setup = alc889_acer_aspire_8930g_setup, 10421 .init_hook = alc_automute_amp, 10422#ifdef CONFIG_SND_HDA_POWER_SAVE 10423 .power_hook = alc_power_eapd, 10424#endif 10425 }, 10426 [ALC888_ACER_ASPIRE_7730G] = { 10427 .mixers = { alc883_3ST_6ch_mixer, 10428 alc883_chmode_mixer }, 10429 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs, 10430 alc888_acer_aspire_7730G_verbs }, 10431 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10432 .dac_nids = alc883_dac_nids, 10433 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev), 10434 .adc_nids = alc883_adc_nids_rev, 10435 .capsrc_nids = alc883_capsrc_nids_rev, 10436 .dig_out_nid = ALC883_DIGOUT_NID, 10437 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 10438 .channel_mode = alc883_3ST_6ch_modes, 10439 .need_dac_fix = 1, 10440 .const_channel_count = 6, 10441 .input_mux = &alc883_capture_source, 10442 .unsol_event = alc_automute_amp_unsol_event, 10443 .setup = alc888_acer_aspire_7730g_setup, 10444 .init_hook = alc_automute_amp, 10445 }, 10446 [ALC883_MEDION] = { 10447 .mixers = { alc883_fivestack_mixer, 10448 alc883_chmode_mixer }, 10449 .init_verbs = { alc883_init_verbs, 10450 alc883_medion_eapd_verbs }, 10451 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10452 .dac_nids = alc883_dac_nids, 10453 .adc_nids = alc883_adc_nids_alt, 10454 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt), 10455 .capsrc_nids = alc883_capsrc_nids, 10456 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), 10457 .channel_mode = alc883_sixstack_modes, 10458 .input_mux = &alc883_capture_source, 10459 }, 10460 [ALC883_MEDION_WIM2160] = { 10461 .mixers = { alc883_medion_wim2160_mixer }, 10462 .init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs }, 10463 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10464 .dac_nids = alc883_dac_nids, 10465 .dig_out_nid = ALC883_DIGOUT_NID, 10466 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 10467 .adc_nids = alc883_adc_nids, 10468 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10469 .channel_mode = alc883_3ST_2ch_modes, 10470 .input_mux = &alc883_capture_source, 10471 .unsol_event = alc_automute_amp_unsol_event, 10472 .setup = alc883_medion_wim2160_setup, 10473 .init_hook = alc_automute_amp, 10474 }, 10475 [ALC883_LAPTOP_EAPD] = { 10476 .mixers = { alc883_base_mixer }, 10477 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs }, 10478 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10479 .dac_nids = alc883_dac_nids, 10480 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10481 .channel_mode = alc883_3ST_2ch_modes, 10482 .input_mux = &alc883_capture_source, 10483 }, 10484 [ALC883_CLEVO_M540R] = { 10485 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, 10486 .init_verbs = { alc883_init_verbs, alc883_clevo_m540r_verbs }, 10487 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10488 .dac_nids = alc883_dac_nids, 10489 .dig_out_nid = ALC883_DIGOUT_NID, 10490 .dig_in_nid = ALC883_DIGIN_NID, 10491 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_clevo_modes), 10492 .channel_mode = alc883_3ST_6ch_clevo_modes, 10493 .need_dac_fix = 1, 10494 .input_mux = &alc883_capture_source, 10495 /* This machine has the hardware HP auto-muting, thus 10496 * we need no software mute via unsol event 10497 */ 10498 }, 10499 [ALC883_CLEVO_M720] = { 10500 .mixers = { alc883_clevo_m720_mixer }, 10501 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs }, 10502 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10503 .dac_nids = alc883_dac_nids, 10504 .dig_out_nid = ALC883_DIGOUT_NID, 10505 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10506 .channel_mode = alc883_3ST_2ch_modes, 10507 .input_mux = &alc883_capture_source, 10508 .unsol_event = alc883_clevo_m720_unsol_event, 10509 .setup = alc883_clevo_m720_setup, 10510 .init_hook = alc883_clevo_m720_init_hook, 10511 }, 10512 [ALC883_LENOVO_101E_2ch] = { 10513 .mixers = { alc883_lenovo_101e_2ch_mixer}, 10514 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs}, 10515 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10516 .dac_nids = alc883_dac_nids, 10517 .adc_nids = alc883_adc_nids_alt, 10518 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt), 10519 .capsrc_nids = alc883_capsrc_nids, 10520 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10521 .channel_mode = alc883_3ST_2ch_modes, 10522 .input_mux = &alc883_lenovo_101e_capture_source, 10523 .unsol_event = alc883_lenovo_101e_unsol_event, 10524 .init_hook = alc883_lenovo_101e_all_automute, 10525 }, 10526 [ALC883_LENOVO_NB0763] = { 10527 .mixers = { alc883_lenovo_nb0763_mixer }, 10528 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs}, 10529 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10530 .dac_nids = alc883_dac_nids, 10531 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10532 .channel_mode = alc883_3ST_2ch_modes, 10533 .need_dac_fix = 1, 10534 .input_mux = &alc883_lenovo_nb0763_capture_source, 10535 .unsol_event = alc_automute_amp_unsol_event, 10536 .setup = alc883_lenovo_nb0763_setup, 10537 .init_hook = alc_automute_amp, 10538 }, 10539 [ALC888_LENOVO_MS7195_DIG] = { 10540 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, 10541 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs}, 10542 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10543 .dac_nids = alc883_dac_nids, 10544 .dig_out_nid = ALC883_DIGOUT_NID, 10545 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 10546 .channel_mode = alc883_3ST_6ch_modes, 10547 .need_dac_fix = 1, 10548 .input_mux = &alc883_capture_source, 10549 .unsol_event = alc883_lenovo_ms7195_unsol_event, 10550 .init_hook = alc888_lenovo_ms7195_front_automute, 10551 }, 10552 [ALC883_HAIER_W66] = { 10553 .mixers = { alc883_targa_2ch_mixer}, 10554 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs}, 10555 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10556 .dac_nids = alc883_dac_nids, 10557 .dig_out_nid = ALC883_DIGOUT_NID, 10558 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10559 .channel_mode = alc883_3ST_2ch_modes, 10560 .input_mux = &alc883_capture_source, 10561 .unsol_event = alc_automute_amp_unsol_event, 10562 .setup = alc883_haier_w66_setup, 10563 .init_hook = alc_automute_amp, 10564 }, 10565 [ALC888_3ST_HP] = { 10566 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, 10567 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs }, 10568 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10569 .dac_nids = alc883_dac_nids, 10570 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes), 10571 .channel_mode = alc888_3st_hp_modes, 10572 .need_dac_fix = 1, 10573 .input_mux = &alc883_capture_source, 10574 .unsol_event = alc_automute_amp_unsol_event, 10575 .setup = alc888_3st_hp_setup, 10576 .init_hook = alc_automute_amp, 10577 }, 10578 [ALC888_6ST_DELL] = { 10579 .mixers = { alc883_base_mixer, alc883_chmode_mixer }, 10580 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs }, 10581 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10582 .dac_nids = alc883_dac_nids, 10583 .dig_out_nid = ALC883_DIGOUT_NID, 10584 .dig_in_nid = ALC883_DIGIN_NID, 10585 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), 10586 .channel_mode = alc883_sixstack_modes, 10587 .input_mux = &alc883_capture_source, 10588 .unsol_event = alc_automute_amp_unsol_event, 10589 .setup = alc888_6st_dell_setup, 10590 .init_hook = alc_automute_amp, 10591 }, 10592 [ALC883_MITAC] = { 10593 .mixers = { alc883_mitac_mixer }, 10594 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs }, 10595 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10596 .dac_nids = alc883_dac_nids, 10597 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10598 .channel_mode = alc883_3ST_2ch_modes, 10599 .input_mux = &alc883_capture_source, 10600 .unsol_event = alc_automute_amp_unsol_event, 10601 .setup = alc883_mitac_setup, 10602 .init_hook = alc_automute_amp, 10603 }, 10604 [ALC883_FUJITSU_PI2515] = { 10605 .mixers = { alc883_2ch_fujitsu_pi2515_mixer }, 10606 .init_verbs = { alc883_init_verbs, 10607 alc883_2ch_fujitsu_pi2515_verbs}, 10608 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10609 .dac_nids = alc883_dac_nids, 10610 .dig_out_nid = ALC883_DIGOUT_NID, 10611 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10612 .channel_mode = alc883_3ST_2ch_modes, 10613 .input_mux = &alc883_fujitsu_pi2515_capture_source, 10614 .unsol_event = alc_automute_amp_unsol_event, 10615 .setup = alc883_2ch_fujitsu_pi2515_setup, 10616 .init_hook = alc_automute_amp, 10617 }, 10618 [ALC888_FUJITSU_XA3530] = { 10619 .mixers = { alc888_base_mixer, alc883_chmode_mixer }, 10620 .init_verbs = { alc883_init_verbs, 10621 alc888_fujitsu_xa3530_verbs }, 10622 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10623 .dac_nids = alc883_dac_nids, 10624 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev), 10625 .adc_nids = alc883_adc_nids_rev, 10626 .capsrc_nids = alc883_capsrc_nids_rev, 10627 .dig_out_nid = ALC883_DIGOUT_NID, 10628 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes), 10629 .channel_mode = alc888_4ST_8ch_intel_modes, 10630 .num_mux_defs = 10631 ARRAY_SIZE(alc888_2_capture_sources), 10632 .input_mux = alc888_2_capture_sources, 10633 .unsol_event = alc_automute_amp_unsol_event, 10634 .setup = alc888_fujitsu_xa3530_setup, 10635 .init_hook = alc_automute_amp, 10636 }, 10637 [ALC888_LENOVO_SKY] = { 10638 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer }, 10639 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs}, 10640 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10641 .dac_nids = alc883_dac_nids, 10642 .dig_out_nid = ALC883_DIGOUT_NID, 10643 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), 10644 .channel_mode = alc883_sixstack_modes, 10645 .need_dac_fix = 1, 10646 .input_mux = &alc883_lenovo_sky_capture_source, 10647 .unsol_event = alc_automute_amp_unsol_event, 10648 .setup = alc888_lenovo_sky_setup, 10649 .init_hook = alc_automute_amp, 10650 }, 10651 [ALC888_ASUS_M90V] = { 10652 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, 10653 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs }, 10654 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10655 .dac_nids = alc883_dac_nids, 10656 .dig_out_nid = ALC883_DIGOUT_NID, 10657 .dig_in_nid = ALC883_DIGIN_NID, 10658 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 10659 .channel_mode = alc883_3ST_6ch_modes, 10660 .need_dac_fix = 1, 10661 .input_mux = &alc883_fujitsu_pi2515_capture_source, 10662 .unsol_event = alc_sku_unsol_event, 10663 .setup = alc883_mode2_setup, 10664 .init_hook = alc_inithook, 10665 }, 10666 [ALC888_ASUS_EEE1601] = { 10667 .mixers = { alc883_asus_eee1601_mixer }, 10668 .cap_mixer = alc883_asus_eee1601_cap_mixer, 10669 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs }, 10670 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10671 .dac_nids = alc883_dac_nids, 10672 .dig_out_nid = ALC883_DIGOUT_NID, 10673 .dig_in_nid = ALC883_DIGIN_NID, 10674 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10675 .channel_mode = alc883_3ST_2ch_modes, 10676 .need_dac_fix = 1, 10677 .input_mux = &alc883_asus_eee1601_capture_source, 10678 .unsol_event = alc_sku_unsol_event, 10679 .init_hook = alc883_eee1601_inithook, 10680 }, 10681 [ALC1200_ASUS_P5Q] = { 10682 .mixers = { alc883_base_mixer, alc883_chmode_mixer }, 10683 .init_verbs = { alc883_init_verbs }, 10684 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10685 .dac_nids = alc883_dac_nids, 10686 .dig_out_nid = ALC1200_DIGOUT_NID, 10687 .dig_in_nid = ALC883_DIGIN_NID, 10688 .slave_dig_outs = alc1200_slave_dig_outs, 10689 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), 10690 .channel_mode = alc883_sixstack_modes, 10691 .input_mux = &alc883_capture_source, 10692 }, 10693 [ALC889A_MB31] = { 10694 .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer}, 10695 .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs, 10696 alc880_gpio1_init_verbs }, 10697 .adc_nids = alc883_adc_nids, 10698 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 10699 .capsrc_nids = alc883_capsrc_nids, 10700 .dac_nids = alc883_dac_nids, 10701 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10702 .channel_mode = alc889A_mb31_6ch_modes, 10703 .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes), 10704 .input_mux = &alc889A_mb31_capture_source, 10705 .dig_out_nid = ALC883_DIGOUT_NID, 10706 .unsol_event = alc889A_mb31_unsol_event, 10707 .init_hook = alc889A_mb31_automute, 10708 }, 10709 [ALC883_SONY_VAIO_TT] = { 10710 .mixers = { alc883_vaiott_mixer }, 10711 .init_verbs = { alc883_init_verbs, alc883_vaiott_verbs }, 10712 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10713 .dac_nids = alc883_dac_nids, 10714 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10715 .channel_mode = alc883_3ST_2ch_modes, 10716 .input_mux = &alc883_capture_source, 10717 .unsol_event = alc_automute_amp_unsol_event, 10718 .setup = alc883_vaiott_setup, 10719 .init_hook = alc_automute_amp, 10720 }, 10721}; 10722 10723 10724/* 10725 * Pin config fixes 10726 */ 10727enum { 10728 PINFIX_ABIT_AW9D_MAX, 10729 PINFIX_PB_M5210, 10730 PINFIX_ACER_ASPIRE_7736, 10731}; 10732 10733static const struct alc_fixup alc882_fixups[] = { 10734 [PINFIX_ABIT_AW9D_MAX] = { 10735 .type = ALC_FIXUP_PINS, 10736 .v.pins = (const struct alc_pincfg[]) { 10737 { 0x15, 0x01080104 }, /* side */ 10738 { 0x16, 0x01011012 }, /* rear */ 10739 { 0x17, 0x01016011 }, /* clfe */ 10740 { } 10741 } 10742 }, 10743 [PINFIX_PB_M5210] = { 10744 .type = ALC_FIXUP_VERBS, 10745 .v.verbs = (const struct hda_verb[]) { 10746 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 }, 10747 {} 10748 } 10749 }, 10750 [PINFIX_ACER_ASPIRE_7736] = { 10751 .type = ALC_FIXUP_SKU, 10752 .v.sku = ALC_FIXUP_SKU_IGNORE, 10753 }, 10754}; 10755 10756static struct snd_pci_quirk alc882_fixup_tbl[] = { 10757 SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", PINFIX_PB_M5210), 10758 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX), 10759 SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", PINFIX_ACER_ASPIRE_7736), 10760 {} 10761}; 10762 10763/* 10764 * BIOS auto configuration 10765 */ 10766static int alc882_auto_create_input_ctls(struct hda_codec *codec, 10767 const struct auto_pin_cfg *cfg) 10768{ 10769 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x23, 0x22); 10770} 10771 10772static void alc882_auto_set_output_and_unmute(struct hda_codec *codec, 10773 hda_nid_t nid, int pin_type, 10774 hda_nid_t dac) 10775{ 10776 int idx; 10777 10778 /* set as output */ 10779 alc_set_pin_output(codec, nid, pin_type); 10780 10781 if (dac == 0x25) 10782 idx = 4; 10783 else if (dac >= 0x02 && dac <= 0x05) 10784 idx = dac - 2; 10785 else 10786 return; 10787 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx); 10788} 10789 10790static void alc882_auto_init_multi_out(struct hda_codec *codec) 10791{ 10792 struct alc_spec *spec = codec->spec; 10793 int i; 10794 10795 for (i = 0; i <= HDA_SIDE; i++) { 10796 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 10797 int pin_type = get_pin_type(spec->autocfg.line_out_type); 10798 if (nid) 10799 alc882_auto_set_output_and_unmute(codec, nid, pin_type, 10800 spec->multiout.dac_nids[i]); 10801 } 10802} 10803 10804static void alc882_auto_init_hp_out(struct hda_codec *codec) 10805{ 10806 struct alc_spec *spec = codec->spec; 10807 hda_nid_t pin, dac; 10808 int i; 10809 10810 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) { 10811 pin = spec->autocfg.hp_pins[i]; 10812 if (!pin) 10813 break; 10814 dac = spec->multiout.hp_nid; 10815 if (!dac) 10816 dac = spec->multiout.dac_nids[0]; /* to front */ 10817 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, dac); 10818 } 10819 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) { 10820 pin = spec->autocfg.speaker_pins[i]; 10821 if (!pin) 10822 break; 10823 dac = spec->multiout.extra_out_nid[0]; 10824 if (!dac) 10825 dac = spec->multiout.dac_nids[0]; /* to front */ 10826 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac); 10827 } 10828} 10829 10830static void alc882_auto_init_analog_input(struct hda_codec *codec) 10831{ 10832 struct alc_spec *spec = codec->spec; 10833 struct auto_pin_cfg *cfg = &spec->autocfg; 10834 int i; 10835 10836 for (i = 0; i < cfg->num_inputs; i++) { 10837 hda_nid_t nid = cfg->inputs[i].pin; 10838 alc_set_input_pin(codec, nid, cfg->inputs[i].type); 10839 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP) 10840 snd_hda_codec_write(codec, nid, 0, 10841 AC_VERB_SET_AMP_GAIN_MUTE, 10842 AMP_OUT_MUTE); 10843 } 10844} 10845 10846static void alc882_auto_init_input_src(struct hda_codec *codec) 10847{ 10848 struct alc_spec *spec = codec->spec; 10849 int c; 10850 10851 for (c = 0; c < spec->num_adc_nids; c++) { 10852 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS]; 10853 hda_nid_t nid = spec->capsrc_nids[c]; 10854 unsigned int mux_idx; 10855 const struct hda_input_mux *imux; 10856 int conns, mute, idx, item; 10857 10858 conns = snd_hda_get_connections(codec, nid, conn_list, 10859 ARRAY_SIZE(conn_list)); 10860 if (conns < 0) 10861 continue; 10862 mux_idx = c >= spec->num_mux_defs ? 0 : c; 10863 imux = &spec->input_mux[mux_idx]; 10864 if (!imux->num_items && mux_idx > 0) 10865 imux = &spec->input_mux[0]; 10866 for (idx = 0; idx < conns; idx++) { 10867 /* if the current connection is the selected one, 10868 * unmute it as default - otherwise mute it 10869 */ 10870 mute = AMP_IN_MUTE(idx); 10871 for (item = 0; item < imux->num_items; item++) { 10872 if (imux->items[item].index == idx) { 10873 if (spec->cur_mux[c] == item) 10874 mute = AMP_IN_UNMUTE(idx); 10875 break; 10876 } 10877 } 10878 /* check if we have a selector or mixer 10879 * we could check for the widget type instead, but 10880 * just check for Amp-In presence (in case of mixer 10881 * without amp-in there is something wrong, this 10882 * function shouldn't be used or capsrc nid is wrong) 10883 */ 10884 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) 10885 snd_hda_codec_write(codec, nid, 0, 10886 AC_VERB_SET_AMP_GAIN_MUTE, 10887 mute); 10888 else if (mute != AMP_IN_MUTE(idx)) 10889 snd_hda_codec_write(codec, nid, 0, 10890 AC_VERB_SET_CONNECT_SEL, 10891 idx); 10892 } 10893 } 10894} 10895 10896/* add mic boosts if needed */ 10897static int alc_auto_add_mic_boost(struct hda_codec *codec) 10898{ 10899 struct alc_spec *spec = codec->spec; 10900 struct auto_pin_cfg *cfg = &spec->autocfg; 10901 int i, err; 10902 int type_idx = 0; 10903 hda_nid_t nid; 10904 const char *prev_label = NULL; 10905 10906 for (i = 0; i < cfg->num_inputs; i++) { 10907 if (cfg->inputs[i].type > AUTO_PIN_MIC) 10908 break; 10909 nid = cfg->inputs[i].pin; 10910 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) { 10911 const char *label; 10912 char boost_label[32]; 10913 10914 label = hda_get_autocfg_input_label(codec, cfg, i); 10915 if (prev_label && !strcmp(label, prev_label)) 10916 type_idx++; 10917 else 10918 type_idx = 0; 10919 prev_label = label; 10920 10921 snprintf(boost_label, sizeof(boost_label), 10922 "%s Boost Volume", label); 10923 err = add_control(spec, ALC_CTL_WIDGET_VOL, 10924 boost_label, type_idx, 10925 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT)); 10926 if (err < 0) 10927 return err; 10928 } 10929 } 10930 return 0; 10931} 10932 10933/* almost identical with ALC880 parser... */ 10934static int alc882_parse_auto_config(struct hda_codec *codec) 10935{ 10936 struct alc_spec *spec = codec->spec; 10937 static hda_nid_t alc882_ignore[] = { 0x1d, 0 }; 10938 int err; 10939 10940 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 10941 alc882_ignore); 10942 if (err < 0) 10943 return err; 10944 if (!spec->autocfg.line_outs) 10945 return 0; /* can't find valid BIOS pin config */ 10946 10947 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); 10948 if (err < 0) 10949 return err; 10950 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg); 10951 if (err < 0) 10952 return err; 10953 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0], 10954 "Headphone"); 10955 if (err < 0) 10956 return err; 10957 err = alc880_auto_create_extra_out(spec, 10958 spec->autocfg.speaker_pins[0], 10959 "Speaker"); 10960 if (err < 0) 10961 return err; 10962 err = alc882_auto_create_input_ctls(codec, &spec->autocfg); 10963 if (err < 0) 10964 return err; 10965 10966 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 10967 10968 alc_auto_parse_digital(codec); 10969 10970 if (spec->kctls.list) 10971 add_mixer(spec, spec->kctls.list); 10972 10973 add_verb(spec, alc883_auto_init_verbs); 10974 /* if ADC 0x07 is available, initialize it, too */ 10975 if (get_wcaps_type(get_wcaps(codec, 0x07)) == AC_WID_AUD_IN) 10976 add_verb(spec, alc882_adc1_init_verbs); 10977 10978 spec->num_mux_defs = 1; 10979 spec->input_mux = &spec->private_imux[0]; 10980 10981 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); 10982 10983 err = alc_auto_add_mic_boost(codec); 10984 if (err < 0) 10985 return err; 10986 10987 return 1; /* config found */ 10988} 10989 10990/* additional initialization for auto-configuration model */ 10991static void alc882_auto_init(struct hda_codec *codec) 10992{ 10993 struct alc_spec *spec = codec->spec; 10994 alc882_auto_init_multi_out(codec); 10995 alc882_auto_init_hp_out(codec); 10996 alc882_auto_init_analog_input(codec); 10997 alc882_auto_init_input_src(codec); 10998 alc_auto_init_digital(codec); 10999 if (spec->unsol_event) 11000 alc_inithook(codec); 11001} 11002 11003static int patch_alc882(struct hda_codec *codec) 11004{ 11005 struct alc_spec *spec; 11006 int err, board_config; 11007 11008 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 11009 if (spec == NULL) 11010 return -ENOMEM; 11011 11012 codec->spec = spec; 11013 11014 switch (codec->vendor_id) { 11015 case 0x10ec0882: 11016 case 0x10ec0885: 11017 break; 11018 default: 11019 /* ALC883 and variants */ 11020 alc_fix_pll_init(codec, 0x20, 0x0a, 10); 11021 break; 11022 } 11023 11024 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST, 11025 alc882_models, 11026 alc882_cfg_tbl); 11027 11028 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) 11029 board_config = snd_hda_check_board_codec_sid_config(codec, 11030 ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl); 11031 11032 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) { 11033 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 11034 codec->chip_name); 11035 board_config = ALC882_AUTO; 11036 } 11037 11038 if (board_config == ALC882_AUTO) { 11039 alc_pick_fixup(codec, NULL, alc882_fixup_tbl, alc882_fixups); 11040 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); 11041 } 11042 11043 alc_auto_parse_customize_define(codec); 11044 11045 if (board_config == ALC882_AUTO) { 11046 /* automatic parse from the BIOS config */ 11047 err = alc882_parse_auto_config(codec); 11048 if (err < 0) { 11049 alc_free(codec); 11050 return err; 11051 } else if (!err) { 11052 printk(KERN_INFO 11053 "hda_codec: Cannot set up configuration " 11054 "from BIOS. Using base mode...\n"); 11055 board_config = ALC882_3ST_DIG; 11056 } 11057 } 11058 11059 if (has_cdefine_beep(codec)) { 11060 err = snd_hda_attach_beep_device(codec, 0x1); 11061 if (err < 0) { 11062 alc_free(codec); 11063 return err; 11064 } 11065 } 11066 11067 if (board_config != ALC882_AUTO) 11068 setup_preset(codec, &alc882_presets[board_config]); 11069 11070 spec->stream_analog_playback = &alc882_pcm_analog_playback; 11071 spec->stream_analog_capture = &alc882_pcm_analog_capture; 11072 /* FIXME: setup DAC5 */ 11073 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/ 11074 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture; 11075 11076 spec->stream_digital_playback = &alc882_pcm_digital_playback; 11077 spec->stream_digital_capture = &alc882_pcm_digital_capture; 11078 11079 if (!spec->adc_nids && spec->input_mux) { 11080 int i, j; 11081 spec->num_adc_nids = 0; 11082 for (i = 0; i < ARRAY_SIZE(alc882_adc_nids); i++) { 11083 const struct hda_input_mux *imux = spec->input_mux; 11084 hda_nid_t cap; 11085 hda_nid_t items[16]; 11086 hda_nid_t nid = alc882_adc_nids[i]; 11087 unsigned int wcap = get_wcaps(codec, nid); 11088 /* get type */ 11089 wcap = get_wcaps_type(wcap); 11090 if (wcap != AC_WID_AUD_IN) 11091 continue; 11092 spec->private_adc_nids[spec->num_adc_nids] = nid; 11093 err = snd_hda_get_connections(codec, nid, &cap, 1); 11094 if (err < 0) 11095 continue; 11096 err = snd_hda_get_connections(codec, cap, items, 11097 ARRAY_SIZE(items)); 11098 if (err < 0) 11099 continue; 11100 for (j = 0; j < imux->num_items; j++) 11101 if (imux->items[j].index >= err) 11102 break; 11103 if (j < imux->num_items) 11104 continue; 11105 spec->private_capsrc_nids[spec->num_adc_nids] = cap; 11106 spec->num_adc_nids++; 11107 } 11108 spec->adc_nids = spec->private_adc_nids; 11109 spec->capsrc_nids = spec->private_capsrc_nids; 11110 } 11111 11112 set_capture_mixer(codec); 11113 11114 if (has_cdefine_beep(codec)) 11115 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 11116 11117 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); 11118 11119 spec->vmaster_nid = 0x0c; 11120 11121 codec->patch_ops = alc_patch_ops; 11122 if (board_config == ALC882_AUTO) 11123 spec->init_hook = alc882_auto_init; 11124 11125 alc_init_jacks(codec); 11126#ifdef CONFIG_SND_HDA_POWER_SAVE 11127 if (!spec->loopback.amplist) 11128 spec->loopback.amplist = alc882_loopbacks; 11129#endif 11130 11131 return 0; 11132} 11133 11134 11135/* 11136 * ALC262 support 11137 */ 11138 11139#define ALC262_DIGOUT_NID ALC880_DIGOUT_NID 11140#define ALC262_DIGIN_NID ALC880_DIGIN_NID 11141 11142#define alc262_dac_nids alc260_dac_nids 11143#define alc262_adc_nids alc882_adc_nids 11144#define alc262_adc_nids_alt alc882_adc_nids_alt 11145#define alc262_capsrc_nids alc882_capsrc_nids 11146#define alc262_capsrc_nids_alt alc882_capsrc_nids_alt 11147 11148#define alc262_modes alc260_modes 11149#define alc262_capture_source alc882_capture_source 11150 11151static hda_nid_t alc262_dmic_adc_nids[1] = { 11152 /* ADC0 */ 11153 0x09 11154}; 11155 11156static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 }; 11157 11158static struct snd_kcontrol_new alc262_base_mixer[] = { 11159 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11160 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 11161 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 11162 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 11163 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 11164 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 11165 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11166 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11167 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 11168 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 11169 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 11170 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), 11171 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT), 11172 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 11173 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 11174 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT), 11175 { } /* end */ 11176}; 11177 11178/* update HP, line and mono-out pins according to the master switch */ 11179static void alc262_hp_master_update(struct hda_codec *codec) 11180{ 11181 struct alc_spec *spec = codec->spec; 11182 int val = spec->master_sw; 11183 11184 /* HP & line-out */ 11185 snd_hda_codec_write_cache(codec, 0x1b, 0, 11186 AC_VERB_SET_PIN_WIDGET_CONTROL, 11187 val ? PIN_HP : 0); 11188 snd_hda_codec_write_cache(codec, 0x15, 0, 11189 AC_VERB_SET_PIN_WIDGET_CONTROL, 11190 val ? PIN_HP : 0); 11191 /* mono (speaker) depending on the HP jack sense */ 11192 val = val && !spec->jack_present; 11193 snd_hda_codec_write_cache(codec, 0x16, 0, 11194 AC_VERB_SET_PIN_WIDGET_CONTROL, 11195 val ? PIN_OUT : 0); 11196} 11197 11198static void alc262_hp_bpc_automute(struct hda_codec *codec) 11199{ 11200 struct alc_spec *spec = codec->spec; 11201 11202 spec->jack_present = snd_hda_jack_detect(codec, 0x1b); 11203 alc262_hp_master_update(codec); 11204} 11205 11206static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res) 11207{ 11208 if ((res >> 26) != ALC880_HP_EVENT) 11209 return; 11210 alc262_hp_bpc_automute(codec); 11211} 11212 11213static void alc262_hp_wildwest_automute(struct hda_codec *codec) 11214{ 11215 struct alc_spec *spec = codec->spec; 11216 11217 spec->jack_present = snd_hda_jack_detect(codec, 0x15); 11218 alc262_hp_master_update(codec); 11219} 11220 11221static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec, 11222 unsigned int res) 11223{ 11224 if ((res >> 26) != ALC880_HP_EVENT) 11225 return; 11226 alc262_hp_wildwest_automute(codec); 11227} 11228 11229#define alc262_hp_master_sw_get alc260_hp_master_sw_get 11230 11231static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol, 11232 struct snd_ctl_elem_value *ucontrol) 11233{ 11234 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 11235 struct alc_spec *spec = codec->spec; 11236 int val = !!*ucontrol->value.integer.value; 11237 11238 if (val == spec->master_sw) 11239 return 0; 11240 spec->master_sw = val; 11241 alc262_hp_master_update(codec); 11242 return 1; 11243} 11244 11245#define ALC262_HP_MASTER_SWITCH \ 11246 { \ 11247 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 11248 .name = "Master Playback Switch", \ 11249 .info = snd_ctl_boolean_mono_info, \ 11250 .get = alc262_hp_master_sw_get, \ 11251 .put = alc262_hp_master_sw_put, \ 11252 }, \ 11253 { \ 11254 .iface = NID_MAPPING, \ 11255 .name = "Master Playback Switch", \ 11256 .private_value = 0x15 | (0x16 << 8) | (0x1b << 16), \ 11257 } 11258 11259 11260static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = { 11261 ALC262_HP_MASTER_SWITCH, 11262 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11263 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT), 11264 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 11265 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0, 11266 HDA_OUTPUT), 11267 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0, 11268 HDA_OUTPUT), 11269 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11270 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11271 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 11272 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 11273 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 11274 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), 11275 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 11276 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 11277 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 11278 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 11279 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT), 11280 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT), 11281 { } /* end */ 11282}; 11283 11284static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = { 11285 ALC262_HP_MASTER_SWITCH, 11286 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11287 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 11288 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 11289 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 11290 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0, 11291 HDA_OUTPUT), 11292 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0, 11293 HDA_OUTPUT), 11294 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT), 11295 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT), 11296 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x1a, 0, HDA_INPUT), 11297 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT), 11298 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT), 11299 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 11300 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 11301 { } /* end */ 11302}; 11303 11304static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = { 11305 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11306 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11307 HDA_CODEC_VOLUME("Rear Mic Boost Volume", 0x18, 0, HDA_INPUT), 11308 { } /* end */ 11309}; 11310 11311/* mute/unmute internal speaker according to the hp jack and mute state */ 11312static void alc262_hp_t5735_setup(struct hda_codec *codec) 11313{ 11314 struct alc_spec *spec = codec->spec; 11315 11316 spec->autocfg.hp_pins[0] = 0x15; 11317 spec->autocfg.speaker_pins[0] = 0x14; 11318} 11319 11320static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = { 11321 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11322 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 11323 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 11324 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 11325 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11326 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11327 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 11328 { } /* end */ 11329}; 11330 11331static struct hda_verb alc262_hp_t5735_verbs[] = { 11332 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 11333 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11334 11335 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 11336 { } 11337}; 11338 11339static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = { 11340 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11341 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 11342 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT), 11343 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT), 11344 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT), 11345 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT), 11346 { } /* end */ 11347}; 11348 11349static struct hda_verb alc262_hp_rp5700_verbs[] = { 11350 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 11351 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 11352 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 11353 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 11354 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 11355 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 11356 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 11357 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 11358 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))}, 11359 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))}, 11360 {} 11361}; 11362 11363static struct hda_input_mux alc262_hp_rp5700_capture_source = { 11364 .num_items = 1, 11365 .items = { 11366 { "Line", 0x1 }, 11367 }, 11368}; 11369 11370/* bind hp and internal speaker mute (with plug check) as master switch */ 11371static void alc262_hippo_master_update(struct hda_codec *codec) 11372{ 11373 struct alc_spec *spec = codec->spec; 11374 hda_nid_t hp_nid = spec->autocfg.hp_pins[0]; 11375 hda_nid_t line_nid = spec->autocfg.line_out_pins[0]; 11376 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0]; 11377 unsigned int mute; 11378 11379 /* HP */ 11380 mute = spec->master_sw ? 0 : HDA_AMP_MUTE; 11381 snd_hda_codec_amp_stereo(codec, hp_nid, HDA_OUTPUT, 0, 11382 HDA_AMP_MUTE, mute); 11383 /* mute internal speaker per jack sense */ 11384 if (spec->jack_present) 11385 mute = HDA_AMP_MUTE; 11386 if (line_nid) 11387 snd_hda_codec_amp_stereo(codec, line_nid, HDA_OUTPUT, 0, 11388 HDA_AMP_MUTE, mute); 11389 if (speaker_nid && speaker_nid != line_nid) 11390 snd_hda_codec_amp_stereo(codec, speaker_nid, HDA_OUTPUT, 0, 11391 HDA_AMP_MUTE, mute); 11392} 11393 11394#define alc262_hippo_master_sw_get alc262_hp_master_sw_get 11395 11396static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol, 11397 struct snd_ctl_elem_value *ucontrol) 11398{ 11399 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 11400 struct alc_spec *spec = codec->spec; 11401 int val = !!*ucontrol->value.integer.value; 11402 11403 if (val == spec->master_sw) 11404 return 0; 11405 spec->master_sw = val; 11406 alc262_hippo_master_update(codec); 11407 return 1; 11408} 11409 11410#define ALC262_HIPPO_MASTER_SWITCH \ 11411 { \ 11412 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 11413 .name = "Master Playback Switch", \ 11414 .info = snd_ctl_boolean_mono_info, \ 11415 .get = alc262_hippo_master_sw_get, \ 11416 .put = alc262_hippo_master_sw_put, \ 11417 }, \ 11418 { \ 11419 .iface = NID_MAPPING, \ 11420 .name = "Master Playback Switch", \ 11421 .subdevice = SUBDEV_HP(0) | (SUBDEV_LINE(0) << 8) | \ 11422 (SUBDEV_SPEAKER(0) << 16), \ 11423 } 11424 11425static struct snd_kcontrol_new alc262_hippo_mixer[] = { 11426 ALC262_HIPPO_MASTER_SWITCH, 11427 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11428 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 11429 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 11430 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 11431 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 11432 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11433 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11434 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 11435 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 11436 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 11437 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), 11438 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 11439 { } /* end */ 11440}; 11441 11442static struct snd_kcontrol_new alc262_hippo1_mixer[] = { 11443 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11444 ALC262_HIPPO_MASTER_SWITCH, 11445 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 11446 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 11447 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 11448 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 11449 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11450 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11451 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 11452 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 11453 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 11454 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), 11455 { } /* end */ 11456}; 11457 11458/* mute/unmute internal speaker according to the hp jack and mute state */ 11459static void alc262_hippo_automute(struct hda_codec *codec) 11460{ 11461 struct alc_spec *spec = codec->spec; 11462 hda_nid_t hp_nid = spec->autocfg.hp_pins[0]; 11463 11464 spec->jack_present = snd_hda_jack_detect(codec, hp_nid); 11465 alc262_hippo_master_update(codec); 11466} 11467 11468static void alc262_hippo_unsol_event(struct hda_codec *codec, unsigned int res) 11469{ 11470 if ((res >> 26) != ALC880_HP_EVENT) 11471 return; 11472 alc262_hippo_automute(codec); 11473} 11474 11475static void alc262_hippo_setup(struct hda_codec *codec) 11476{ 11477 struct alc_spec *spec = codec->spec; 11478 11479 spec->autocfg.hp_pins[0] = 0x15; 11480 spec->autocfg.speaker_pins[0] = 0x14; 11481} 11482 11483static void alc262_hippo1_setup(struct hda_codec *codec) 11484{ 11485 struct alc_spec *spec = codec->spec; 11486 11487 spec->autocfg.hp_pins[0] = 0x1b; 11488 spec->autocfg.speaker_pins[0] = 0x14; 11489} 11490 11491 11492static struct snd_kcontrol_new alc262_sony_mixer[] = { 11493 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11494 ALC262_HIPPO_MASTER_SWITCH, 11495 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11496 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11497 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 11498 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 11499 { } /* end */ 11500}; 11501 11502static struct snd_kcontrol_new alc262_benq_t31_mixer[] = { 11503 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11504 ALC262_HIPPO_MASTER_SWITCH, 11505 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 11506 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11507 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11508 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 11509 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 11510 { } /* end */ 11511}; 11512 11513static struct snd_kcontrol_new alc262_tyan_mixer[] = { 11514 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11515 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT), 11516 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT), 11517 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT), 11518 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 11519 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 11520 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11521 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11522 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 11523 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 11524 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 11525 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), 11526 { } /* end */ 11527}; 11528 11529static struct hda_verb alc262_tyan_verbs[] = { 11530 /* Headphone automute */ 11531 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 11532 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11533 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 11534 11535 /* P11 AUX_IN, white 4-pin connector */ 11536 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 11537 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1}, 11538 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93}, 11539 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19}, 11540 11541 {} 11542}; 11543 11544/* unsolicited event for HP jack sensing */ 11545static void alc262_tyan_setup(struct hda_codec *codec) 11546{ 11547 struct alc_spec *spec = codec->spec; 11548 11549 spec->autocfg.hp_pins[0] = 0x1b; 11550 spec->autocfg.speaker_pins[0] = 0x15; 11551} 11552 11553 11554#define alc262_capture_mixer alc882_capture_mixer 11555#define alc262_capture_alt_mixer alc882_capture_alt_mixer 11556 11557/* 11558 * generic initialization of ADC, input mixers and output mixers 11559 */ 11560static struct hda_verb alc262_init_verbs[] = { 11561 /* 11562 * Unmute ADC0-2 and set the default input to mic-in 11563 */ 11564 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 11565 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11566 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 11567 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11568 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 11569 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11570 11571 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 11572 * mixer widget 11573 * Note: PASD motherboards uses the Line In 2 as the input for 11574 * front panel mic (mic 2) 11575 */ 11576 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 11577 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 11578 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 11579 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 11580 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 11581 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 11582 11583 /* 11584 * Set up output mixers (0x0c - 0x0e) 11585 */ 11586 /* set vol=0 to output mixers */ 11587 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 11588 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 11589 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 11590 /* set up input amps for analog loopback */ 11591 /* Amp Indices: DAC = 0, mixer = 1 */ 11592 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11593 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11594 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11595 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11596 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11597 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11598 11599 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 11600 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 11601 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 11602 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 11603 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 11604 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 11605 11606 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 11607 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 11608 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 11609 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 11610 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 11611 11612 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 11613 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 11614 11615 /* FIXME: use matrix-type input source selection */ 11616 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 11617 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 11618 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 11619 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 11620 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 11621 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 11622 /* Input mixer2 */ 11623 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 11624 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 11625 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 11626 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 11627 /* Input mixer3 */ 11628 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 11629 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 11630 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 11631 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 11632 11633 { } 11634}; 11635 11636static struct hda_verb alc262_eapd_verbs[] = { 11637 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 11638 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, 11639 { } 11640}; 11641 11642static struct hda_verb alc262_hippo1_unsol_verbs[] = { 11643 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 11644 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 11645 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 11646 11647 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 11648 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11649 {} 11650}; 11651 11652static struct hda_verb alc262_sony_unsol_verbs[] = { 11653 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 11654 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 11655 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic 11656 11657 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 11658 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11659 {} 11660}; 11661 11662static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = { 11663 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11664 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 11665 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 11666 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11667 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11668 { } /* end */ 11669}; 11670 11671static struct hda_verb alc262_toshiba_s06_verbs[] = { 11672 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 11673 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 11674 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11675 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 11676 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09}, 11677 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 11678 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 11679 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 11680 {} 11681}; 11682 11683static void alc262_toshiba_s06_setup(struct hda_codec *codec) 11684{ 11685 struct alc_spec *spec = codec->spec; 11686 11687 spec->autocfg.hp_pins[0] = 0x15; 11688 spec->autocfg.speaker_pins[0] = 0x14; 11689 spec->ext_mic.pin = 0x18; 11690 spec->ext_mic.mux_idx = 0; 11691 spec->int_mic.pin = 0x12; 11692 spec->int_mic.mux_idx = 9; 11693 spec->auto_mic = 1; 11694} 11695 11696/* 11697 * nec model 11698 * 0x15 = headphone 11699 * 0x16 = internal speaker 11700 * 0x18 = external mic 11701 */ 11702 11703static struct snd_kcontrol_new alc262_nec_mixer[] = { 11704 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 11705 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT), 11706 11707 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11708 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11709 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 11710 11711 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 11712 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 11713 { } /* end */ 11714}; 11715 11716static struct hda_verb alc262_nec_verbs[] = { 11717 /* Unmute Speaker */ 11718 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 11719 11720 /* Headphone */ 11721 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 11722 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 11723 11724 /* External mic to headphone */ 11725 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11726 /* External mic to speaker */ 11727 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11728 {} 11729}; 11730 11731/* 11732 * fujitsu model 11733 * 0x14 = headphone/spdif-out, 0x15 = internal speaker, 11734 * 0x1b = port replicator headphone out 11735 */ 11736 11737#define ALC_HP_EVENT 0x37 11738 11739static struct hda_verb alc262_fujitsu_unsol_verbs[] = { 11740 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, 11741 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11742 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, 11743 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11744 {} 11745}; 11746 11747static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = { 11748 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, 11749 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11750 {} 11751}; 11752 11753static struct hda_verb alc262_lenovo_3000_init_verbs[] = { 11754 /* Front Mic pin: input vref at 50% */ 11755 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, 11756 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 11757 {} 11758}; 11759 11760static struct hda_input_mux alc262_fujitsu_capture_source = { 11761 .num_items = 3, 11762 .items = { 11763 { "Mic", 0x0 }, 11764 { "Internal Mic", 0x1 }, 11765 { "CD", 0x4 }, 11766 }, 11767}; 11768 11769static struct hda_input_mux alc262_HP_capture_source = { 11770 .num_items = 5, 11771 .items = { 11772 { "Mic", 0x0 }, 11773 { "Front Mic", 0x1 }, 11774 { "Line", 0x2 }, 11775 { "CD", 0x4 }, 11776 { "AUX IN", 0x6 }, 11777 }, 11778}; 11779 11780static struct hda_input_mux alc262_HP_D7000_capture_source = { 11781 .num_items = 4, 11782 .items = { 11783 { "Mic", 0x0 }, 11784 { "Front Mic", 0x2 }, 11785 { "Line", 0x1 }, 11786 { "CD", 0x4 }, 11787 }, 11788}; 11789 11790/* mute/unmute internal speaker according to the hp jacks and mute state */ 11791static void alc262_fujitsu_automute(struct hda_codec *codec, int force) 11792{ 11793 struct alc_spec *spec = codec->spec; 11794 unsigned int mute; 11795 11796 if (force || !spec->sense_updated) { 11797 spec->jack_present = snd_hda_jack_detect(codec, 0x14) || 11798 snd_hda_jack_detect(codec, 0x1b); 11799 spec->sense_updated = 1; 11800 } 11801 /* unmute internal speaker only if both HPs are unplugged and 11802 * master switch is on 11803 */ 11804 if (spec->jack_present) 11805 mute = HDA_AMP_MUTE; 11806 else 11807 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0); 11808 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 11809 HDA_AMP_MUTE, mute); 11810} 11811 11812/* unsolicited event for HP jack sensing */ 11813static void alc262_fujitsu_unsol_event(struct hda_codec *codec, 11814 unsigned int res) 11815{ 11816 if ((res >> 26) != ALC_HP_EVENT) 11817 return; 11818 alc262_fujitsu_automute(codec, 1); 11819} 11820 11821static void alc262_fujitsu_init_hook(struct hda_codec *codec) 11822{ 11823 alc262_fujitsu_automute(codec, 1); 11824} 11825 11826/* bind volumes of both NID 0x0c and 0x0d */ 11827static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = { 11828 .ops = &snd_hda_bind_vol, 11829 .values = { 11830 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT), 11831 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT), 11832 0 11833 }, 11834}; 11835 11836/* mute/unmute internal speaker according to the hp jack and mute state */ 11837static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force) 11838{ 11839 struct alc_spec *spec = codec->spec; 11840 unsigned int mute; 11841 11842 if (force || !spec->sense_updated) { 11843 spec->jack_present = snd_hda_jack_detect(codec, 0x1b); 11844 spec->sense_updated = 1; 11845 } 11846 if (spec->jack_present) { 11847 /* mute internal speaker */ 11848 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 11849 HDA_AMP_MUTE, HDA_AMP_MUTE); 11850 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0, 11851 HDA_AMP_MUTE, HDA_AMP_MUTE); 11852 } else { 11853 /* unmute internal speaker if necessary */ 11854 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0); 11855 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 11856 HDA_AMP_MUTE, mute); 11857 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0, 11858 HDA_AMP_MUTE, mute); 11859 } 11860} 11861 11862/* unsolicited event for HP jack sensing */ 11863static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec, 11864 unsigned int res) 11865{ 11866 if ((res >> 26) != ALC_HP_EVENT) 11867 return; 11868 alc262_lenovo_3000_automute(codec, 1); 11869} 11870 11871static int amp_stereo_mute_update(struct hda_codec *codec, hda_nid_t nid, 11872 int dir, int idx, long *valp) 11873{ 11874 int i, change = 0; 11875 11876 for (i = 0; i < 2; i++, valp++) 11877 change |= snd_hda_codec_amp_update(codec, nid, i, dir, idx, 11878 HDA_AMP_MUTE, 11879 *valp ? 0 : HDA_AMP_MUTE); 11880 return change; 11881} 11882 11883/* bind hp and internal speaker mute (with plug check) */ 11884static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol, 11885 struct snd_ctl_elem_value *ucontrol) 11886{ 11887 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 11888 long *valp = ucontrol->value.integer.value; 11889 int change; 11890 11891 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp); 11892 change |= amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp); 11893 if (change) 11894 alc262_fujitsu_automute(codec, 0); 11895 return change; 11896} 11897 11898static struct snd_kcontrol_new alc262_fujitsu_mixer[] = { 11899 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol), 11900 { 11901 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 11902 .name = "Master Playback Switch", 11903 .subdevice = HDA_SUBDEV_AMP_FLAG, 11904 .info = snd_hda_mixer_amp_switch_info, 11905 .get = snd_hda_mixer_amp_switch_get, 11906 .put = alc262_fujitsu_master_sw_put, 11907 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 11908 }, 11909 { 11910 .iface = NID_MAPPING, 11911 .name = "Master Playback Switch", 11912 .private_value = 0x1b, 11913 }, 11914 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 11915 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 11916 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 11917 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11918 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11919 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), 11920 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 11921 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 11922 { } /* end */ 11923}; 11924 11925/* bind hp and internal speaker mute (with plug check) */ 11926static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol, 11927 struct snd_ctl_elem_value *ucontrol) 11928{ 11929 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 11930 long *valp = ucontrol->value.integer.value; 11931 int change; 11932 11933 change = amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp); 11934 if (change) 11935 alc262_lenovo_3000_automute(codec, 0); 11936 return change; 11937} 11938 11939static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = { 11940 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol), 11941 { 11942 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 11943 .name = "Master Playback Switch", 11944 .subdevice = HDA_SUBDEV_AMP_FLAG, 11945 .info = snd_hda_mixer_amp_switch_info, 11946 .get = snd_hda_mixer_amp_switch_get, 11947 .put = alc262_lenovo_3000_master_sw_put, 11948 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT), 11949 }, 11950 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 11951 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 11952 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 11953 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11954 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11955 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), 11956 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 11957 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 11958 { } /* end */ 11959}; 11960 11961static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = { 11962 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol), 11963 ALC262_HIPPO_MASTER_SWITCH, 11964 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11965 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11966 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 11967 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 11968 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 11969 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), 11970 { } /* end */ 11971}; 11972 11973/* additional init verbs for Benq laptops */ 11974static struct hda_verb alc262_EAPD_verbs[] = { 11975 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 11976 {0x20, AC_VERB_SET_PROC_COEF, 0x3070}, 11977 {} 11978}; 11979 11980static struct hda_verb alc262_benq_t31_EAPD_verbs[] = { 11981 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 11982 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 11983 11984 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 11985 {0x20, AC_VERB_SET_PROC_COEF, 0x3050}, 11986 {} 11987}; 11988 11989/* Samsung Q1 Ultra Vista model setup */ 11990static struct snd_kcontrol_new alc262_ultra_mixer[] = { 11991 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11992 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT), 11993 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 11994 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 11995 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT), 11996 HDA_CODEC_VOLUME("Headphone Mic Boost Volume", 0x15, 0, HDA_INPUT), 11997 { } /* end */ 11998}; 11999 12000static struct hda_verb alc262_ultra_verbs[] = { 12001 /* output mixer */ 12002 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 12003 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 12004 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 12005 /* speaker */ 12006 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 12007 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 12008 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12009 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 12010 /* HP */ 12011 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 12012 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 12013 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12014 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 12015 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 12016 /* internal mic */ 12017 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 12018 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 12019 /* ADC, choose mic */ 12020 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 12021 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 12022 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12023 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 12024 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 12025 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 12026 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, 12027 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, 12028 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, 12029 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)}, 12030 {} 12031}; 12032 12033/* mute/unmute internal speaker according to the hp jack and mute state */ 12034static void alc262_ultra_automute(struct hda_codec *codec) 12035{ 12036 struct alc_spec *spec = codec->spec; 12037 unsigned int mute; 12038 12039 mute = 0; 12040 /* auto-mute only when HP is used as HP */ 12041 if (!spec->cur_mux[0]) { 12042 spec->jack_present = snd_hda_jack_detect(codec, 0x15); 12043 if (spec->jack_present) 12044 mute = HDA_AMP_MUTE; 12045 } 12046 /* mute/unmute internal speaker */ 12047 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 12048 HDA_AMP_MUTE, mute); 12049 /* mute/unmute HP */ 12050 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 12051 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE); 12052} 12053 12054/* unsolicited event for HP jack sensing */ 12055static void alc262_ultra_unsol_event(struct hda_codec *codec, 12056 unsigned int res) 12057{ 12058 if ((res >> 26) != ALC880_HP_EVENT) 12059 return; 12060 alc262_ultra_automute(codec); 12061} 12062 12063static struct hda_input_mux alc262_ultra_capture_source = { 12064 .num_items = 2, 12065 .items = { 12066 { "Mic", 0x1 }, 12067 { "Headphone", 0x7 }, 12068 }, 12069}; 12070 12071static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol, 12072 struct snd_ctl_elem_value *ucontrol) 12073{ 12074 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 12075 struct alc_spec *spec = codec->spec; 12076 int ret; 12077 12078 ret = alc_mux_enum_put(kcontrol, ucontrol); 12079 if (!ret) 12080 return 0; 12081 /* reprogram the HP pin as mic or HP according to the input source */ 12082 snd_hda_codec_write_cache(codec, 0x15, 0, 12083 AC_VERB_SET_PIN_WIDGET_CONTROL, 12084 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP); 12085 alc262_ultra_automute(codec); /* mute/unmute HP */ 12086 return ret; 12087} 12088 12089static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = { 12090 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT), 12091 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT), 12092 { 12093 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 12094 .name = "Capture Source", 12095 .info = alc_mux_enum_info, 12096 .get = alc_mux_enum_get, 12097 .put = alc262_ultra_mux_enum_put, 12098 }, 12099 { 12100 .iface = NID_MAPPING, 12101 .name = "Capture Source", 12102 .private_value = 0x15, 12103 }, 12104 { } /* end */ 12105}; 12106 12107/* We use two mixers depending on the output pin; 0x16 is a mono output 12108 * and thus it's bound with a different mixer. 12109 * This function returns which mixer amp should be used. 12110 */ 12111static int alc262_check_volbit(hda_nid_t nid) 12112{ 12113 if (!nid) 12114 return 0; 12115 else if (nid == 0x16) 12116 return 2; 12117 else 12118 return 1; 12119} 12120 12121static int alc262_add_out_vol_ctl(struct alc_spec *spec, hda_nid_t nid, 12122 const char *pfx, int *vbits, int idx) 12123{ 12124 unsigned long val; 12125 int vbit; 12126 12127 vbit = alc262_check_volbit(nid); 12128 if (!vbit) 12129 return 0; 12130 if (*vbits & vbit) /* a volume control for this mixer already there */ 12131 return 0; 12132 *vbits |= vbit; 12133 if (vbit == 2) 12134 val = HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT); 12135 else 12136 val = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT); 12137 return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx, val); 12138} 12139 12140static int alc262_add_out_sw_ctl(struct alc_spec *spec, hda_nid_t nid, 12141 const char *pfx, int idx) 12142{ 12143 unsigned long val; 12144 12145 if (!nid) 12146 return 0; 12147 if (nid == 0x16) 12148 val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT); 12149 else 12150 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT); 12151 return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx, val); 12152} 12153 12154/* add playback controls from the parsed DAC table */ 12155static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, 12156 const struct auto_pin_cfg *cfg) 12157{ 12158 const char *pfx; 12159 int vbits; 12160 int i, err; 12161 12162 spec->multiout.num_dacs = 1; /* only use one dac */ 12163 spec->multiout.dac_nids = spec->private_dac_nids; 12164 spec->multiout.dac_nids[0] = 2; 12165 12166 pfx = alc_get_line_out_pfx(cfg, true); 12167 if (!pfx) 12168 pfx = "Front"; 12169 for (i = 0; i < 2; i++) { 12170 err = alc262_add_out_sw_ctl(spec, cfg->line_out_pins[i], pfx, i); 12171 if (err < 0) 12172 return err; 12173 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { 12174 err = alc262_add_out_sw_ctl(spec, cfg->speaker_pins[i], 12175 "Speaker", i); 12176 if (err < 0) 12177 return err; 12178 } 12179 if (cfg->line_out_type != AUTO_PIN_HP_OUT) { 12180 err = alc262_add_out_sw_ctl(spec, cfg->hp_pins[i], 12181 "Headphone", i); 12182 if (err < 0) 12183 return err; 12184 } 12185 } 12186 12187 vbits = alc262_check_volbit(cfg->line_out_pins[0]) | 12188 alc262_check_volbit(cfg->speaker_pins[0]) | 12189 alc262_check_volbit(cfg->hp_pins[0]); 12190 if (vbits == 1 || vbits == 2) 12191 pfx = "Master"; /* only one mixer is used */ 12192 vbits = 0; 12193 for (i = 0; i < 2; i++) { 12194 err = alc262_add_out_vol_ctl(spec, cfg->line_out_pins[i], pfx, 12195 &vbits, i); 12196 if (err < 0) 12197 return err; 12198 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { 12199 err = alc262_add_out_vol_ctl(spec, cfg->speaker_pins[i], 12200 "Speaker", &vbits, i); 12201 if (err < 0) 12202 return err; 12203 } 12204 if (cfg->line_out_type != AUTO_PIN_HP_OUT) { 12205 err = alc262_add_out_vol_ctl(spec, cfg->hp_pins[i], 12206 "Headphone", &vbits, i); 12207 if (err < 0) 12208 return err; 12209 } 12210 } 12211 return 0; 12212} 12213 12214#define alc262_auto_create_input_ctls \ 12215 alc882_auto_create_input_ctls 12216 12217/* 12218 * generic initialization of ADC, input mixers and output mixers 12219 */ 12220static struct hda_verb alc262_volume_init_verbs[] = { 12221 /* 12222 * Unmute ADC0-2 and set the default input to mic-in 12223 */ 12224 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 12225 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12226 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 12227 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12228 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 12229 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12230 12231 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 12232 * mixer widget 12233 * Note: PASD motherboards uses the Line In 2 as the input for 12234 * front panel mic (mic 2) 12235 */ 12236 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 12237 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 12238 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 12239 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 12240 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 12241 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 12242 12243 /* 12244 * Set up output mixers (0x0c - 0x0f) 12245 */ 12246 /* set vol=0 to output mixers */ 12247 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 12248 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 12249 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 12250 12251 /* set up input amps for analog loopback */ 12252 /* Amp Indices: DAC = 0, mixer = 1 */ 12253 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12254 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12255 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12256 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12257 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12258 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12259 12260 /* FIXME: use matrix-type input source selection */ 12261 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 12262 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 12263 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 12264 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 12265 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 12266 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 12267 /* Input mixer2 */ 12268 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 12269 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 12270 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 12271 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 12272 /* Input mixer3 */ 12273 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 12274 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 12275 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 12276 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 12277 12278 { } 12279}; 12280 12281static struct hda_verb alc262_HP_BPC_init_verbs[] = { 12282 /* 12283 * Unmute ADC0-2 and set the default input to mic-in 12284 */ 12285 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 12286 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12287 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 12288 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12289 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 12290 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12291 12292 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 12293 * mixer widget 12294 * Note: PASD motherboards uses the Line In 2 as the input for 12295 * front panel mic (mic 2) 12296 */ 12297 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 12298 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 12299 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 12300 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 12301 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 12302 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 12303 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, 12304 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, 12305 12306 /* 12307 * Set up output mixers (0x0c - 0x0e) 12308 */ 12309 /* set vol=0 to output mixers */ 12310 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 12311 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 12312 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 12313 12314 /* set up input amps for analog loopback */ 12315 /* Amp Indices: DAC = 0, mixer = 1 */ 12316 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12317 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12318 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12319 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12320 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12321 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12322 12323 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 12324 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 12325 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 12326 12327 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 12328 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 12329 12330 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 12331 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 12332 12333 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 12334 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 12335 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 12336 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 12337 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 12338 12339 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 12340 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 12341 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 12342 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 12343 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 12344 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 12345 12346 12347 /* FIXME: use matrix-type input source selection */ 12348 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */ 12349 /* Input mixer1: only unmute Mic */ 12350 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 12351 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))}, 12352 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 12353 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 12354 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 12355 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))}, 12356 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))}, 12357 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))}, 12358 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))}, 12359 /* Input mixer2 */ 12360 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 12361 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))}, 12362 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 12363 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 12364 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 12365 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))}, 12366 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))}, 12367 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))}, 12368 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))}, 12369 /* Input mixer3 */ 12370 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 12371 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))}, 12372 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 12373 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 12374 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 12375 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))}, 12376 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))}, 12377 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))}, 12378 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))}, 12379 12380 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 12381 12382 { } 12383}; 12384 12385static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = { 12386 /* 12387 * Unmute ADC0-2 and set the default input to mic-in 12388 */ 12389 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 12390 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12391 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 12392 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12393 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 12394 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12395 12396 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 12397 * mixer widget 12398 * Note: PASD motherboards uses the Line In 2 as the input for front 12399 * panel mic (mic 2) 12400 */ 12401 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 12402 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 12403 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 12404 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 12405 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 12406 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 12407 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, 12408 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, 12409 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, 12410 /* 12411 * Set up output mixers (0x0c - 0x0e) 12412 */ 12413 /* set vol=0 to output mixers */ 12414 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 12415 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 12416 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 12417 12418 /* set up input amps for analog loopback */ 12419 /* Amp Indices: DAC = 0, mixer = 1 */ 12420 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12421 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12422 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12423 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12424 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12425 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12426 12427 12428 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */ 12429 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */ 12430 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */ 12431 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */ 12432 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */ 12433 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */ 12434 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */ 12435 12436 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 12437 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 12438 12439 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 12440 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 12441 12442 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */ 12443 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 12444 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 12445 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, 12446 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 12447 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 12448 12449 /* FIXME: use matrix-type input source selection */ 12450 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 12451 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 12452 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/ 12453 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/ 12454 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/ 12455 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/ 12456 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/ 12457 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */ 12458 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/ 12459 /* Input mixer2 */ 12460 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 12461 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 12462 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, 12463 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, 12464 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, 12465 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */ 12466 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, 12467 /* Input mixer3 */ 12468 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 12469 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 12470 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, 12471 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, 12472 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, 12473 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */ 12474 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, 12475 12476 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 12477 12478 { } 12479}; 12480 12481static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = { 12482 12483 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */ 12484 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 12485 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01}, 12486 12487 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */ 12488 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */ 12489 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) }, 12490 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) }, 12491 12492 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */ 12493 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 12494 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 12495 {} 12496}; 12497 12498/* 12499 * Pin config fixes 12500 */ 12501enum { 12502 PINFIX_FSC_H270, 12503}; 12504 12505static const struct alc_fixup alc262_fixups[] = { 12506 [PINFIX_FSC_H270] = { 12507 .type = ALC_FIXUP_PINS, 12508 .v.pins = (const struct alc_pincfg[]) { 12509 { 0x14, 0x99130110 }, /* speaker */ 12510 { 0x15, 0x0221142f }, /* front HP */ 12511 { 0x1b, 0x0121141f }, /* rear HP */ 12512 { } 12513 } 12514 }, 12515}; 12516 12517static struct snd_pci_quirk alc262_fixup_tbl[] = { 12518 SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", PINFIX_FSC_H270), 12519 {} 12520}; 12521 12522 12523#ifdef CONFIG_SND_HDA_POWER_SAVE 12524#define alc262_loopbacks alc880_loopbacks 12525#endif 12526 12527/* pcm configuration: identical with ALC880 */ 12528#define alc262_pcm_analog_playback alc880_pcm_analog_playback 12529#define alc262_pcm_analog_capture alc880_pcm_analog_capture 12530#define alc262_pcm_digital_playback alc880_pcm_digital_playback 12531#define alc262_pcm_digital_capture alc880_pcm_digital_capture 12532 12533/* 12534 * BIOS auto configuration 12535 */ 12536static int alc262_parse_auto_config(struct hda_codec *codec) 12537{ 12538 struct alc_spec *spec = codec->spec; 12539 int err; 12540 static hda_nid_t alc262_ignore[] = { 0x1d, 0 }; 12541 12542 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 12543 alc262_ignore); 12544 if (err < 0) 12545 return err; 12546 if (!spec->autocfg.line_outs) { 12547 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) { 12548 spec->multiout.max_channels = 2; 12549 spec->no_analog = 1; 12550 goto dig_only; 12551 } 12552 return 0; /* can't find valid BIOS pin config */ 12553 } 12554 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg); 12555 if (err < 0) 12556 return err; 12557 err = alc262_auto_create_input_ctls(codec, &spec->autocfg); 12558 if (err < 0) 12559 return err; 12560 12561 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 12562 12563 dig_only: 12564 alc_auto_parse_digital(codec); 12565 12566 if (spec->kctls.list) 12567 add_mixer(spec, spec->kctls.list); 12568 12569 add_verb(spec, alc262_volume_init_verbs); 12570 spec->num_mux_defs = 1; 12571 spec->input_mux = &spec->private_imux[0]; 12572 12573 err = alc_auto_add_mic_boost(codec); 12574 if (err < 0) 12575 return err; 12576 12577 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); 12578 12579 return 1; 12580} 12581 12582#define alc262_auto_init_multi_out alc882_auto_init_multi_out 12583#define alc262_auto_init_hp_out alc882_auto_init_hp_out 12584#define alc262_auto_init_analog_input alc882_auto_init_analog_input 12585#define alc262_auto_init_input_src alc882_auto_init_input_src 12586 12587 12588/* init callback for auto-configuration model -- overriding the default init */ 12589static void alc262_auto_init(struct hda_codec *codec) 12590{ 12591 struct alc_spec *spec = codec->spec; 12592 alc262_auto_init_multi_out(codec); 12593 alc262_auto_init_hp_out(codec); 12594 alc262_auto_init_analog_input(codec); 12595 alc262_auto_init_input_src(codec); 12596 alc_auto_init_digital(codec); 12597 if (spec->unsol_event) 12598 alc_inithook(codec); 12599} 12600 12601/* 12602 * configuration and preset 12603 */ 12604static const char * const alc262_models[ALC262_MODEL_LAST] = { 12605 [ALC262_BASIC] = "basic", 12606 [ALC262_HIPPO] = "hippo", 12607 [ALC262_HIPPO_1] = "hippo_1", 12608 [ALC262_FUJITSU] = "fujitsu", 12609 [ALC262_HP_BPC] = "hp-bpc", 12610 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000", 12611 [ALC262_HP_TC_T5735] = "hp-tc-t5735", 12612 [ALC262_HP_RP5700] = "hp-rp5700", 12613 [ALC262_BENQ_ED8] = "benq", 12614 [ALC262_BENQ_T31] = "benq-t31", 12615 [ALC262_SONY_ASSAMD] = "sony-assamd", 12616 [ALC262_TOSHIBA_S06] = "toshiba-s06", 12617 [ALC262_TOSHIBA_RX1] = "toshiba-rx1", 12618 [ALC262_ULTRA] = "ultra", 12619 [ALC262_LENOVO_3000] = "lenovo-3000", 12620 [ALC262_NEC] = "nec", 12621 [ALC262_TYAN] = "tyan", 12622 [ALC262_AUTO] = "auto", 12623}; 12624 12625static struct snd_pci_quirk alc262_cfg_tbl[] = { 12626 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO), 12627 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC), 12628 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series", 12629 ALC262_HP_BPC), 12630 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series", 12631 ALC262_HP_BPC), 12632 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1500, "HP z series", 12633 ALC262_HP_BPC), 12634 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series", 12635 ALC262_HP_BPC), 12636 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL), 12637 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF), 12638 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL), 12639 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF), 12640 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL), 12641 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF), 12642 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL), 12643 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF), 12644 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC), 12645 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC), 12646 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC), 12647 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735", 12648 ALC262_HP_TC_T5735), 12649 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700), 12650 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD), 12651 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO), 12652 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD), 12653 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */ 12654 SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06), 12655 SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO), 12656 SND_PCI_QUIRK(0x104d, 0x9047, "Sony VAIO Type G", ALC262_AUTO), 12657#if 0 /* disable the quirk since model=auto works better in recent versions */ 12658 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO", 12659 ALC262_SONY_ASSAMD), 12660#endif 12661 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1", 12662 ALC262_TOSHIBA_RX1), 12663 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06), 12664 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU), 12665 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU), 12666 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN), 12667 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1", 12668 ALC262_ULTRA), 12669 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO), 12670 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000), 12671 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8), 12672 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31), 12673 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1), 12674 {} 12675}; 12676 12677static struct alc_config_preset alc262_presets[] = { 12678 [ALC262_BASIC] = { 12679 .mixers = { alc262_base_mixer }, 12680 .init_verbs = { alc262_init_verbs }, 12681 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12682 .dac_nids = alc262_dac_nids, 12683 .hp_nid = 0x03, 12684 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12685 .channel_mode = alc262_modes, 12686 .input_mux = &alc262_capture_source, 12687 }, 12688 [ALC262_HIPPO] = { 12689 .mixers = { alc262_hippo_mixer }, 12690 .init_verbs = { alc262_init_verbs, alc_hp15_unsol_verbs}, 12691 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12692 .dac_nids = alc262_dac_nids, 12693 .hp_nid = 0x03, 12694 .dig_out_nid = ALC262_DIGOUT_NID, 12695 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12696 .channel_mode = alc262_modes, 12697 .input_mux = &alc262_capture_source, 12698 .unsol_event = alc262_hippo_unsol_event, 12699 .setup = alc262_hippo_setup, 12700 .init_hook = alc262_hippo_automute, 12701 }, 12702 [ALC262_HIPPO_1] = { 12703 .mixers = { alc262_hippo1_mixer }, 12704 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs}, 12705 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12706 .dac_nids = alc262_dac_nids, 12707 .hp_nid = 0x02, 12708 .dig_out_nid = ALC262_DIGOUT_NID, 12709 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12710 .channel_mode = alc262_modes, 12711 .input_mux = &alc262_capture_source, 12712 .unsol_event = alc262_hippo_unsol_event, 12713 .setup = alc262_hippo1_setup, 12714 .init_hook = alc262_hippo_automute, 12715 }, 12716 [ALC262_FUJITSU] = { 12717 .mixers = { alc262_fujitsu_mixer }, 12718 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs, 12719 alc262_fujitsu_unsol_verbs }, 12720 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12721 .dac_nids = alc262_dac_nids, 12722 .hp_nid = 0x03, 12723 .dig_out_nid = ALC262_DIGOUT_NID, 12724 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12725 .channel_mode = alc262_modes, 12726 .input_mux = &alc262_fujitsu_capture_source, 12727 .unsol_event = alc262_fujitsu_unsol_event, 12728 .init_hook = alc262_fujitsu_init_hook, 12729 }, 12730 [ALC262_HP_BPC] = { 12731 .mixers = { alc262_HP_BPC_mixer }, 12732 .init_verbs = { alc262_HP_BPC_init_verbs }, 12733 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12734 .dac_nids = alc262_dac_nids, 12735 .hp_nid = 0x03, 12736 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12737 .channel_mode = alc262_modes, 12738 .input_mux = &alc262_HP_capture_source, 12739 .unsol_event = alc262_hp_bpc_unsol_event, 12740 .init_hook = alc262_hp_bpc_automute, 12741 }, 12742 [ALC262_HP_BPC_D7000_WF] = { 12743 .mixers = { alc262_HP_BPC_WildWest_mixer }, 12744 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs }, 12745 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12746 .dac_nids = alc262_dac_nids, 12747 .hp_nid = 0x03, 12748 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12749 .channel_mode = alc262_modes, 12750 .input_mux = &alc262_HP_D7000_capture_source, 12751 .unsol_event = alc262_hp_wildwest_unsol_event, 12752 .init_hook = alc262_hp_wildwest_automute, 12753 }, 12754 [ALC262_HP_BPC_D7000_WL] = { 12755 .mixers = { alc262_HP_BPC_WildWest_mixer, 12756 alc262_HP_BPC_WildWest_option_mixer }, 12757 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs }, 12758 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12759 .dac_nids = alc262_dac_nids, 12760 .hp_nid = 0x03, 12761 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12762 .channel_mode = alc262_modes, 12763 .input_mux = &alc262_HP_D7000_capture_source, 12764 .unsol_event = alc262_hp_wildwest_unsol_event, 12765 .init_hook = alc262_hp_wildwest_automute, 12766 }, 12767 [ALC262_HP_TC_T5735] = { 12768 .mixers = { alc262_hp_t5735_mixer }, 12769 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs }, 12770 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12771 .dac_nids = alc262_dac_nids, 12772 .hp_nid = 0x03, 12773 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12774 .channel_mode = alc262_modes, 12775 .input_mux = &alc262_capture_source, 12776 .unsol_event = alc_sku_unsol_event, 12777 .setup = alc262_hp_t5735_setup, 12778 .init_hook = alc_inithook, 12779 }, 12780 [ALC262_HP_RP5700] = { 12781 .mixers = { alc262_hp_rp5700_mixer }, 12782 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs }, 12783 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12784 .dac_nids = alc262_dac_nids, 12785 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12786 .channel_mode = alc262_modes, 12787 .input_mux = &alc262_hp_rp5700_capture_source, 12788 }, 12789 [ALC262_BENQ_ED8] = { 12790 .mixers = { alc262_base_mixer }, 12791 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs }, 12792 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12793 .dac_nids = alc262_dac_nids, 12794 .hp_nid = 0x03, 12795 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12796 .channel_mode = alc262_modes, 12797 .input_mux = &alc262_capture_source, 12798 }, 12799 [ALC262_SONY_ASSAMD] = { 12800 .mixers = { alc262_sony_mixer }, 12801 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs}, 12802 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12803 .dac_nids = alc262_dac_nids, 12804 .hp_nid = 0x02, 12805 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12806 .channel_mode = alc262_modes, 12807 .input_mux = &alc262_capture_source, 12808 .unsol_event = alc262_hippo_unsol_event, 12809 .setup = alc262_hippo_setup, 12810 .init_hook = alc262_hippo_automute, 12811 }, 12812 [ALC262_BENQ_T31] = { 12813 .mixers = { alc262_benq_t31_mixer }, 12814 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, 12815 alc_hp15_unsol_verbs }, 12816 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12817 .dac_nids = alc262_dac_nids, 12818 .hp_nid = 0x03, 12819 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12820 .channel_mode = alc262_modes, 12821 .input_mux = &alc262_capture_source, 12822 .unsol_event = alc262_hippo_unsol_event, 12823 .setup = alc262_hippo_setup, 12824 .init_hook = alc262_hippo_automute, 12825 }, 12826 [ALC262_ULTRA] = { 12827 .mixers = { alc262_ultra_mixer }, 12828 .cap_mixer = alc262_ultra_capture_mixer, 12829 .init_verbs = { alc262_ultra_verbs }, 12830 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12831 .dac_nids = alc262_dac_nids, 12832 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12833 .channel_mode = alc262_modes, 12834 .input_mux = &alc262_ultra_capture_source, 12835 .adc_nids = alc262_adc_nids, /* ADC0 */ 12836 .capsrc_nids = alc262_capsrc_nids, 12837 .num_adc_nids = 1, /* single ADC */ 12838 .unsol_event = alc262_ultra_unsol_event, 12839 .init_hook = alc262_ultra_automute, 12840 }, 12841 [ALC262_LENOVO_3000] = { 12842 .mixers = { alc262_lenovo_3000_mixer }, 12843 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs, 12844 alc262_lenovo_3000_unsol_verbs, 12845 alc262_lenovo_3000_init_verbs }, 12846 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12847 .dac_nids = alc262_dac_nids, 12848 .hp_nid = 0x03, 12849 .dig_out_nid = ALC262_DIGOUT_NID, 12850 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12851 .channel_mode = alc262_modes, 12852 .input_mux = &alc262_fujitsu_capture_source, 12853 .unsol_event = alc262_lenovo_3000_unsol_event, 12854 }, 12855 [ALC262_NEC] = { 12856 .mixers = { alc262_nec_mixer }, 12857 .init_verbs = { alc262_nec_verbs }, 12858 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12859 .dac_nids = alc262_dac_nids, 12860 .hp_nid = 0x03, 12861 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12862 .channel_mode = alc262_modes, 12863 .input_mux = &alc262_capture_source, 12864 }, 12865 [ALC262_TOSHIBA_S06] = { 12866 .mixers = { alc262_toshiba_s06_mixer }, 12867 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs, 12868 alc262_eapd_verbs }, 12869 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12870 .capsrc_nids = alc262_dmic_capsrc_nids, 12871 .dac_nids = alc262_dac_nids, 12872 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */ 12873 .num_adc_nids = 1, /* single ADC */ 12874 .dig_out_nid = ALC262_DIGOUT_NID, 12875 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12876 .channel_mode = alc262_modes, 12877 .unsol_event = alc_sku_unsol_event, 12878 .setup = alc262_toshiba_s06_setup, 12879 .init_hook = alc_inithook, 12880 }, 12881 [ALC262_TOSHIBA_RX1] = { 12882 .mixers = { alc262_toshiba_rx1_mixer }, 12883 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs }, 12884 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12885 .dac_nids = alc262_dac_nids, 12886 .hp_nid = 0x03, 12887 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12888 .channel_mode = alc262_modes, 12889 .input_mux = &alc262_capture_source, 12890 .unsol_event = alc262_hippo_unsol_event, 12891 .setup = alc262_hippo_setup, 12892 .init_hook = alc262_hippo_automute, 12893 }, 12894 [ALC262_TYAN] = { 12895 .mixers = { alc262_tyan_mixer }, 12896 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs}, 12897 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12898 .dac_nids = alc262_dac_nids, 12899 .hp_nid = 0x02, 12900 .dig_out_nid = ALC262_DIGOUT_NID, 12901 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12902 .channel_mode = alc262_modes, 12903 .input_mux = &alc262_capture_source, 12904 .unsol_event = alc_automute_amp_unsol_event, 12905 .setup = alc262_tyan_setup, 12906 .init_hook = alc_automute_amp, 12907 }, 12908}; 12909 12910static int patch_alc262(struct hda_codec *codec) 12911{ 12912 struct alc_spec *spec; 12913 int board_config; 12914 int err; 12915 12916 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 12917 if (spec == NULL) 12918 return -ENOMEM; 12919 12920 codec->spec = spec; 12921#if 0 12922 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is 12923 * under-run 12924 */ 12925 { 12926 int tmp; 12927 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7); 12928 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0); 12929 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7); 12930 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80); 12931 } 12932#endif 12933 alc_auto_parse_customize_define(codec); 12934 12935 alc_fix_pll_init(codec, 0x20, 0x0a, 10); 12936 12937 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST, 12938 alc262_models, 12939 alc262_cfg_tbl); 12940 12941 if (board_config < 0) { 12942 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 12943 codec->chip_name); 12944 board_config = ALC262_AUTO; 12945 } 12946 12947 if (board_config == ALC262_AUTO) { 12948 alc_pick_fixup(codec, NULL, alc262_fixup_tbl, alc262_fixups); 12949 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); 12950 } 12951 12952 if (board_config == ALC262_AUTO) { 12953 /* automatic parse from the BIOS config */ 12954 err = alc262_parse_auto_config(codec); 12955 if (err < 0) { 12956 alc_free(codec); 12957 return err; 12958 } else if (!err) { 12959 printk(KERN_INFO 12960 "hda_codec: Cannot set up configuration " 12961 "from BIOS. Using base mode...\n"); 12962 board_config = ALC262_BASIC; 12963 } 12964 } 12965 12966 if (!spec->no_analog && has_cdefine_beep(codec)) { 12967 err = snd_hda_attach_beep_device(codec, 0x1); 12968 if (err < 0) { 12969 alc_free(codec); 12970 return err; 12971 } 12972 } 12973 12974 if (board_config != ALC262_AUTO) 12975 setup_preset(codec, &alc262_presets[board_config]); 12976 12977 spec->stream_analog_playback = &alc262_pcm_analog_playback; 12978 spec->stream_analog_capture = &alc262_pcm_analog_capture; 12979 12980 spec->stream_digital_playback = &alc262_pcm_digital_playback; 12981 spec->stream_digital_capture = &alc262_pcm_digital_capture; 12982 12983 if (!spec->adc_nids && spec->input_mux) { 12984 int i; 12985 /* check whether the digital-mic has to be supported */ 12986 for (i = 0; i < spec->input_mux->num_items; i++) { 12987 if (spec->input_mux->items[i].index >= 9) 12988 break; 12989 } 12990 if (i < spec->input_mux->num_items) { 12991 /* use only ADC0 */ 12992 spec->adc_nids = alc262_dmic_adc_nids; 12993 spec->num_adc_nids = 1; 12994 spec->capsrc_nids = alc262_dmic_capsrc_nids; 12995 } else { 12996 /* all analog inputs */ 12997 /* check whether NID 0x07 is valid */ 12998 unsigned int wcap = get_wcaps(codec, 0x07); 12999 13000 /* get type */ 13001 wcap = get_wcaps_type(wcap); 13002 if (wcap != AC_WID_AUD_IN) { 13003 spec->adc_nids = alc262_adc_nids_alt; 13004 spec->num_adc_nids = 13005 ARRAY_SIZE(alc262_adc_nids_alt); 13006 spec->capsrc_nids = alc262_capsrc_nids_alt; 13007 } else { 13008 spec->adc_nids = alc262_adc_nids; 13009 spec->num_adc_nids = 13010 ARRAY_SIZE(alc262_adc_nids); 13011 spec->capsrc_nids = alc262_capsrc_nids; 13012 } 13013 } 13014 } 13015 if (!spec->cap_mixer && !spec->no_analog) 13016 set_capture_mixer(codec); 13017 if (!spec->no_analog && has_cdefine_beep(codec)) 13018 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 13019 13020 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); 13021 13022 spec->vmaster_nid = 0x0c; 13023 13024 codec->patch_ops = alc_patch_ops; 13025 if (board_config == ALC262_AUTO) 13026 spec->init_hook = alc262_auto_init; 13027 13028 alc_init_jacks(codec); 13029#ifdef CONFIG_SND_HDA_POWER_SAVE 13030 if (!spec->loopback.amplist) 13031 spec->loopback.amplist = alc262_loopbacks; 13032#endif 13033 13034 return 0; 13035} 13036 13037/* 13038 * ALC268 channel source setting (2 channel) 13039 */ 13040#define ALC268_DIGOUT_NID ALC880_DIGOUT_NID 13041#define alc268_modes alc260_modes 13042 13043static hda_nid_t alc268_dac_nids[2] = { 13044 /* front, hp */ 13045 0x02, 0x03 13046}; 13047 13048static hda_nid_t alc268_adc_nids[2] = { 13049 /* ADC0-1 */ 13050 0x08, 0x07 13051}; 13052 13053static hda_nid_t alc268_adc_nids_alt[1] = { 13054 /* ADC0 */ 13055 0x08 13056}; 13057 13058static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 }; 13059 13060static struct snd_kcontrol_new alc268_base_mixer[] = { 13061 /* output mixer control */ 13062 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), 13063 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 13064 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT), 13065 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 13066 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 13067 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), 13068 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT), 13069 { } 13070}; 13071 13072static struct snd_kcontrol_new alc268_toshiba_mixer[] = { 13073 /* output mixer control */ 13074 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), 13075 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT), 13076 ALC262_HIPPO_MASTER_SWITCH, 13077 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 13078 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), 13079 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT), 13080 { } 13081}; 13082 13083/* bind Beep switches of both NID 0x0f and 0x10 */ 13084static struct hda_bind_ctls alc268_bind_beep_sw = { 13085 .ops = &snd_hda_bind_sw, 13086 .values = { 13087 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT), 13088 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT), 13089 0 13090 }, 13091}; 13092 13093static struct snd_kcontrol_new alc268_beep_mixer[] = { 13094 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT), 13095 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw), 13096 { } 13097}; 13098 13099static struct hda_verb alc268_eapd_verbs[] = { 13100 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 13101 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, 13102 { } 13103}; 13104 13105/* Toshiba specific */ 13106static struct hda_verb alc268_toshiba_verbs[] = { 13107 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 13108 { } /* end */ 13109}; 13110 13111/* Acer specific */ 13112/* bind volumes of both NID 0x02 and 0x03 */ 13113static struct hda_bind_ctls alc268_acer_bind_master_vol = { 13114 .ops = &snd_hda_bind_vol, 13115 .values = { 13116 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), 13117 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT), 13118 0 13119 }, 13120}; 13121 13122/* mute/unmute internal speaker according to the hp jack and mute state */ 13123static void alc268_acer_automute(struct hda_codec *codec, int force) 13124{ 13125 struct alc_spec *spec = codec->spec; 13126 unsigned int mute; 13127 13128 if (force || !spec->sense_updated) { 13129 spec->jack_present = snd_hda_jack_detect(codec, 0x14); 13130 spec->sense_updated = 1; 13131 } 13132 if (spec->jack_present) 13133 mute = HDA_AMP_MUTE; /* mute internal speaker */ 13134 else /* unmute internal speaker if necessary */ 13135 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0); 13136 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 13137 HDA_AMP_MUTE, mute); 13138} 13139 13140 13141/* bind hp and internal speaker mute (with plug check) */ 13142static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol, 13143 struct snd_ctl_elem_value *ucontrol) 13144{ 13145 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 13146 long *valp = ucontrol->value.integer.value; 13147 int change; 13148 13149 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp); 13150 if (change) 13151 alc268_acer_automute(codec, 0); 13152 return change; 13153} 13154 13155static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = { 13156 /* output mixer control */ 13157 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), 13158 { 13159 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 13160 .name = "Master Playback Switch", 13161 .subdevice = HDA_SUBDEV_AMP_FLAG, 13162 .info = snd_hda_mixer_amp_switch_info, 13163 .get = snd_hda_mixer_amp_switch_get, 13164 .put = alc268_acer_master_sw_put, 13165 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 13166 }, 13167 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT), 13168 { } 13169}; 13170 13171static struct snd_kcontrol_new alc268_acer_mixer[] = { 13172 /* output mixer control */ 13173 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), 13174 { 13175 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 13176 .name = "Master Playback Switch", 13177 .subdevice = HDA_SUBDEV_AMP_FLAG, 13178 .info = snd_hda_mixer_amp_switch_info, 13179 .get = snd_hda_mixer_amp_switch_get, 13180 .put = alc268_acer_master_sw_put, 13181 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 13182 }, 13183 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 13184 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), 13185 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT), 13186 { } 13187}; 13188 13189static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = { 13190 /* output mixer control */ 13191 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), 13192 { 13193 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 13194 .name = "Master Playback Switch", 13195 .subdevice = HDA_SUBDEV_AMP_FLAG, 13196 .info = snd_hda_mixer_amp_switch_info, 13197 .get = snd_hda_mixer_amp_switch_get, 13198 .put = alc268_acer_master_sw_put, 13199 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 13200 }, 13201 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 13202 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT), 13203 { } 13204}; 13205 13206static struct hda_verb alc268_acer_aspire_one_verbs[] = { 13207 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 13208 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 13209 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 13210 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 13211 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06}, 13212 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017}, 13213 { } 13214}; 13215 13216static struct hda_verb alc268_acer_verbs[] = { 13217 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */ 13218 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 13219 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 13220 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 13221 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 13222 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 13223 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 13224 { } 13225}; 13226 13227/* unsolicited event for HP jack sensing */ 13228#define alc268_toshiba_unsol_event alc262_hippo_unsol_event 13229#define alc268_toshiba_setup alc262_hippo_setup 13230#define alc268_toshiba_automute alc262_hippo_automute 13231 13232static void alc268_acer_unsol_event(struct hda_codec *codec, 13233 unsigned int res) 13234{ 13235 if ((res >> 26) != ALC880_HP_EVENT) 13236 return; 13237 alc268_acer_automute(codec, 1); 13238} 13239 13240static void alc268_acer_init_hook(struct hda_codec *codec) 13241{ 13242 alc268_acer_automute(codec, 1); 13243} 13244 13245/* toggle speaker-output according to the hp-jack state */ 13246static void alc268_aspire_one_speaker_automute(struct hda_codec *codec) 13247{ 13248 unsigned int present; 13249 unsigned char bits; 13250 13251 present = snd_hda_jack_detect(codec, 0x15); 13252 bits = present ? HDA_AMP_MUTE : 0; 13253 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0, 13254 HDA_AMP_MUTE, bits); 13255 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1, 13256 HDA_AMP_MUTE, bits); 13257} 13258 13259static void alc268_acer_lc_unsol_event(struct hda_codec *codec, 13260 unsigned int res) 13261{ 13262 switch (res >> 26) { 13263 case ALC880_HP_EVENT: 13264 alc268_aspire_one_speaker_automute(codec); 13265 break; 13266 case ALC880_MIC_EVENT: 13267 alc_mic_automute(codec); 13268 break; 13269 } 13270} 13271 13272static void alc268_acer_lc_setup(struct hda_codec *codec) 13273{ 13274 struct alc_spec *spec = codec->spec; 13275 spec->ext_mic.pin = 0x18; 13276 spec->ext_mic.mux_idx = 0; 13277 spec->int_mic.pin = 0x12; 13278 spec->int_mic.mux_idx = 6; 13279 spec->auto_mic = 1; 13280} 13281 13282static void alc268_acer_lc_init_hook(struct hda_codec *codec) 13283{ 13284 alc268_aspire_one_speaker_automute(codec); 13285 alc_mic_automute(codec); 13286} 13287 13288static struct snd_kcontrol_new alc268_dell_mixer[] = { 13289 /* output mixer control */ 13290 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 13291 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 13292 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 13293 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 13294 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 13295 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), 13296 { } 13297}; 13298 13299static struct hda_verb alc268_dell_verbs[] = { 13300 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 13301 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 13302 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 13303 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, 13304 { } 13305}; 13306 13307/* mute/unmute internal speaker according to the hp jack and mute state */ 13308static void alc268_dell_setup(struct hda_codec *codec) 13309{ 13310 struct alc_spec *spec = codec->spec; 13311 13312 spec->autocfg.hp_pins[0] = 0x15; 13313 spec->autocfg.speaker_pins[0] = 0x14; 13314 spec->ext_mic.pin = 0x18; 13315 spec->ext_mic.mux_idx = 0; 13316 spec->int_mic.pin = 0x19; 13317 spec->int_mic.mux_idx = 1; 13318 spec->auto_mic = 1; 13319} 13320 13321static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = { 13322 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT), 13323 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 13324 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT), 13325 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 13326 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT), 13327 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT), 13328 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 13329 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), 13330 { } 13331}; 13332 13333static struct hda_verb alc267_quanta_il1_verbs[] = { 13334 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 13335 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, 13336 { } 13337}; 13338 13339static void alc267_quanta_il1_setup(struct hda_codec *codec) 13340{ 13341 struct alc_spec *spec = codec->spec; 13342 spec->autocfg.hp_pins[0] = 0x15; 13343 spec->autocfg.speaker_pins[0] = 0x14; 13344 spec->ext_mic.pin = 0x18; 13345 spec->ext_mic.mux_idx = 0; 13346 spec->int_mic.pin = 0x19; 13347 spec->int_mic.mux_idx = 1; 13348 spec->auto_mic = 1; 13349} 13350 13351/* 13352 * generic initialization of ADC, input mixers and output mixers 13353 */ 13354static struct hda_verb alc268_base_init_verbs[] = { 13355 /* Unmute DAC0-1 and set vol = 0 */ 13356 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 13357 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 13358 13359 /* 13360 * Set up output mixers (0x0c - 0x0e) 13361 */ 13362 /* set vol=0 to output mixers */ 13363 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13364 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00}, 13365 13366 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13367 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13368 13369 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 13370 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 13371 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 13372 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 13373 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 13374 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 13375 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 13376 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 13377 13378 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 13379 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 13380 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 13381 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 13382 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 13383 13384 /* set PCBEEP vol = 0, mute connections */ 13385 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13386 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 13387 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 13388 13389 /* Unmute Selector 23h,24h and set the default input to mic-in */ 13390 13391 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00}, 13392 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 13393 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00}, 13394 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 13395 13396 { } 13397}; 13398 13399/* 13400 * generic initialization of ADC, input mixers and output mixers 13401 */ 13402static struct hda_verb alc268_volume_init_verbs[] = { 13403 /* set output DAC */ 13404 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 13405 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 13406 13407 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 13408 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 13409 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 13410 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 13411 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 13412 13413 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13414 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13415 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13416 13417 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 13418 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 13419 13420 /* set PCBEEP vol = 0, mute connections */ 13421 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13422 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 13423 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 13424 13425 { } 13426}; 13427 13428static struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = { 13429 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT), 13430 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT), 13431 { } /* end */ 13432}; 13433 13434static struct snd_kcontrol_new alc268_capture_alt_mixer[] = { 13435 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT), 13436 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT), 13437 _DEFINE_CAPSRC(1), 13438 { } /* end */ 13439}; 13440 13441static struct snd_kcontrol_new alc268_capture_mixer[] = { 13442 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT), 13443 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT), 13444 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT), 13445 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT), 13446 _DEFINE_CAPSRC(2), 13447 { } /* end */ 13448}; 13449 13450static struct hda_input_mux alc268_capture_source = { 13451 .num_items = 4, 13452 .items = { 13453 { "Mic", 0x0 }, 13454 { "Front Mic", 0x1 }, 13455 { "Line", 0x2 }, 13456 { "CD", 0x3 }, 13457 }, 13458}; 13459 13460static struct hda_input_mux alc268_acer_capture_source = { 13461 .num_items = 3, 13462 .items = { 13463 { "Mic", 0x0 }, 13464 { "Internal Mic", 0x1 }, 13465 { "Line", 0x2 }, 13466 }, 13467}; 13468 13469static struct hda_input_mux alc268_acer_dmic_capture_source = { 13470 .num_items = 3, 13471 .items = { 13472 { "Mic", 0x0 }, 13473 { "Internal Mic", 0x6 }, 13474 { "Line", 0x2 }, 13475 }, 13476}; 13477 13478#ifdef CONFIG_SND_DEBUG 13479static struct snd_kcontrol_new alc268_test_mixer[] = { 13480 /* Volume widgets */ 13481 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT), 13482 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT), 13483 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT), 13484 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT), 13485 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT), 13486 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT), 13487 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT), 13488 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT), 13489 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT), 13490 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT), 13491 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT), 13492 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT), 13493 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT), 13494 /* The below appears problematic on some hardwares */ 13495 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/ 13496 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT), 13497 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT), 13498 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT), 13499 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT), 13500 13501 /* Modes for retasking pin widgets */ 13502 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT), 13503 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT), 13504 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT), 13505 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT), 13506 13507 /* Controls for GPIO pins, assuming they are configured as outputs */ 13508 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01), 13509 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02), 13510 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04), 13511 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08), 13512 13513 /* Switches to allow the digital SPDIF output pin to be enabled. 13514 * The ALC268 does not have an SPDIF input. 13515 */ 13516 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01), 13517 13518 /* A switch allowing EAPD to be enabled. Some laptops seem to use 13519 * this output to turn on an external amplifier. 13520 */ 13521 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02), 13522 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02), 13523 13524 { } /* end */ 13525}; 13526#endif 13527 13528/* create input playback/capture controls for the given pin */ 13529static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid, 13530 const char *ctlname, int idx) 13531{ 13532 hda_nid_t dac; 13533 int err; 13534 13535 switch (nid) { 13536 case 0x14: 13537 case 0x16: 13538 dac = 0x02; 13539 break; 13540 case 0x15: 13541 case 0x1a: /* ALC259/269 only */ 13542 case 0x1b: /* ALC259/269 only */ 13543 case 0x21: /* ALC269vb has this pin, too */ 13544 dac = 0x03; 13545 break; 13546 default: 13547 snd_printd(KERN_WARNING "hda_codec: " 13548 "ignoring pin 0x%x as unknown\n", nid); 13549 return 0; 13550 } 13551 if (spec->multiout.dac_nids[0] != dac && 13552 spec->multiout.dac_nids[1] != dac) { 13553 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname, 13554 HDA_COMPOSE_AMP_VAL(dac, 3, idx, 13555 HDA_OUTPUT)); 13556 if (err < 0) 13557 return err; 13558 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac; 13559 } 13560 13561 if (nid != 0x16) 13562 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname, 13563 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT)); 13564 else /* mono */ 13565 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname, 13566 HDA_COMPOSE_AMP_VAL(nid, 2, idx, HDA_OUTPUT)); 13567 if (err < 0) 13568 return err; 13569 return 0; 13570} 13571 13572/* add playback controls from the parsed DAC table */ 13573static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec, 13574 const struct auto_pin_cfg *cfg) 13575{ 13576 hda_nid_t nid; 13577 int err; 13578 13579 spec->multiout.dac_nids = spec->private_dac_nids; 13580 13581 nid = cfg->line_out_pins[0]; 13582 if (nid) { 13583 const char *name; 13584 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) 13585 name = "Speaker"; 13586 else 13587 name = "Front"; 13588 err = alc268_new_analog_output(spec, nid, name, 0); 13589 if (err < 0) 13590 return err; 13591 } 13592 13593 nid = cfg->speaker_pins[0]; 13594 if (nid == 0x1d) { 13595 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, "Speaker", 13596 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT)); 13597 if (err < 0) 13598 return err; 13599 } else if (nid) { 13600 err = alc268_new_analog_output(spec, nid, "Speaker", 0); 13601 if (err < 0) 13602 return err; 13603 } 13604 nid = cfg->hp_pins[0]; 13605 if (nid) { 13606 err = alc268_new_analog_output(spec, nid, "Headphone", 0); 13607 if (err < 0) 13608 return err; 13609 } 13610 13611 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2]; 13612 if (nid == 0x16) { 13613 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, "Mono", 13614 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT)); 13615 if (err < 0) 13616 return err; 13617 } 13618 return 0; 13619} 13620 13621/* create playback/capture controls for input pins */ 13622static int alc268_auto_create_input_ctls(struct hda_codec *codec, 13623 const struct auto_pin_cfg *cfg) 13624{ 13625 return alc_auto_create_input_ctls(codec, cfg, 0, 0x23, 0x24); 13626} 13627 13628static void alc268_auto_set_output_and_unmute(struct hda_codec *codec, 13629 hda_nid_t nid, int pin_type) 13630{ 13631 int idx; 13632 13633 alc_set_pin_output(codec, nid, pin_type); 13634 if (nid == 0x14 || nid == 0x16) 13635 idx = 0; 13636 else 13637 idx = 1; 13638 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx); 13639} 13640 13641static void alc268_auto_init_multi_out(struct hda_codec *codec) 13642{ 13643 struct alc_spec *spec = codec->spec; 13644 int i; 13645 13646 for (i = 0; i < spec->autocfg.line_outs; i++) { 13647 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 13648 int pin_type = get_pin_type(spec->autocfg.line_out_type); 13649 alc268_auto_set_output_and_unmute(codec, nid, pin_type); 13650 } 13651} 13652 13653static void alc268_auto_init_hp_out(struct hda_codec *codec) 13654{ 13655 struct alc_spec *spec = codec->spec; 13656 hda_nid_t pin; 13657 int i; 13658 13659 for (i = 0; i < spec->autocfg.hp_outs; i++) { 13660 pin = spec->autocfg.hp_pins[i]; 13661 alc268_auto_set_output_and_unmute(codec, pin, PIN_HP); 13662 } 13663 for (i = 0; i < spec->autocfg.speaker_outs; i++) { 13664 pin = spec->autocfg.speaker_pins[i]; 13665 alc268_auto_set_output_and_unmute(codec, pin, PIN_OUT); 13666 } 13667 if (spec->autocfg.mono_out_pin) 13668 snd_hda_codec_write(codec, spec->autocfg.mono_out_pin, 0, 13669 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); 13670} 13671 13672static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec) 13673{ 13674 struct alc_spec *spec = codec->spec; 13675 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0]; 13676 hda_nid_t hp_nid = spec->autocfg.hp_pins[0]; 13677 hda_nid_t line_nid = spec->autocfg.line_out_pins[0]; 13678 unsigned int dac_vol1, dac_vol2; 13679 13680 if (line_nid == 0x1d || speaker_nid == 0x1d) { 13681 snd_hda_codec_write(codec, speaker_nid, 0, 13682 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); 13683 /* mute mixer inputs from 0x1d */ 13684 snd_hda_codec_write(codec, 0x0f, 0, 13685 AC_VERB_SET_AMP_GAIN_MUTE, 13686 AMP_IN_UNMUTE(1)); 13687 snd_hda_codec_write(codec, 0x10, 0, 13688 AC_VERB_SET_AMP_GAIN_MUTE, 13689 AMP_IN_UNMUTE(1)); 13690 } else { 13691 /* unmute mixer inputs from 0x1d */ 13692 snd_hda_codec_write(codec, 0x0f, 0, 13693 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)); 13694 snd_hda_codec_write(codec, 0x10, 0, 13695 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)); 13696 } 13697 13698 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */ 13699 if (line_nid == 0x14) 13700 dac_vol2 = AMP_OUT_ZERO; 13701 else if (line_nid == 0x15) 13702 dac_vol1 = AMP_OUT_ZERO; 13703 if (hp_nid == 0x14) 13704 dac_vol2 = AMP_OUT_ZERO; 13705 else if (hp_nid == 0x15) 13706 dac_vol1 = AMP_OUT_ZERO; 13707 if (line_nid != 0x16 || hp_nid != 0x16 || 13708 spec->autocfg.line_out_pins[1] != 0x16 || 13709 spec->autocfg.line_out_pins[2] != 0x16) 13710 dac_vol1 = dac_vol2 = AMP_OUT_ZERO; 13711 13712 snd_hda_codec_write(codec, 0x02, 0, 13713 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1); 13714 snd_hda_codec_write(codec, 0x03, 0, 13715 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2); 13716} 13717 13718/* pcm configuration: identical with ALC880 */ 13719#define alc268_pcm_analog_playback alc880_pcm_analog_playback 13720#define alc268_pcm_analog_capture alc880_pcm_analog_capture 13721#define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture 13722#define alc268_pcm_digital_playback alc880_pcm_digital_playback 13723 13724/* 13725 * BIOS auto configuration 13726 */ 13727static int alc268_parse_auto_config(struct hda_codec *codec) 13728{ 13729 struct alc_spec *spec = codec->spec; 13730 int err; 13731 static hda_nid_t alc268_ignore[] = { 0 }; 13732 13733 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 13734 alc268_ignore); 13735 if (err < 0) 13736 return err; 13737 if (!spec->autocfg.line_outs) { 13738 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) { 13739 spec->multiout.max_channels = 2; 13740 spec->no_analog = 1; 13741 goto dig_only; 13742 } 13743 return 0; /* can't find valid BIOS pin config */ 13744 } 13745 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg); 13746 if (err < 0) 13747 return err; 13748 err = alc268_auto_create_input_ctls(codec, &spec->autocfg); 13749 if (err < 0) 13750 return err; 13751 13752 spec->multiout.max_channels = 2; 13753 13754 dig_only: 13755 /* digital only support output */ 13756 alc_auto_parse_digital(codec); 13757 if (spec->kctls.list) 13758 add_mixer(spec, spec->kctls.list); 13759 13760 if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d) 13761 add_mixer(spec, alc268_beep_mixer); 13762 13763 add_verb(spec, alc268_volume_init_verbs); 13764 spec->num_mux_defs = 2; 13765 spec->input_mux = &spec->private_imux[0]; 13766 13767 err = alc_auto_add_mic_boost(codec); 13768 if (err < 0) 13769 return err; 13770 13771 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); 13772 13773 return 1; 13774} 13775 13776#define alc268_auto_init_analog_input alc882_auto_init_analog_input 13777 13778/* init callback for auto-configuration model -- overriding the default init */ 13779static void alc268_auto_init(struct hda_codec *codec) 13780{ 13781 struct alc_spec *spec = codec->spec; 13782 alc268_auto_init_multi_out(codec); 13783 alc268_auto_init_hp_out(codec); 13784 alc268_auto_init_mono_speaker_out(codec); 13785 alc268_auto_init_analog_input(codec); 13786 alc_auto_init_digital(codec); 13787 if (spec->unsol_event) 13788 alc_inithook(codec); 13789} 13790 13791/* 13792 * configuration and preset 13793 */ 13794static const char * const alc268_models[ALC268_MODEL_LAST] = { 13795 [ALC267_QUANTA_IL1] = "quanta-il1", 13796 [ALC268_3ST] = "3stack", 13797 [ALC268_TOSHIBA] = "toshiba", 13798 [ALC268_ACER] = "acer", 13799 [ALC268_ACER_DMIC] = "acer-dmic", 13800 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire", 13801 [ALC268_DELL] = "dell", 13802 [ALC268_ZEPTO] = "zepto", 13803#ifdef CONFIG_SND_DEBUG 13804 [ALC268_TEST] = "test", 13805#endif 13806 [ALC268_AUTO] = "auto", 13807}; 13808 13809static struct snd_pci_quirk alc268_cfg_tbl[] = { 13810 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER), 13811 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER), 13812 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER), 13813 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER), 13814 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER), 13815 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One", 13816 ALC268_ACER_ASPIRE_ONE), 13817 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL), 13818 SND_PCI_QUIRK_MASK(0x1028, 0xfff0, 0x02b0, 13819 "Dell Inspiron Mini9/Vostro A90", ALC268_DELL), 13820 /* almost compatible with toshiba but with optional digital outs; 13821 * auto-probing seems working fine 13822 */ 13823 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series", 13824 ALC268_AUTO), 13825 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST), 13826 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO), 13827 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA), 13828 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER), 13829 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1), 13830 {} 13831}; 13832 13833/* Toshiba laptops have no unique PCI SSID but only codec SSID */ 13834static struct snd_pci_quirk alc268_ssid_cfg_tbl[] = { 13835 SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO), 13836 SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO), 13837 SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05", 13838 ALC268_TOSHIBA), 13839 {} 13840}; 13841 13842static struct alc_config_preset alc268_presets[] = { 13843 [ALC267_QUANTA_IL1] = { 13844 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer, 13845 alc268_capture_nosrc_mixer }, 13846 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 13847 alc267_quanta_il1_verbs }, 13848 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 13849 .dac_nids = alc268_dac_nids, 13850 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 13851 .adc_nids = alc268_adc_nids_alt, 13852 .hp_nid = 0x03, 13853 .num_channel_mode = ARRAY_SIZE(alc268_modes), 13854 .channel_mode = alc268_modes, 13855 .unsol_event = alc_sku_unsol_event, 13856 .setup = alc267_quanta_il1_setup, 13857 .init_hook = alc_inithook, 13858 }, 13859 [ALC268_3ST] = { 13860 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer, 13861 alc268_beep_mixer }, 13862 .init_verbs = { alc268_base_init_verbs }, 13863 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 13864 .dac_nids = alc268_dac_nids, 13865 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 13866 .adc_nids = alc268_adc_nids_alt, 13867 .capsrc_nids = alc268_capsrc_nids, 13868 .hp_nid = 0x03, 13869 .dig_out_nid = ALC268_DIGOUT_NID, 13870 .num_channel_mode = ARRAY_SIZE(alc268_modes), 13871 .channel_mode = alc268_modes, 13872 .input_mux = &alc268_capture_source, 13873 }, 13874 [ALC268_TOSHIBA] = { 13875 .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer, 13876 alc268_beep_mixer }, 13877 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 13878 alc268_toshiba_verbs }, 13879 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 13880 .dac_nids = alc268_dac_nids, 13881 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 13882 .adc_nids = alc268_adc_nids_alt, 13883 .capsrc_nids = alc268_capsrc_nids, 13884 .hp_nid = 0x03, 13885 .num_channel_mode = ARRAY_SIZE(alc268_modes), 13886 .channel_mode = alc268_modes, 13887 .input_mux = &alc268_capture_source, 13888 .unsol_event = alc268_toshiba_unsol_event, 13889 .setup = alc268_toshiba_setup, 13890 .init_hook = alc268_toshiba_automute, 13891 }, 13892 [ALC268_ACER] = { 13893 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer, 13894 alc268_beep_mixer }, 13895 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 13896 alc268_acer_verbs }, 13897 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 13898 .dac_nids = alc268_dac_nids, 13899 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 13900 .adc_nids = alc268_adc_nids_alt, 13901 .capsrc_nids = alc268_capsrc_nids, 13902 .hp_nid = 0x02, 13903 .num_channel_mode = ARRAY_SIZE(alc268_modes), 13904 .channel_mode = alc268_modes, 13905 .input_mux = &alc268_acer_capture_source, 13906 .unsol_event = alc268_acer_unsol_event, 13907 .init_hook = alc268_acer_init_hook, 13908 }, 13909 [ALC268_ACER_DMIC] = { 13910 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer, 13911 alc268_beep_mixer }, 13912 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 13913 alc268_acer_verbs }, 13914 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 13915 .dac_nids = alc268_dac_nids, 13916 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 13917 .adc_nids = alc268_adc_nids_alt, 13918 .capsrc_nids = alc268_capsrc_nids, 13919 .hp_nid = 0x02, 13920 .num_channel_mode = ARRAY_SIZE(alc268_modes), 13921 .channel_mode = alc268_modes, 13922 .input_mux = &alc268_acer_dmic_capture_source, 13923 .unsol_event = alc268_acer_unsol_event, 13924 .init_hook = alc268_acer_init_hook, 13925 }, 13926 [ALC268_ACER_ASPIRE_ONE] = { 13927 .mixers = { alc268_acer_aspire_one_mixer, 13928 alc268_beep_mixer, 13929 alc268_capture_nosrc_mixer }, 13930 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 13931 alc268_acer_aspire_one_verbs }, 13932 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 13933 .dac_nids = alc268_dac_nids, 13934 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 13935 .adc_nids = alc268_adc_nids_alt, 13936 .capsrc_nids = alc268_capsrc_nids, 13937 .hp_nid = 0x03, 13938 .num_channel_mode = ARRAY_SIZE(alc268_modes), 13939 .channel_mode = alc268_modes, 13940 .unsol_event = alc268_acer_lc_unsol_event, 13941 .setup = alc268_acer_lc_setup, 13942 .init_hook = alc268_acer_lc_init_hook, 13943 }, 13944 [ALC268_DELL] = { 13945 .mixers = { alc268_dell_mixer, alc268_beep_mixer, 13946 alc268_capture_nosrc_mixer }, 13947 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 13948 alc268_dell_verbs }, 13949 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 13950 .dac_nids = alc268_dac_nids, 13951 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 13952 .adc_nids = alc268_adc_nids_alt, 13953 .capsrc_nids = alc268_capsrc_nids, 13954 .hp_nid = 0x02, 13955 .num_channel_mode = ARRAY_SIZE(alc268_modes), 13956 .channel_mode = alc268_modes, 13957 .unsol_event = alc_sku_unsol_event, 13958 .setup = alc268_dell_setup, 13959 .init_hook = alc_inithook, 13960 }, 13961 [ALC268_ZEPTO] = { 13962 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer, 13963 alc268_beep_mixer }, 13964 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 13965 alc268_toshiba_verbs }, 13966 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 13967 .dac_nids = alc268_dac_nids, 13968 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 13969 .adc_nids = alc268_adc_nids_alt, 13970 .capsrc_nids = alc268_capsrc_nids, 13971 .hp_nid = 0x03, 13972 .dig_out_nid = ALC268_DIGOUT_NID, 13973 .num_channel_mode = ARRAY_SIZE(alc268_modes), 13974 .channel_mode = alc268_modes, 13975 .input_mux = &alc268_capture_source, 13976 .setup = alc268_toshiba_setup, 13977 .init_hook = alc268_toshiba_automute, 13978 }, 13979#ifdef CONFIG_SND_DEBUG 13980 [ALC268_TEST] = { 13981 .mixers = { alc268_test_mixer, alc268_capture_mixer }, 13982 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 13983 alc268_volume_init_verbs }, 13984 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 13985 .dac_nids = alc268_dac_nids, 13986 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 13987 .adc_nids = alc268_adc_nids_alt, 13988 .capsrc_nids = alc268_capsrc_nids, 13989 .hp_nid = 0x03, 13990 .dig_out_nid = ALC268_DIGOUT_NID, 13991 .num_channel_mode = ARRAY_SIZE(alc268_modes), 13992 .channel_mode = alc268_modes, 13993 .input_mux = &alc268_capture_source, 13994 }, 13995#endif 13996}; 13997 13998static int patch_alc268(struct hda_codec *codec) 13999{ 14000 struct alc_spec *spec; 14001 int board_config; 14002 int i, has_beep, err; 14003 14004 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 14005 if (spec == NULL) 14006 return -ENOMEM; 14007 14008 codec->spec = spec; 14009 14010 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST, 14011 alc268_models, 14012 alc268_cfg_tbl); 14013 14014 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) 14015 board_config = snd_hda_check_board_codec_sid_config(codec, 14016 ALC268_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl); 14017 14018 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) { 14019 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 14020 codec->chip_name); 14021 board_config = ALC268_AUTO; 14022 } 14023 14024 if (board_config == ALC268_AUTO) { 14025 /* automatic parse from the BIOS config */ 14026 err = alc268_parse_auto_config(codec); 14027 if (err < 0) { 14028 alc_free(codec); 14029 return err; 14030 } else if (!err) { 14031 printk(KERN_INFO 14032 "hda_codec: Cannot set up configuration " 14033 "from BIOS. Using base mode...\n"); 14034 board_config = ALC268_3ST; 14035 } 14036 } 14037 14038 if (board_config != ALC268_AUTO) 14039 setup_preset(codec, &alc268_presets[board_config]); 14040 14041 spec->stream_analog_playback = &alc268_pcm_analog_playback; 14042 spec->stream_analog_capture = &alc268_pcm_analog_capture; 14043 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture; 14044 14045 spec->stream_digital_playback = &alc268_pcm_digital_playback; 14046 14047 has_beep = 0; 14048 for (i = 0; i < spec->num_mixers; i++) { 14049 if (spec->mixers[i] == alc268_beep_mixer) { 14050 has_beep = 1; 14051 break; 14052 } 14053 } 14054 14055 if (has_beep) { 14056 err = snd_hda_attach_beep_device(codec, 0x1); 14057 if (err < 0) { 14058 alc_free(codec); 14059 return err; 14060 } 14061 if (!query_amp_caps(codec, 0x1d, HDA_INPUT)) 14062 /* override the amp caps for beep generator */ 14063 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT, 14064 (0x0c << AC_AMPCAP_OFFSET_SHIFT) | 14065 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) | 14066 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) | 14067 (0 << AC_AMPCAP_MUTE_SHIFT)); 14068 } 14069 14070 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) { 14071 /* check whether NID 0x07 is valid */ 14072 unsigned int wcap = get_wcaps(codec, 0x07); 14073 int i; 14074 14075 spec->capsrc_nids = alc268_capsrc_nids; 14076 /* get type */ 14077 wcap = get_wcaps_type(wcap); 14078 if (spec->auto_mic || 14079 wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) { 14080 spec->adc_nids = alc268_adc_nids_alt; 14081 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt); 14082 if (spec->auto_mic) 14083 fixup_automic_adc(codec); 14084 if (spec->auto_mic || spec->input_mux->num_items == 1) 14085 add_mixer(spec, alc268_capture_nosrc_mixer); 14086 else 14087 add_mixer(spec, alc268_capture_alt_mixer); 14088 } else { 14089 spec->adc_nids = alc268_adc_nids; 14090 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids); 14091 add_mixer(spec, alc268_capture_mixer); 14092 } 14093 /* set default input source */ 14094 for (i = 0; i < spec->num_adc_nids; i++) 14095 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i], 14096 0, AC_VERB_SET_CONNECT_SEL, 14097 i < spec->num_mux_defs ? 14098 spec->input_mux[i].items[0].index : 14099 spec->input_mux->items[0].index); 14100 } 14101 14102 spec->vmaster_nid = 0x02; 14103 14104 codec->patch_ops = alc_patch_ops; 14105 if (board_config == ALC268_AUTO) 14106 spec->init_hook = alc268_auto_init; 14107 14108 alc_init_jacks(codec); 14109 14110 return 0; 14111} 14112 14113/* 14114 * ALC269 channel source setting (2 channel) 14115 */ 14116#define ALC269_DIGOUT_NID ALC880_DIGOUT_NID 14117 14118#define alc269_dac_nids alc260_dac_nids 14119 14120static hda_nid_t alc269_adc_nids[1] = { 14121 /* ADC1 */ 14122 0x08, 14123}; 14124 14125static hda_nid_t alc269_capsrc_nids[1] = { 14126 0x23, 14127}; 14128 14129static hda_nid_t alc269vb_adc_nids[1] = { 14130 /* ADC1 */ 14131 0x09, 14132}; 14133 14134static hda_nid_t alc269vb_capsrc_nids[1] = { 14135 0x22, 14136}; 14137 14138static hda_nid_t alc269_adc_candidates[] = { 14139 0x08, 0x09, 0x07, 14140}; 14141 14142#define alc269_modes alc260_modes 14143#define alc269_capture_source alc880_lg_lw_capture_source 14144 14145static struct snd_kcontrol_new alc269_base_mixer[] = { 14146 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 14147 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 14148 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 14149 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 14150 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 14151 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 14152 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 14153 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 14154 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 14155 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), 14156 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 14157 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT), 14158 { } /* end */ 14159}; 14160 14161static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = { 14162 /* output mixer control */ 14163 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), 14164 { 14165 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 14166 .name = "Master Playback Switch", 14167 .subdevice = HDA_SUBDEV_AMP_FLAG, 14168 .info = snd_hda_mixer_amp_switch_info, 14169 .get = snd_hda_mixer_amp_switch_get, 14170 .put = alc268_acer_master_sw_put, 14171 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 14172 }, 14173 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 14174 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 14175 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 14176 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 14177 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 14178 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), 14179 { } 14180}; 14181 14182static struct snd_kcontrol_new alc269_lifebook_mixer[] = { 14183 /* output mixer control */ 14184 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), 14185 { 14186 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 14187 .name = "Master Playback Switch", 14188 .subdevice = HDA_SUBDEV_AMP_FLAG, 14189 .info = snd_hda_mixer_amp_switch_info, 14190 .get = snd_hda_mixer_amp_switch_get, 14191 .put = alc268_acer_master_sw_put, 14192 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 14193 }, 14194 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 14195 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 14196 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 14197 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 14198 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 14199 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), 14200 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT), 14201 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT), 14202 HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x1b, 0, HDA_INPUT), 14203 { } 14204}; 14205 14206static struct snd_kcontrol_new alc269_laptop_mixer[] = { 14207 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 14208 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 14209 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 14210 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 14211 { } /* end */ 14212}; 14213 14214static struct snd_kcontrol_new alc269vb_laptop_mixer[] = { 14215 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 14216 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 14217 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT), 14218 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 14219 { } /* end */ 14220}; 14221 14222static struct snd_kcontrol_new alc269_asus_mixer[] = { 14223 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT), 14224 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x0, HDA_INPUT), 14225 { } /* end */ 14226}; 14227 14228/* capture mixer elements */ 14229static struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = { 14230 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 14231 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 14232 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 14233 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), 14234 { } /* end */ 14235}; 14236 14237static struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = { 14238 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 14239 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 14240 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 14241 { } /* end */ 14242}; 14243 14244static struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = { 14245 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), 14246 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), 14247 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 14248 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), 14249 { } /* end */ 14250}; 14251 14252static struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = { 14253 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), 14254 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), 14255 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 14256 { } /* end */ 14257}; 14258 14259/* FSC amilo */ 14260#define alc269_fujitsu_mixer alc269_laptop_mixer 14261 14262static struct hda_verb alc269_quanta_fl1_verbs[] = { 14263 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 14264 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14265 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 14266 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 14267 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 14268 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14269 { } 14270}; 14271 14272static struct hda_verb alc269_lifebook_verbs[] = { 14273 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 14274 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, 14275 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14276 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 14277 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 14278 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 14279 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 14280 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 14281 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 14282 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14283 { } 14284}; 14285 14286/* toggle speaker-output according to the hp-jack state */ 14287static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec) 14288{ 14289 unsigned int present; 14290 unsigned char bits; 14291 14292 present = snd_hda_jack_detect(codec, 0x15); 14293 bits = present ? HDA_AMP_MUTE : 0; 14294 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 14295 HDA_AMP_MUTE, bits); 14296 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 14297 HDA_AMP_MUTE, bits); 14298 14299 snd_hda_codec_write(codec, 0x20, 0, 14300 AC_VERB_SET_COEF_INDEX, 0x0c); 14301 snd_hda_codec_write(codec, 0x20, 0, 14302 AC_VERB_SET_PROC_COEF, 0x680); 14303 14304 snd_hda_codec_write(codec, 0x20, 0, 14305 AC_VERB_SET_COEF_INDEX, 0x0c); 14306 snd_hda_codec_write(codec, 0x20, 0, 14307 AC_VERB_SET_PROC_COEF, 0x480); 14308} 14309 14310/* toggle speaker-output according to the hp-jacks state */ 14311static void alc269_lifebook_speaker_automute(struct hda_codec *codec) 14312{ 14313 unsigned int present; 14314 unsigned char bits; 14315 14316 /* Check laptop headphone socket */ 14317 present = snd_hda_jack_detect(codec, 0x15); 14318 14319 /* Check port replicator headphone socket */ 14320 present |= snd_hda_jack_detect(codec, 0x1a); 14321 14322 bits = present ? HDA_AMP_MUTE : 0; 14323 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 14324 HDA_AMP_MUTE, bits); 14325 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 14326 HDA_AMP_MUTE, bits); 14327 14328 snd_hda_codec_write(codec, 0x20, 0, 14329 AC_VERB_SET_COEF_INDEX, 0x0c); 14330 snd_hda_codec_write(codec, 0x20, 0, 14331 AC_VERB_SET_PROC_COEF, 0x680); 14332 14333 snd_hda_codec_write(codec, 0x20, 0, 14334 AC_VERB_SET_COEF_INDEX, 0x0c); 14335 snd_hda_codec_write(codec, 0x20, 0, 14336 AC_VERB_SET_PROC_COEF, 0x480); 14337} 14338 14339static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec) 14340{ 14341 unsigned int present_laptop; 14342 unsigned int present_dock; 14343 14344 present_laptop = snd_hda_jack_detect(codec, 0x18); 14345 present_dock = snd_hda_jack_detect(codec, 0x1b); 14346 14347 /* Laptop mic port overrides dock mic port, design decision */ 14348 if (present_dock) 14349 snd_hda_codec_write(codec, 0x23, 0, 14350 AC_VERB_SET_CONNECT_SEL, 0x3); 14351 if (present_laptop) 14352 snd_hda_codec_write(codec, 0x23, 0, 14353 AC_VERB_SET_CONNECT_SEL, 0x0); 14354 if (!present_dock && !present_laptop) 14355 snd_hda_codec_write(codec, 0x23, 0, 14356 AC_VERB_SET_CONNECT_SEL, 0x1); 14357} 14358 14359static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec, 14360 unsigned int res) 14361{ 14362 switch (res >> 26) { 14363 case ALC880_HP_EVENT: 14364 alc269_quanta_fl1_speaker_automute(codec); 14365 break; 14366 case ALC880_MIC_EVENT: 14367 alc_mic_automute(codec); 14368 break; 14369 } 14370} 14371 14372static void alc269_lifebook_unsol_event(struct hda_codec *codec, 14373 unsigned int res) 14374{ 14375 if ((res >> 26) == ALC880_HP_EVENT) 14376 alc269_lifebook_speaker_automute(codec); 14377 if ((res >> 26) == ALC880_MIC_EVENT) 14378 alc269_lifebook_mic_autoswitch(codec); 14379} 14380 14381static void alc269_quanta_fl1_setup(struct hda_codec *codec) 14382{ 14383 struct alc_spec *spec = codec->spec; 14384 spec->autocfg.hp_pins[0] = 0x15; 14385 spec->autocfg.speaker_pins[0] = 0x14; 14386 spec->ext_mic.pin = 0x18; 14387 spec->ext_mic.mux_idx = 0; 14388 spec->int_mic.pin = 0x19; 14389 spec->int_mic.mux_idx = 1; 14390 spec->auto_mic = 1; 14391} 14392 14393static void alc269_quanta_fl1_init_hook(struct hda_codec *codec) 14394{ 14395 alc269_quanta_fl1_speaker_automute(codec); 14396 alc_mic_automute(codec); 14397} 14398 14399static void alc269_lifebook_init_hook(struct hda_codec *codec) 14400{ 14401 alc269_lifebook_speaker_automute(codec); 14402 alc269_lifebook_mic_autoswitch(codec); 14403} 14404 14405static struct hda_verb alc269_laptop_dmic_init_verbs[] = { 14406 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 14407 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05}, 14408 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 }, 14409 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))}, 14410 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14411 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 14412 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 14413 {} 14414}; 14415 14416static struct hda_verb alc269_laptop_amic_init_verbs[] = { 14417 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 14418 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01}, 14419 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 }, 14420 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))}, 14421 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 14422 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 14423 {} 14424}; 14425 14426static struct hda_verb alc269vb_laptop_dmic_init_verbs[] = { 14427 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, 14428 {0x22, AC_VERB_SET_CONNECT_SEL, 0x06}, 14429 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 }, 14430 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))}, 14431 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14432 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 14433 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 14434 {} 14435}; 14436 14437static struct hda_verb alc269vb_laptop_amic_init_verbs[] = { 14438 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, 14439 {0x22, AC_VERB_SET_CONNECT_SEL, 0x01}, 14440 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 }, 14441 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))}, 14442 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14443 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 14444 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 14445 {} 14446}; 14447 14448static struct hda_verb alc271_acer_dmic_verbs[] = { 14449 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d}, 14450 {0x20, AC_VERB_SET_PROC_COEF, 0x4000}, 14451 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14452 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 14453 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 14454 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 14455 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, 14456 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 14457 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 14458 {0x22, AC_VERB_SET_CONNECT_SEL, 6}, 14459 { } 14460}; 14461 14462/* toggle speaker-output according to the hp-jack state */ 14463static void alc269_speaker_automute(struct hda_codec *codec) 14464{ 14465 struct alc_spec *spec = codec->spec; 14466 unsigned int nid = spec->autocfg.hp_pins[0]; 14467 unsigned int present; 14468 unsigned char bits; 14469 14470 present = snd_hda_jack_detect(codec, nid); 14471 bits = present ? HDA_AMP_MUTE : 0; 14472 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 14473 HDA_AMP_MUTE, bits); 14474 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 14475 HDA_AMP_MUTE, bits); 14476 alc_report_jack(codec, nid); 14477} 14478 14479/* unsolicited event for HP jack sensing */ 14480static void alc269_laptop_unsol_event(struct hda_codec *codec, 14481 unsigned int res) 14482{ 14483 switch (res >> 26) { 14484 case ALC880_HP_EVENT: 14485 alc269_speaker_automute(codec); 14486 break; 14487 case ALC880_MIC_EVENT: 14488 alc_mic_automute(codec); 14489 break; 14490 } 14491} 14492 14493static void alc269_laptop_amic_setup(struct hda_codec *codec) 14494{ 14495 struct alc_spec *spec = codec->spec; 14496 spec->autocfg.hp_pins[0] = 0x15; 14497 spec->autocfg.speaker_pins[0] = 0x14; 14498 spec->ext_mic.pin = 0x18; 14499 spec->ext_mic.mux_idx = 0; 14500 spec->int_mic.pin = 0x19; 14501 spec->int_mic.mux_idx = 1; 14502 spec->auto_mic = 1; 14503} 14504 14505static void alc269_laptop_dmic_setup(struct hda_codec *codec) 14506{ 14507 struct alc_spec *spec = codec->spec; 14508 spec->autocfg.hp_pins[0] = 0x15; 14509 spec->autocfg.speaker_pins[0] = 0x14; 14510 spec->ext_mic.pin = 0x18; 14511 spec->ext_mic.mux_idx = 0; 14512 spec->int_mic.pin = 0x12; 14513 spec->int_mic.mux_idx = 5; 14514 spec->auto_mic = 1; 14515} 14516 14517static void alc269vb_laptop_amic_setup(struct hda_codec *codec) 14518{ 14519 struct alc_spec *spec = codec->spec; 14520 spec->autocfg.hp_pins[0] = 0x21; 14521 spec->autocfg.speaker_pins[0] = 0x14; 14522 spec->ext_mic.pin = 0x18; 14523 spec->ext_mic.mux_idx = 0; 14524 spec->int_mic.pin = 0x19; 14525 spec->int_mic.mux_idx = 1; 14526 spec->auto_mic = 1; 14527} 14528 14529static void alc269vb_laptop_dmic_setup(struct hda_codec *codec) 14530{ 14531 struct alc_spec *spec = codec->spec; 14532 spec->autocfg.hp_pins[0] = 0x21; 14533 spec->autocfg.speaker_pins[0] = 0x14; 14534 spec->ext_mic.pin = 0x18; 14535 spec->ext_mic.mux_idx = 0; 14536 spec->int_mic.pin = 0x12; 14537 spec->int_mic.mux_idx = 6; 14538 spec->auto_mic = 1; 14539} 14540 14541static void alc269_laptop_inithook(struct hda_codec *codec) 14542{ 14543 alc269_speaker_automute(codec); 14544 alc_mic_automute(codec); 14545} 14546 14547/* 14548 * generic initialization of ADC, input mixers and output mixers 14549 */ 14550static struct hda_verb alc269_init_verbs[] = { 14551 /* 14552 * Unmute ADC0 and set the default input to mic-in 14553 */ 14554 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14555 14556 /* 14557 * Set up output mixers (0x02 - 0x03) 14558 */ 14559 /* set vol=0 to output mixers */ 14560 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 14561 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 14562 14563 /* set up input amps for analog loopback */ 14564 /* Amp Indices: DAC = 0, mixer = 1 */ 14565 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14566 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 14567 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14568 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 14569 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14570 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 14571 14572 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 14573 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 14574 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 14575 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 14576 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 14577 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14578 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14579 14580 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 14581 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 14582 14583 /* FIXME: use Mux-type input source selection */ 14584 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */ 14585 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 14586 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00}, 14587 14588 /* set EAPD */ 14589 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 14590 { } 14591}; 14592 14593static struct hda_verb alc269vb_init_verbs[] = { 14594 /* 14595 * Unmute ADC0 and set the default input to mic-in 14596 */ 14597 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14598 14599 /* 14600 * Set up output mixers (0x02 - 0x03) 14601 */ 14602 /* set vol=0 to output mixers */ 14603 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 14604 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 14605 14606 /* set up input amps for analog loopback */ 14607 /* Amp Indices: DAC = 0, mixer = 1 */ 14608 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14609 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 14610 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14611 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 14612 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14613 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 14614 14615 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 14616 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 14617 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 14618 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 14619 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 14620 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14621 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14622 14623 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 14624 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 14625 14626 /* FIXME: use Mux-type input source selection */ 14627 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */ 14628 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 14629 {0x22, AC_VERB_SET_CONNECT_SEL, 0x00}, 14630 14631 /* set EAPD */ 14632 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 14633 { } 14634}; 14635 14636#define alc269_auto_create_multi_out_ctls \ 14637 alc268_auto_create_multi_out_ctls 14638#define alc269_auto_create_input_ctls \ 14639 alc268_auto_create_input_ctls 14640 14641#ifdef CONFIG_SND_HDA_POWER_SAVE 14642#define alc269_loopbacks alc880_loopbacks 14643#endif 14644 14645/* pcm configuration: identical with ALC880 */ 14646#define alc269_pcm_analog_playback alc880_pcm_analog_playback 14647#define alc269_pcm_analog_capture alc880_pcm_analog_capture 14648#define alc269_pcm_digital_playback alc880_pcm_digital_playback 14649#define alc269_pcm_digital_capture alc880_pcm_digital_capture 14650 14651static struct hda_pcm_stream alc269_44k_pcm_analog_playback = { 14652 .substreams = 1, 14653 .channels_min = 2, 14654 .channels_max = 8, 14655 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */ 14656 /* NID is set in alc_build_pcms */ 14657 .ops = { 14658 .open = alc880_playback_pcm_open, 14659 .prepare = alc880_playback_pcm_prepare, 14660 .cleanup = alc880_playback_pcm_cleanup 14661 }, 14662}; 14663 14664static struct hda_pcm_stream alc269_44k_pcm_analog_capture = { 14665 .substreams = 1, 14666 .channels_min = 2, 14667 .channels_max = 2, 14668 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */ 14669 /* NID is set in alc_build_pcms */ 14670}; 14671 14672#ifdef CONFIG_SND_HDA_POWER_SAVE 14673static int alc269_mic2_for_mute_led(struct hda_codec *codec) 14674{ 14675 switch (codec->subsystem_id) { 14676 case 0x103c1586: 14677 return 1; 14678 } 14679 return 0; 14680} 14681 14682static int alc269_mic2_mute_check_ps(struct hda_codec *codec, hda_nid_t nid) 14683{ 14684 /* update mute-LED according to the speaker mute state */ 14685 if (nid == 0x01 || nid == 0x14) { 14686 int pinval; 14687 if (snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0) & 14688 HDA_AMP_MUTE) 14689 pinval = 0x24; 14690 else 14691 pinval = 0x20; 14692 /* mic2 vref pin is used for mute LED control */ 14693 snd_hda_codec_update_cache(codec, 0x19, 0, 14694 AC_VERB_SET_PIN_WIDGET_CONTROL, 14695 pinval); 14696 } 14697 return alc_check_power_status(codec, nid); 14698} 14699#endif /* CONFIG_SND_HDA_POWER_SAVE */ 14700 14701static int alc275_setup_dual_adc(struct hda_codec *codec) 14702{ 14703 struct alc_spec *spec = codec->spec; 14704 14705 if (codec->vendor_id != 0x10ec0275 || !spec->auto_mic) 14706 return 0; 14707 if ((spec->ext_mic.pin >= 0x18 && spec->int_mic.pin <= 0x13) || 14708 (spec->ext_mic.pin <= 0x12 && spec->int_mic.pin >= 0x18)) { 14709 if (spec->ext_mic.pin <= 0x12) { 14710 spec->private_adc_nids[0] = 0x08; 14711 spec->private_adc_nids[1] = 0x11; 14712 spec->private_capsrc_nids[0] = 0x23; 14713 spec->private_capsrc_nids[1] = 0x22; 14714 } else { 14715 spec->private_adc_nids[0] = 0x11; 14716 spec->private_adc_nids[1] = 0x08; 14717 spec->private_capsrc_nids[0] = 0x22; 14718 spec->private_capsrc_nids[1] = 0x23; 14719 } 14720 spec->adc_nids = spec->private_adc_nids; 14721 spec->capsrc_nids = spec->private_capsrc_nids; 14722 spec->num_adc_nids = 2; 14723 spec->dual_adc_switch = 1; 14724 snd_printdd("realtek: enabling dual ADC switchg (%02x:%02x)\n", 14725 spec->adc_nids[0], spec->adc_nids[1]); 14726 return 1; 14727 } 14728 return 0; 14729} 14730 14731/* different alc269-variants */ 14732enum { 14733 ALC269_TYPE_NORMAL, 14734 ALC269_TYPE_ALC258, 14735 ALC269_TYPE_ALC259, 14736 ALC269_TYPE_ALC269VB, 14737 ALC269_TYPE_ALC270, 14738 ALC269_TYPE_ALC271X, 14739}; 14740 14741/* 14742 * BIOS auto configuration 14743 */ 14744static int alc269_parse_auto_config(struct hda_codec *codec) 14745{ 14746 struct alc_spec *spec = codec->spec; 14747 int err; 14748 static hda_nid_t alc269_ignore[] = { 0x1d, 0 }; 14749 14750 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 14751 alc269_ignore); 14752 if (err < 0) 14753 return err; 14754 14755 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg); 14756 if (err < 0) 14757 return err; 14758 if (spec->codec_variant == ALC269_TYPE_NORMAL) 14759 err = alc269_auto_create_input_ctls(codec, &spec->autocfg); 14760 else 14761 err = alc_auto_create_input_ctls(codec, &spec->autocfg, 0, 14762 0x22, 0); 14763 if (err < 0) 14764 return err; 14765 14766 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 14767 14768 alc_auto_parse_digital(codec); 14769 14770 if (spec->kctls.list) 14771 add_mixer(spec, spec->kctls.list); 14772 14773 if (spec->codec_variant != ALC269_TYPE_NORMAL) { 14774 add_verb(spec, alc269vb_init_verbs); 14775 alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21); 14776 } else { 14777 add_verb(spec, alc269_init_verbs); 14778 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); 14779 } 14780 14781 spec->num_mux_defs = 1; 14782 spec->input_mux = &spec->private_imux[0]; 14783 14784 if (!alc275_setup_dual_adc(codec)) 14785 fillup_priv_adc_nids(codec, alc269_adc_candidates, 14786 sizeof(alc269_adc_candidates)); 14787 14788 /* set default input source */ 14789 if (!spec->dual_adc_switch) 14790 select_or_unmute_capsrc(codec, spec->capsrc_nids[0], 14791 spec->input_mux->items[0].index); 14792 14793 err = alc_auto_add_mic_boost(codec); 14794 if (err < 0) 14795 return err; 14796 14797 if (!spec->cap_mixer && !spec->no_analog) 14798 set_capture_mixer(codec); 14799 14800 return 1; 14801} 14802 14803#define alc269_auto_init_multi_out alc268_auto_init_multi_out 14804#define alc269_auto_init_hp_out alc268_auto_init_hp_out 14805#define alc269_auto_init_analog_input alc882_auto_init_analog_input 14806 14807 14808/* init callback for auto-configuration model -- overriding the default init */ 14809static void alc269_auto_init(struct hda_codec *codec) 14810{ 14811 struct alc_spec *spec = codec->spec; 14812 alc269_auto_init_multi_out(codec); 14813 alc269_auto_init_hp_out(codec); 14814 alc269_auto_init_analog_input(codec); 14815 alc_auto_init_digital(codec); 14816 if (spec->unsol_event) 14817 alc_inithook(codec); 14818} 14819 14820#ifdef SND_HDA_NEEDS_RESUME 14821static void alc269_toggle_power_output(struct hda_codec *codec, int power_up) 14822{ 14823 int val = alc_read_coef_idx(codec, 0x04); 14824 if (power_up) 14825 val |= 1 << 11; 14826 else 14827 val &= ~(1 << 11); 14828 alc_write_coef_idx(codec, 0x04, val); 14829} 14830 14831#ifdef CONFIG_SND_HDA_POWER_SAVE 14832static int alc269_suspend(struct hda_codec *codec, pm_message_t state) 14833{ 14834 struct alc_spec *spec = codec->spec; 14835 14836 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) 14837 alc269_toggle_power_output(codec, 0); 14838 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) { 14839 alc269_toggle_power_output(codec, 0); 14840 msleep(150); 14841 } 14842 14843 alc_shutup(codec); 14844 if (spec && spec->power_hook) 14845 spec->power_hook(codec); 14846 return 0; 14847} 14848#endif /* CONFIG_SND_HDA_POWER_SAVE */ 14849 14850static int alc269_resume(struct hda_codec *codec) 14851{ 14852 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) { 14853 alc269_toggle_power_output(codec, 0); 14854 msleep(150); 14855 } 14856 14857 codec->patch_ops.init(codec); 14858 14859 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) { 14860 alc269_toggle_power_output(codec, 1); 14861 msleep(200); 14862 } 14863 14864 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) 14865 alc269_toggle_power_output(codec, 1); 14866 14867 snd_hda_codec_resume_amp(codec); 14868 snd_hda_codec_resume_cache(codec); 14869 hda_call_check_power_status(codec, 0x01); 14870 return 0; 14871} 14872#endif /* SND_HDA_NEEDS_RESUME */ 14873 14874static void alc269_fixup_hweq(struct hda_codec *codec, 14875 const struct alc_fixup *fix, int action) 14876{ 14877 int coef; 14878 14879 if (action != ALC_FIXUP_ACT_INIT) 14880 return; 14881 coef = alc_read_coef_idx(codec, 0x1e); 14882 alc_write_coef_idx(codec, 0x1e, coef | 0x80); 14883} 14884 14885enum { 14886 ALC269_FIXUP_SONY_VAIO, 14887 ALC275_FIXUP_SONY_VAIO_GPIO2, 14888 ALC269_FIXUP_DELL_M101Z, 14889 ALC269_FIXUP_SKU_IGNORE, 14890 ALC269_FIXUP_ASUS_G73JW, 14891 ALC269_FIXUP_LENOVO_EAPD, 14892 ALC275_FIXUP_SONY_HWEQ, 14893}; 14894 14895static const struct alc_fixup alc269_fixups[] = { 14896 [ALC269_FIXUP_SONY_VAIO] = { 14897 .type = ALC_FIXUP_VERBS, 14898 .v.verbs = (const struct hda_verb[]) { 14899 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD}, 14900 {} 14901 } 14902 }, 14903 [ALC275_FIXUP_SONY_VAIO_GPIO2] = { 14904 .type = ALC_FIXUP_VERBS, 14905 .v.verbs = (const struct hda_verb[]) { 14906 {0x01, AC_VERB_SET_GPIO_MASK, 0x04}, 14907 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04}, 14908 {0x01, AC_VERB_SET_GPIO_DATA, 0x00}, 14909 { } 14910 }, 14911 .chained = true, 14912 .chain_id = ALC269_FIXUP_SONY_VAIO 14913 }, 14914 [ALC269_FIXUP_DELL_M101Z] = { 14915 .type = ALC_FIXUP_VERBS, 14916 .v.verbs = (const struct hda_verb[]) { 14917 /* Enables internal speaker */ 14918 {0x20, AC_VERB_SET_COEF_INDEX, 13}, 14919 {0x20, AC_VERB_SET_PROC_COEF, 0x4040}, 14920 {} 14921 } 14922 }, 14923 [ALC269_FIXUP_SKU_IGNORE] = { 14924 .type = ALC_FIXUP_SKU, 14925 .v.sku = ALC_FIXUP_SKU_IGNORE, 14926 }, 14927 [ALC269_FIXUP_ASUS_G73JW] = { 14928 .type = ALC_FIXUP_PINS, 14929 .v.pins = (const struct alc_pincfg[]) { 14930 { 0x17, 0x99130111 }, /* subwoofer */ 14931 { } 14932 } 14933 }, 14934 [ALC269_FIXUP_LENOVO_EAPD] = { 14935 .type = ALC_FIXUP_VERBS, 14936 .v.verbs = (const struct hda_verb[]) { 14937 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0}, 14938 {} 14939 } 14940 }, 14941 [ALC275_FIXUP_SONY_HWEQ] = { 14942 .type = ALC_FIXUP_FUNC, 14943 .v.func = alc269_fixup_hweq, 14944 .chained = true, 14945 .chain_id = ALC275_FIXUP_SONY_VAIO_GPIO2 14946 } 14947}; 14948 14949static struct snd_pci_quirk alc269_fixup_tbl[] = { 14950 SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2), 14951 SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ), 14952 SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ), 14953 SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO), 14954 SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z), 14955 SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE), 14956 SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE), 14957 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW), 14958 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD), 14959 {} 14960}; 14961 14962 14963/* 14964 * configuration and preset 14965 */ 14966static const char * const alc269_models[ALC269_MODEL_LAST] = { 14967 [ALC269_BASIC] = "basic", 14968 [ALC269_QUANTA_FL1] = "quanta", 14969 [ALC269_AMIC] = "laptop-amic", 14970 [ALC269_DMIC] = "laptop-dmic", 14971 [ALC269_FUJITSU] = "fujitsu", 14972 [ALC269_LIFEBOOK] = "lifebook", 14973 [ALC269_AUTO] = "auto", 14974}; 14975 14976static struct snd_pci_quirk alc269_cfg_tbl[] = { 14977 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1), 14978 SND_PCI_QUIRK(0x1025, 0x047c, "ACER ZGA", ALC271_ACER), 14979 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A", 14980 ALC269_AMIC), 14981 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269VB_AMIC), 14982 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269VB_AMIC), 14983 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269VB_AMIC), 14984 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_AMIC), 14985 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269VB_AMIC), 14986 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269VB_AMIC), 14987 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269VB_AMIC), 14988 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269VB_AMIC), 14989 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_AMIC), 14990 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82Jv", ALC269_AMIC), 14991 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_AMIC), 14992 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_AMIC), 14993 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_AMIC), 14994 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_AMIC), 14995 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_AMIC), 14996 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_AMIC), 14997 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_AMIC), 14998 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_AMIC), 14999 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_AMIC), 15000 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_AMIC), 15001 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_AMIC), 15002 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_AMIC), 15003 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_AMIC), 15004 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_AMIC), 15005 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_AMIC), 15006 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_AMIC), 15007 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_AMIC), 15008 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_AMIC), 15009 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_AMIC), 15010 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_AMIC), 15011 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_AMIC), 15012 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_DMIC), 15013 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_AMIC), 15014 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_AMIC), 15015 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_AMIC), 15016 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_AMIC), 15017 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901", 15018 ALC269_DMIC), 15019 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101", 15020 ALC269_DMIC), 15021 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC), 15022 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC), 15023 SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_AUTO), 15024 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK), 15025 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC), 15026 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU), 15027 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_AMIC), 15028 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_AMIC), 15029 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_DMIC), 15030 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_DMIC), 15031 {} 15032}; 15033 15034static struct alc_config_preset alc269_presets[] = { 15035 [ALC269_BASIC] = { 15036 .mixers = { alc269_base_mixer }, 15037 .init_verbs = { alc269_init_verbs }, 15038 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 15039 .dac_nids = alc269_dac_nids, 15040 .hp_nid = 0x03, 15041 .num_channel_mode = ARRAY_SIZE(alc269_modes), 15042 .channel_mode = alc269_modes, 15043 .input_mux = &alc269_capture_source, 15044 }, 15045 [ALC269_QUANTA_FL1] = { 15046 .mixers = { alc269_quanta_fl1_mixer }, 15047 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs }, 15048 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 15049 .dac_nids = alc269_dac_nids, 15050 .hp_nid = 0x03, 15051 .num_channel_mode = ARRAY_SIZE(alc269_modes), 15052 .channel_mode = alc269_modes, 15053 .input_mux = &alc269_capture_source, 15054 .unsol_event = alc269_quanta_fl1_unsol_event, 15055 .setup = alc269_quanta_fl1_setup, 15056 .init_hook = alc269_quanta_fl1_init_hook, 15057 }, 15058 [ALC269_AMIC] = { 15059 .mixers = { alc269_laptop_mixer }, 15060 .cap_mixer = alc269_laptop_analog_capture_mixer, 15061 .init_verbs = { alc269_init_verbs, 15062 alc269_laptop_amic_init_verbs }, 15063 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 15064 .dac_nids = alc269_dac_nids, 15065 .hp_nid = 0x03, 15066 .num_channel_mode = ARRAY_SIZE(alc269_modes), 15067 .channel_mode = alc269_modes, 15068 .unsol_event = alc269_laptop_unsol_event, 15069 .setup = alc269_laptop_amic_setup, 15070 .init_hook = alc269_laptop_inithook, 15071 }, 15072 [ALC269_DMIC] = { 15073 .mixers = { alc269_laptop_mixer }, 15074 .cap_mixer = alc269_laptop_digital_capture_mixer, 15075 .init_verbs = { alc269_init_verbs, 15076 alc269_laptop_dmic_init_verbs }, 15077 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 15078 .dac_nids = alc269_dac_nids, 15079 .hp_nid = 0x03, 15080 .num_channel_mode = ARRAY_SIZE(alc269_modes), 15081 .channel_mode = alc269_modes, 15082 .unsol_event = alc269_laptop_unsol_event, 15083 .setup = alc269_laptop_dmic_setup, 15084 .init_hook = alc269_laptop_inithook, 15085 }, 15086 [ALC269VB_AMIC] = { 15087 .mixers = { alc269vb_laptop_mixer }, 15088 .cap_mixer = alc269vb_laptop_analog_capture_mixer, 15089 .init_verbs = { alc269vb_init_verbs, 15090 alc269vb_laptop_amic_init_verbs }, 15091 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 15092 .dac_nids = alc269_dac_nids, 15093 .hp_nid = 0x03, 15094 .num_channel_mode = ARRAY_SIZE(alc269_modes), 15095 .channel_mode = alc269_modes, 15096 .unsol_event = alc269_laptop_unsol_event, 15097 .setup = alc269vb_laptop_amic_setup, 15098 .init_hook = alc269_laptop_inithook, 15099 }, 15100 [ALC269VB_DMIC] = { 15101 .mixers = { alc269vb_laptop_mixer }, 15102 .cap_mixer = alc269vb_laptop_digital_capture_mixer, 15103 .init_verbs = { alc269vb_init_verbs, 15104 alc269vb_laptop_dmic_init_verbs }, 15105 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 15106 .dac_nids = alc269_dac_nids, 15107 .hp_nid = 0x03, 15108 .num_channel_mode = ARRAY_SIZE(alc269_modes), 15109 .channel_mode = alc269_modes, 15110 .unsol_event = alc269_laptop_unsol_event, 15111 .setup = alc269vb_laptop_dmic_setup, 15112 .init_hook = alc269_laptop_inithook, 15113 }, 15114 [ALC269_FUJITSU] = { 15115 .mixers = { alc269_fujitsu_mixer }, 15116 .cap_mixer = alc269_laptop_digital_capture_mixer, 15117 .init_verbs = { alc269_init_verbs, 15118 alc269_laptop_dmic_init_verbs }, 15119 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 15120 .dac_nids = alc269_dac_nids, 15121 .hp_nid = 0x03, 15122 .num_channel_mode = ARRAY_SIZE(alc269_modes), 15123 .channel_mode = alc269_modes, 15124 .unsol_event = alc269_laptop_unsol_event, 15125 .setup = alc269_laptop_dmic_setup, 15126 .init_hook = alc269_laptop_inithook, 15127 }, 15128 [ALC269_LIFEBOOK] = { 15129 .mixers = { alc269_lifebook_mixer }, 15130 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs }, 15131 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 15132 .dac_nids = alc269_dac_nids, 15133 .hp_nid = 0x03, 15134 .num_channel_mode = ARRAY_SIZE(alc269_modes), 15135 .channel_mode = alc269_modes, 15136 .input_mux = &alc269_capture_source, 15137 .unsol_event = alc269_lifebook_unsol_event, 15138 .init_hook = alc269_lifebook_init_hook, 15139 }, 15140 [ALC271_ACER] = { 15141 .mixers = { alc269_asus_mixer }, 15142 .cap_mixer = alc269vb_laptop_digital_capture_mixer, 15143 .init_verbs = { alc269_init_verbs, alc271_acer_dmic_verbs }, 15144 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 15145 .dac_nids = alc269_dac_nids, 15146 .adc_nids = alc262_dmic_adc_nids, 15147 .num_adc_nids = ARRAY_SIZE(alc262_dmic_adc_nids), 15148 .capsrc_nids = alc262_dmic_capsrc_nids, 15149 .num_channel_mode = ARRAY_SIZE(alc269_modes), 15150 .channel_mode = alc269_modes, 15151 .input_mux = &alc269_capture_source, 15152 .dig_out_nid = ALC880_DIGOUT_NID, 15153 .unsol_event = alc_sku_unsol_event, 15154 .setup = alc269vb_laptop_dmic_setup, 15155 .init_hook = alc_inithook, 15156 }, 15157}; 15158 15159static int alc269_fill_coef(struct hda_codec *codec) 15160{ 15161 int val; 15162 15163 if ((alc_read_coef_idx(codec, 0) & 0x00ff) < 0x015) { 15164 alc_write_coef_idx(codec, 0xf, 0x960b); 15165 alc_write_coef_idx(codec, 0xe, 0x8817); 15166 } 15167 15168 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x016) { 15169 alc_write_coef_idx(codec, 0xf, 0x960b); 15170 alc_write_coef_idx(codec, 0xe, 0x8814); 15171 } 15172 15173 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) { 15174 val = alc_read_coef_idx(codec, 0x04); 15175 /* Power up output pin */ 15176 alc_write_coef_idx(codec, 0x04, val | (1<<11)); 15177 } 15178 15179 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) { 15180 val = alc_read_coef_idx(codec, 0xd); 15181 if ((val & 0x0c00) >> 10 != 0x1) { 15182 /* Capless ramp up clock control */ 15183 alc_write_coef_idx(codec, 0xd, val | 1<<10); 15184 } 15185 val = alc_read_coef_idx(codec, 0x17); 15186 if ((val & 0x01c0) >> 6 != 0x4) { 15187 /* Class D power on reset */ 15188 alc_write_coef_idx(codec, 0x17, val | 1<<7); 15189 } 15190 } 15191 return 0; 15192} 15193 15194static int patch_alc269(struct hda_codec *codec) 15195{ 15196 struct alc_spec *spec; 15197 int board_config, coef; 15198 int err; 15199 15200 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 15201 if (spec == NULL) 15202 return -ENOMEM; 15203 15204 codec->spec = spec; 15205 15206 alc_auto_parse_customize_define(codec); 15207 15208 if (codec->vendor_id == 0x10ec0269) { 15209 coef = alc_read_coef_idx(codec, 0); 15210 if ((coef & 0x00f0) == 0x0010) { 15211 if (codec->bus->pci->subsystem_vendor == 0x1025 && 15212 spec->cdefine.platform_type == 1) { 15213 alc_codec_rename(codec, "ALC271X"); 15214 spec->codec_variant = ALC269_TYPE_ALC271X; 15215 } else if ((coef & 0xf000) == 0x1000) { 15216 spec->codec_variant = ALC269_TYPE_ALC270; 15217 } else if ((coef & 0xf000) == 0x2000) { 15218 alc_codec_rename(codec, "ALC259"); 15219 spec->codec_variant = ALC269_TYPE_ALC259; 15220 } else if ((coef & 0xf000) == 0x3000) { 15221 alc_codec_rename(codec, "ALC258"); 15222 spec->codec_variant = ALC269_TYPE_ALC258; 15223 } else { 15224 alc_codec_rename(codec, "ALC269VB"); 15225 spec->codec_variant = ALC269_TYPE_ALC269VB; 15226 } 15227 } else 15228 alc_fix_pll_init(codec, 0x20, 0x04, 15); 15229 alc269_fill_coef(codec); 15230 } 15231 15232 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST, 15233 alc269_models, 15234 alc269_cfg_tbl); 15235 15236 if (board_config < 0) { 15237 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 15238 codec->chip_name); 15239 board_config = ALC269_AUTO; 15240 } 15241 15242 if (board_config == ALC269_AUTO) { 15243 alc_pick_fixup(codec, NULL, alc269_fixup_tbl, alc269_fixups); 15244 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); 15245 } 15246 15247 if (board_config == ALC269_AUTO) { 15248 /* automatic parse from the BIOS config */ 15249 err = alc269_parse_auto_config(codec); 15250 if (err < 0) { 15251 alc_free(codec); 15252 return err; 15253 } else if (!err) { 15254 printk(KERN_INFO 15255 "hda_codec: Cannot set up configuration " 15256 "from BIOS. Using base mode...\n"); 15257 board_config = ALC269_BASIC; 15258 } 15259 } 15260 15261 if (has_cdefine_beep(codec)) { 15262 err = snd_hda_attach_beep_device(codec, 0x1); 15263 if (err < 0) { 15264 alc_free(codec); 15265 return err; 15266 } 15267 } 15268 15269 if (board_config != ALC269_AUTO) 15270 setup_preset(codec, &alc269_presets[board_config]); 15271 15272 if (board_config == ALC269_QUANTA_FL1) { 15273 /* Due to a hardware problem on Lenovo Ideadpad, we need to 15274 * fix the sample rate of analog I/O to 44.1kHz 15275 */ 15276 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback; 15277 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture; 15278 } else if (spec->dual_adc_switch) { 15279 spec->stream_analog_playback = &alc269_pcm_analog_playback; 15280 /* switch ADC dynamically */ 15281 spec->stream_analog_capture = &dualmic_pcm_analog_capture; 15282 } else { 15283 spec->stream_analog_playback = &alc269_pcm_analog_playback; 15284 spec->stream_analog_capture = &alc269_pcm_analog_capture; 15285 } 15286 spec->stream_digital_playback = &alc269_pcm_digital_playback; 15287 spec->stream_digital_capture = &alc269_pcm_digital_capture; 15288 15289 if (!spec->adc_nids) { /* wasn't filled automatically? use default */ 15290 if (spec->codec_variant == ALC269_TYPE_NORMAL) { 15291 spec->adc_nids = alc269_adc_nids; 15292 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids); 15293 spec->capsrc_nids = alc269_capsrc_nids; 15294 } else { 15295 spec->adc_nids = alc269vb_adc_nids; 15296 spec->num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids); 15297 spec->capsrc_nids = alc269vb_capsrc_nids; 15298 } 15299 } 15300 15301 if (!spec->cap_mixer) 15302 set_capture_mixer(codec); 15303 if (has_cdefine_beep(codec)) 15304 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); 15305 15306 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); 15307 15308 spec->vmaster_nid = 0x02; 15309 15310 codec->patch_ops = alc_patch_ops; 15311#ifdef CONFIG_SND_HDA_POWER_SAVE 15312 codec->patch_ops.suspend = alc269_suspend; 15313#endif 15314#ifdef SND_HDA_NEEDS_RESUME 15315 codec->patch_ops.resume = alc269_resume; 15316#endif 15317 if (board_config == ALC269_AUTO) 15318 spec->init_hook = alc269_auto_init; 15319 15320 alc_init_jacks(codec); 15321#ifdef CONFIG_SND_HDA_POWER_SAVE 15322 if (!spec->loopback.amplist) 15323 spec->loopback.amplist = alc269_loopbacks; 15324 if (alc269_mic2_for_mute_led(codec)) 15325 codec->patch_ops.check_power_status = alc269_mic2_mute_check_ps; 15326#endif 15327 15328 return 0; 15329} 15330 15331/* 15332 * ALC861 channel source setting (2/6 channel selection for 3-stack) 15333 */ 15334 15335/* 15336 * set the path ways for 2 channel output 15337 * need to set the codec line out and mic 1 pin widgets to inputs 15338 */ 15339static struct hda_verb alc861_threestack_ch2_init[] = { 15340 /* set pin widget 1Ah (line in) for input */ 15341 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 15342 /* set pin widget 18h (mic1/2) for input, for mic also enable 15343 * the vref 15344 */ 15345 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15346 15347 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, 15348#if 0 15349 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/ 15350 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/ 15351#endif 15352 { } /* end */ 15353}; 15354/* 15355 * 6ch mode 15356 * need to set the codec line out and mic 1 pin widgets to outputs 15357 */ 15358static struct hda_verb alc861_threestack_ch6_init[] = { 15359 /* set pin widget 1Ah (line in) for output (Back Surround)*/ 15360 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15361 /* set pin widget 18h (mic1) for output (CLFE)*/ 15362 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15363 15364 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15365 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15366 15367 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 }, 15368#if 0 15369 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/ 15370 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/ 15371#endif 15372 { } /* end */ 15373}; 15374 15375static struct hda_channel_mode alc861_threestack_modes[2] = { 15376 { 2, alc861_threestack_ch2_init }, 15377 { 6, alc861_threestack_ch6_init }, 15378}; 15379/* Set mic1 as input and unmute the mixer */ 15380static struct hda_verb alc861_uniwill_m31_ch2_init[] = { 15381 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15382 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/ 15383 { } /* end */ 15384}; 15385/* Set mic1 as output and mute mixer */ 15386static struct hda_verb alc861_uniwill_m31_ch4_init[] = { 15387 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15388 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/ 15389 { } /* end */ 15390}; 15391 15392static struct hda_channel_mode alc861_uniwill_m31_modes[2] = { 15393 { 2, alc861_uniwill_m31_ch2_init }, 15394 { 4, alc861_uniwill_m31_ch4_init }, 15395}; 15396 15397/* Set mic1 and line-in as input and unmute the mixer */ 15398static struct hda_verb alc861_asus_ch2_init[] = { 15399 /* set pin widget 1Ah (line in) for input */ 15400 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 15401 /* set pin widget 18h (mic1/2) for input, for mic also enable 15402 * the vref 15403 */ 15404 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15405 15406 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, 15407#if 0 15408 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/ 15409 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/ 15410#endif 15411 { } /* end */ 15412}; 15413/* Set mic1 nad line-in as output and mute mixer */ 15414static struct hda_verb alc861_asus_ch6_init[] = { 15415 /* set pin widget 1Ah (line in) for output (Back Surround)*/ 15416 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15417 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */ 15418 /* set pin widget 18h (mic1) for output (CLFE)*/ 15419 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15420 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */ 15421 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15422 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15423 15424 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 }, 15425#if 0 15426 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/ 15427 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/ 15428#endif 15429 { } /* end */ 15430}; 15431 15432static struct hda_channel_mode alc861_asus_modes[2] = { 15433 { 2, alc861_asus_ch2_init }, 15434 { 6, alc861_asus_ch6_init }, 15435}; 15436 15437/* patch-ALC861 */ 15438 15439static struct snd_kcontrol_new alc861_base_mixer[] = { 15440 /* output mixer control */ 15441 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), 15442 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), 15443 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT), 15444 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT), 15445 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), 15446 15447 /*Input mixer control */ 15448 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT), 15449 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */ 15450 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), 15451 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), 15452 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT), 15453 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT), 15454 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), 15455 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), 15456 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), 15457 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT), 15458 15459 { } /* end */ 15460}; 15461 15462static struct snd_kcontrol_new alc861_3ST_mixer[] = { 15463 /* output mixer control */ 15464 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), 15465 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), 15466 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT), 15467 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT), 15468 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */ 15469 15470 /* Input mixer control */ 15471 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT), 15472 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */ 15473 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), 15474 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), 15475 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT), 15476 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT), 15477 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), 15478 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), 15479 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), 15480 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT), 15481 15482 { 15483 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 15484 .name = "Channel Mode", 15485 .info = alc_ch_mode_info, 15486 .get = alc_ch_mode_get, 15487 .put = alc_ch_mode_put, 15488 .private_value = ARRAY_SIZE(alc861_threestack_modes), 15489 }, 15490 { } /* end */ 15491}; 15492 15493static struct snd_kcontrol_new alc861_toshiba_mixer[] = { 15494 /* output mixer control */ 15495 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT), 15496 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), 15497 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), 15498 15499 { } /* end */ 15500}; 15501 15502static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = { 15503 /* output mixer control */ 15504 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), 15505 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), 15506 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT), 15507 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT), 15508 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */ 15509 15510 /* Input mixer control */ 15511 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT), 15512 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */ 15513 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), 15514 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), 15515 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT), 15516 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT), 15517 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), 15518 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), 15519 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), 15520 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT), 15521 15522 { 15523 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 15524 .name = "Channel Mode", 15525 .info = alc_ch_mode_info, 15526 .get = alc_ch_mode_get, 15527 .put = alc_ch_mode_put, 15528 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes), 15529 }, 15530 { } /* end */ 15531}; 15532 15533static struct snd_kcontrol_new alc861_asus_mixer[] = { 15534 /* output mixer control */ 15535 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), 15536 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), 15537 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT), 15538 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT), 15539 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), 15540 15541 /* Input mixer control */ 15542 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT), 15543 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), 15544 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), 15545 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), 15546 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT), 15547 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT), 15548 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), 15549 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), 15550 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), 15551 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT), 15552 15553 { 15554 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 15555 .name = "Channel Mode", 15556 .info = alc_ch_mode_info, 15557 .get = alc_ch_mode_get, 15558 .put = alc_ch_mode_put, 15559 .private_value = ARRAY_SIZE(alc861_asus_modes), 15560 }, 15561 { } 15562}; 15563 15564/* additional mixer */ 15565static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = { 15566 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), 15567 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), 15568 { } 15569}; 15570 15571/* 15572 * generic initialization of ADC, input mixers and output mixers 15573 */ 15574static struct hda_verb alc861_base_init_verbs[] = { 15575 /* 15576 * Unmute ADC0 and set the default input to mic-in 15577 */ 15578 /* port-A for surround (rear panel) */ 15579 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15580 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15581 /* port-B for mic-in (rear panel) with vref */ 15582 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15583 /* port-C for line-in (rear panel) */ 15584 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 15585 /* port-D for Front */ 15586 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15587 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15588 /* port-E for HP out (front panel) */ 15589 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, 15590 /* route front PCM to HP */ 15591 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15592 /* port-F for mic-in (front panel) with vref */ 15593 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15594 /* port-G for CLFE (rear panel) */ 15595 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15596 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15597 /* port-H for side (rear panel) */ 15598 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15599 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15600 /* CD-in */ 15601 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 15602 /* route front mic to ADC1*/ 15603 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 15604 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15605 15606 /* Unmute DAC0~3 & spdif out*/ 15607 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15608 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15609 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15610 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15611 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15612 15613 /* Unmute Mixer 14 (mic) 1c (Line in)*/ 15614 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15615 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15616 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15617 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15618 15619 /* Unmute Stereo Mixer 15 */ 15620 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15621 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15622 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 15623 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */ 15624 15625 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15626 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15627 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15628 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15629 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15630 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15631 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15632 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15633 /* hp used DAC 3 (Front) */ 15634 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 15635 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 15636 15637 { } 15638}; 15639 15640static struct hda_verb alc861_threestack_init_verbs[] = { 15641 /* 15642 * Unmute ADC0 and set the default input to mic-in 15643 */ 15644 /* port-A for surround (rear panel) */ 15645 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 15646 /* port-B for mic-in (rear panel) with vref */ 15647 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15648 /* port-C for line-in (rear panel) */ 15649 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 15650 /* port-D for Front */ 15651 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15652 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15653 /* port-E for HP out (front panel) */ 15654 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, 15655 /* route front PCM to HP */ 15656 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15657 /* port-F for mic-in (front panel) with vref */ 15658 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15659 /* port-G for CLFE (rear panel) */ 15660 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 15661 /* port-H for side (rear panel) */ 15662 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 15663 /* CD-in */ 15664 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 15665 /* route front mic to ADC1*/ 15666 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 15667 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15668 /* Unmute DAC0~3 & spdif out*/ 15669 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15670 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15671 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15672 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15673 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15674 15675 /* Unmute Mixer 14 (mic) 1c (Line in)*/ 15676 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15677 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15678 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15679 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15680 15681 /* Unmute Stereo Mixer 15 */ 15682 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15683 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15684 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 15685 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */ 15686 15687 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15688 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15689 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15690 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15691 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15692 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15693 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15694 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15695 /* hp used DAC 3 (Front) */ 15696 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 15697 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 15698 { } 15699}; 15700 15701static struct hda_verb alc861_uniwill_m31_init_verbs[] = { 15702 /* 15703 * Unmute ADC0 and set the default input to mic-in 15704 */ 15705 /* port-A for surround (rear panel) */ 15706 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 15707 /* port-B for mic-in (rear panel) with vref */ 15708 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15709 /* port-C for line-in (rear panel) */ 15710 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 15711 /* port-D for Front */ 15712 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15713 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15714 /* port-E for HP out (front panel) */ 15715 /* this has to be set to VREF80 */ 15716 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15717 /* route front PCM to HP */ 15718 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15719 /* port-F for mic-in (front panel) with vref */ 15720 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15721 /* port-G for CLFE (rear panel) */ 15722 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 15723 /* port-H for side (rear panel) */ 15724 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 15725 /* CD-in */ 15726 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 15727 /* route front mic to ADC1*/ 15728 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 15729 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15730 /* Unmute DAC0~3 & spdif out*/ 15731 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15732 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15733 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15734 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15735 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15736 15737 /* Unmute Mixer 14 (mic) 1c (Line in)*/ 15738 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15739 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15740 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15741 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15742 15743 /* Unmute Stereo Mixer 15 */ 15744 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15745 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15746 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 15747 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */ 15748 15749 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15750 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15751 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15752 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15753 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15754 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15755 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15756 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15757 /* hp used DAC 3 (Front) */ 15758 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 15759 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 15760 { } 15761}; 15762 15763static struct hda_verb alc861_asus_init_verbs[] = { 15764 /* 15765 * Unmute ADC0 and set the default input to mic-in 15766 */ 15767 /* port-A for surround (rear panel) 15768 * according to codec#0 this is the HP jack 15769 */ 15770 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */ 15771 /* route front PCM to HP */ 15772 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 }, 15773 /* port-B for mic-in (rear panel) with vref */ 15774 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15775 /* port-C for line-in (rear panel) */ 15776 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 15777 /* port-D for Front */ 15778 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15779 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15780 /* port-E for HP out (front panel) */ 15781 /* this has to be set to VREF80 */ 15782 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15783 /* route front PCM to HP */ 15784 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15785 /* port-F for mic-in (front panel) with vref */ 15786 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15787 /* port-G for CLFE (rear panel) */ 15788 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15789 /* port-H for side (rear panel) */ 15790 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15791 /* CD-in */ 15792 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 15793 /* route front mic to ADC1*/ 15794 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 15795 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15796 /* Unmute DAC0~3 & spdif out*/ 15797 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15798 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15799 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15800 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15801 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15802 /* Unmute Mixer 14 (mic) 1c (Line in)*/ 15803 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15804 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15805 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15806 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15807 15808 /* Unmute Stereo Mixer 15 */ 15809 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15810 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15811 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 15812 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */ 15813 15814 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15815 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15816 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15817 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15818 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15819 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15820 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15821 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15822 /* hp used DAC 3 (Front) */ 15823 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 15824 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 15825 { } 15826}; 15827 15828/* additional init verbs for ASUS laptops */ 15829static struct hda_verb alc861_asus_laptop_init_verbs[] = { 15830 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */ 15831 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */ 15832 { } 15833}; 15834 15835/* 15836 * generic initialization of ADC, input mixers and output mixers 15837 */ 15838static struct hda_verb alc861_auto_init_verbs[] = { 15839 /* 15840 * Unmute ADC0 and set the default input to mic-in 15841 */ 15842 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */ 15843 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15844 15845 /* Unmute DAC0~3 & spdif out*/ 15846 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 15847 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 15848 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 15849 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 15850 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15851 15852 /* Unmute Mixer 14 (mic) 1c (Line in)*/ 15853 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15854 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15855 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15856 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15857 15858 /* Unmute Stereo Mixer 15 */ 15859 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15860 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15861 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 15862 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, 15863 15864 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 15865 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 15866 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 15867 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 15868 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 15869 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 15870 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 15871 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 15872 15873 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 15874 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 15875 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 15876 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 15877 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 15878 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 15879 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 15880 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 15881 15882 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */ 15883 15884 { } 15885}; 15886 15887static struct hda_verb alc861_toshiba_init_verbs[] = { 15888 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 15889 15890 { } 15891}; 15892 15893/* toggle speaker-output according to the hp-jack state */ 15894static void alc861_toshiba_automute(struct hda_codec *codec) 15895{ 15896 unsigned int present = snd_hda_jack_detect(codec, 0x0f); 15897 15898 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0, 15899 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 15900 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3, 15901 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE); 15902} 15903 15904static void alc861_toshiba_unsol_event(struct hda_codec *codec, 15905 unsigned int res) 15906{ 15907 if ((res >> 26) == ALC880_HP_EVENT) 15908 alc861_toshiba_automute(codec); 15909} 15910 15911/* pcm configuration: identical with ALC880 */ 15912#define alc861_pcm_analog_playback alc880_pcm_analog_playback 15913#define alc861_pcm_analog_capture alc880_pcm_analog_capture 15914#define alc861_pcm_digital_playback alc880_pcm_digital_playback 15915#define alc861_pcm_digital_capture alc880_pcm_digital_capture 15916 15917 15918#define ALC861_DIGOUT_NID 0x07 15919 15920static struct hda_channel_mode alc861_8ch_modes[1] = { 15921 { 8, NULL } 15922}; 15923 15924static hda_nid_t alc861_dac_nids[4] = { 15925 /* front, surround, clfe, side */ 15926 0x03, 0x06, 0x05, 0x04 15927}; 15928 15929static hda_nid_t alc660_dac_nids[3] = { 15930 /* front, clfe, surround */ 15931 0x03, 0x05, 0x06 15932}; 15933 15934static hda_nid_t alc861_adc_nids[1] = { 15935 /* ADC0-2 */ 15936 0x08, 15937}; 15938 15939static struct hda_input_mux alc861_capture_source = { 15940 .num_items = 5, 15941 .items = { 15942 { "Mic", 0x0 }, 15943 { "Front Mic", 0x3 }, 15944 { "Line", 0x1 }, 15945 { "CD", 0x4 }, 15946 { "Mixer", 0x5 }, 15947 }, 15948}; 15949 15950static hda_nid_t alc861_look_for_dac(struct hda_codec *codec, hda_nid_t pin) 15951{ 15952 struct alc_spec *spec = codec->spec; 15953 hda_nid_t mix, srcs[5]; 15954 int i, j, num; 15955 15956 if (snd_hda_get_connections(codec, pin, &mix, 1) != 1) 15957 return 0; 15958 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs)); 15959 if (num < 0) 15960 return 0; 15961 for (i = 0; i < num; i++) { 15962 unsigned int type; 15963 type = get_wcaps_type(get_wcaps(codec, srcs[i])); 15964 if (type != AC_WID_AUD_OUT) 15965 continue; 15966 for (j = 0; j < spec->multiout.num_dacs; j++) 15967 if (spec->multiout.dac_nids[j] == srcs[i]) 15968 break; 15969 if (j >= spec->multiout.num_dacs) 15970 return srcs[i]; 15971 } 15972 return 0; 15973} 15974 15975/* fill in the dac_nids table from the parsed pin configuration */ 15976static int alc861_auto_fill_dac_nids(struct hda_codec *codec, 15977 const struct auto_pin_cfg *cfg) 15978{ 15979 struct alc_spec *spec = codec->spec; 15980 int i; 15981 hda_nid_t nid, dac; 15982 15983 spec->multiout.dac_nids = spec->private_dac_nids; 15984 for (i = 0; i < cfg->line_outs; i++) { 15985 nid = cfg->line_out_pins[i]; 15986 dac = alc861_look_for_dac(codec, nid); 15987 if (!dac) 15988 continue; 15989 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac; 15990 } 15991 return 0; 15992} 15993 15994static int __alc861_create_out_sw(struct hda_codec *codec, const char *pfx, 15995 hda_nid_t nid, int idx, unsigned int chs) 15996{ 15997 return __add_pb_sw_ctrl(codec->spec, ALC_CTL_WIDGET_MUTE, pfx, idx, 15998 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT)); 15999} 16000 16001#define alc861_create_out_sw(codec, pfx, nid, chs) \ 16002 __alc861_create_out_sw(codec, pfx, nid, 0, chs) 16003 16004/* add playback controls from the parsed DAC table */ 16005static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec, 16006 const struct auto_pin_cfg *cfg) 16007{ 16008 struct alc_spec *spec = codec->spec; 16009 static const char * const chname[4] = { 16010 "Front", "Surround", NULL /*CLFE*/, "Side" 16011 }; 16012 const char *pfx = alc_get_line_out_pfx(cfg, true); 16013 hda_nid_t nid; 16014 int i, err; 16015 16016 for (i = 0; i < cfg->line_outs; i++) { 16017 nid = spec->multiout.dac_nids[i]; 16018 if (!nid) 16019 continue; 16020 if (!pfx && i == 2) { 16021 /* Center/LFE */ 16022 err = alc861_create_out_sw(codec, "Center", nid, 1); 16023 if (err < 0) 16024 return err; 16025 err = alc861_create_out_sw(codec, "LFE", nid, 2); 16026 if (err < 0) 16027 return err; 16028 } else { 16029 const char *name = pfx; 16030 if (!name) 16031 name = chname[i]; 16032 err = __alc861_create_out_sw(codec, name, nid, i, 3); 16033 if (err < 0) 16034 return err; 16035 } 16036 } 16037 return 0; 16038} 16039 16040static int alc861_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin) 16041{ 16042 struct alc_spec *spec = codec->spec; 16043 int err; 16044 hda_nid_t nid; 16045 16046 if (!pin) 16047 return 0; 16048 16049 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) { 16050 nid = alc861_look_for_dac(codec, pin); 16051 if (nid) { 16052 err = alc861_create_out_sw(codec, "Headphone", nid, 3); 16053 if (err < 0) 16054 return err; 16055 spec->multiout.hp_nid = nid; 16056 } 16057 } 16058 return 0; 16059} 16060 16061/* create playback/capture controls for input pins */ 16062static int alc861_auto_create_input_ctls(struct hda_codec *codec, 16063 const struct auto_pin_cfg *cfg) 16064{ 16065 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x08, 0); 16066} 16067 16068static void alc861_auto_set_output_and_unmute(struct hda_codec *codec, 16069 hda_nid_t nid, 16070 int pin_type, hda_nid_t dac) 16071{ 16072 hda_nid_t mix, srcs[5]; 16073 int i, num; 16074 16075 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 16076 pin_type); 16077 snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE, 16078 AMP_OUT_UNMUTE); 16079 if (snd_hda_get_connections(codec, nid, &mix, 1) != 1) 16080 return; 16081 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs)); 16082 if (num < 0) 16083 return; 16084 for (i = 0; i < num; i++) { 16085 unsigned int mute; 16086 if (srcs[i] == dac || srcs[i] == 0x15) 16087 mute = AMP_IN_UNMUTE(i); 16088 else 16089 mute = AMP_IN_MUTE(i); 16090 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE, 16091 mute); 16092 } 16093} 16094 16095static void alc861_auto_init_multi_out(struct hda_codec *codec) 16096{ 16097 struct alc_spec *spec = codec->spec; 16098 int i; 16099 16100 for (i = 0; i < spec->autocfg.line_outs; i++) { 16101 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 16102 int pin_type = get_pin_type(spec->autocfg.line_out_type); 16103 if (nid) 16104 alc861_auto_set_output_and_unmute(codec, nid, pin_type, 16105 spec->multiout.dac_nids[i]); 16106 } 16107} 16108 16109static void alc861_auto_init_hp_out(struct hda_codec *codec) 16110{ 16111 struct alc_spec *spec = codec->spec; 16112 16113 if (spec->autocfg.hp_outs) 16114 alc861_auto_set_output_and_unmute(codec, 16115 spec->autocfg.hp_pins[0], 16116 PIN_HP, 16117 spec->multiout.hp_nid); 16118 if (spec->autocfg.speaker_outs) 16119 alc861_auto_set_output_and_unmute(codec, 16120 spec->autocfg.speaker_pins[0], 16121 PIN_OUT, 16122 spec->multiout.dac_nids[0]); 16123} 16124 16125static void alc861_auto_init_analog_input(struct hda_codec *codec) 16126{ 16127 struct alc_spec *spec = codec->spec; 16128 struct auto_pin_cfg *cfg = &spec->autocfg; 16129 int i; 16130 16131 for (i = 0; i < cfg->num_inputs; i++) { 16132 hda_nid_t nid = cfg->inputs[i].pin; 16133 if (nid >= 0x0c && nid <= 0x11) 16134 alc_set_input_pin(codec, nid, cfg->inputs[i].type); 16135 } 16136} 16137 16138/* parse the BIOS configuration and set up the alc_spec */ 16139/* return 1 if successful, 0 if the proper config is not found, 16140 * or a negative error code 16141 */ 16142static int alc861_parse_auto_config(struct hda_codec *codec) 16143{ 16144 struct alc_spec *spec = codec->spec; 16145 int err; 16146 static hda_nid_t alc861_ignore[] = { 0x1d, 0 }; 16147 16148 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 16149 alc861_ignore); 16150 if (err < 0) 16151 return err; 16152 if (!spec->autocfg.line_outs) 16153 return 0; /* can't find valid BIOS pin config */ 16154 16155 err = alc861_auto_fill_dac_nids(codec, &spec->autocfg); 16156 if (err < 0) 16157 return err; 16158 err = alc861_auto_create_multi_out_ctls(codec, &spec->autocfg); 16159 if (err < 0) 16160 return err; 16161 err = alc861_auto_create_hp_ctls(codec, spec->autocfg.hp_pins[0]); 16162 if (err < 0) 16163 return err; 16164 err = alc861_auto_create_input_ctls(codec, &spec->autocfg); 16165 if (err < 0) 16166 return err; 16167 16168 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 16169 16170 alc_auto_parse_digital(codec); 16171 16172 if (spec->kctls.list) 16173 add_mixer(spec, spec->kctls.list); 16174 16175 add_verb(spec, alc861_auto_init_verbs); 16176 16177 spec->num_mux_defs = 1; 16178 spec->input_mux = &spec->private_imux[0]; 16179 16180 spec->adc_nids = alc861_adc_nids; 16181 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids); 16182 set_capture_mixer(codec); 16183 16184 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b, 0); 16185 16186 return 1; 16187} 16188 16189/* additional initialization for auto-configuration model */ 16190static void alc861_auto_init(struct hda_codec *codec) 16191{ 16192 struct alc_spec *spec = codec->spec; 16193 alc861_auto_init_multi_out(codec); 16194 alc861_auto_init_hp_out(codec); 16195 alc861_auto_init_analog_input(codec); 16196 alc_auto_init_digital(codec); 16197 if (spec->unsol_event) 16198 alc_inithook(codec); 16199} 16200 16201#ifdef CONFIG_SND_HDA_POWER_SAVE 16202static struct hda_amp_list alc861_loopbacks[] = { 16203 { 0x15, HDA_INPUT, 0 }, 16204 { 0x15, HDA_INPUT, 1 }, 16205 { 0x15, HDA_INPUT, 2 }, 16206 { 0x15, HDA_INPUT, 3 }, 16207 { } /* end */ 16208}; 16209#endif 16210 16211 16212/* 16213 * configuration and preset 16214 */ 16215static const char * const alc861_models[ALC861_MODEL_LAST] = { 16216 [ALC861_3ST] = "3stack", 16217 [ALC660_3ST] = "3stack-660", 16218 [ALC861_3ST_DIG] = "3stack-dig", 16219 [ALC861_6ST_DIG] = "6stack-dig", 16220 [ALC861_UNIWILL_M31] = "uniwill-m31", 16221 [ALC861_TOSHIBA] = "toshiba", 16222 [ALC861_ASUS] = "asus", 16223 [ALC861_ASUS_LAPTOP] = "asus-laptop", 16224 [ALC861_AUTO] = "auto", 16225}; 16226 16227static struct snd_pci_quirk alc861_cfg_tbl[] = { 16228 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST), 16229 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP), 16230 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP), 16231 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS), 16232 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP), 16233 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG), 16234 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA), 16235 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!) 16236 * Any other models that need this preset? 16237 */ 16238 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */ 16239 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST), 16240 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST), 16241 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31), 16242 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31), 16243 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP), 16244 /* FIXME: the below seems conflict */ 16245 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */ 16246 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST), 16247 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST), 16248 {} 16249}; 16250 16251static struct alc_config_preset alc861_presets[] = { 16252 [ALC861_3ST] = { 16253 .mixers = { alc861_3ST_mixer }, 16254 .init_verbs = { alc861_threestack_init_verbs }, 16255 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 16256 .dac_nids = alc861_dac_nids, 16257 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes), 16258 .channel_mode = alc861_threestack_modes, 16259 .need_dac_fix = 1, 16260 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 16261 .adc_nids = alc861_adc_nids, 16262 .input_mux = &alc861_capture_source, 16263 }, 16264 [ALC861_3ST_DIG] = { 16265 .mixers = { alc861_base_mixer }, 16266 .init_verbs = { alc861_threestack_init_verbs }, 16267 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 16268 .dac_nids = alc861_dac_nids, 16269 .dig_out_nid = ALC861_DIGOUT_NID, 16270 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes), 16271 .channel_mode = alc861_threestack_modes, 16272 .need_dac_fix = 1, 16273 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 16274 .adc_nids = alc861_adc_nids, 16275 .input_mux = &alc861_capture_source, 16276 }, 16277 [ALC861_6ST_DIG] = { 16278 .mixers = { alc861_base_mixer }, 16279 .init_verbs = { alc861_base_init_verbs }, 16280 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 16281 .dac_nids = alc861_dac_nids, 16282 .dig_out_nid = ALC861_DIGOUT_NID, 16283 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes), 16284 .channel_mode = alc861_8ch_modes, 16285 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 16286 .adc_nids = alc861_adc_nids, 16287 .input_mux = &alc861_capture_source, 16288 }, 16289 [ALC660_3ST] = { 16290 .mixers = { alc861_3ST_mixer }, 16291 .init_verbs = { alc861_threestack_init_verbs }, 16292 .num_dacs = ARRAY_SIZE(alc660_dac_nids), 16293 .dac_nids = alc660_dac_nids, 16294 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes), 16295 .channel_mode = alc861_threestack_modes, 16296 .need_dac_fix = 1, 16297 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 16298 .adc_nids = alc861_adc_nids, 16299 .input_mux = &alc861_capture_source, 16300 }, 16301 [ALC861_UNIWILL_M31] = { 16302 .mixers = { alc861_uniwill_m31_mixer }, 16303 .init_verbs = { alc861_uniwill_m31_init_verbs }, 16304 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 16305 .dac_nids = alc861_dac_nids, 16306 .dig_out_nid = ALC861_DIGOUT_NID, 16307 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes), 16308 .channel_mode = alc861_uniwill_m31_modes, 16309 .need_dac_fix = 1, 16310 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 16311 .adc_nids = alc861_adc_nids, 16312 .input_mux = &alc861_capture_source, 16313 }, 16314 [ALC861_TOSHIBA] = { 16315 .mixers = { alc861_toshiba_mixer }, 16316 .init_verbs = { alc861_base_init_verbs, 16317 alc861_toshiba_init_verbs }, 16318 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 16319 .dac_nids = alc861_dac_nids, 16320 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 16321 .channel_mode = alc883_3ST_2ch_modes, 16322 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 16323 .adc_nids = alc861_adc_nids, 16324 .input_mux = &alc861_capture_source, 16325 .unsol_event = alc861_toshiba_unsol_event, 16326 .init_hook = alc861_toshiba_automute, 16327 }, 16328 [ALC861_ASUS] = { 16329 .mixers = { alc861_asus_mixer }, 16330 .init_verbs = { alc861_asus_init_verbs }, 16331 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 16332 .dac_nids = alc861_dac_nids, 16333 .dig_out_nid = ALC861_DIGOUT_NID, 16334 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes), 16335 .channel_mode = alc861_asus_modes, 16336 .need_dac_fix = 1, 16337 .hp_nid = 0x06, 16338 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 16339 .adc_nids = alc861_adc_nids, 16340 .input_mux = &alc861_capture_source, 16341 }, 16342 [ALC861_ASUS_LAPTOP] = { 16343 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer }, 16344 .init_verbs = { alc861_asus_init_verbs, 16345 alc861_asus_laptop_init_verbs }, 16346 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 16347 .dac_nids = alc861_dac_nids, 16348 .dig_out_nid = ALC861_DIGOUT_NID, 16349 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 16350 .channel_mode = alc883_3ST_2ch_modes, 16351 .need_dac_fix = 1, 16352 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 16353 .adc_nids = alc861_adc_nids, 16354 .input_mux = &alc861_capture_source, 16355 }, 16356}; 16357 16358/* Pin config fixes */ 16359enum { 16360 PINFIX_FSC_AMILO_PI1505, 16361}; 16362 16363static const struct alc_fixup alc861_fixups[] = { 16364 [PINFIX_FSC_AMILO_PI1505] = { 16365 .type = ALC_FIXUP_PINS, 16366 .v.pins = (const struct alc_pincfg[]) { 16367 { 0x0b, 0x0221101f }, /* HP */ 16368 { 0x0f, 0x90170310 }, /* speaker */ 16369 { } 16370 } 16371 }, 16372}; 16373 16374static struct snd_pci_quirk alc861_fixup_tbl[] = { 16375 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505), 16376 {} 16377}; 16378 16379static int patch_alc861(struct hda_codec *codec) 16380{ 16381 struct alc_spec *spec; 16382 int board_config; 16383 int err; 16384 16385 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 16386 if (spec == NULL) 16387 return -ENOMEM; 16388 16389 codec->spec = spec; 16390 16391 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST, 16392 alc861_models, 16393 alc861_cfg_tbl); 16394 16395 if (board_config < 0) { 16396 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 16397 codec->chip_name); 16398 board_config = ALC861_AUTO; 16399 } 16400 16401 if (board_config == ALC861_AUTO) { 16402 alc_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups); 16403 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); 16404 } 16405 16406 if (board_config == ALC861_AUTO) { 16407 /* automatic parse from the BIOS config */ 16408 err = alc861_parse_auto_config(codec); 16409 if (err < 0) { 16410 alc_free(codec); 16411 return err; 16412 } else if (!err) { 16413 printk(KERN_INFO 16414 "hda_codec: Cannot set up configuration " 16415 "from BIOS. Using base mode...\n"); 16416 board_config = ALC861_3ST_DIG; 16417 } 16418 } 16419 16420 err = snd_hda_attach_beep_device(codec, 0x23); 16421 if (err < 0) { 16422 alc_free(codec); 16423 return err; 16424 } 16425 16426 if (board_config != ALC861_AUTO) 16427 setup_preset(codec, &alc861_presets[board_config]); 16428 16429 spec->stream_analog_playback = &alc861_pcm_analog_playback; 16430 spec->stream_analog_capture = &alc861_pcm_analog_capture; 16431 16432 spec->stream_digital_playback = &alc861_pcm_digital_playback; 16433 spec->stream_digital_capture = &alc861_pcm_digital_capture; 16434 16435 if (!spec->cap_mixer) 16436 set_capture_mixer(codec); 16437 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT); 16438 16439 spec->vmaster_nid = 0x03; 16440 16441 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); 16442 16443 codec->patch_ops = alc_patch_ops; 16444 if (board_config == ALC861_AUTO) { 16445 spec->init_hook = alc861_auto_init; 16446#ifdef CONFIG_SND_HDA_POWER_SAVE 16447 spec->power_hook = alc_power_eapd; 16448#endif 16449 } 16450#ifdef CONFIG_SND_HDA_POWER_SAVE 16451 if (!spec->loopback.amplist) 16452 spec->loopback.amplist = alc861_loopbacks; 16453#endif 16454 16455 return 0; 16456} 16457 16458/* 16459 * ALC861-VD support 16460 * 16461 * Based on ALC882 16462 * 16463 * In addition, an independent DAC 16464 */ 16465#define ALC861VD_DIGOUT_NID 0x06 16466 16467static hda_nid_t alc861vd_dac_nids[4] = { 16468 /* front, surr, clfe, side surr */ 16469 0x02, 0x03, 0x04, 0x05 16470}; 16471 16472/* dac_nids for ALC660vd are in a different order - according to 16473 * Realtek's driver. 16474 * This should probably result in a different mixer for 6stack models 16475 * of ALC660vd codecs, but for now there is only 3stack mixer 16476 * - and it is the same as in 861vd. 16477 * adc_nids in ALC660vd are (is) the same as in 861vd 16478 */ 16479static hda_nid_t alc660vd_dac_nids[3] = { 16480 /* front, rear, clfe, rear_surr */ 16481 0x02, 0x04, 0x03 16482}; 16483 16484static hda_nid_t alc861vd_adc_nids[1] = { 16485 /* ADC0 */ 16486 0x09, 16487}; 16488 16489static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 }; 16490 16491/* input MUX */ 16492/* FIXME: should be a matrix-type input source selection */ 16493static struct hda_input_mux alc861vd_capture_source = { 16494 .num_items = 4, 16495 .items = { 16496 { "Mic", 0x0 }, 16497 { "Front Mic", 0x1 }, 16498 { "Line", 0x2 }, 16499 { "CD", 0x4 }, 16500 }, 16501}; 16502 16503static struct hda_input_mux alc861vd_dallas_capture_source = { 16504 .num_items = 2, 16505 .items = { 16506 { "Mic", 0x0 }, 16507 { "Internal Mic", 0x1 }, 16508 }, 16509}; 16510 16511static struct hda_input_mux alc861vd_hp_capture_source = { 16512 .num_items = 2, 16513 .items = { 16514 { "Front Mic", 0x0 }, 16515 { "ATAPI Mic", 0x1 }, 16516 }, 16517}; 16518 16519/* 16520 * 2ch mode 16521 */ 16522static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = { 16523 { 2, NULL } 16524}; 16525 16526/* 16527 * 6ch mode 16528 */ 16529static struct hda_verb alc861vd_6stack_ch6_init[] = { 16530 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 16531 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 16532 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 16533 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 16534 { } /* end */ 16535}; 16536 16537/* 16538 * 8ch mode 16539 */ 16540static struct hda_verb alc861vd_6stack_ch8_init[] = { 16541 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 16542 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 16543 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 16544 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 16545 { } /* end */ 16546}; 16547 16548static struct hda_channel_mode alc861vd_6stack_modes[2] = { 16549 { 6, alc861vd_6stack_ch6_init }, 16550 { 8, alc861vd_6stack_ch8_init }, 16551}; 16552 16553static struct snd_kcontrol_new alc861vd_chmode_mixer[] = { 16554 { 16555 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 16556 .name = "Channel Mode", 16557 .info = alc_ch_mode_info, 16558 .get = alc_ch_mode_get, 16559 .put = alc_ch_mode_put, 16560 }, 16561 { } /* end */ 16562}; 16563 16564/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 16565 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b 16566 */ 16567static struct snd_kcontrol_new alc861vd_6st_mixer[] = { 16568 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 16569 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 16570 16571 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT), 16572 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 16573 16574 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, 16575 HDA_OUTPUT), 16576 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, 16577 HDA_OUTPUT), 16578 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 16579 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 16580 16581 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT), 16582 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 16583 16584 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 16585 16586 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 16587 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 16588 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 16589 16590 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), 16591 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 16592 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 16593 16594 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 16595 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 16596 16597 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 16598 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 16599 16600 { } /* end */ 16601}; 16602 16603static struct snd_kcontrol_new alc861vd_3st_mixer[] = { 16604 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 16605 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 16606 16607 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 16608 16609 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 16610 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 16611 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 16612 16613 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), 16614 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 16615 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 16616 16617 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 16618 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 16619 16620 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 16621 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 16622 16623 { } /* end */ 16624}; 16625 16626static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = { 16627 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 16628 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/ 16629 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 16630 16631 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 16632 16633 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 16634 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 16635 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 16636 16637 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), 16638 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 16639 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 16640 16641 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 16642 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 16643 16644 { } /* end */ 16645}; 16646 16647/* Pin assignment: Speaker=0x14, HP = 0x15, 16648 * Mic=0x18, Internal Mic = 0x19, CD = 0x1c, PC Beep = 0x1d 16649 */ 16650static struct snd_kcontrol_new alc861vd_dallas_mixer[] = { 16651 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 16652 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT), 16653 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 16654 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT), 16655 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 16656 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 16657 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 16658 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), 16659 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 16660 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 16661 { } /* end */ 16662}; 16663 16664/* Pin assignment: Speaker=0x14, Line-out = 0x15, 16665 * Front Mic=0x18, ATAPI Mic = 0x19, 16666 */ 16667static struct snd_kcontrol_new alc861vd_hp_mixer[] = { 16668 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 16669 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 16670 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 16671 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT), 16672 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 16673 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 16674 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 16675 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 16676 16677 { } /* end */ 16678}; 16679 16680/* 16681 * generic initialization of ADC, input mixers and output mixers 16682 */ 16683static struct hda_verb alc861vd_volume_init_verbs[] = { 16684 /* 16685 * Unmute ADC0 and set the default input to mic-in 16686 */ 16687 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 16688 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 16689 16690 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of 16691 * the analog-loopback mixer widget 16692 */ 16693 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 16694 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 16695 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 16696 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 16697 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 16698 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 16699 16700 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */ 16701 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 16702 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 16703 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 16704 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, 16705 16706 /* 16707 * Set up output mixers (0x02 - 0x05) 16708 */ 16709 /* set vol=0 to output mixers */ 16710 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 16711 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 16712 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 16713 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 16714 16715 /* set up input amps for analog loopback */ 16716 /* Amp Indices: DAC = 0, mixer = 1 */ 16717 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 16718 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 16719 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 16720 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 16721 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 16722 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 16723 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 16724 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 16725 16726 { } 16727}; 16728 16729/* 16730 * 3-stack pin configuration: 16731 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b 16732 */ 16733static struct hda_verb alc861vd_3stack_init_verbs[] = { 16734 /* 16735 * Set pin mode and muting 16736 */ 16737 /* set front pin widgets 0x14 for output */ 16738 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 16739 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 16740 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 16741 16742 /* Mic (rear) pin: input vref at 80% */ 16743 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 16744 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 16745 /* Front Mic pin: input vref at 80% */ 16746 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 16747 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 16748 /* Line In pin: input */ 16749 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 16750 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 16751 /* Line-2 In: Headphone output (output 0 - 0x0c) */ 16752 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 16753 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 16754 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 16755 /* CD pin widget for input */ 16756 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 16757 16758 { } 16759}; 16760 16761/* 16762 * 6-stack pin configuration: 16763 */ 16764static struct hda_verb alc861vd_6stack_init_verbs[] = { 16765 /* 16766 * Set pin mode and muting 16767 */ 16768 /* set front pin widgets 0x14 for output */ 16769 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 16770 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 16771 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 16772 16773 /* Rear Pin: output 1 (0x0d) */ 16774 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 16775 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 16776 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 16777 /* CLFE Pin: output 2 (0x0e) */ 16778 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 16779 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 16780 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, 16781 /* Side Pin: output 3 (0x0f) */ 16782 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 16783 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 16784 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, 16785 16786 /* Mic (rear) pin: input vref at 80% */ 16787 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 16788 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 16789 /* Front Mic pin: input vref at 80% */ 16790 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 16791 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 16792 /* Line In pin: input */ 16793 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 16794 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 16795 /* Line-2 In: Headphone output (output 0 - 0x0c) */ 16796 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 16797 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 16798 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 16799 /* CD pin widget for input */ 16800 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 16801 16802 { } 16803}; 16804 16805static struct hda_verb alc861vd_eapd_verbs[] = { 16806 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 16807 { } 16808}; 16809 16810static struct hda_verb alc660vd_eapd_verbs[] = { 16811 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 16812 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, 16813 { } 16814}; 16815 16816static struct hda_verb alc861vd_lenovo_unsol_verbs[] = { 16817 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 16818 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 16819 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, 16820 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 16821 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 16822 {} 16823}; 16824 16825static void alc861vd_lenovo_setup(struct hda_codec *codec) 16826{ 16827 struct alc_spec *spec = codec->spec; 16828 spec->autocfg.hp_pins[0] = 0x1b; 16829 spec->autocfg.speaker_pins[0] = 0x14; 16830} 16831 16832static void alc861vd_lenovo_init_hook(struct hda_codec *codec) 16833{ 16834 alc_automute_amp(codec); 16835 alc88x_simple_mic_automute(codec); 16836} 16837 16838static void alc861vd_lenovo_unsol_event(struct hda_codec *codec, 16839 unsigned int res) 16840{ 16841 switch (res >> 26) { 16842 case ALC880_MIC_EVENT: 16843 alc88x_simple_mic_automute(codec); 16844 break; 16845 default: 16846 alc_automute_amp_unsol_event(codec, res); 16847 break; 16848 } 16849} 16850 16851static struct hda_verb alc861vd_dallas_verbs[] = { 16852 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 16853 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 16854 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 16855 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 16856 16857 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 16858 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 16859 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 16860 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 16861 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 16862 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 16863 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 16864 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 16865 16866 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 16867 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 16868 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 16869 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 16870 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 16871 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 16872 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 16873 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 16874 16875 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, 16876 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 16877 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, 16878 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 16879 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 16880 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 16881 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 16882 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 16883 16884 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 16885 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 16886 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 16887 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 16888 16889 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 16890 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 16891 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 16892 16893 { } /* end */ 16894}; 16895 16896/* toggle speaker-output according to the hp-jack state */ 16897static void alc861vd_dallas_setup(struct hda_codec *codec) 16898{ 16899 struct alc_spec *spec = codec->spec; 16900 16901 spec->autocfg.hp_pins[0] = 0x15; 16902 spec->autocfg.speaker_pins[0] = 0x14; 16903} 16904 16905#ifdef CONFIG_SND_HDA_POWER_SAVE 16906#define alc861vd_loopbacks alc880_loopbacks 16907#endif 16908 16909/* pcm configuration: identical with ALC880 */ 16910#define alc861vd_pcm_analog_playback alc880_pcm_analog_playback 16911#define alc861vd_pcm_analog_capture alc880_pcm_analog_capture 16912#define alc861vd_pcm_digital_playback alc880_pcm_digital_playback 16913#define alc861vd_pcm_digital_capture alc880_pcm_digital_capture 16914 16915/* 16916 * configuration and preset 16917 */ 16918static const char * const alc861vd_models[ALC861VD_MODEL_LAST] = { 16919 [ALC660VD_3ST] = "3stack-660", 16920 [ALC660VD_3ST_DIG] = "3stack-660-digout", 16921 [ALC660VD_ASUS_V1S] = "asus-v1s", 16922 [ALC861VD_3ST] = "3stack", 16923 [ALC861VD_3ST_DIG] = "3stack-digout", 16924 [ALC861VD_6ST_DIG] = "6stack-digout", 16925 [ALC861VD_LENOVO] = "lenovo", 16926 [ALC861VD_DALLAS] = "dallas", 16927 [ALC861VD_HP] = "hp", 16928 [ALC861VD_AUTO] = "auto", 16929}; 16930 16931static struct snd_pci_quirk alc861vd_cfg_tbl[] = { 16932 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST), 16933 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP), 16934 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST), 16935 /*SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),*/ /* auto */ 16936 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S), 16937 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG), 16938 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST), 16939 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO), 16940 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/ 16941 SND_PCI_QUIRK(0x1179, 0xff01, "Toshiba A135", ALC861VD_LENOVO), 16942 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO), 16943 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS), 16944 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG), 16945 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO), 16946 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG), 16947 {} 16948}; 16949 16950static struct alc_config_preset alc861vd_presets[] = { 16951 [ALC660VD_3ST] = { 16952 .mixers = { alc861vd_3st_mixer }, 16953 .init_verbs = { alc861vd_volume_init_verbs, 16954 alc861vd_3stack_init_verbs }, 16955 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids), 16956 .dac_nids = alc660vd_dac_nids, 16957 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 16958 .channel_mode = alc861vd_3stack_2ch_modes, 16959 .input_mux = &alc861vd_capture_source, 16960 }, 16961 [ALC660VD_3ST_DIG] = { 16962 .mixers = { alc861vd_3st_mixer }, 16963 .init_verbs = { alc861vd_volume_init_verbs, 16964 alc861vd_3stack_init_verbs }, 16965 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids), 16966 .dac_nids = alc660vd_dac_nids, 16967 .dig_out_nid = ALC861VD_DIGOUT_NID, 16968 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 16969 .channel_mode = alc861vd_3stack_2ch_modes, 16970 .input_mux = &alc861vd_capture_source, 16971 }, 16972 [ALC861VD_3ST] = { 16973 .mixers = { alc861vd_3st_mixer }, 16974 .init_verbs = { alc861vd_volume_init_verbs, 16975 alc861vd_3stack_init_verbs }, 16976 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids), 16977 .dac_nids = alc861vd_dac_nids, 16978 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 16979 .channel_mode = alc861vd_3stack_2ch_modes, 16980 .input_mux = &alc861vd_capture_source, 16981 }, 16982 [ALC861VD_3ST_DIG] = { 16983 .mixers = { alc861vd_3st_mixer }, 16984 .init_verbs = { alc861vd_volume_init_verbs, 16985 alc861vd_3stack_init_verbs }, 16986 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids), 16987 .dac_nids = alc861vd_dac_nids, 16988 .dig_out_nid = ALC861VD_DIGOUT_NID, 16989 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 16990 .channel_mode = alc861vd_3stack_2ch_modes, 16991 .input_mux = &alc861vd_capture_source, 16992 }, 16993 [ALC861VD_6ST_DIG] = { 16994 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer }, 16995 .init_verbs = { alc861vd_volume_init_verbs, 16996 alc861vd_6stack_init_verbs }, 16997 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids), 16998 .dac_nids = alc861vd_dac_nids, 16999 .dig_out_nid = ALC861VD_DIGOUT_NID, 17000 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes), 17001 .channel_mode = alc861vd_6stack_modes, 17002 .input_mux = &alc861vd_capture_source, 17003 }, 17004 [ALC861VD_LENOVO] = { 17005 .mixers = { alc861vd_lenovo_mixer }, 17006 .init_verbs = { alc861vd_volume_init_verbs, 17007 alc861vd_3stack_init_verbs, 17008 alc861vd_eapd_verbs, 17009 alc861vd_lenovo_unsol_verbs }, 17010 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids), 17011 .dac_nids = alc660vd_dac_nids, 17012 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 17013 .channel_mode = alc861vd_3stack_2ch_modes, 17014 .input_mux = &alc861vd_capture_source, 17015 .unsol_event = alc861vd_lenovo_unsol_event, 17016 .setup = alc861vd_lenovo_setup, 17017 .init_hook = alc861vd_lenovo_init_hook, 17018 }, 17019 [ALC861VD_DALLAS] = { 17020 .mixers = { alc861vd_dallas_mixer }, 17021 .init_verbs = { alc861vd_dallas_verbs }, 17022 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids), 17023 .dac_nids = alc861vd_dac_nids, 17024 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 17025 .channel_mode = alc861vd_3stack_2ch_modes, 17026 .input_mux = &alc861vd_dallas_capture_source, 17027 .unsol_event = alc_automute_amp_unsol_event, 17028 .setup = alc861vd_dallas_setup, 17029 .init_hook = alc_automute_amp, 17030 }, 17031 [ALC861VD_HP] = { 17032 .mixers = { alc861vd_hp_mixer }, 17033 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs }, 17034 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids), 17035 .dac_nids = alc861vd_dac_nids, 17036 .dig_out_nid = ALC861VD_DIGOUT_NID, 17037 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 17038 .channel_mode = alc861vd_3stack_2ch_modes, 17039 .input_mux = &alc861vd_hp_capture_source, 17040 .unsol_event = alc_automute_amp_unsol_event, 17041 .setup = alc861vd_dallas_setup, 17042 .init_hook = alc_automute_amp, 17043 }, 17044 [ALC660VD_ASUS_V1S] = { 17045 .mixers = { alc861vd_lenovo_mixer }, 17046 .init_verbs = { alc861vd_volume_init_verbs, 17047 alc861vd_3stack_init_verbs, 17048 alc861vd_eapd_verbs, 17049 alc861vd_lenovo_unsol_verbs }, 17050 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids), 17051 .dac_nids = alc660vd_dac_nids, 17052 .dig_out_nid = ALC861VD_DIGOUT_NID, 17053 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 17054 .channel_mode = alc861vd_3stack_2ch_modes, 17055 .input_mux = &alc861vd_capture_source, 17056 .unsol_event = alc861vd_lenovo_unsol_event, 17057 .setup = alc861vd_lenovo_setup, 17058 .init_hook = alc861vd_lenovo_init_hook, 17059 }, 17060}; 17061 17062/* 17063 * BIOS auto configuration 17064 */ 17065static int alc861vd_auto_create_input_ctls(struct hda_codec *codec, 17066 const struct auto_pin_cfg *cfg) 17067{ 17068 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x22, 0); 17069} 17070 17071 17072static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec, 17073 hda_nid_t nid, int pin_type, int dac_idx) 17074{ 17075 alc_set_pin_output(codec, nid, pin_type); 17076} 17077 17078static void alc861vd_auto_init_multi_out(struct hda_codec *codec) 17079{ 17080 struct alc_spec *spec = codec->spec; 17081 int i; 17082 17083 for (i = 0; i <= HDA_SIDE; i++) { 17084 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 17085 int pin_type = get_pin_type(spec->autocfg.line_out_type); 17086 if (nid) 17087 alc861vd_auto_set_output_and_unmute(codec, nid, 17088 pin_type, i); 17089 } 17090} 17091 17092 17093static void alc861vd_auto_init_hp_out(struct hda_codec *codec) 17094{ 17095 struct alc_spec *spec = codec->spec; 17096 hda_nid_t pin; 17097 17098 pin = spec->autocfg.hp_pins[0]; 17099 if (pin) /* connect to front and use dac 0 */ 17100 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); 17101 pin = spec->autocfg.speaker_pins[0]; 17102 if (pin) 17103 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0); 17104} 17105 17106#define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID 17107 17108static void alc861vd_auto_init_analog_input(struct hda_codec *codec) 17109{ 17110 struct alc_spec *spec = codec->spec; 17111 struct auto_pin_cfg *cfg = &spec->autocfg; 17112 int i; 17113 17114 for (i = 0; i < cfg->num_inputs; i++) { 17115 hda_nid_t nid = cfg->inputs[i].pin; 17116 if (alc_is_input_pin(codec, nid)) { 17117 alc_set_input_pin(codec, nid, cfg->inputs[i].type); 17118 if (nid != ALC861VD_PIN_CD_NID && 17119 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)) 17120 snd_hda_codec_write(codec, nid, 0, 17121 AC_VERB_SET_AMP_GAIN_MUTE, 17122 AMP_OUT_MUTE); 17123 } 17124 } 17125} 17126 17127#define alc861vd_auto_init_input_src alc882_auto_init_input_src 17128 17129#define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02) 17130#define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c) 17131 17132/* add playback controls from the parsed DAC table */ 17133/* Based on ALC880 version. But ALC861VD has separate, 17134 * different NIDs for mute/unmute switch and volume control */ 17135static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec, 17136 const struct auto_pin_cfg *cfg) 17137{ 17138 static const char * const chname[4] = { 17139 "Front", "Surround", "CLFE", "Side" 17140 }; 17141 const char *pfx = alc_get_line_out_pfx(cfg, true); 17142 hda_nid_t nid_v, nid_s; 17143 int i, err; 17144 17145 for (i = 0; i < cfg->line_outs; i++) { 17146 if (!spec->multiout.dac_nids[i]) 17147 continue; 17148 nid_v = alc861vd_idx_to_mixer_vol( 17149 alc880_dac_to_idx( 17150 spec->multiout.dac_nids[i])); 17151 nid_s = alc861vd_idx_to_mixer_switch( 17152 alc880_dac_to_idx( 17153 spec->multiout.dac_nids[i])); 17154 17155 if (!pfx && i == 2) { 17156 /* Center/LFE */ 17157 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, 17158 "Center", 17159 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0, 17160 HDA_OUTPUT)); 17161 if (err < 0) 17162 return err; 17163 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, 17164 "LFE", 17165 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0, 17166 HDA_OUTPUT)); 17167 if (err < 0) 17168 return err; 17169 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, 17170 "Center", 17171 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2, 17172 HDA_INPUT)); 17173 if (err < 0) 17174 return err; 17175 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, 17176 "LFE", 17177 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2, 17178 HDA_INPUT)); 17179 if (err < 0) 17180 return err; 17181 } else { 17182 const char *name = pfx; 17183 if (!name) 17184 name = chname[i]; 17185 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, 17186 name, i, 17187 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, 17188 HDA_OUTPUT)); 17189 if (err < 0) 17190 return err; 17191 err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, 17192 name, i, 17193 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, 17194 HDA_INPUT)); 17195 if (err < 0) 17196 return err; 17197 } 17198 } 17199 return 0; 17200} 17201 17202/* add playback controls for speaker and HP outputs */ 17203/* Based on ALC880 version. But ALC861VD has separate, 17204 * different NIDs for mute/unmute switch and volume control */ 17205static int alc861vd_auto_create_extra_out(struct alc_spec *spec, 17206 hda_nid_t pin, const char *pfx) 17207{ 17208 hda_nid_t nid_v, nid_s; 17209 int err; 17210 17211 if (!pin) 17212 return 0; 17213 17214 if (alc880_is_fixed_pin(pin)) { 17215 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); 17216 /* specify the DAC as the extra output */ 17217 if (!spec->multiout.hp_nid) 17218 spec->multiout.hp_nid = nid_v; 17219 else 17220 spec->multiout.extra_out_nid[0] = nid_v; 17221 /* control HP volume/switch on the output mixer amp */ 17222 nid_v = alc861vd_idx_to_mixer_vol( 17223 alc880_fixed_pin_idx(pin)); 17224 nid_s = alc861vd_idx_to_mixer_switch( 17225 alc880_fixed_pin_idx(pin)); 17226 17227 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, 17228 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT)); 17229 if (err < 0) 17230 return err; 17231 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx, 17232 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT)); 17233 if (err < 0) 17234 return err; 17235 } else if (alc880_is_multi_pin(pin)) { 17236 /* set manual connection */ 17237 /* we have only a switch on HP-out PIN */ 17238 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, 17239 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); 17240 if (err < 0) 17241 return err; 17242 } 17243 return 0; 17244} 17245 17246/* parse the BIOS configuration and set up the alc_spec 17247 * return 1 if successful, 0 if the proper config is not found, 17248 * or a negative error code 17249 * Based on ALC880 version - had to change it to override 17250 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */ 17251static int alc861vd_parse_auto_config(struct hda_codec *codec) 17252{ 17253 struct alc_spec *spec = codec->spec; 17254 int err; 17255 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 }; 17256 17257 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 17258 alc861vd_ignore); 17259 if (err < 0) 17260 return err; 17261 if (!spec->autocfg.line_outs) 17262 return 0; /* can't find valid BIOS pin config */ 17263 17264 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); 17265 if (err < 0) 17266 return err; 17267 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg); 17268 if (err < 0) 17269 return err; 17270 err = alc861vd_auto_create_extra_out(spec, 17271 spec->autocfg.speaker_pins[0], 17272 "Speaker"); 17273 if (err < 0) 17274 return err; 17275 err = alc861vd_auto_create_extra_out(spec, 17276 spec->autocfg.hp_pins[0], 17277 "Headphone"); 17278 if (err < 0) 17279 return err; 17280 err = alc861vd_auto_create_input_ctls(codec, &spec->autocfg); 17281 if (err < 0) 17282 return err; 17283 17284 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 17285 17286 alc_auto_parse_digital(codec); 17287 17288 if (spec->kctls.list) 17289 add_mixer(spec, spec->kctls.list); 17290 17291 add_verb(spec, alc861vd_volume_init_verbs); 17292 17293 spec->num_mux_defs = 1; 17294 spec->input_mux = &spec->private_imux[0]; 17295 17296 err = alc_auto_add_mic_boost(codec); 17297 if (err < 0) 17298 return err; 17299 17300 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); 17301 17302 return 1; 17303} 17304 17305/* additional initialization for auto-configuration model */ 17306static void alc861vd_auto_init(struct hda_codec *codec) 17307{ 17308 struct alc_spec *spec = codec->spec; 17309 alc861vd_auto_init_multi_out(codec); 17310 alc861vd_auto_init_hp_out(codec); 17311 alc861vd_auto_init_analog_input(codec); 17312 alc861vd_auto_init_input_src(codec); 17313 alc_auto_init_digital(codec); 17314 if (spec->unsol_event) 17315 alc_inithook(codec); 17316} 17317 17318enum { 17319 ALC660VD_FIX_ASUS_GPIO1 17320}; 17321 17322/* reset GPIO1 */ 17323static const struct alc_fixup alc861vd_fixups[] = { 17324 [ALC660VD_FIX_ASUS_GPIO1] = { 17325 .type = ALC_FIXUP_VERBS, 17326 .v.verbs = (const struct hda_verb[]) { 17327 {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, 17328 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, 17329 {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, 17330 { } 17331 } 17332 }, 17333}; 17334 17335static struct snd_pci_quirk alc861vd_fixup_tbl[] = { 17336 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1), 17337 {} 17338}; 17339 17340static int patch_alc861vd(struct hda_codec *codec) 17341{ 17342 struct alc_spec *spec; 17343 int err, board_config; 17344 17345 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 17346 if (spec == NULL) 17347 return -ENOMEM; 17348 17349 codec->spec = spec; 17350 17351 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST, 17352 alc861vd_models, 17353 alc861vd_cfg_tbl); 17354 17355 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) { 17356 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 17357 codec->chip_name); 17358 board_config = ALC861VD_AUTO; 17359 } 17360 17361 if (board_config == ALC861VD_AUTO) { 17362 alc_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups); 17363 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); 17364 } 17365 17366 if (board_config == ALC861VD_AUTO) { 17367 /* automatic parse from the BIOS config */ 17368 err = alc861vd_parse_auto_config(codec); 17369 if (err < 0) { 17370 alc_free(codec); 17371 return err; 17372 } else if (!err) { 17373 printk(KERN_INFO 17374 "hda_codec: Cannot set up configuration " 17375 "from BIOS. Using base mode...\n"); 17376 board_config = ALC861VD_3ST; 17377 } 17378 } 17379 17380 err = snd_hda_attach_beep_device(codec, 0x23); 17381 if (err < 0) { 17382 alc_free(codec); 17383 return err; 17384 } 17385 17386 if (board_config != ALC861VD_AUTO) 17387 setup_preset(codec, &alc861vd_presets[board_config]); 17388 17389 if (codec->vendor_id == 0x10ec0660) { 17390 /* always turn on EAPD */ 17391 add_verb(spec, alc660vd_eapd_verbs); 17392 } 17393 17394 spec->stream_analog_playback = &alc861vd_pcm_analog_playback; 17395 spec->stream_analog_capture = &alc861vd_pcm_analog_capture; 17396 17397 spec->stream_digital_playback = &alc861vd_pcm_digital_playback; 17398 spec->stream_digital_capture = &alc861vd_pcm_digital_capture; 17399 17400 if (!spec->adc_nids) { 17401 spec->adc_nids = alc861vd_adc_nids; 17402 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids); 17403 } 17404 if (!spec->capsrc_nids) 17405 spec->capsrc_nids = alc861vd_capsrc_nids; 17406 17407 set_capture_mixer(codec); 17408 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 17409 17410 spec->vmaster_nid = 0x02; 17411 17412 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); 17413 17414 codec->patch_ops = alc_patch_ops; 17415 17416 if (board_config == ALC861VD_AUTO) 17417 spec->init_hook = alc861vd_auto_init; 17418#ifdef CONFIG_SND_HDA_POWER_SAVE 17419 if (!spec->loopback.amplist) 17420 spec->loopback.amplist = alc861vd_loopbacks; 17421#endif 17422 17423 return 0; 17424} 17425 17426/* 17427 * ALC662 support 17428 * 17429 * ALC662 is almost identical with ALC880 but has cleaner and more flexible 17430 * configuration. Each pin widget can choose any input DACs and a mixer. 17431 * Each ADC is connected from a mixer of all inputs. This makes possible 17432 * 6-channel independent captures. 17433 * 17434 * In addition, an independent DAC for the multi-playback (not used in this 17435 * driver yet). 17436 */ 17437#define ALC662_DIGOUT_NID 0x06 17438#define ALC662_DIGIN_NID 0x0a 17439 17440static hda_nid_t alc662_dac_nids[4] = { 17441 /* front, rear, clfe, rear_surr */ 17442 0x02, 0x03, 0x04 17443}; 17444 17445static hda_nid_t alc272_dac_nids[2] = { 17446 0x02, 0x03 17447}; 17448 17449static hda_nid_t alc662_adc_nids[2] = { 17450 /* ADC1-2 */ 17451 0x09, 0x08 17452}; 17453 17454static hda_nid_t alc272_adc_nids[1] = { 17455 /* ADC1-2 */ 17456 0x08, 17457}; 17458 17459static hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 }; 17460static hda_nid_t alc272_capsrc_nids[1] = { 0x23 }; 17461 17462 17463/* input MUX */ 17464/* FIXME: should be a matrix-type input source selection */ 17465static struct hda_input_mux alc662_capture_source = { 17466 .num_items = 4, 17467 .items = { 17468 { "Mic", 0x0 }, 17469 { "Front Mic", 0x1 }, 17470 { "Line", 0x2 }, 17471 { "CD", 0x4 }, 17472 }, 17473}; 17474 17475static struct hda_input_mux alc662_lenovo_101e_capture_source = { 17476 .num_items = 2, 17477 .items = { 17478 { "Mic", 0x1 }, 17479 { "Line", 0x2 }, 17480 }, 17481}; 17482 17483static struct hda_input_mux alc663_capture_source = { 17484 .num_items = 3, 17485 .items = { 17486 { "Mic", 0x0 }, 17487 { "Front Mic", 0x1 }, 17488 { "Line", 0x2 }, 17489 }, 17490}; 17491 17492#if 0 /* set to 1 for testing other input sources below */ 17493static struct hda_input_mux alc272_nc10_capture_source = { 17494 .num_items = 16, 17495 .items = { 17496 { "Autoselect Mic", 0x0 }, 17497 { "Internal Mic", 0x1 }, 17498 { "In-0x02", 0x2 }, 17499 { "In-0x03", 0x3 }, 17500 { "In-0x04", 0x4 }, 17501 { "In-0x05", 0x5 }, 17502 { "In-0x06", 0x6 }, 17503 { "In-0x07", 0x7 }, 17504 { "In-0x08", 0x8 }, 17505 { "In-0x09", 0x9 }, 17506 { "In-0x0a", 0x0a }, 17507 { "In-0x0b", 0x0b }, 17508 { "In-0x0c", 0x0c }, 17509 { "In-0x0d", 0x0d }, 17510 { "In-0x0e", 0x0e }, 17511 { "In-0x0f", 0x0f }, 17512 }, 17513}; 17514#endif 17515 17516/* 17517 * 2ch mode 17518 */ 17519static struct hda_channel_mode alc662_3ST_2ch_modes[1] = { 17520 { 2, NULL } 17521}; 17522 17523/* 17524 * 2ch mode 17525 */ 17526static struct hda_verb alc662_3ST_ch2_init[] = { 17527 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 17528 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 17529 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 17530 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 17531 { } /* end */ 17532}; 17533 17534/* 17535 * 6ch mode 17536 */ 17537static struct hda_verb alc662_3ST_ch6_init[] = { 17538 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 17539 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 17540 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, 17541 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 17542 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 17543 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 17544 { } /* end */ 17545}; 17546 17547static struct hda_channel_mode alc662_3ST_6ch_modes[2] = { 17548 { 2, alc662_3ST_ch2_init }, 17549 { 6, alc662_3ST_ch6_init }, 17550}; 17551 17552/* 17553 * 2ch mode 17554 */ 17555static struct hda_verb alc662_sixstack_ch6_init[] = { 17556 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 17557 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 17558 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 17559 { } /* end */ 17560}; 17561 17562/* 17563 * 6ch mode 17564 */ 17565static struct hda_verb alc662_sixstack_ch8_init[] = { 17566 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 17567 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 17568 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 17569 { } /* end */ 17570}; 17571 17572static struct hda_channel_mode alc662_5stack_modes[2] = { 17573 { 2, alc662_sixstack_ch6_init }, 17574 { 6, alc662_sixstack_ch8_init }, 17575}; 17576 17577/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 17578 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b 17579 */ 17580 17581static struct snd_kcontrol_new alc662_base_mixer[] = { 17582 /* output mixer control */ 17583 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), 17584 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT), 17585 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT), 17586 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT), 17587 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT), 17588 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT), 17589 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT), 17590 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT), 17591 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 17592 17593 /*Input mixer control */ 17594 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT), 17595 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT), 17596 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT), 17597 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT), 17598 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT), 17599 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT), 17600 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT), 17601 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT), 17602 { } /* end */ 17603}; 17604 17605static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = { 17606 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 17607 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT), 17608 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 17609 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 17610 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 17611 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 17612 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 17613 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17614 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17615 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 17616 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 17617 { } /* end */ 17618}; 17619 17620static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = { 17621 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 17622 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT), 17623 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT), 17624 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT), 17625 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT), 17626 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT), 17627 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT), 17628 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT), 17629 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 17630 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 17631 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 17632 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 17633 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 17634 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17635 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17636 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 17637 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 17638 { } /* end */ 17639}; 17640 17641static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = { 17642 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 17643 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT), 17644 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT), 17645 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT), 17646 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 17647 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 17648 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 17649 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 17650 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 17651 { } /* end */ 17652}; 17653 17654static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = { 17655 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT), 17656 ALC262_HIPPO_MASTER_SWITCH, 17657 17658 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 17659 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17660 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17661 17662 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), 17663 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 17664 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 17665 { } /* end */ 17666}; 17667 17668static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = { 17669 ALC262_HIPPO_MASTER_SWITCH, 17670 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 17671 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT), 17672 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT), 17673 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT), 17674 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT), 17675 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 17676 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 17677 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17678 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17679 { } /* end */ 17680}; 17681 17682static struct hda_bind_ctls alc663_asus_bind_master_vol = { 17683 .ops = &snd_hda_bind_vol, 17684 .values = { 17685 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), 17686 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT), 17687 0 17688 }, 17689}; 17690 17691static struct hda_bind_ctls alc663_asus_one_bind_switch = { 17692 .ops = &snd_hda_bind_sw, 17693 .values = { 17694 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 17695 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT), 17696 0 17697 }, 17698}; 17699 17700static struct snd_kcontrol_new alc663_m51va_mixer[] = { 17701 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol), 17702 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch), 17703 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17704 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17705 { } /* end */ 17706}; 17707 17708static struct hda_bind_ctls alc663_asus_tree_bind_switch = { 17709 .ops = &snd_hda_bind_sw, 17710 .values = { 17711 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 17712 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT), 17713 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT), 17714 0 17715 }, 17716}; 17717 17718static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = { 17719 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol), 17720 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch), 17721 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17722 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17723 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 17724 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 17725 17726 { } /* end */ 17727}; 17728 17729static struct hda_bind_ctls alc663_asus_four_bind_switch = { 17730 .ops = &snd_hda_bind_sw, 17731 .values = { 17732 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 17733 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT), 17734 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT), 17735 0 17736 }, 17737}; 17738 17739static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = { 17740 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol), 17741 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch), 17742 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17743 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17744 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 17745 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 17746 { } /* end */ 17747}; 17748 17749static struct snd_kcontrol_new alc662_1bjd_mixer[] = { 17750 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 17751 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 17752 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 17753 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17754 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17755 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 17756 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 17757 { } /* end */ 17758}; 17759 17760static struct hda_bind_ctls alc663_asus_two_bind_master_vol = { 17761 .ops = &snd_hda_bind_vol, 17762 .values = { 17763 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), 17764 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT), 17765 0 17766 }, 17767}; 17768 17769static struct hda_bind_ctls alc663_asus_two_bind_switch = { 17770 .ops = &snd_hda_bind_sw, 17771 .values = { 17772 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 17773 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT), 17774 0 17775 }, 17776}; 17777 17778static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = { 17779 HDA_BIND_VOL("Master Playback Volume", 17780 &alc663_asus_two_bind_master_vol), 17781 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch), 17782 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 17783 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT), 17784 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17785 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17786 { } /* end */ 17787}; 17788 17789static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = { 17790 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol), 17791 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch), 17792 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 17793 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 17794 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17795 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17796 { } /* end */ 17797}; 17798 17799static struct snd_kcontrol_new alc663_g71v_mixer[] = { 17800 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 17801 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 17802 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT), 17803 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT), 17804 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT), 17805 17806 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17807 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17808 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 17809 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 17810 { } /* end */ 17811}; 17812 17813static struct snd_kcontrol_new alc663_g50v_mixer[] = { 17814 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 17815 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 17816 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT), 17817 17818 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17819 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17820 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 17821 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 17822 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 17823 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 17824 { } /* end */ 17825}; 17826 17827static struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = { 17828 .ops = &snd_hda_bind_sw, 17829 .values = { 17830 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 17831 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT), 17832 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT), 17833 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT), 17834 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT), 17835 0 17836 }, 17837}; 17838 17839static struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = { 17840 .ops = &snd_hda_bind_sw, 17841 .values = { 17842 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 17843 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT), 17844 0 17845 }, 17846}; 17847 17848static struct snd_kcontrol_new alc663_mode7_mixer[] = { 17849 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch), 17850 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol), 17851 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch), 17852 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 17853 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT), 17854 HDA_CODEC_VOLUME("IntMic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17855 HDA_CODEC_MUTE("IntMic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17856 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 17857 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 17858 { } /* end */ 17859}; 17860 17861static struct snd_kcontrol_new alc663_mode8_mixer[] = { 17862 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch), 17863 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol), 17864 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch), 17865 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x15, 0x0, HDA_OUTPUT), 17866 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT), 17867 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17868 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17869 { } /* end */ 17870}; 17871 17872 17873static struct snd_kcontrol_new alc662_chmode_mixer[] = { 17874 { 17875 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 17876 .name = "Channel Mode", 17877 .info = alc_ch_mode_info, 17878 .get = alc_ch_mode_get, 17879 .put = alc_ch_mode_put, 17880 }, 17881 { } /* end */ 17882}; 17883 17884static struct hda_verb alc662_init_verbs[] = { 17885 /* ADC: mute amp left and right */ 17886 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 17887 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 17888 17889 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 17890 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 17891 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 17892 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 17893 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 17894 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 17895 17896 /* Front Pin: output 0 (0x0c) */ 17897 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 17898 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17899 17900 /* Rear Pin: output 1 (0x0d) */ 17901 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 17902 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17903 17904 /* CLFE Pin: output 2 (0x0e) */ 17905 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 17906 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17907 17908 /* Mic (rear) pin: input vref at 80% */ 17909 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 17910 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 17911 /* Front Mic pin: input vref at 80% */ 17912 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 17913 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 17914 /* Line In pin: input */ 17915 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17916 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 17917 /* Line-2 In: Headphone output (output 0 - 0x0c) */ 17918 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17919 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17920 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 17921 /* CD pin widget for input */ 17922 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17923 17924 /* FIXME: use matrix-type input source selection */ 17925 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 17926 /* Input mixer */ 17927 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 17928 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 17929 17930 /* always trun on EAPD */ 17931 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 17932 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, 17933 17934 { } 17935}; 17936 17937static struct hda_verb alc663_init_verbs[] = { 17938 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 17939 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17940 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 17941 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17942 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 17943 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 17944 { } 17945}; 17946 17947static struct hda_verb alc272_init_verbs[] = { 17948 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17949 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 17950 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 17951 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17952 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 17953 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17954 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 17955 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 17956 { } 17957}; 17958 17959static struct hda_verb alc662_sue_init_verbs[] = { 17960 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT}, 17961 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT}, 17962 {} 17963}; 17964 17965static struct hda_verb alc662_eeepc_sue_init_verbs[] = { 17966 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 17967 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17968 {} 17969}; 17970 17971/* Set Unsolicited Event*/ 17972static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = { 17973 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 17974 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17975 {} 17976}; 17977 17978static struct hda_verb alc663_m51va_init_verbs[] = { 17979 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17980 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17981 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17982 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17983 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ 17984 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 17985 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)}, 17986 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 17987 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17988 {} 17989}; 17990 17991static struct hda_verb alc663_21jd_amic_init_verbs[] = { 17992 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17993 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17994 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ 17995 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 17996 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 17997 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 17998 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17999 {} 18000}; 18001 18002static struct hda_verb alc662_1bjd_amic_init_verbs[] = { 18003 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 18004 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 18005 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 18006 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */ 18007 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 18008 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 18009 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 18010 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 18011 {} 18012}; 18013 18014static struct hda_verb alc663_15jd_amic_init_verbs[] = { 18015 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 18016 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 18017 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ 18018 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 18019 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 18020 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 18021 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 18022 {} 18023}; 18024 18025static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = { 18026 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 18027 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 18028 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 18029 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */ 18030 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 18031 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 18032 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */ 18033 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 18034 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 18035 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 18036 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 18037 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 18038 {} 18039}; 18040 18041static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = { 18042 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 18043 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 18044 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 18045 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ 18046 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 18047 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 18048 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ 18049 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 18050 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 18051 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 18052 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 18053 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 18054 {} 18055}; 18056 18057static struct hda_verb alc663_g71v_init_verbs[] = { 18058 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 18059 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */ 18060 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */ 18061 18062 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 18063 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 18064 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */ 18065 18066 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT}, 18067 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT}, 18068 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT}, 18069 {} 18070}; 18071 18072static struct hda_verb alc663_g50v_init_verbs[] = { 18073 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 18074 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 18075 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */ 18076 18077 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 18078 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 18079 {} 18080}; 18081 18082static struct hda_verb alc662_ecs_init_verbs[] = { 18083 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f}, 18084 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 18085 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 18086 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 18087 {} 18088}; 18089 18090static struct hda_verb alc272_dell_zm1_init_verbs[] = { 18091 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 18092 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 18093 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 18094 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 18095 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 18096 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 18097 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ 18098 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 18099 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)}, 18100 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 18101 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 18102 {} 18103}; 18104 18105static struct hda_verb alc272_dell_init_verbs[] = { 18106 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 18107 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 18108 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 18109 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 18110 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 18111 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 18112 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ 18113 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 18114 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)}, 18115 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 18116 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 18117 {} 18118}; 18119 18120static struct hda_verb alc663_mode7_init_verbs[] = { 18121 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 18122 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 18123 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 18124 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 18125 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 18126 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 18127 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, 18128 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 18129 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 18130 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ 18131 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 18132 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)}, 18133 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 18134 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 18135 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 18136 {} 18137}; 18138 18139static struct hda_verb alc663_mode8_init_verbs[] = { 18140 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 18141 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 18142 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 18143 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 18144 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 18145 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 18146 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 18147 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 18148 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 18149 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 18150 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ 18151 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 18152 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)}, 18153 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 18154 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 18155 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 18156 {} 18157}; 18158 18159static struct snd_kcontrol_new alc662_auto_capture_mixer[] = { 18160 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), 18161 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), 18162 { } /* end */ 18163}; 18164 18165static struct snd_kcontrol_new alc272_auto_capture_mixer[] = { 18166 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 18167 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 18168 { } /* end */ 18169}; 18170 18171static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec) 18172{ 18173 unsigned int present; 18174 unsigned char bits; 18175 18176 present = snd_hda_jack_detect(codec, 0x14); 18177 bits = present ? HDA_AMP_MUTE : 0; 18178 18179 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 18180 HDA_AMP_MUTE, bits); 18181} 18182 18183static void alc662_lenovo_101e_all_automute(struct hda_codec *codec) 18184{ 18185 unsigned int present; 18186 unsigned char bits; 18187 18188 present = snd_hda_jack_detect(codec, 0x1b); 18189 bits = present ? HDA_AMP_MUTE : 0; 18190 18191 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 18192 HDA_AMP_MUTE, bits); 18193 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 18194 HDA_AMP_MUTE, bits); 18195} 18196 18197static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec, 18198 unsigned int res) 18199{ 18200 if ((res >> 26) == ALC880_HP_EVENT) 18201 alc662_lenovo_101e_all_automute(codec); 18202 if ((res >> 26) == ALC880_FRONT_EVENT) 18203 alc662_lenovo_101e_ispeaker_automute(codec); 18204} 18205 18206/* unsolicited event for HP jack sensing */ 18207static void alc662_eeepc_unsol_event(struct hda_codec *codec, 18208 unsigned int res) 18209{ 18210 if ((res >> 26) == ALC880_MIC_EVENT) 18211 alc_mic_automute(codec); 18212 else 18213 alc262_hippo_unsol_event(codec, res); 18214} 18215 18216static void alc662_eeepc_setup(struct hda_codec *codec) 18217{ 18218 struct alc_spec *spec = codec->spec; 18219 18220 alc262_hippo1_setup(codec); 18221 spec->ext_mic.pin = 0x18; 18222 spec->ext_mic.mux_idx = 0; 18223 spec->int_mic.pin = 0x19; 18224 spec->int_mic.mux_idx = 1; 18225 spec->auto_mic = 1; 18226} 18227 18228static void alc662_eeepc_inithook(struct hda_codec *codec) 18229{ 18230 alc262_hippo_automute(codec); 18231 alc_mic_automute(codec); 18232} 18233 18234static void alc662_eeepc_ep20_setup(struct hda_codec *codec) 18235{ 18236 struct alc_spec *spec = codec->spec; 18237 18238 spec->autocfg.hp_pins[0] = 0x14; 18239 spec->autocfg.speaker_pins[0] = 0x1b; 18240} 18241 18242#define alc662_eeepc_ep20_inithook alc262_hippo_master_update 18243 18244static void alc663_m51va_speaker_automute(struct hda_codec *codec) 18245{ 18246 unsigned int present; 18247 unsigned char bits; 18248 18249 present = snd_hda_jack_detect(codec, 0x21); 18250 bits = present ? HDA_AMP_MUTE : 0; 18251 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 18252 HDA_AMP_MUTE, bits); 18253 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 18254 HDA_AMP_MUTE, bits); 18255} 18256 18257static void alc663_21jd_two_speaker_automute(struct hda_codec *codec) 18258{ 18259 unsigned int present; 18260 unsigned char bits; 18261 18262 present = snd_hda_jack_detect(codec, 0x21); 18263 bits = present ? HDA_AMP_MUTE : 0; 18264 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 18265 HDA_AMP_MUTE, bits); 18266 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 18267 HDA_AMP_MUTE, bits); 18268 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0, 18269 HDA_AMP_MUTE, bits); 18270 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1, 18271 HDA_AMP_MUTE, bits); 18272} 18273 18274static void alc663_15jd_two_speaker_automute(struct hda_codec *codec) 18275{ 18276 unsigned int present; 18277 unsigned char bits; 18278 18279 present = snd_hda_jack_detect(codec, 0x15); 18280 bits = present ? HDA_AMP_MUTE : 0; 18281 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 18282 HDA_AMP_MUTE, bits); 18283 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 18284 HDA_AMP_MUTE, bits); 18285 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0, 18286 HDA_AMP_MUTE, bits); 18287 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1, 18288 HDA_AMP_MUTE, bits); 18289} 18290 18291static void alc662_f5z_speaker_automute(struct hda_codec *codec) 18292{ 18293 unsigned int present; 18294 unsigned char bits; 18295 18296 present = snd_hda_jack_detect(codec, 0x1b); 18297 bits = present ? 0 : PIN_OUT; 18298 snd_hda_codec_write(codec, 0x14, 0, 18299 AC_VERB_SET_PIN_WIDGET_CONTROL, bits); 18300} 18301 18302static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec) 18303{ 18304 unsigned int present1, present2; 18305 18306 present1 = snd_hda_jack_detect(codec, 0x21); 18307 present2 = snd_hda_jack_detect(codec, 0x15); 18308 18309 if (present1 || present2) { 18310 snd_hda_codec_write_cache(codec, 0x14, 0, 18311 AC_VERB_SET_PIN_WIDGET_CONTROL, 0); 18312 } else { 18313 snd_hda_codec_write_cache(codec, 0x14, 0, 18314 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); 18315 } 18316} 18317 18318static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec) 18319{ 18320 unsigned int present1, present2; 18321 18322 present1 = snd_hda_jack_detect(codec, 0x1b); 18323 present2 = snd_hda_jack_detect(codec, 0x15); 18324 18325 if (present1 || present2) { 18326 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 18327 HDA_AMP_MUTE, HDA_AMP_MUTE); 18328 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 18329 HDA_AMP_MUTE, HDA_AMP_MUTE); 18330 } else { 18331 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 18332 HDA_AMP_MUTE, 0); 18333 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 18334 HDA_AMP_MUTE, 0); 18335 } 18336} 18337 18338static void alc663_two_hp_m7_speaker_automute(struct hda_codec *codec) 18339{ 18340 unsigned int present1, present2; 18341 18342 present1 = snd_hda_codec_read(codec, 0x1b, 0, 18343 AC_VERB_GET_PIN_SENSE, 0) 18344 & AC_PINSENSE_PRESENCE; 18345 present2 = snd_hda_codec_read(codec, 0x21, 0, 18346 AC_VERB_GET_PIN_SENSE, 0) 18347 & AC_PINSENSE_PRESENCE; 18348 18349 if (present1 || present2) { 18350 snd_hda_codec_write_cache(codec, 0x14, 0, 18351 AC_VERB_SET_PIN_WIDGET_CONTROL, 0); 18352 snd_hda_codec_write_cache(codec, 0x17, 0, 18353 AC_VERB_SET_PIN_WIDGET_CONTROL, 0); 18354 } else { 18355 snd_hda_codec_write_cache(codec, 0x14, 0, 18356 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); 18357 snd_hda_codec_write_cache(codec, 0x17, 0, 18358 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); 18359 } 18360} 18361 18362static void alc663_two_hp_m8_speaker_automute(struct hda_codec *codec) 18363{ 18364 unsigned int present1, present2; 18365 18366 present1 = snd_hda_codec_read(codec, 0x21, 0, 18367 AC_VERB_GET_PIN_SENSE, 0) 18368 & AC_PINSENSE_PRESENCE; 18369 present2 = snd_hda_codec_read(codec, 0x15, 0, 18370 AC_VERB_GET_PIN_SENSE, 0) 18371 & AC_PINSENSE_PRESENCE; 18372 18373 if (present1 || present2) { 18374 snd_hda_codec_write_cache(codec, 0x14, 0, 18375 AC_VERB_SET_PIN_WIDGET_CONTROL, 0); 18376 snd_hda_codec_write_cache(codec, 0x17, 0, 18377 AC_VERB_SET_PIN_WIDGET_CONTROL, 0); 18378 } else { 18379 snd_hda_codec_write_cache(codec, 0x14, 0, 18380 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); 18381 snd_hda_codec_write_cache(codec, 0x17, 0, 18382 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); 18383 } 18384} 18385 18386static void alc663_m51va_unsol_event(struct hda_codec *codec, 18387 unsigned int res) 18388{ 18389 switch (res >> 26) { 18390 case ALC880_HP_EVENT: 18391 alc663_m51va_speaker_automute(codec); 18392 break; 18393 case ALC880_MIC_EVENT: 18394 alc_mic_automute(codec); 18395 break; 18396 } 18397} 18398 18399static void alc663_m51va_setup(struct hda_codec *codec) 18400{ 18401 struct alc_spec *spec = codec->spec; 18402 spec->ext_mic.pin = 0x18; 18403 spec->ext_mic.mux_idx = 0; 18404 spec->int_mic.pin = 0x12; 18405 spec->int_mic.mux_idx = 9; 18406 spec->auto_mic = 1; 18407} 18408 18409static void alc663_m51va_inithook(struct hda_codec *codec) 18410{ 18411 alc663_m51va_speaker_automute(codec); 18412 alc_mic_automute(codec); 18413} 18414 18415/* ***************** Mode1 ******************************/ 18416#define alc663_mode1_unsol_event alc663_m51va_unsol_event 18417 18418static void alc663_mode1_setup(struct hda_codec *codec) 18419{ 18420 struct alc_spec *spec = codec->spec; 18421 spec->ext_mic.pin = 0x18; 18422 spec->ext_mic.mux_idx = 0; 18423 spec->int_mic.pin = 0x19; 18424 spec->int_mic.mux_idx = 1; 18425 spec->auto_mic = 1; 18426} 18427 18428#define alc663_mode1_inithook alc663_m51va_inithook 18429 18430/* ***************** Mode2 ******************************/ 18431static void alc662_mode2_unsol_event(struct hda_codec *codec, 18432 unsigned int res) 18433{ 18434 switch (res >> 26) { 18435 case ALC880_HP_EVENT: 18436 alc662_f5z_speaker_automute(codec); 18437 break; 18438 case ALC880_MIC_EVENT: 18439 alc_mic_automute(codec); 18440 break; 18441 } 18442} 18443 18444#define alc662_mode2_setup alc663_mode1_setup 18445 18446static void alc662_mode2_inithook(struct hda_codec *codec) 18447{ 18448 alc662_f5z_speaker_automute(codec); 18449 alc_mic_automute(codec); 18450} 18451/* ***************** Mode3 ******************************/ 18452static void alc663_mode3_unsol_event(struct hda_codec *codec, 18453 unsigned int res) 18454{ 18455 switch (res >> 26) { 18456 case ALC880_HP_EVENT: 18457 alc663_two_hp_m1_speaker_automute(codec); 18458 break; 18459 case ALC880_MIC_EVENT: 18460 alc_mic_automute(codec); 18461 break; 18462 } 18463} 18464 18465#define alc663_mode3_setup alc663_mode1_setup 18466 18467static void alc663_mode3_inithook(struct hda_codec *codec) 18468{ 18469 alc663_two_hp_m1_speaker_automute(codec); 18470 alc_mic_automute(codec); 18471} 18472/* ***************** Mode4 ******************************/ 18473static void alc663_mode4_unsol_event(struct hda_codec *codec, 18474 unsigned int res) 18475{ 18476 switch (res >> 26) { 18477 case ALC880_HP_EVENT: 18478 alc663_21jd_two_speaker_automute(codec); 18479 break; 18480 case ALC880_MIC_EVENT: 18481 alc_mic_automute(codec); 18482 break; 18483 } 18484} 18485 18486#define alc663_mode4_setup alc663_mode1_setup 18487 18488static void alc663_mode4_inithook(struct hda_codec *codec) 18489{ 18490 alc663_21jd_two_speaker_automute(codec); 18491 alc_mic_automute(codec); 18492} 18493/* ***************** Mode5 ******************************/ 18494static void alc663_mode5_unsol_event(struct hda_codec *codec, 18495 unsigned int res) 18496{ 18497 switch (res >> 26) { 18498 case ALC880_HP_EVENT: 18499 alc663_15jd_two_speaker_automute(codec); 18500 break; 18501 case ALC880_MIC_EVENT: 18502 alc_mic_automute(codec); 18503 break; 18504 } 18505} 18506 18507#define alc663_mode5_setup alc663_mode1_setup 18508 18509static void alc663_mode5_inithook(struct hda_codec *codec) 18510{ 18511 alc663_15jd_two_speaker_automute(codec); 18512 alc_mic_automute(codec); 18513} 18514/* ***************** Mode6 ******************************/ 18515static void alc663_mode6_unsol_event(struct hda_codec *codec, 18516 unsigned int res) 18517{ 18518 switch (res >> 26) { 18519 case ALC880_HP_EVENT: 18520 alc663_two_hp_m2_speaker_automute(codec); 18521 break; 18522 case ALC880_MIC_EVENT: 18523 alc_mic_automute(codec); 18524 break; 18525 } 18526} 18527 18528#define alc663_mode6_setup alc663_mode1_setup 18529 18530static void alc663_mode6_inithook(struct hda_codec *codec) 18531{ 18532 alc663_two_hp_m2_speaker_automute(codec); 18533 alc_mic_automute(codec); 18534} 18535 18536/* ***************** Mode7 ******************************/ 18537static void alc663_mode7_unsol_event(struct hda_codec *codec, 18538 unsigned int res) 18539{ 18540 switch (res >> 26) { 18541 case ALC880_HP_EVENT: 18542 alc663_two_hp_m7_speaker_automute(codec); 18543 break; 18544 case ALC880_MIC_EVENT: 18545 alc_mic_automute(codec); 18546 break; 18547 } 18548} 18549 18550#define alc663_mode7_setup alc663_mode1_setup 18551 18552static void alc663_mode7_inithook(struct hda_codec *codec) 18553{ 18554 alc663_two_hp_m7_speaker_automute(codec); 18555 alc_mic_automute(codec); 18556} 18557 18558/* ***************** Mode8 ******************************/ 18559static void alc663_mode8_unsol_event(struct hda_codec *codec, 18560 unsigned int res) 18561{ 18562 switch (res >> 26) { 18563 case ALC880_HP_EVENT: 18564 alc663_two_hp_m8_speaker_automute(codec); 18565 break; 18566 case ALC880_MIC_EVENT: 18567 alc_mic_automute(codec); 18568 break; 18569 } 18570} 18571 18572#define alc663_mode8_setup alc663_m51va_setup 18573 18574static void alc663_mode8_inithook(struct hda_codec *codec) 18575{ 18576 alc663_two_hp_m8_speaker_automute(codec); 18577 alc_mic_automute(codec); 18578} 18579 18580static void alc663_g71v_hp_automute(struct hda_codec *codec) 18581{ 18582 unsigned int present; 18583 unsigned char bits; 18584 18585 present = snd_hda_jack_detect(codec, 0x21); 18586 bits = present ? HDA_AMP_MUTE : 0; 18587 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 18588 HDA_AMP_MUTE, bits); 18589 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 18590 HDA_AMP_MUTE, bits); 18591} 18592 18593static void alc663_g71v_front_automute(struct hda_codec *codec) 18594{ 18595 unsigned int present; 18596 unsigned char bits; 18597 18598 present = snd_hda_jack_detect(codec, 0x15); 18599 bits = present ? HDA_AMP_MUTE : 0; 18600 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 18601 HDA_AMP_MUTE, bits); 18602} 18603 18604static void alc663_g71v_unsol_event(struct hda_codec *codec, 18605 unsigned int res) 18606{ 18607 switch (res >> 26) { 18608 case ALC880_HP_EVENT: 18609 alc663_g71v_hp_automute(codec); 18610 break; 18611 case ALC880_FRONT_EVENT: 18612 alc663_g71v_front_automute(codec); 18613 break; 18614 case ALC880_MIC_EVENT: 18615 alc_mic_automute(codec); 18616 break; 18617 } 18618} 18619 18620#define alc663_g71v_setup alc663_m51va_setup 18621 18622static void alc663_g71v_inithook(struct hda_codec *codec) 18623{ 18624 alc663_g71v_front_automute(codec); 18625 alc663_g71v_hp_automute(codec); 18626 alc_mic_automute(codec); 18627} 18628 18629static void alc663_g50v_unsol_event(struct hda_codec *codec, 18630 unsigned int res) 18631{ 18632 switch (res >> 26) { 18633 case ALC880_HP_EVENT: 18634 alc663_m51va_speaker_automute(codec); 18635 break; 18636 case ALC880_MIC_EVENT: 18637 alc_mic_automute(codec); 18638 break; 18639 } 18640} 18641 18642#define alc663_g50v_setup alc663_m51va_setup 18643 18644static void alc663_g50v_inithook(struct hda_codec *codec) 18645{ 18646 alc663_m51va_speaker_automute(codec); 18647 alc_mic_automute(codec); 18648} 18649 18650static struct snd_kcontrol_new alc662_ecs_mixer[] = { 18651 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT), 18652 ALC262_HIPPO_MASTER_SWITCH, 18653 18654 HDA_CODEC_VOLUME("Mic/LineIn Boost Volume", 0x18, 0, HDA_INPUT), 18655 HDA_CODEC_VOLUME("Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT), 18656 HDA_CODEC_MUTE("Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT), 18657 18658 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), 18659 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 18660 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 18661 { } /* end */ 18662}; 18663 18664static struct snd_kcontrol_new alc272_nc10_mixer[] = { 18665 /* Master Playback automatically created from Speaker and Headphone */ 18666 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 18667 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 18668 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 18669 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT), 18670 18671 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 18672 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 18673 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 18674 18675 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 18676 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 18677 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), 18678 { } /* end */ 18679}; 18680 18681#ifdef CONFIG_SND_HDA_POWER_SAVE 18682#define alc662_loopbacks alc880_loopbacks 18683#endif 18684 18685 18686/* pcm configuration: identical with ALC880 */ 18687#define alc662_pcm_analog_playback alc880_pcm_analog_playback 18688#define alc662_pcm_analog_capture alc880_pcm_analog_capture 18689#define alc662_pcm_digital_playback alc880_pcm_digital_playback 18690#define alc662_pcm_digital_capture alc880_pcm_digital_capture 18691 18692/* 18693 * configuration and preset 18694 */ 18695static const char * const alc662_models[ALC662_MODEL_LAST] = { 18696 [ALC662_3ST_2ch_DIG] = "3stack-dig", 18697 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig", 18698 [ALC662_3ST_6ch] = "3stack-6ch", 18699 [ALC662_5ST_DIG] = "6stack-dig", 18700 [ALC662_LENOVO_101E] = "lenovo-101e", 18701 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701", 18702 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20", 18703 [ALC662_ECS] = "ecs", 18704 [ALC663_ASUS_M51VA] = "m51va", 18705 [ALC663_ASUS_G71V] = "g71v", 18706 [ALC663_ASUS_H13] = "h13", 18707 [ALC663_ASUS_G50V] = "g50v", 18708 [ALC663_ASUS_MODE1] = "asus-mode1", 18709 [ALC662_ASUS_MODE2] = "asus-mode2", 18710 [ALC663_ASUS_MODE3] = "asus-mode3", 18711 [ALC663_ASUS_MODE4] = "asus-mode4", 18712 [ALC663_ASUS_MODE5] = "asus-mode5", 18713 [ALC663_ASUS_MODE6] = "asus-mode6", 18714 [ALC663_ASUS_MODE7] = "asus-mode7", 18715 [ALC663_ASUS_MODE8] = "asus-mode8", 18716 [ALC272_DELL] = "dell", 18717 [ALC272_DELL_ZM1] = "dell-zm1", 18718 [ALC272_SAMSUNG_NC10] = "samsung-nc10", 18719 [ALC662_AUTO] = "auto", 18720}; 18721 18722static struct snd_pci_quirk alc662_cfg_tbl[] = { 18723 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS), 18724 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL), 18725 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1), 18726 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1), 18727 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3), 18728 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC663_ASUS_MODE1), 18729 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3), 18730 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1), 18731 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2), 18732 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1), 18733 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC663_ASUS_MODE1), 18734 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC663_ASUS_MODE1), 18735 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2), 18736 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC663_ASUS_MODE7), 18737 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC663_ASUS_MODE7), 18738 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC663_ASUS_MODE8), 18739 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC663_ASUS_MODE3), 18740 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC663_ASUS_MODE1), 18741 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2), 18742 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_ASUS_MODE2), 18743 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC663_ASUS_MODE1), 18744 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2), 18745 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6), 18746 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6), 18747 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2), 18748 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC663_ASUS_MODE1), 18749 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3), 18750 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA), 18751 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2), 18752 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2), 18753 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5), 18754 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6), 18755 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2), 18756 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1), 18757 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2), 18758 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2), 18759 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA), 18760 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/ 18761 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3), 18762 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3), 18763 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1), 18764 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC663_ASUS_MODE1), 18765 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1), 18766 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1), 18767 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1), 18768 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2), 18769 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2), 18770 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1), 18771 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1), 18772 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3), 18773 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1), 18774 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1), 18775 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V), 18776 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/ 18777 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1), 18778 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2), 18779 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA), 18780 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1), 18781 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4), 18782 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG), 18783 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701), 18784 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20), 18785 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS), 18786 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K", 18787 ALC662_3ST_6ch_DIG), 18788 SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO), 18789 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10), 18790 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L", 18791 ALC662_3ST_6ch_DIG), 18792 SND_PCI_QUIRK(0x152d, 0x2304, "Quanta WH1", ALC663_ASUS_H13), 18793 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG), 18794 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA), 18795 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E), 18796 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0", 18797 ALC662_3ST_6ch_DIG), 18798 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x", 18799 ALC663_ASUS_H13), 18800 {} 18801}; 18802 18803static struct alc_config_preset alc662_presets[] = { 18804 [ALC662_3ST_2ch_DIG] = { 18805 .mixers = { alc662_3ST_2ch_mixer }, 18806 .init_verbs = { alc662_init_verbs }, 18807 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18808 .dac_nids = alc662_dac_nids, 18809 .dig_out_nid = ALC662_DIGOUT_NID, 18810 .dig_in_nid = ALC662_DIGIN_NID, 18811 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18812 .channel_mode = alc662_3ST_2ch_modes, 18813 .input_mux = &alc662_capture_source, 18814 }, 18815 [ALC662_3ST_6ch_DIG] = { 18816 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer }, 18817 .init_verbs = { alc662_init_verbs }, 18818 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18819 .dac_nids = alc662_dac_nids, 18820 .dig_out_nid = ALC662_DIGOUT_NID, 18821 .dig_in_nid = ALC662_DIGIN_NID, 18822 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), 18823 .channel_mode = alc662_3ST_6ch_modes, 18824 .need_dac_fix = 1, 18825 .input_mux = &alc662_capture_source, 18826 }, 18827 [ALC662_3ST_6ch] = { 18828 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer }, 18829 .init_verbs = { alc662_init_verbs }, 18830 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18831 .dac_nids = alc662_dac_nids, 18832 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), 18833 .channel_mode = alc662_3ST_6ch_modes, 18834 .need_dac_fix = 1, 18835 .input_mux = &alc662_capture_source, 18836 }, 18837 [ALC662_5ST_DIG] = { 18838 .mixers = { alc662_base_mixer, alc662_chmode_mixer }, 18839 .init_verbs = { alc662_init_verbs }, 18840 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18841 .dac_nids = alc662_dac_nids, 18842 .dig_out_nid = ALC662_DIGOUT_NID, 18843 .dig_in_nid = ALC662_DIGIN_NID, 18844 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes), 18845 .channel_mode = alc662_5stack_modes, 18846 .input_mux = &alc662_capture_source, 18847 }, 18848 [ALC662_LENOVO_101E] = { 18849 .mixers = { alc662_lenovo_101e_mixer }, 18850 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs }, 18851 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18852 .dac_nids = alc662_dac_nids, 18853 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18854 .channel_mode = alc662_3ST_2ch_modes, 18855 .input_mux = &alc662_lenovo_101e_capture_source, 18856 .unsol_event = alc662_lenovo_101e_unsol_event, 18857 .init_hook = alc662_lenovo_101e_all_automute, 18858 }, 18859 [ALC662_ASUS_EEEPC_P701] = { 18860 .mixers = { alc662_eeepc_p701_mixer }, 18861 .init_verbs = { alc662_init_verbs, 18862 alc662_eeepc_sue_init_verbs }, 18863 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18864 .dac_nids = alc662_dac_nids, 18865 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18866 .channel_mode = alc662_3ST_2ch_modes, 18867 .unsol_event = alc662_eeepc_unsol_event, 18868 .setup = alc662_eeepc_setup, 18869 .init_hook = alc662_eeepc_inithook, 18870 }, 18871 [ALC662_ASUS_EEEPC_EP20] = { 18872 .mixers = { alc662_eeepc_ep20_mixer, 18873 alc662_chmode_mixer }, 18874 .init_verbs = { alc662_init_verbs, 18875 alc662_eeepc_ep20_sue_init_verbs }, 18876 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18877 .dac_nids = alc662_dac_nids, 18878 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), 18879 .channel_mode = alc662_3ST_6ch_modes, 18880 .input_mux = &alc662_lenovo_101e_capture_source, 18881 .unsol_event = alc662_eeepc_unsol_event, 18882 .setup = alc662_eeepc_ep20_setup, 18883 .init_hook = alc662_eeepc_ep20_inithook, 18884 }, 18885 [ALC662_ECS] = { 18886 .mixers = { alc662_ecs_mixer }, 18887 .init_verbs = { alc662_init_verbs, 18888 alc662_ecs_init_verbs }, 18889 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18890 .dac_nids = alc662_dac_nids, 18891 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18892 .channel_mode = alc662_3ST_2ch_modes, 18893 .unsol_event = alc662_eeepc_unsol_event, 18894 .setup = alc662_eeepc_setup, 18895 .init_hook = alc662_eeepc_inithook, 18896 }, 18897 [ALC663_ASUS_M51VA] = { 18898 .mixers = { alc663_m51va_mixer }, 18899 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs }, 18900 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18901 .dac_nids = alc662_dac_nids, 18902 .dig_out_nid = ALC662_DIGOUT_NID, 18903 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18904 .channel_mode = alc662_3ST_2ch_modes, 18905 .unsol_event = alc663_m51va_unsol_event, 18906 .setup = alc663_m51va_setup, 18907 .init_hook = alc663_m51va_inithook, 18908 }, 18909 [ALC663_ASUS_G71V] = { 18910 .mixers = { alc663_g71v_mixer }, 18911 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs }, 18912 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18913 .dac_nids = alc662_dac_nids, 18914 .dig_out_nid = ALC662_DIGOUT_NID, 18915 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18916 .channel_mode = alc662_3ST_2ch_modes, 18917 .unsol_event = alc663_g71v_unsol_event, 18918 .setup = alc663_g71v_setup, 18919 .init_hook = alc663_g71v_inithook, 18920 }, 18921 [ALC663_ASUS_H13] = { 18922 .mixers = { alc663_m51va_mixer }, 18923 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs }, 18924 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18925 .dac_nids = alc662_dac_nids, 18926 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18927 .channel_mode = alc662_3ST_2ch_modes, 18928 .unsol_event = alc663_m51va_unsol_event, 18929 .init_hook = alc663_m51va_inithook, 18930 }, 18931 [ALC663_ASUS_G50V] = { 18932 .mixers = { alc663_g50v_mixer }, 18933 .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs }, 18934 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18935 .dac_nids = alc662_dac_nids, 18936 .dig_out_nid = ALC662_DIGOUT_NID, 18937 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), 18938 .channel_mode = alc662_3ST_6ch_modes, 18939 .input_mux = &alc663_capture_source, 18940 .unsol_event = alc663_g50v_unsol_event, 18941 .setup = alc663_g50v_setup, 18942 .init_hook = alc663_g50v_inithook, 18943 }, 18944 [ALC663_ASUS_MODE1] = { 18945 .mixers = { alc663_m51va_mixer }, 18946 .cap_mixer = alc662_auto_capture_mixer, 18947 .init_verbs = { alc662_init_verbs, 18948 alc663_21jd_amic_init_verbs }, 18949 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18950 .hp_nid = 0x03, 18951 .dac_nids = alc662_dac_nids, 18952 .dig_out_nid = ALC662_DIGOUT_NID, 18953 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18954 .channel_mode = alc662_3ST_2ch_modes, 18955 .unsol_event = alc663_mode1_unsol_event, 18956 .setup = alc663_mode1_setup, 18957 .init_hook = alc663_mode1_inithook, 18958 }, 18959 [ALC662_ASUS_MODE2] = { 18960 .mixers = { alc662_1bjd_mixer }, 18961 .cap_mixer = alc662_auto_capture_mixer, 18962 .init_verbs = { alc662_init_verbs, 18963 alc662_1bjd_amic_init_verbs }, 18964 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18965 .dac_nids = alc662_dac_nids, 18966 .dig_out_nid = ALC662_DIGOUT_NID, 18967 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18968 .channel_mode = alc662_3ST_2ch_modes, 18969 .unsol_event = alc662_mode2_unsol_event, 18970 .setup = alc662_mode2_setup, 18971 .init_hook = alc662_mode2_inithook, 18972 }, 18973 [ALC663_ASUS_MODE3] = { 18974 .mixers = { alc663_two_hp_m1_mixer }, 18975 .cap_mixer = alc662_auto_capture_mixer, 18976 .init_verbs = { alc662_init_verbs, 18977 alc663_two_hp_amic_m1_init_verbs }, 18978 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18979 .hp_nid = 0x03, 18980 .dac_nids = alc662_dac_nids, 18981 .dig_out_nid = ALC662_DIGOUT_NID, 18982 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18983 .channel_mode = alc662_3ST_2ch_modes, 18984 .unsol_event = alc663_mode3_unsol_event, 18985 .setup = alc663_mode3_setup, 18986 .init_hook = alc663_mode3_inithook, 18987 }, 18988 [ALC663_ASUS_MODE4] = { 18989 .mixers = { alc663_asus_21jd_clfe_mixer }, 18990 .cap_mixer = alc662_auto_capture_mixer, 18991 .init_verbs = { alc662_init_verbs, 18992 alc663_21jd_amic_init_verbs}, 18993 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18994 .hp_nid = 0x03, 18995 .dac_nids = alc662_dac_nids, 18996 .dig_out_nid = ALC662_DIGOUT_NID, 18997 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18998 .channel_mode = alc662_3ST_2ch_modes, 18999 .unsol_event = alc663_mode4_unsol_event, 19000 .setup = alc663_mode4_setup, 19001 .init_hook = alc663_mode4_inithook, 19002 }, 19003 [ALC663_ASUS_MODE5] = { 19004 .mixers = { alc663_asus_15jd_clfe_mixer }, 19005 .cap_mixer = alc662_auto_capture_mixer, 19006 .init_verbs = { alc662_init_verbs, 19007 alc663_15jd_amic_init_verbs }, 19008 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 19009 .hp_nid = 0x03, 19010 .dac_nids = alc662_dac_nids, 19011 .dig_out_nid = ALC662_DIGOUT_NID, 19012 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 19013 .channel_mode = alc662_3ST_2ch_modes, 19014 .unsol_event = alc663_mode5_unsol_event, 19015 .setup = alc663_mode5_setup, 19016 .init_hook = alc663_mode5_inithook, 19017 }, 19018 [ALC663_ASUS_MODE6] = { 19019 .mixers = { alc663_two_hp_m2_mixer }, 19020 .cap_mixer = alc662_auto_capture_mixer, 19021 .init_verbs = { alc662_init_verbs, 19022 alc663_two_hp_amic_m2_init_verbs }, 19023 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 19024 .hp_nid = 0x03, 19025 .dac_nids = alc662_dac_nids, 19026 .dig_out_nid = ALC662_DIGOUT_NID, 19027 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 19028 .channel_mode = alc662_3ST_2ch_modes, 19029 .unsol_event = alc663_mode6_unsol_event, 19030 .setup = alc663_mode6_setup, 19031 .init_hook = alc663_mode6_inithook, 19032 }, 19033 [ALC663_ASUS_MODE7] = { 19034 .mixers = { alc663_mode7_mixer }, 19035 .cap_mixer = alc662_auto_capture_mixer, 19036 .init_verbs = { alc662_init_verbs, 19037 alc663_mode7_init_verbs }, 19038 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 19039 .hp_nid = 0x03, 19040 .dac_nids = alc662_dac_nids, 19041 .dig_out_nid = ALC662_DIGOUT_NID, 19042 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 19043 .channel_mode = alc662_3ST_2ch_modes, 19044 .unsol_event = alc663_mode7_unsol_event, 19045 .setup = alc663_mode7_setup, 19046 .init_hook = alc663_mode7_inithook, 19047 }, 19048 [ALC663_ASUS_MODE8] = { 19049 .mixers = { alc663_mode8_mixer }, 19050 .cap_mixer = alc662_auto_capture_mixer, 19051 .init_verbs = { alc662_init_verbs, 19052 alc663_mode8_init_verbs }, 19053 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 19054 .hp_nid = 0x03, 19055 .dac_nids = alc662_dac_nids, 19056 .dig_out_nid = ALC662_DIGOUT_NID, 19057 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 19058 .channel_mode = alc662_3ST_2ch_modes, 19059 .unsol_event = alc663_mode8_unsol_event, 19060 .setup = alc663_mode8_setup, 19061 .init_hook = alc663_mode8_inithook, 19062 }, 19063 [ALC272_DELL] = { 19064 .mixers = { alc663_m51va_mixer }, 19065 .cap_mixer = alc272_auto_capture_mixer, 19066 .init_verbs = { alc662_init_verbs, alc272_dell_init_verbs }, 19067 .num_dacs = ARRAY_SIZE(alc272_dac_nids), 19068 .dac_nids = alc662_dac_nids, 19069 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 19070 .adc_nids = alc272_adc_nids, 19071 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids), 19072 .capsrc_nids = alc272_capsrc_nids, 19073 .channel_mode = alc662_3ST_2ch_modes, 19074 .unsol_event = alc663_m51va_unsol_event, 19075 .setup = alc663_m51va_setup, 19076 .init_hook = alc663_m51va_inithook, 19077 }, 19078 [ALC272_DELL_ZM1] = { 19079 .mixers = { alc663_m51va_mixer }, 19080 .cap_mixer = alc662_auto_capture_mixer, 19081 .init_verbs = { alc662_init_verbs, alc272_dell_zm1_init_verbs }, 19082 .num_dacs = ARRAY_SIZE(alc272_dac_nids), 19083 .dac_nids = alc662_dac_nids, 19084 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 19085 .adc_nids = alc662_adc_nids, 19086 .num_adc_nids = 1, 19087 .capsrc_nids = alc662_capsrc_nids, 19088 .channel_mode = alc662_3ST_2ch_modes, 19089 .unsol_event = alc663_m51va_unsol_event, 19090 .setup = alc663_m51va_setup, 19091 .init_hook = alc663_m51va_inithook, 19092 }, 19093 [ALC272_SAMSUNG_NC10] = { 19094 .mixers = { alc272_nc10_mixer }, 19095 .init_verbs = { alc662_init_verbs, 19096 alc663_21jd_amic_init_verbs }, 19097 .num_dacs = ARRAY_SIZE(alc272_dac_nids), 19098 .dac_nids = alc272_dac_nids, 19099 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 19100 .channel_mode = alc662_3ST_2ch_modes, 19101 /*.input_mux = &alc272_nc10_capture_source,*/ 19102 .unsol_event = alc663_mode4_unsol_event, 19103 .setup = alc663_mode4_setup, 19104 .init_hook = alc663_mode4_inithook, 19105 }, 19106}; 19107 19108 19109/* 19110 * BIOS auto configuration 19111 */ 19112 19113/* convert from MIX nid to DAC */ 19114static inline hda_nid_t alc662_mix_to_dac(hda_nid_t nid) 19115{ 19116 if (nid == 0x0f) 19117 return 0x02; 19118 else if (nid >= 0x0c && nid <= 0x0e) 19119 return nid - 0x0c + 0x02; 19120 else if (nid == 0x26) /* ALC887-VD has this DAC too */ 19121 return 0x25; 19122 else 19123 return 0; 19124} 19125 19126/* get MIX nid connected to the given pin targeted to DAC */ 19127static hda_nid_t alc662_dac_to_mix(struct hda_codec *codec, hda_nid_t pin, 19128 hda_nid_t dac) 19129{ 19130 hda_nid_t mix[5]; 19131 int i, num; 19132 19133 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix)); 19134 for (i = 0; i < num; i++) { 19135 if (alc662_mix_to_dac(mix[i]) == dac) 19136 return mix[i]; 19137 } 19138 return 0; 19139} 19140 19141/* look for an empty DAC slot */ 19142static hda_nid_t alc662_look_for_dac(struct hda_codec *codec, hda_nid_t pin) 19143{ 19144 struct alc_spec *spec = codec->spec; 19145 hda_nid_t srcs[5]; 19146 int i, j, num; 19147 19148 num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs)); 19149 if (num < 0) 19150 return 0; 19151 for (i = 0; i < num; i++) { 19152 hda_nid_t nid = alc662_mix_to_dac(srcs[i]); 19153 if (!nid) 19154 continue; 19155 for (j = 0; j < spec->multiout.num_dacs; j++) 19156 if (spec->multiout.dac_nids[j] == nid) 19157 break; 19158 if (j >= spec->multiout.num_dacs) 19159 return nid; 19160 } 19161 return 0; 19162} 19163 19164/* fill in the dac_nids table from the parsed pin configuration */ 19165static int alc662_auto_fill_dac_nids(struct hda_codec *codec, 19166 const struct auto_pin_cfg *cfg) 19167{ 19168 struct alc_spec *spec = codec->spec; 19169 int i; 19170 hda_nid_t dac; 19171 19172 spec->multiout.dac_nids = spec->private_dac_nids; 19173 for (i = 0; i < cfg->line_outs; i++) { 19174 dac = alc662_look_for_dac(codec, cfg->line_out_pins[i]); 19175 if (!dac) 19176 continue; 19177 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac; 19178 } 19179 return 0; 19180} 19181 19182static inline int __alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx, 19183 hda_nid_t nid, int idx, unsigned int chs) 19184{ 19185 return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx, 19186 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT)); 19187} 19188 19189static inline int __alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx, 19190 hda_nid_t nid, int idx, unsigned int chs) 19191{ 19192 return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx, 19193 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT)); 19194} 19195 19196#define alc662_add_vol_ctl(spec, pfx, nid, chs) \ 19197 __alc662_add_vol_ctl(spec, pfx, nid, 0, chs) 19198#define alc662_add_sw_ctl(spec, pfx, nid, chs) \ 19199 __alc662_add_sw_ctl(spec, pfx, nid, 0, chs) 19200#define alc662_add_stereo_vol(spec, pfx, nid) \ 19201 alc662_add_vol_ctl(spec, pfx, nid, 3) 19202#define alc662_add_stereo_sw(spec, pfx, nid) \ 19203 alc662_add_sw_ctl(spec, pfx, nid, 3) 19204 19205/* add playback controls from the parsed DAC table */ 19206static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec, 19207 const struct auto_pin_cfg *cfg) 19208{ 19209 struct alc_spec *spec = codec->spec; 19210 static const char * const chname[4] = { 19211 "Front", "Surround", NULL /*CLFE*/, "Side" 19212 }; 19213 const char *pfx = alc_get_line_out_pfx(cfg, true); 19214 hda_nid_t nid, mix; 19215 int i, err; 19216 19217 for (i = 0; i < cfg->line_outs; i++) { 19218 nid = spec->multiout.dac_nids[i]; 19219 if (!nid) 19220 continue; 19221 mix = alc662_dac_to_mix(codec, cfg->line_out_pins[i], nid); 19222 if (!mix) 19223 continue; 19224 if (!pfx && i == 2) { 19225 /* Center/LFE */ 19226 err = alc662_add_vol_ctl(spec, "Center", nid, 1); 19227 if (err < 0) 19228 return err; 19229 err = alc662_add_vol_ctl(spec, "LFE", nid, 2); 19230 if (err < 0) 19231 return err; 19232 err = alc662_add_sw_ctl(spec, "Center", mix, 1); 19233 if (err < 0) 19234 return err; 19235 err = alc662_add_sw_ctl(spec, "LFE", mix, 2); 19236 if (err < 0) 19237 return err; 19238 } else { 19239 const char *name = pfx; 19240 if (!name) 19241 name = chname[i]; 19242 err = __alc662_add_vol_ctl(spec, name, nid, i, 3); 19243 if (err < 0) 19244 return err; 19245 err = __alc662_add_sw_ctl(spec, name, mix, i, 3); 19246 if (err < 0) 19247 return err; 19248 } 19249 } 19250 return 0; 19251} 19252 19253/* add playback controls for speaker and HP outputs */ 19254/* return DAC nid if any new DAC is assigned */ 19255static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin, 19256 const char *pfx) 19257{ 19258 struct alc_spec *spec = codec->spec; 19259 hda_nid_t nid, mix; 19260 int err; 19261 19262 if (!pin) 19263 return 0; 19264 nid = alc662_look_for_dac(codec, pin); 19265 if (!nid) { 19266 /* the corresponding DAC is already occupied */ 19267 if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP)) 19268 return 0; /* no way */ 19269 /* create a switch only */ 19270 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, 19271 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); 19272 } 19273 19274 mix = alc662_dac_to_mix(codec, pin, nid); 19275 if (!mix) 19276 return 0; 19277 err = alc662_add_vol_ctl(spec, pfx, nid, 3); 19278 if (err < 0) 19279 return err; 19280 err = alc662_add_sw_ctl(spec, pfx, mix, 3); 19281 if (err < 0) 19282 return err; 19283 return nid; 19284} 19285 19286/* create playback/capture controls for input pins */ 19287#define alc662_auto_create_input_ctls \ 19288 alc882_auto_create_input_ctls 19289 19290static void alc662_auto_set_output_and_unmute(struct hda_codec *codec, 19291 hda_nid_t nid, int pin_type, 19292 hda_nid_t dac) 19293{ 19294 int i, num; 19295 hda_nid_t srcs[HDA_MAX_CONNECTIONS]; 19296 19297 alc_set_pin_output(codec, nid, pin_type); 19298 /* need the manual connection? */ 19299 num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs)); 19300 if (num <= 1) 19301 return; 19302 for (i = 0; i < num; i++) { 19303 if (alc662_mix_to_dac(srcs[i]) != dac) 19304 continue; 19305 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, i); 19306 return; 19307 } 19308} 19309 19310static void alc662_auto_init_multi_out(struct hda_codec *codec) 19311{ 19312 struct alc_spec *spec = codec->spec; 19313 int pin_type = get_pin_type(spec->autocfg.line_out_type); 19314 int i; 19315 19316 for (i = 0; i <= HDA_SIDE; i++) { 19317 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 19318 if (nid) 19319 alc662_auto_set_output_and_unmute(codec, nid, pin_type, 19320 spec->multiout.dac_nids[i]); 19321 } 19322} 19323 19324static void alc662_auto_init_hp_out(struct hda_codec *codec) 19325{ 19326 struct alc_spec *spec = codec->spec; 19327 hda_nid_t pin; 19328 19329 pin = spec->autocfg.hp_pins[0]; 19330 if (pin) 19331 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 19332 spec->multiout.hp_nid); 19333 pin = spec->autocfg.speaker_pins[0]; 19334 if (pin) 19335 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT, 19336 spec->multiout.extra_out_nid[0]); 19337} 19338 19339#define ALC662_PIN_CD_NID ALC880_PIN_CD_NID 19340 19341static void alc662_auto_init_analog_input(struct hda_codec *codec) 19342{ 19343 struct alc_spec *spec = codec->spec; 19344 struct auto_pin_cfg *cfg = &spec->autocfg; 19345 int i; 19346 19347 for (i = 0; i < cfg->num_inputs; i++) { 19348 hda_nid_t nid = cfg->inputs[i].pin; 19349 if (alc_is_input_pin(codec, nid)) { 19350 alc_set_input_pin(codec, nid, cfg->inputs[i].type); 19351 if (nid != ALC662_PIN_CD_NID && 19352 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)) 19353 snd_hda_codec_write(codec, nid, 0, 19354 AC_VERB_SET_AMP_GAIN_MUTE, 19355 AMP_OUT_MUTE); 19356 } 19357 } 19358} 19359 19360#define alc662_auto_init_input_src alc882_auto_init_input_src 19361 19362static int alc662_parse_auto_config(struct hda_codec *codec) 19363{ 19364 struct alc_spec *spec = codec->spec; 19365 int err; 19366 static hda_nid_t alc662_ignore[] = { 0x1d, 0 }; 19367 19368 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 19369 alc662_ignore); 19370 if (err < 0) 19371 return err; 19372 if (!spec->autocfg.line_outs) 19373 return 0; /* can't find valid BIOS pin config */ 19374 19375 err = alc662_auto_fill_dac_nids(codec, &spec->autocfg); 19376 if (err < 0) 19377 return err; 19378 err = alc662_auto_create_multi_out_ctls(codec, &spec->autocfg); 19379 if (err < 0) 19380 return err; 19381 err = alc662_auto_create_extra_out(codec, 19382 spec->autocfg.speaker_pins[0], 19383 "Speaker"); 19384 if (err < 0) 19385 return err; 19386 if (err) 19387 spec->multiout.extra_out_nid[0] = err; 19388 err = alc662_auto_create_extra_out(codec, spec->autocfg.hp_pins[0], 19389 "Headphone"); 19390 if (err < 0) 19391 return err; 19392 if (err) 19393 spec->multiout.hp_nid = err; 19394 err = alc662_auto_create_input_ctls(codec, &spec->autocfg); 19395 if (err < 0) 19396 return err; 19397 19398 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 19399 19400 alc_auto_parse_digital(codec); 19401 19402 if (spec->kctls.list) 19403 add_mixer(spec, spec->kctls.list); 19404 19405 spec->num_mux_defs = 1; 19406 spec->input_mux = &spec->private_imux[0]; 19407 19408 add_verb(spec, alc662_init_verbs); 19409 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 || 19410 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670) 19411 add_verb(spec, alc663_init_verbs); 19412 19413 if (codec->vendor_id == 0x10ec0272) 19414 add_verb(spec, alc272_init_verbs); 19415 19416 err = alc_auto_add_mic_boost(codec); 19417 if (err < 0) 19418 return err; 19419 19420 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 || 19421 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670) 19422 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0x21); 19423 else 19424 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); 19425 19426 return 1; 19427} 19428 19429/* additional initialization for auto-configuration model */ 19430static void alc662_auto_init(struct hda_codec *codec) 19431{ 19432 struct alc_spec *spec = codec->spec; 19433 alc662_auto_init_multi_out(codec); 19434 alc662_auto_init_hp_out(codec); 19435 alc662_auto_init_analog_input(codec); 19436 alc662_auto_init_input_src(codec); 19437 alc_auto_init_digital(codec); 19438 if (spec->unsol_event) 19439 alc_inithook(codec); 19440} 19441 19442static void alc272_fixup_mario(struct hda_codec *codec, 19443 const struct alc_fixup *fix, int action) 19444{ 19445 if (action != ALC_FIXUP_ACT_PROBE) 19446 return; 19447 if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT, 19448 (0x3b << AC_AMPCAP_OFFSET_SHIFT) | 19449 (0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) | 19450 (0x03 << AC_AMPCAP_STEP_SIZE_SHIFT) | 19451 (0 << AC_AMPCAP_MUTE_SHIFT))) 19452 printk(KERN_WARNING 19453 "hda_codec: failed to override amp caps for NID 0x2\n"); 19454} 19455 19456enum { 19457 ALC662_FIXUP_ASPIRE, 19458 ALC662_FIXUP_IDEAPAD, 19459 ALC272_FIXUP_MARIO, 19460}; 19461 19462static const struct alc_fixup alc662_fixups[] = { 19463 [ALC662_FIXUP_ASPIRE] = { 19464 .type = ALC_FIXUP_PINS, 19465 .v.pins = (const struct alc_pincfg[]) { 19466 { 0x15, 0x99130112 }, /* subwoofer */ 19467 { } 19468 } 19469 }, 19470 [ALC662_FIXUP_IDEAPAD] = { 19471 .type = ALC_FIXUP_PINS, 19472 .v.pins = (const struct alc_pincfg[]) { 19473 { 0x17, 0x99130112 }, /* subwoofer */ 19474 { } 19475 } 19476 }, 19477 [ALC272_FIXUP_MARIO] = { 19478 .type = ALC_FIXUP_FUNC, 19479 .v.func = alc272_fixup_mario, 19480 } 19481}; 19482 19483static struct snd_pci_quirk alc662_fixup_tbl[] = { 19484 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE), 19485 SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD), 19486 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD), 19487 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD), 19488 {} 19489}; 19490 19491static const struct alc_model_fixup alc662_fixup_models[] = { 19492 {.id = ALC272_FIXUP_MARIO, .name = "mario"}, 19493 {} 19494}; 19495 19496 19497static int patch_alc662(struct hda_codec *codec) 19498{ 19499 struct alc_spec *spec; 19500 int err, board_config; 19501 int coef; 19502 19503 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 19504 if (!spec) 19505 return -ENOMEM; 19506 19507 codec->spec = spec; 19508 19509 alc_auto_parse_customize_define(codec); 19510 19511 alc_fix_pll_init(codec, 0x20, 0x04, 15); 19512 19513 coef = alc_read_coef_idx(codec, 0); 19514 if (coef == 0x8020 || coef == 0x8011) 19515 alc_codec_rename(codec, "ALC661"); 19516 else if (coef & (1 << 14) && 19517 codec->bus->pci->subsystem_vendor == 0x1025 && 19518 spec->cdefine.platform_type == 1) 19519 alc_codec_rename(codec, "ALC272X"); 19520 else if (coef == 0x4011) 19521 alc_codec_rename(codec, "ALC656"); 19522 19523 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST, 19524 alc662_models, 19525 alc662_cfg_tbl); 19526 if (board_config < 0) { 19527 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 19528 codec->chip_name); 19529 board_config = ALC662_AUTO; 19530 } 19531 19532 if (board_config == ALC662_AUTO) { 19533 alc_pick_fixup(codec, alc662_fixup_models, 19534 alc662_fixup_tbl, alc662_fixups); 19535 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); 19536 /* automatic parse from the BIOS config */ 19537 err = alc662_parse_auto_config(codec); 19538 if (err < 0) { 19539 alc_free(codec); 19540 return err; 19541 } else if (!err) { 19542 printk(KERN_INFO 19543 "hda_codec: Cannot set up configuration " 19544 "from BIOS. Using base mode...\n"); 19545 board_config = ALC662_3ST_2ch_DIG; 19546 } 19547 } 19548 19549 if (has_cdefine_beep(codec)) { 19550 err = snd_hda_attach_beep_device(codec, 0x1); 19551 if (err < 0) { 19552 alc_free(codec); 19553 return err; 19554 } 19555 } 19556 19557 if (board_config != ALC662_AUTO) 19558 setup_preset(codec, &alc662_presets[board_config]); 19559 19560 spec->stream_analog_playback = &alc662_pcm_analog_playback; 19561 spec->stream_analog_capture = &alc662_pcm_analog_capture; 19562 19563 spec->stream_digital_playback = &alc662_pcm_digital_playback; 19564 spec->stream_digital_capture = &alc662_pcm_digital_capture; 19565 19566 if (!spec->adc_nids) { 19567 spec->adc_nids = alc662_adc_nids; 19568 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids); 19569 } 19570 if (!spec->capsrc_nids) 19571 spec->capsrc_nids = alc662_capsrc_nids; 19572 19573 if (!spec->cap_mixer) 19574 set_capture_mixer(codec); 19575 19576 if (has_cdefine_beep(codec)) { 19577 switch (codec->vendor_id) { 19578 case 0x10ec0662: 19579 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 19580 break; 19581 case 0x10ec0272: 19582 case 0x10ec0663: 19583 case 0x10ec0665: 19584 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); 19585 break; 19586 case 0x10ec0273: 19587 set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT); 19588 break; 19589 } 19590 } 19591 spec->vmaster_nid = 0x02; 19592 19593 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); 19594 19595 codec->patch_ops = alc_patch_ops; 19596 if (board_config == ALC662_AUTO) 19597 spec->init_hook = alc662_auto_init; 19598 19599 alc_init_jacks(codec); 19600 19601#ifdef CONFIG_SND_HDA_POWER_SAVE 19602 if (!spec->loopback.amplist) 19603 spec->loopback.amplist = alc662_loopbacks; 19604#endif 19605 19606 return 0; 19607} 19608 19609static int patch_alc888(struct hda_codec *codec) 19610{ 19611 if ((alc_read_coef_idx(codec, 0) & 0x00f0)==0x0030){ 19612 kfree(codec->chip_name); 19613 if (codec->vendor_id == 0x10ec0887) 19614 codec->chip_name = kstrdup("ALC887-VD", GFP_KERNEL); 19615 else 19616 codec->chip_name = kstrdup("ALC888-VD", GFP_KERNEL); 19617 if (!codec->chip_name) { 19618 alc_free(codec); 19619 return -ENOMEM; 19620 } 19621 return patch_alc662(codec); 19622 } 19623 return patch_alc882(codec); 19624} 19625 19626/* 19627 * ALC680 support 19628 */ 19629#define ALC680_DIGIN_NID ALC880_DIGIN_NID 19630#define ALC680_DIGOUT_NID ALC880_DIGOUT_NID 19631#define alc680_modes alc260_modes 19632 19633static hda_nid_t alc680_dac_nids[3] = { 19634 /* Lout1, Lout2, hp */ 19635 0x02, 0x03, 0x04 19636}; 19637 19638static hda_nid_t alc680_adc_nids[3] = { 19639 /* ADC0-2 */ 19640 /* DMIC, MIC, Line-in*/ 19641 0x07, 0x08, 0x09 19642}; 19643 19644/* 19645 * Analog capture ADC cgange 19646 */ 19647static void alc680_rec_autoswitch(struct hda_codec *codec) 19648{ 19649 struct alc_spec *spec = codec->spec; 19650 struct auto_pin_cfg *cfg = &spec->autocfg; 19651 int pin_found = 0; 19652 int type_found = AUTO_PIN_LAST; 19653 hda_nid_t nid; 19654 int i; 19655 19656 for (i = 0; i < cfg->num_inputs; i++) { 19657 nid = cfg->inputs[i].pin; 19658 if (!(snd_hda_query_pin_caps(codec, nid) & 19659 AC_PINCAP_PRES_DETECT)) 19660 continue; 19661 if (snd_hda_jack_detect(codec, nid)) { 19662 if (cfg->inputs[i].type < type_found) { 19663 type_found = cfg->inputs[i].type; 19664 pin_found = nid; 19665 } 19666 } 19667 } 19668 19669 nid = 0x07; 19670 if (pin_found) 19671 snd_hda_get_connections(codec, pin_found, &nid, 1); 19672 19673 if (nid != spec->cur_adc) 19674 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1); 19675 spec->cur_adc = nid; 19676 snd_hda_codec_setup_stream(codec, nid, spec->cur_adc_stream_tag, 0, 19677 spec->cur_adc_format); 19678} 19679 19680static int alc680_capture_pcm_prepare(struct hda_pcm_stream *hinfo, 19681 struct hda_codec *codec, 19682 unsigned int stream_tag, 19683 unsigned int format, 19684 struct snd_pcm_substream *substream) 19685{ 19686 struct alc_spec *spec = codec->spec; 19687 19688 spec->cur_adc = 0x07; 19689 spec->cur_adc_stream_tag = stream_tag; 19690 spec->cur_adc_format = format; 19691 19692 alc680_rec_autoswitch(codec); 19693 return 0; 19694} 19695 19696static int alc680_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, 19697 struct hda_codec *codec, 19698 struct snd_pcm_substream *substream) 19699{ 19700 snd_hda_codec_cleanup_stream(codec, 0x07); 19701 snd_hda_codec_cleanup_stream(codec, 0x08); 19702 snd_hda_codec_cleanup_stream(codec, 0x09); 19703 return 0; 19704} 19705 19706static struct hda_pcm_stream alc680_pcm_analog_auto_capture = { 19707 .substreams = 1, /* can be overridden */ 19708 .channels_min = 2, 19709 .channels_max = 2, 19710 /* NID is set in alc_build_pcms */ 19711 .ops = { 19712 .prepare = alc680_capture_pcm_prepare, 19713 .cleanup = alc680_capture_pcm_cleanup 19714 }, 19715}; 19716 19717static struct snd_kcontrol_new alc680_base_mixer[] = { 19718 /* output mixer control */ 19719 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), 19720 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 19721 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT), 19722 HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT), 19723 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x12, 0, HDA_INPUT), 19724 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 19725 HDA_CODEC_VOLUME("Line In Boost Volume", 0x19, 0, HDA_INPUT), 19726 { } 19727}; 19728 19729static struct hda_bind_ctls alc680_bind_cap_vol = { 19730 .ops = &snd_hda_bind_vol, 19731 .values = { 19732 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT), 19733 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT), 19734 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT), 19735 0 19736 }, 19737}; 19738 19739static struct hda_bind_ctls alc680_bind_cap_switch = { 19740 .ops = &snd_hda_bind_sw, 19741 .values = { 19742 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT), 19743 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT), 19744 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT), 19745 0 19746 }, 19747}; 19748 19749static struct snd_kcontrol_new alc680_master_capture_mixer[] = { 19750 HDA_BIND_VOL("Capture Volume", &alc680_bind_cap_vol), 19751 HDA_BIND_SW("Capture Switch", &alc680_bind_cap_switch), 19752 { } /* end */ 19753}; 19754 19755/* 19756 * generic initialization of ADC, input mixers and output mixers 19757 */ 19758static struct hda_verb alc680_init_verbs[] = { 19759 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 19760 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 19761 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 19762 19763 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 19764 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 19765 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 19766 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 19767 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 19768 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 19769 19770 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 19771 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 19772 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 19773 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 19774 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 19775 19776 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 19777 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, 19778 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, 19779 19780 { } 19781}; 19782 19783/* toggle speaker-output according to the hp-jack state */ 19784static void alc680_base_setup(struct hda_codec *codec) 19785{ 19786 struct alc_spec *spec = codec->spec; 19787 19788 spec->autocfg.hp_pins[0] = 0x16; 19789 spec->autocfg.speaker_pins[0] = 0x14; 19790 spec->autocfg.speaker_pins[1] = 0x15; 19791 spec->autocfg.num_inputs = 2; 19792 spec->autocfg.inputs[0].pin = 0x18; 19793 spec->autocfg.inputs[0].type = AUTO_PIN_MIC; 19794 spec->autocfg.inputs[1].pin = 0x19; 19795 spec->autocfg.inputs[1].type = AUTO_PIN_LINE_IN; 19796} 19797 19798static void alc680_unsol_event(struct hda_codec *codec, 19799 unsigned int res) 19800{ 19801 if ((res >> 26) == ALC880_HP_EVENT) 19802 alc_automute_amp(codec); 19803 if ((res >> 26) == ALC880_MIC_EVENT) 19804 alc680_rec_autoswitch(codec); 19805} 19806 19807static void alc680_inithook(struct hda_codec *codec) 19808{ 19809 alc_automute_amp(codec); 19810 alc680_rec_autoswitch(codec); 19811} 19812 19813/* create input playback/capture controls for the given pin */ 19814static int alc680_new_analog_output(struct alc_spec *spec, hda_nid_t nid, 19815 const char *ctlname, int idx) 19816{ 19817 hda_nid_t dac; 19818 int err; 19819 19820 switch (nid) { 19821 case 0x14: 19822 dac = 0x02; 19823 break; 19824 case 0x15: 19825 dac = 0x03; 19826 break; 19827 case 0x16: 19828 dac = 0x04; 19829 break; 19830 default: 19831 return 0; 19832 } 19833 if (spec->multiout.dac_nids[0] != dac && 19834 spec->multiout.dac_nids[1] != dac) { 19835 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname, 19836 HDA_COMPOSE_AMP_VAL(dac, 3, idx, 19837 HDA_OUTPUT)); 19838 if (err < 0) 19839 return err; 19840 19841 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname, 19842 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT)); 19843 19844 if (err < 0) 19845 return err; 19846 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac; 19847 } 19848 19849 return 0; 19850} 19851 19852/* add playback controls from the parsed DAC table */ 19853static int alc680_auto_create_multi_out_ctls(struct alc_spec *spec, 19854 const struct auto_pin_cfg *cfg) 19855{ 19856 hda_nid_t nid; 19857 int err; 19858 19859 spec->multiout.dac_nids = spec->private_dac_nids; 19860 19861 nid = cfg->line_out_pins[0]; 19862 if (nid) { 19863 const char *name; 19864 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) 19865 name = "Speaker"; 19866 else 19867 name = "Front"; 19868 err = alc680_new_analog_output(spec, nid, name, 0); 19869 if (err < 0) 19870 return err; 19871 } 19872 19873 nid = cfg->speaker_pins[0]; 19874 if (nid) { 19875 err = alc680_new_analog_output(spec, nid, "Speaker", 0); 19876 if (err < 0) 19877 return err; 19878 } 19879 nid = cfg->hp_pins[0]; 19880 if (nid) { 19881 err = alc680_new_analog_output(spec, nid, "Headphone", 0); 19882 if (err < 0) 19883 return err; 19884 } 19885 19886 return 0; 19887} 19888 19889static void alc680_auto_set_output_and_unmute(struct hda_codec *codec, 19890 hda_nid_t nid, int pin_type) 19891{ 19892 alc_set_pin_output(codec, nid, pin_type); 19893} 19894 19895static void alc680_auto_init_multi_out(struct hda_codec *codec) 19896{ 19897 struct alc_spec *spec = codec->spec; 19898 hda_nid_t nid = spec->autocfg.line_out_pins[0]; 19899 if (nid) { 19900 int pin_type = get_pin_type(spec->autocfg.line_out_type); 19901 alc680_auto_set_output_and_unmute(codec, nid, pin_type); 19902 } 19903} 19904 19905static void alc680_auto_init_hp_out(struct hda_codec *codec) 19906{ 19907 struct alc_spec *spec = codec->spec; 19908 hda_nid_t pin; 19909 19910 pin = spec->autocfg.hp_pins[0]; 19911 if (pin) 19912 alc680_auto_set_output_and_unmute(codec, pin, PIN_HP); 19913 pin = spec->autocfg.speaker_pins[0]; 19914 if (pin) 19915 alc680_auto_set_output_and_unmute(codec, pin, PIN_OUT); 19916} 19917 19918/* pcm configuration: identical with ALC880 */ 19919#define alc680_pcm_analog_playback alc880_pcm_analog_playback 19920#define alc680_pcm_analog_capture alc880_pcm_analog_capture 19921#define alc680_pcm_analog_alt_capture alc880_pcm_analog_alt_capture 19922#define alc680_pcm_digital_playback alc880_pcm_digital_playback 19923#define alc680_pcm_digital_capture alc880_pcm_digital_capture 19924 19925/* 19926 * BIOS auto configuration 19927 */ 19928static int alc680_parse_auto_config(struct hda_codec *codec) 19929{ 19930 struct alc_spec *spec = codec->spec; 19931 int err; 19932 static hda_nid_t alc680_ignore[] = { 0 }; 19933 19934 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 19935 alc680_ignore); 19936 if (err < 0) 19937 return err; 19938 19939 if (!spec->autocfg.line_outs) { 19940 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) { 19941 spec->multiout.max_channels = 2; 19942 spec->no_analog = 1; 19943 goto dig_only; 19944 } 19945 return 0; /* can't find valid BIOS pin config */ 19946 } 19947 err = alc680_auto_create_multi_out_ctls(spec, &spec->autocfg); 19948 if (err < 0) 19949 return err; 19950 19951 spec->multiout.max_channels = 2; 19952 19953 dig_only: 19954 /* digital only support output */ 19955 alc_auto_parse_digital(codec); 19956 if (spec->kctls.list) 19957 add_mixer(spec, spec->kctls.list); 19958 19959 add_verb(spec, alc680_init_verbs); 19960 19961 err = alc_auto_add_mic_boost(codec); 19962 if (err < 0) 19963 return err; 19964 19965 return 1; 19966} 19967 19968#define alc680_auto_init_analog_input alc882_auto_init_analog_input 19969 19970/* init callback for auto-configuration model -- overriding the default init */ 19971static void alc680_auto_init(struct hda_codec *codec) 19972{ 19973 struct alc_spec *spec = codec->spec; 19974 alc680_auto_init_multi_out(codec); 19975 alc680_auto_init_hp_out(codec); 19976 alc680_auto_init_analog_input(codec); 19977 alc_auto_init_digital(codec); 19978 if (spec->unsol_event) 19979 alc_inithook(codec); 19980} 19981 19982/* 19983 * configuration and preset 19984 */ 19985static const char * const alc680_models[ALC680_MODEL_LAST] = { 19986 [ALC680_BASE] = "base", 19987 [ALC680_AUTO] = "auto", 19988}; 19989 19990static struct snd_pci_quirk alc680_cfg_tbl[] = { 19991 SND_PCI_QUIRK(0x1043, 0x12f3, "ASUS NX90", ALC680_BASE), 19992 {} 19993}; 19994 19995static struct alc_config_preset alc680_presets[] = { 19996 [ALC680_BASE] = { 19997 .mixers = { alc680_base_mixer }, 19998 .cap_mixer = alc680_master_capture_mixer, 19999 .init_verbs = { alc680_init_verbs }, 20000 .num_dacs = ARRAY_SIZE(alc680_dac_nids), 20001 .dac_nids = alc680_dac_nids, 20002 .dig_out_nid = ALC680_DIGOUT_NID, 20003 .num_channel_mode = ARRAY_SIZE(alc680_modes), 20004 .channel_mode = alc680_modes, 20005 .unsol_event = alc680_unsol_event, 20006 .setup = alc680_base_setup, 20007 .init_hook = alc680_inithook, 20008 20009 }, 20010}; 20011 20012static int patch_alc680(struct hda_codec *codec) 20013{ 20014 struct alc_spec *spec; 20015 int board_config; 20016 int err; 20017 20018 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 20019 if (spec == NULL) 20020 return -ENOMEM; 20021 20022 codec->spec = spec; 20023 20024 board_config = snd_hda_check_board_config(codec, ALC680_MODEL_LAST, 20025 alc680_models, 20026 alc680_cfg_tbl); 20027 20028 if (board_config < 0 || board_config >= ALC680_MODEL_LAST) { 20029 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 20030 codec->chip_name); 20031 board_config = ALC680_AUTO; 20032 } 20033 20034 if (board_config == ALC680_AUTO) { 20035 /* automatic parse from the BIOS config */ 20036 err = alc680_parse_auto_config(codec); 20037 if (err < 0) { 20038 alc_free(codec); 20039 return err; 20040 } else if (!err) { 20041 printk(KERN_INFO 20042 "hda_codec: Cannot set up configuration " 20043 "from BIOS. Using base mode...\n"); 20044 board_config = ALC680_BASE; 20045 } 20046 } 20047 20048 if (board_config != ALC680_AUTO) 20049 setup_preset(codec, &alc680_presets[board_config]); 20050 20051 spec->stream_analog_playback = &alc680_pcm_analog_playback; 20052 spec->stream_analog_capture = &alc680_pcm_analog_auto_capture; 20053 spec->stream_digital_playback = &alc680_pcm_digital_playback; 20054 spec->stream_digital_capture = &alc680_pcm_digital_capture; 20055 20056 if (!spec->adc_nids) { 20057 spec->adc_nids = alc680_adc_nids; 20058 spec->num_adc_nids = ARRAY_SIZE(alc680_adc_nids); 20059 } 20060 20061 if (!spec->cap_mixer) 20062 set_capture_mixer(codec); 20063 20064 spec->vmaster_nid = 0x02; 20065 20066 codec->patch_ops = alc_patch_ops; 20067 if (board_config == ALC680_AUTO) 20068 spec->init_hook = alc680_auto_init; 20069 20070 return 0; 20071} 20072 20073/* 20074 * patch entries 20075 */ 20076static struct hda_codec_preset snd_hda_preset_realtek[] = { 20077 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 }, 20078 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 }, 20079 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 }, 20080 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 }, 20081 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 }, 20082 { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 }, 20083 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 }, 20084 { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 }, 20085 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660", 20086 .patch = patch_alc861 }, 20087 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd }, 20088 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 }, 20089 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd }, 20090 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2", 20091 .patch = patch_alc882 }, 20092 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1", 20093 .patch = patch_alc662 }, 20094 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 }, 20095 { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 }, 20096 { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 }, 20097 { .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 }, 20098 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 }, 20099 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 }, 20100 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 }, 20101 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A", 20102 .patch = patch_alc882 }, 20103 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A", 20104 .patch = patch_alc882 }, 20105 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 }, 20106 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc888 }, 20107 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200", 20108 .patch = patch_alc882 }, 20109 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc888 }, 20110 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 }, 20111 { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 }, 20112 {} /* terminator */ 20113}; 20114 20115MODULE_ALIAS("snd-hda-codec-id:10ec*"); 20116 20117MODULE_LICENSE("GPL"); 20118MODULE_DESCRIPTION("Realtek HD-audio codec"); 20119 20120static struct hda_codec_preset_list realtek_list = { 20121 .preset = snd_hda_preset_realtek, 20122 .owner = THIS_MODULE, 20123}; 20124 20125static int __init patch_realtek_init(void) 20126{ 20127 return snd_hda_add_codec_preset(&realtek_list); 20128} 20129 20130static void __exit patch_realtek_exit(void) 20131{ 20132 snd_hda_delete_codec_preset(&realtek_list); 20133} 20134 20135module_init(patch_realtek_init) 20136module_exit(patch_realtek_exit) 20137