patch_realtek.c revision 2df03514de41f3bbb5623f2e7f2bf594e49cb2ec
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_MD2, 235 ALC883_MEDION_WIM2160, 236 ALC883_LAPTOP_EAPD, 237 ALC883_LENOVO_101E_2ch, 238 ALC883_LENOVO_NB0763, 239 ALC888_LENOVO_MS7195_DIG, 240 ALC888_LENOVO_SKY, 241 ALC883_HAIER_W66, 242 ALC888_3ST_HP, 243 ALC888_6ST_DELL, 244 ALC883_MITAC, 245 ALC883_CLEVO_M540R, 246 ALC883_CLEVO_M720, 247 ALC883_FUJITSU_PI2515, 248 ALC888_FUJITSU_XA3530, 249 ALC883_3ST_6ch_INTEL, 250 ALC889A_INTEL, 251 ALC889_INTEL, 252 ALC888_ASUS_M90V, 253 ALC888_ASUS_EEE1601, 254 ALC889A_MB31, 255 ALC1200_ASUS_P5Q, 256 ALC883_SONY_VAIO_TT, 257 ALC882_AUTO, 258 ALC882_MODEL_LAST, 259}; 260 261/* ALC680 models */ 262enum { 263 ALC680_BASE, 264 ALC680_AUTO, 265 ALC680_MODEL_LAST, 266}; 267 268/* for GPIO Poll */ 269#define GPIO_MASK 0x03 270 271/* extra amp-initialization sequence types */ 272enum { 273 ALC_INIT_NONE, 274 ALC_INIT_DEFAULT, 275 ALC_INIT_GPIO1, 276 ALC_INIT_GPIO2, 277 ALC_INIT_GPIO3, 278}; 279 280struct alc_mic_route { 281 hda_nid_t pin; 282 unsigned char mux_idx; 283 unsigned char amix_idx; 284}; 285 286struct alc_jack { 287 hda_nid_t nid; 288 int type; 289 struct snd_jack *jack; 290}; 291 292#define MUX_IDX_UNDEF ((unsigned char)-1) 293 294struct alc_customize_define { 295 unsigned int sku_cfg; 296 unsigned char port_connectivity; 297 unsigned char check_sum; 298 unsigned char customization; 299 unsigned char external_amp; 300 unsigned int enable_pcbeep:1; 301 unsigned int platform_type:1; 302 unsigned int swap:1; 303 unsigned int override:1; 304}; 305 306struct alc_spec { 307 /* codec parameterization */ 308 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */ 309 unsigned int num_mixers; 310 struct snd_kcontrol_new *cap_mixer; /* capture mixer */ 311 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */ 312 313 const struct hda_verb *init_verbs[10]; /* initialization verbs 314 * don't forget NULL 315 * termination! 316 */ 317 unsigned int num_init_verbs; 318 319 char stream_name_analog[32]; /* analog PCM stream */ 320 struct hda_pcm_stream *stream_analog_playback; 321 struct hda_pcm_stream *stream_analog_capture; 322 struct hda_pcm_stream *stream_analog_alt_playback; 323 struct hda_pcm_stream *stream_analog_alt_capture; 324 325 char stream_name_digital[32]; /* digital PCM stream */ 326 struct hda_pcm_stream *stream_digital_playback; 327 struct hda_pcm_stream *stream_digital_capture; 328 329 /* playback */ 330 struct hda_multi_out multiout; /* playback set-up 331 * max_channels, dacs must be set 332 * dig_out_nid and hp_nid are optional 333 */ 334 hda_nid_t alt_dac_nid; 335 hda_nid_t slave_dig_outs[3]; /* optional - for auto-parsing */ 336 int dig_out_type; 337 338 /* capture */ 339 unsigned int num_adc_nids; 340 hda_nid_t *adc_nids; 341 hda_nid_t *capsrc_nids; 342 hda_nid_t dig_in_nid; /* digital-in NID; optional */ 343 344 /* capture setup for dynamic dual-adc switch */ 345 unsigned int cur_adc_idx; 346 hda_nid_t cur_adc; 347 unsigned int cur_adc_stream_tag; 348 unsigned int cur_adc_format; 349 350 /* capture source */ 351 unsigned int num_mux_defs; 352 const struct hda_input_mux *input_mux; 353 unsigned int cur_mux[3]; 354 struct alc_mic_route ext_mic; 355 struct alc_mic_route int_mic; 356 357 /* channel model */ 358 const struct hda_channel_mode *channel_mode; 359 int num_channel_mode; 360 int need_dac_fix; 361 int const_channel_count; 362 int ext_channel_count; 363 364 /* PCM information */ 365 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */ 366 367 /* jack detection */ 368 struct snd_array jacks; 369 370 /* dynamic controls, init_verbs and input_mux */ 371 struct auto_pin_cfg autocfg; 372 struct alc_customize_define cdefine; 373 struct snd_array kctls; 374 struct hda_input_mux private_imux[3]; 375 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; 376 hda_nid_t private_adc_nids[AUTO_CFG_MAX_OUTS]; 377 hda_nid_t private_capsrc_nids[AUTO_CFG_MAX_OUTS]; 378 379 /* hooks */ 380 void (*init_hook)(struct hda_codec *codec); 381 void (*unsol_event)(struct hda_codec *codec, unsigned int res); 382#ifdef CONFIG_SND_HDA_POWER_SAVE 383 void (*power_hook)(struct hda_codec *codec); 384#endif 385 386 /* for pin sensing */ 387 unsigned int sense_updated: 1; 388 unsigned int jack_present: 1; 389 unsigned int master_sw: 1; 390 unsigned int auto_mic:1; 391 392 /* other flags */ 393 unsigned int no_analog :1; /* digital I/O only */ 394 unsigned int dual_adc_switch:1; /* switch ADCs (for ALC275) */ 395 int init_amp; 396 int codec_variant; /* flag for other variants */ 397 398 /* for virtual master */ 399 hda_nid_t vmaster_nid; 400#ifdef CONFIG_SND_HDA_POWER_SAVE 401 struct hda_loopback_check loopback; 402#endif 403 404 /* for PLL fix */ 405 hda_nid_t pll_nid; 406 unsigned int pll_coef_idx, pll_coef_bit; 407}; 408 409/* 410 * configuration template - to be copied to the spec instance 411 */ 412struct alc_config_preset { 413 struct snd_kcontrol_new *mixers[5]; /* should be identical size 414 * with spec 415 */ 416 struct snd_kcontrol_new *cap_mixer; /* capture mixer */ 417 const struct hda_verb *init_verbs[5]; 418 unsigned int num_dacs; 419 hda_nid_t *dac_nids; 420 hda_nid_t dig_out_nid; /* optional */ 421 hda_nid_t hp_nid; /* optional */ 422 hda_nid_t *slave_dig_outs; 423 unsigned int num_adc_nids; 424 hda_nid_t *adc_nids; 425 hda_nid_t *capsrc_nids; 426 hda_nid_t dig_in_nid; 427 unsigned int num_channel_mode; 428 const struct hda_channel_mode *channel_mode; 429 int need_dac_fix; 430 int const_channel_count; 431 unsigned int num_mux_defs; 432 const struct hda_input_mux *input_mux; 433 void (*unsol_event)(struct hda_codec *, unsigned int); 434 void (*setup)(struct hda_codec *); 435 void (*init_hook)(struct hda_codec *); 436#ifdef CONFIG_SND_HDA_POWER_SAVE 437 struct hda_amp_list *loopbacks; 438 void (*power_hook)(struct hda_codec *codec); 439#endif 440}; 441 442 443/* 444 * input MUX handling 445 */ 446static int alc_mux_enum_info(struct snd_kcontrol *kcontrol, 447 struct snd_ctl_elem_info *uinfo) 448{ 449 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 450 struct alc_spec *spec = codec->spec; 451 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id); 452 if (mux_idx >= spec->num_mux_defs) 453 mux_idx = 0; 454 if (!spec->input_mux[mux_idx].num_items && mux_idx > 0) 455 mux_idx = 0; 456 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo); 457} 458 459static int alc_mux_enum_get(struct snd_kcontrol *kcontrol, 460 struct snd_ctl_elem_value *ucontrol) 461{ 462 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 463 struct alc_spec *spec = codec->spec; 464 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 465 466 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx]; 467 return 0; 468} 469 470static int alc_mux_enum_put(struct snd_kcontrol *kcontrol, 471 struct snd_ctl_elem_value *ucontrol) 472{ 473 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 474 struct alc_spec *spec = codec->spec; 475 const struct hda_input_mux *imux; 476 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 477 unsigned int mux_idx; 478 hda_nid_t nid = spec->capsrc_nids ? 479 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx]; 480 unsigned int type; 481 482 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx; 483 imux = &spec->input_mux[mux_idx]; 484 if (!imux->num_items && mux_idx > 0) 485 imux = &spec->input_mux[0]; 486 487 type = get_wcaps_type(get_wcaps(codec, nid)); 488 if (type == AC_WID_AUD_MIX) { 489 /* Matrix-mixer style (e.g. ALC882) */ 490 unsigned int *cur_val = &spec->cur_mux[adc_idx]; 491 unsigned int i, idx; 492 493 idx = ucontrol->value.enumerated.item[0]; 494 if (idx >= imux->num_items) 495 idx = imux->num_items - 1; 496 if (*cur_val == idx) 497 return 0; 498 for (i = 0; i < imux->num_items; i++) { 499 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE; 500 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 501 imux->items[i].index, 502 HDA_AMP_MUTE, v); 503 } 504 *cur_val = idx; 505 return 1; 506 } else { 507 /* MUX style (e.g. ALC880) */ 508 return snd_hda_input_mux_put(codec, imux, ucontrol, nid, 509 &spec->cur_mux[adc_idx]); 510 } 511} 512 513/* 514 * channel mode setting 515 */ 516static int alc_ch_mode_info(struct snd_kcontrol *kcontrol, 517 struct snd_ctl_elem_info *uinfo) 518{ 519 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 520 struct alc_spec *spec = codec->spec; 521 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode, 522 spec->num_channel_mode); 523} 524 525static int alc_ch_mode_get(struct snd_kcontrol *kcontrol, 526 struct snd_ctl_elem_value *ucontrol) 527{ 528 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 529 struct alc_spec *spec = codec->spec; 530 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode, 531 spec->num_channel_mode, 532 spec->ext_channel_count); 533} 534 535static int alc_ch_mode_put(struct snd_kcontrol *kcontrol, 536 struct snd_ctl_elem_value *ucontrol) 537{ 538 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 539 struct alc_spec *spec = codec->spec; 540 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode, 541 spec->num_channel_mode, 542 &spec->ext_channel_count); 543 if (err >= 0 && !spec->const_channel_count) { 544 spec->multiout.max_channels = spec->ext_channel_count; 545 if (spec->need_dac_fix) 546 spec->multiout.num_dacs = spec->multiout.max_channels / 2; 547 } 548 return err; 549} 550 551/* 552 * Control the mode of pin widget settings via the mixer. "pc" is used 553 * instead of "%" to avoid consequences of accidently treating the % as 554 * being part of a format specifier. Maximum allowed length of a value is 555 * 63 characters plus NULL terminator. 556 * 557 * Note: some retasking pin complexes seem to ignore requests for input 558 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these 559 * are requested. Therefore order this list so that this behaviour will not 560 * cause problems when mixer clients move through the enum sequentially. 561 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of 562 * March 2006. 563 */ 564static char *alc_pin_mode_names[] = { 565 "Mic 50pc bias", "Mic 80pc bias", 566 "Line in", "Line out", "Headphone out", 567}; 568static unsigned char alc_pin_mode_values[] = { 569 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP, 570}; 571/* The control can present all 5 options, or it can limit the options based 572 * in the pin being assumed to be exclusively an input or an output pin. In 573 * addition, "input" pins may or may not process the mic bias option 574 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to 575 * accept requests for bias as of chip versions up to March 2006) and/or 576 * wiring in the computer. 577 */ 578#define ALC_PIN_DIR_IN 0x00 579#define ALC_PIN_DIR_OUT 0x01 580#define ALC_PIN_DIR_INOUT 0x02 581#define ALC_PIN_DIR_IN_NOMICBIAS 0x03 582#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04 583 584/* Info about the pin modes supported by the different pin direction modes. 585 * For each direction the minimum and maximum values are given. 586 */ 587static signed char alc_pin_mode_dir_info[5][2] = { 588 { 0, 2 }, /* ALC_PIN_DIR_IN */ 589 { 3, 4 }, /* ALC_PIN_DIR_OUT */ 590 { 0, 4 }, /* ALC_PIN_DIR_INOUT */ 591 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */ 592 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */ 593}; 594#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0]) 595#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1]) 596#define alc_pin_mode_n_items(_dir) \ 597 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1) 598 599static int alc_pin_mode_info(struct snd_kcontrol *kcontrol, 600 struct snd_ctl_elem_info *uinfo) 601{ 602 unsigned int item_num = uinfo->value.enumerated.item; 603 unsigned char dir = (kcontrol->private_value >> 16) & 0xff; 604 605 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 606 uinfo->count = 1; 607 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir); 608 609 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir)) 610 item_num = alc_pin_mode_min(dir); 611 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]); 612 return 0; 613} 614 615static int alc_pin_mode_get(struct snd_kcontrol *kcontrol, 616 struct snd_ctl_elem_value *ucontrol) 617{ 618 unsigned int i; 619 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 620 hda_nid_t nid = kcontrol->private_value & 0xffff; 621 unsigned char dir = (kcontrol->private_value >> 16) & 0xff; 622 long *valp = ucontrol->value.integer.value; 623 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0, 624 AC_VERB_GET_PIN_WIDGET_CONTROL, 625 0x00); 626 627 /* Find enumerated value for current pinctl setting */ 628 i = alc_pin_mode_min(dir); 629 while (i <= alc_pin_mode_max(dir) && alc_pin_mode_values[i] != pinctl) 630 i++; 631 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir); 632 return 0; 633} 634 635static int alc_pin_mode_put(struct snd_kcontrol *kcontrol, 636 struct snd_ctl_elem_value *ucontrol) 637{ 638 signed int change; 639 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 640 hda_nid_t nid = kcontrol->private_value & 0xffff; 641 unsigned char dir = (kcontrol->private_value >> 16) & 0xff; 642 long val = *ucontrol->value.integer.value; 643 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0, 644 AC_VERB_GET_PIN_WIDGET_CONTROL, 645 0x00); 646 647 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir)) 648 val = alc_pin_mode_min(dir); 649 650 change = pinctl != alc_pin_mode_values[val]; 651 if (change) { 652 /* Set pin mode to that requested */ 653 snd_hda_codec_write_cache(codec, nid, 0, 654 AC_VERB_SET_PIN_WIDGET_CONTROL, 655 alc_pin_mode_values[val]); 656 657 /* Also enable the retasking pin's input/output as required 658 * for the requested pin mode. Enum values of 2 or less are 659 * input modes. 660 * 661 * Dynamically switching the input/output buffers probably 662 * reduces noise slightly (particularly on input) so we'll 663 * do it. However, having both input and output buffers 664 * enabled simultaneously doesn't seem to be problematic if 665 * this turns out to be necessary in the future. 666 */ 667 if (val <= 2) { 668 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, 669 HDA_AMP_MUTE, HDA_AMP_MUTE); 670 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0, 671 HDA_AMP_MUTE, 0); 672 } else { 673 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0, 674 HDA_AMP_MUTE, HDA_AMP_MUTE); 675 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, 676 HDA_AMP_MUTE, 0); 677 } 678 } 679 return change; 680} 681 682#define ALC_PIN_MODE(xname, nid, dir) \ 683 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 684 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \ 685 .info = alc_pin_mode_info, \ 686 .get = alc_pin_mode_get, \ 687 .put = alc_pin_mode_put, \ 688 .private_value = nid | (dir<<16) } 689 690/* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged 691 * together using a mask with more than one bit set. This control is 692 * currently used only by the ALC260 test model. At this stage they are not 693 * needed for any "production" models. 694 */ 695#ifdef CONFIG_SND_DEBUG 696#define alc_gpio_data_info snd_ctl_boolean_mono_info 697 698static int alc_gpio_data_get(struct snd_kcontrol *kcontrol, 699 struct snd_ctl_elem_value *ucontrol) 700{ 701 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 702 hda_nid_t nid = kcontrol->private_value & 0xffff; 703 unsigned char mask = (kcontrol->private_value >> 16) & 0xff; 704 long *valp = ucontrol->value.integer.value; 705 unsigned int val = snd_hda_codec_read(codec, nid, 0, 706 AC_VERB_GET_GPIO_DATA, 0x00); 707 708 *valp = (val & mask) != 0; 709 return 0; 710} 711static int alc_gpio_data_put(struct snd_kcontrol *kcontrol, 712 struct snd_ctl_elem_value *ucontrol) 713{ 714 signed int change; 715 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 716 hda_nid_t nid = kcontrol->private_value & 0xffff; 717 unsigned char mask = (kcontrol->private_value >> 16) & 0xff; 718 long val = *ucontrol->value.integer.value; 719 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0, 720 AC_VERB_GET_GPIO_DATA, 721 0x00); 722 723 /* Set/unset the masked GPIO bit(s) as needed */ 724 change = (val == 0 ? 0 : mask) != (gpio_data & mask); 725 if (val == 0) 726 gpio_data &= ~mask; 727 else 728 gpio_data |= mask; 729 snd_hda_codec_write_cache(codec, nid, 0, 730 AC_VERB_SET_GPIO_DATA, gpio_data); 731 732 return change; 733} 734#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \ 735 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 736 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \ 737 .info = alc_gpio_data_info, \ 738 .get = alc_gpio_data_get, \ 739 .put = alc_gpio_data_put, \ 740 .private_value = nid | (mask<<16) } 741#endif /* CONFIG_SND_DEBUG */ 742 743/* A switch control to allow the enabling of the digital IO pins on the 744 * ALC260. This is incredibly simplistic; the intention of this control is 745 * to provide something in the test model allowing digital outputs to be 746 * identified if present. If models are found which can utilise these 747 * outputs a more complete mixer control can be devised for those models if 748 * necessary. 749 */ 750#ifdef CONFIG_SND_DEBUG 751#define alc_spdif_ctrl_info snd_ctl_boolean_mono_info 752 753static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol, 754 struct snd_ctl_elem_value *ucontrol) 755{ 756 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 757 hda_nid_t nid = kcontrol->private_value & 0xffff; 758 unsigned char mask = (kcontrol->private_value >> 16) & 0xff; 759 long *valp = ucontrol->value.integer.value; 760 unsigned int val = snd_hda_codec_read(codec, nid, 0, 761 AC_VERB_GET_DIGI_CONVERT_1, 0x00); 762 763 *valp = (val & mask) != 0; 764 return 0; 765} 766static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol, 767 struct snd_ctl_elem_value *ucontrol) 768{ 769 signed int change; 770 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 771 hda_nid_t nid = kcontrol->private_value & 0xffff; 772 unsigned char mask = (kcontrol->private_value >> 16) & 0xff; 773 long val = *ucontrol->value.integer.value; 774 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0, 775 AC_VERB_GET_DIGI_CONVERT_1, 776 0x00); 777 778 /* Set/unset the masked control bit(s) as needed */ 779 change = (val == 0 ? 0 : mask) != (ctrl_data & mask); 780 if (val==0) 781 ctrl_data &= ~mask; 782 else 783 ctrl_data |= mask; 784 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, 785 ctrl_data); 786 787 return change; 788} 789#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \ 790 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 791 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \ 792 .info = alc_spdif_ctrl_info, \ 793 .get = alc_spdif_ctrl_get, \ 794 .put = alc_spdif_ctrl_put, \ 795 .private_value = nid | (mask<<16) } 796#endif /* CONFIG_SND_DEBUG */ 797 798/* A switch control to allow the enabling EAPD digital outputs on the ALC26x. 799 * Again, this is only used in the ALC26x test models to help identify when 800 * the EAPD line must be asserted for features to work. 801 */ 802#ifdef CONFIG_SND_DEBUG 803#define alc_eapd_ctrl_info snd_ctl_boolean_mono_info 804 805static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol, 806 struct snd_ctl_elem_value *ucontrol) 807{ 808 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 809 hda_nid_t nid = kcontrol->private_value & 0xffff; 810 unsigned char mask = (kcontrol->private_value >> 16) & 0xff; 811 long *valp = ucontrol->value.integer.value; 812 unsigned int val = snd_hda_codec_read(codec, nid, 0, 813 AC_VERB_GET_EAPD_BTLENABLE, 0x00); 814 815 *valp = (val & mask) != 0; 816 return 0; 817} 818 819static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol, 820 struct snd_ctl_elem_value *ucontrol) 821{ 822 int change; 823 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 824 hda_nid_t nid = kcontrol->private_value & 0xffff; 825 unsigned char mask = (kcontrol->private_value >> 16) & 0xff; 826 long val = *ucontrol->value.integer.value; 827 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0, 828 AC_VERB_GET_EAPD_BTLENABLE, 829 0x00); 830 831 /* Set/unset the masked control bit(s) as needed */ 832 change = (!val ? 0 : mask) != (ctrl_data & mask); 833 if (!val) 834 ctrl_data &= ~mask; 835 else 836 ctrl_data |= mask; 837 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE, 838 ctrl_data); 839 840 return change; 841} 842 843#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \ 844 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 845 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \ 846 .info = alc_eapd_ctrl_info, \ 847 .get = alc_eapd_ctrl_get, \ 848 .put = alc_eapd_ctrl_put, \ 849 .private_value = nid | (mask<<16) } 850#endif /* CONFIG_SND_DEBUG */ 851 852/* 853 * set up the input pin config (depending on the given auto-pin type) 854 */ 855static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid, 856 int auto_pin_type) 857{ 858 unsigned int val = PIN_IN; 859 860 if (auto_pin_type == AUTO_PIN_MIC) { 861 unsigned int pincap; 862 unsigned int oldval; 863 oldval = snd_hda_codec_read(codec, nid, 0, 864 AC_VERB_GET_PIN_WIDGET_CONTROL, 0); 865 pincap = snd_hda_query_pin_caps(codec, nid); 866 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT; 867 /* if the default pin setup is vref50, we give it priority */ 868 if ((pincap & AC_PINCAP_VREF_80) && oldval != PIN_VREF50) 869 val = PIN_VREF80; 870 else if (pincap & AC_PINCAP_VREF_50) 871 val = PIN_VREF50; 872 else if (pincap & AC_PINCAP_VREF_100) 873 val = PIN_VREF100; 874 else if (pincap & AC_PINCAP_VREF_GRD) 875 val = PIN_VREFGRD; 876 } 877 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val); 878} 879 880static void alc_fixup_autocfg_pin_nums(struct hda_codec *codec) 881{ 882 struct alc_spec *spec = codec->spec; 883 struct auto_pin_cfg *cfg = &spec->autocfg; 884 885 if (!cfg->line_outs) { 886 while (cfg->line_outs < AUTO_CFG_MAX_OUTS && 887 cfg->line_out_pins[cfg->line_outs]) 888 cfg->line_outs++; 889 } 890 if (!cfg->speaker_outs) { 891 while (cfg->speaker_outs < AUTO_CFG_MAX_OUTS && 892 cfg->speaker_pins[cfg->speaker_outs]) 893 cfg->speaker_outs++; 894 } 895 if (!cfg->hp_outs) { 896 while (cfg->hp_outs < AUTO_CFG_MAX_OUTS && 897 cfg->hp_pins[cfg->hp_outs]) 898 cfg->hp_outs++; 899 } 900} 901 902/* 903 */ 904static void add_mixer(struct alc_spec *spec, struct snd_kcontrol_new *mix) 905{ 906 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers))) 907 return; 908 spec->mixers[spec->num_mixers++] = mix; 909} 910 911static void add_verb(struct alc_spec *spec, const struct hda_verb *verb) 912{ 913 if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs))) 914 return; 915 spec->init_verbs[spec->num_init_verbs++] = verb; 916} 917 918/* 919 * set up from the preset table 920 */ 921static void setup_preset(struct hda_codec *codec, 922 const struct alc_config_preset *preset) 923{ 924 struct alc_spec *spec = codec->spec; 925 int i; 926 927 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++) 928 add_mixer(spec, preset->mixers[i]); 929 spec->cap_mixer = preset->cap_mixer; 930 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i]; 931 i++) 932 add_verb(spec, preset->init_verbs[i]); 933 934 spec->channel_mode = preset->channel_mode; 935 spec->num_channel_mode = preset->num_channel_mode; 936 spec->need_dac_fix = preset->need_dac_fix; 937 spec->const_channel_count = preset->const_channel_count; 938 939 if (preset->const_channel_count) 940 spec->multiout.max_channels = preset->const_channel_count; 941 else 942 spec->multiout.max_channels = spec->channel_mode[0].channels; 943 spec->ext_channel_count = spec->channel_mode[0].channels; 944 945 spec->multiout.num_dacs = preset->num_dacs; 946 spec->multiout.dac_nids = preset->dac_nids; 947 spec->multiout.dig_out_nid = preset->dig_out_nid; 948 spec->multiout.slave_dig_outs = preset->slave_dig_outs; 949 spec->multiout.hp_nid = preset->hp_nid; 950 951 spec->num_mux_defs = preset->num_mux_defs; 952 if (!spec->num_mux_defs) 953 spec->num_mux_defs = 1; 954 spec->input_mux = preset->input_mux; 955 956 spec->num_adc_nids = preset->num_adc_nids; 957 spec->adc_nids = preset->adc_nids; 958 spec->capsrc_nids = preset->capsrc_nids; 959 spec->dig_in_nid = preset->dig_in_nid; 960 961 spec->unsol_event = preset->unsol_event; 962 spec->init_hook = preset->init_hook; 963#ifdef CONFIG_SND_HDA_POWER_SAVE 964 spec->power_hook = preset->power_hook; 965 spec->loopback.amplist = preset->loopbacks; 966#endif 967 968 if (preset->setup) 969 preset->setup(codec); 970 971 alc_fixup_autocfg_pin_nums(codec); 972} 973 974/* Enable GPIO mask and set output */ 975static struct hda_verb alc_gpio1_init_verbs[] = { 976 {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, 977 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, 978 {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, 979 { } 980}; 981 982static struct hda_verb alc_gpio2_init_verbs[] = { 983 {0x01, AC_VERB_SET_GPIO_MASK, 0x02}, 984 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02}, 985 {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, 986 { } 987}; 988 989static struct hda_verb alc_gpio3_init_verbs[] = { 990 {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, 991 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03}, 992 {0x01, AC_VERB_SET_GPIO_DATA, 0x03}, 993 { } 994}; 995 996/* 997 * Fix hardware PLL issue 998 * On some codecs, the analog PLL gating control must be off while 999 * the default value is 1. 1000 */ 1001static void alc_fix_pll(struct hda_codec *codec) 1002{ 1003 struct alc_spec *spec = codec->spec; 1004 unsigned int val; 1005 1006 if (!spec->pll_nid) 1007 return; 1008 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX, 1009 spec->pll_coef_idx); 1010 val = snd_hda_codec_read(codec, spec->pll_nid, 0, 1011 AC_VERB_GET_PROC_COEF, 0); 1012 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX, 1013 spec->pll_coef_idx); 1014 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF, 1015 val & ~(1 << spec->pll_coef_bit)); 1016} 1017 1018static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid, 1019 unsigned int coef_idx, unsigned int coef_bit) 1020{ 1021 struct alc_spec *spec = codec->spec; 1022 spec->pll_nid = nid; 1023 spec->pll_coef_idx = coef_idx; 1024 spec->pll_coef_bit = coef_bit; 1025 alc_fix_pll(codec); 1026} 1027 1028#ifdef CONFIG_SND_HDA_INPUT_JACK 1029static void alc_free_jack_priv(struct snd_jack *jack) 1030{ 1031 struct alc_jack *jacks = jack->private_data; 1032 jacks->nid = 0; 1033 jacks->jack = NULL; 1034} 1035 1036static int alc_add_jack(struct hda_codec *codec, 1037 hda_nid_t nid, int type) 1038{ 1039 struct alc_spec *spec; 1040 struct alc_jack *jack; 1041 const char *name; 1042 int err; 1043 1044 spec = codec->spec; 1045 snd_array_init(&spec->jacks, sizeof(*jack), 32); 1046 jack = snd_array_new(&spec->jacks); 1047 if (!jack) 1048 return -ENOMEM; 1049 1050 jack->nid = nid; 1051 jack->type = type; 1052 name = (type == SND_JACK_HEADPHONE) ? "Headphone" : "Mic" ; 1053 1054 err = snd_jack_new(codec->bus->card, name, type, &jack->jack); 1055 if (err < 0) 1056 return err; 1057 jack->jack->private_data = jack; 1058 jack->jack->private_free = alc_free_jack_priv; 1059 return 0; 1060} 1061 1062static void alc_report_jack(struct hda_codec *codec, hda_nid_t nid) 1063{ 1064 struct alc_spec *spec = codec->spec; 1065 struct alc_jack *jacks = spec->jacks.list; 1066 1067 if (jacks) { 1068 int i; 1069 for (i = 0; i < spec->jacks.used; i++) { 1070 if (jacks->nid == nid) { 1071 unsigned int present; 1072 present = snd_hda_jack_detect(codec, nid); 1073 1074 present = (present) ? jacks->type : 0; 1075 1076 snd_jack_report(jacks->jack, present); 1077 } 1078 jacks++; 1079 } 1080 } 1081} 1082 1083static int alc_init_jacks(struct hda_codec *codec) 1084{ 1085 struct alc_spec *spec = codec->spec; 1086 int err; 1087 unsigned int hp_nid = spec->autocfg.hp_pins[0]; 1088 unsigned int mic_nid = spec->ext_mic.pin; 1089 1090 if (hp_nid) { 1091 err = alc_add_jack(codec, hp_nid, SND_JACK_HEADPHONE); 1092 if (err < 0) 1093 return err; 1094 alc_report_jack(codec, hp_nid); 1095 } 1096 1097 if (mic_nid) { 1098 err = alc_add_jack(codec, mic_nid, SND_JACK_MICROPHONE); 1099 if (err < 0) 1100 return err; 1101 alc_report_jack(codec, mic_nid); 1102 } 1103 1104 return 0; 1105} 1106#else 1107static inline void alc_report_jack(struct hda_codec *codec, hda_nid_t nid) 1108{ 1109} 1110 1111static inline int alc_init_jacks(struct hda_codec *codec) 1112{ 1113 return 0; 1114} 1115#endif 1116 1117static void alc_automute_speaker(struct hda_codec *codec, int pinctl) 1118{ 1119 struct alc_spec *spec = codec->spec; 1120 unsigned int mute; 1121 hda_nid_t nid; 1122 int i; 1123 1124 spec->jack_present = 0; 1125 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) { 1126 nid = spec->autocfg.hp_pins[i]; 1127 if (!nid) 1128 break; 1129 if (snd_hda_jack_detect(codec, nid)) { 1130 spec->jack_present = 1; 1131 break; 1132 } 1133 alc_report_jack(codec, spec->autocfg.hp_pins[i]); 1134 } 1135 1136 mute = spec->jack_present ? HDA_AMP_MUTE : 0; 1137 /* Toggle internal speakers muting */ 1138 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) { 1139 nid = spec->autocfg.speaker_pins[i]; 1140 if (!nid) 1141 break; 1142 if (pinctl) { 1143 snd_hda_codec_write(codec, nid, 0, 1144 AC_VERB_SET_PIN_WIDGET_CONTROL, 1145 spec->jack_present ? 0 : PIN_OUT); 1146 } else { 1147 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, 1148 HDA_AMP_MUTE, mute); 1149 } 1150 } 1151} 1152 1153static void alc_automute_pin(struct hda_codec *codec) 1154{ 1155 alc_automute_speaker(codec, 1); 1156} 1157 1158static int get_connection_index(struct hda_codec *codec, hda_nid_t mux, 1159 hda_nid_t nid) 1160{ 1161 hda_nid_t conn[HDA_MAX_NUM_INPUTS]; 1162 int i, nums; 1163 1164 nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn)); 1165 for (i = 0; i < nums; i++) 1166 if (conn[i] == nid) 1167 return i; 1168 return -1; 1169} 1170 1171/* switch the current ADC according to the jack state */ 1172static void alc_dual_mic_adc_auto_switch(struct hda_codec *codec) 1173{ 1174 struct alc_spec *spec = codec->spec; 1175 unsigned int present; 1176 hda_nid_t new_adc; 1177 1178 present = snd_hda_jack_detect(codec, spec->ext_mic.pin); 1179 if (present) 1180 spec->cur_adc_idx = 1; 1181 else 1182 spec->cur_adc_idx = 0; 1183 new_adc = spec->adc_nids[spec->cur_adc_idx]; 1184 if (spec->cur_adc && spec->cur_adc != new_adc) { 1185 /* stream is running, let's swap the current ADC */ 1186 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1); 1187 spec->cur_adc = new_adc; 1188 snd_hda_codec_setup_stream(codec, new_adc, 1189 spec->cur_adc_stream_tag, 0, 1190 spec->cur_adc_format); 1191 } 1192} 1193 1194static void alc_mic_automute(struct hda_codec *codec) 1195{ 1196 struct alc_spec *spec = codec->spec; 1197 struct alc_mic_route *dead, *alive; 1198 unsigned int present, type; 1199 hda_nid_t cap_nid; 1200 1201 if (!spec->auto_mic) 1202 return; 1203 if (!spec->int_mic.pin || !spec->ext_mic.pin) 1204 return; 1205 if (snd_BUG_ON(!spec->adc_nids)) 1206 return; 1207 1208 if (spec->dual_adc_switch) { 1209 alc_dual_mic_adc_auto_switch(codec); 1210 return; 1211 } 1212 1213 cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0]; 1214 1215 present = snd_hda_jack_detect(codec, spec->ext_mic.pin); 1216 if (present) { 1217 alive = &spec->ext_mic; 1218 dead = &spec->int_mic; 1219 } else { 1220 alive = &spec->int_mic; 1221 dead = &spec->ext_mic; 1222 } 1223 1224 type = get_wcaps_type(get_wcaps(codec, cap_nid)); 1225 if (type == AC_WID_AUD_MIX) { 1226 /* Matrix-mixer style (e.g. ALC882) */ 1227 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT, 1228 alive->mux_idx, 1229 HDA_AMP_MUTE, 0); 1230 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT, 1231 dead->mux_idx, 1232 HDA_AMP_MUTE, HDA_AMP_MUTE); 1233 } else { 1234 /* MUX style (e.g. ALC880) */ 1235 snd_hda_codec_write_cache(codec, cap_nid, 0, 1236 AC_VERB_SET_CONNECT_SEL, 1237 alive->mux_idx); 1238 } 1239 alc_report_jack(codec, spec->ext_mic.pin); 1240 1241 /* FIXME: analog mixer */ 1242} 1243 1244/* unsolicited event for HP jack sensing */ 1245static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res) 1246{ 1247 if (codec->vendor_id == 0x10ec0880) 1248 res >>= 28; 1249 else 1250 res >>= 26; 1251 switch (res) { 1252 case ALC880_HP_EVENT: 1253 alc_automute_pin(codec); 1254 break; 1255 case ALC880_MIC_EVENT: 1256 alc_mic_automute(codec); 1257 break; 1258 } 1259} 1260 1261static void alc_inithook(struct hda_codec *codec) 1262{ 1263 alc_automute_pin(codec); 1264 alc_mic_automute(codec); 1265} 1266 1267/* additional initialization for ALC888 variants */ 1268static void alc888_coef_init(struct hda_codec *codec) 1269{ 1270 unsigned int tmp; 1271 1272 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0); 1273 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0); 1274 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7); 1275 if ((tmp & 0xf0) == 0x20) 1276 /* alc888S-VC */ 1277 snd_hda_codec_read(codec, 0x20, 0, 1278 AC_VERB_SET_PROC_COEF, 0x830); 1279 else 1280 /* alc888-VB */ 1281 snd_hda_codec_read(codec, 0x20, 0, 1282 AC_VERB_SET_PROC_COEF, 0x3030); 1283} 1284 1285static void alc889_coef_init(struct hda_codec *codec) 1286{ 1287 unsigned int tmp; 1288 1289 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7); 1290 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0); 1291 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7); 1292 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, tmp|0x2010); 1293} 1294 1295/* turn on/off EAPD control (only if available) */ 1296static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on) 1297{ 1298 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN) 1299 return; 1300 if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD) 1301 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE, 1302 on ? 2 : 0); 1303} 1304 1305static void alc_auto_init_amp(struct hda_codec *codec, int type) 1306{ 1307 unsigned int tmp; 1308 1309 switch (type) { 1310 case ALC_INIT_GPIO1: 1311 snd_hda_sequence_write(codec, alc_gpio1_init_verbs); 1312 break; 1313 case ALC_INIT_GPIO2: 1314 snd_hda_sequence_write(codec, alc_gpio2_init_verbs); 1315 break; 1316 case ALC_INIT_GPIO3: 1317 snd_hda_sequence_write(codec, alc_gpio3_init_verbs); 1318 break; 1319 case ALC_INIT_DEFAULT: 1320 switch (codec->vendor_id) { 1321 case 0x10ec0260: 1322 set_eapd(codec, 0x0f, 1); 1323 set_eapd(codec, 0x10, 1); 1324 break; 1325 case 0x10ec0262: 1326 case 0x10ec0267: 1327 case 0x10ec0268: 1328 case 0x10ec0269: 1329 case 0x10ec0270: 1330 case 0x10ec0272: 1331 case 0x10ec0660: 1332 case 0x10ec0662: 1333 case 0x10ec0663: 1334 case 0x10ec0862: 1335 case 0x10ec0889: 1336 set_eapd(codec, 0x14, 1); 1337 set_eapd(codec, 0x15, 1); 1338 break; 1339 } 1340 switch (codec->vendor_id) { 1341 case 0x10ec0260: 1342 snd_hda_codec_write(codec, 0x1a, 0, 1343 AC_VERB_SET_COEF_INDEX, 7); 1344 tmp = snd_hda_codec_read(codec, 0x1a, 0, 1345 AC_VERB_GET_PROC_COEF, 0); 1346 snd_hda_codec_write(codec, 0x1a, 0, 1347 AC_VERB_SET_COEF_INDEX, 7); 1348 snd_hda_codec_write(codec, 0x1a, 0, 1349 AC_VERB_SET_PROC_COEF, 1350 tmp | 0x2010); 1351 break; 1352 case 0x10ec0262: 1353 case 0x10ec0880: 1354 case 0x10ec0882: 1355 case 0x10ec0883: 1356 case 0x10ec0885: 1357 case 0x10ec0887: 1358 case 0x10ec0889: 1359 alc889_coef_init(codec); 1360 break; 1361 case 0x10ec0888: 1362 alc888_coef_init(codec); 1363 break; 1364#if 0 /* XXX: This may cause the silent output on speaker on some machines */ 1365 case 0x10ec0267: 1366 case 0x10ec0268: 1367 snd_hda_codec_write(codec, 0x20, 0, 1368 AC_VERB_SET_COEF_INDEX, 7); 1369 tmp = snd_hda_codec_read(codec, 0x20, 0, 1370 AC_VERB_GET_PROC_COEF, 0); 1371 snd_hda_codec_write(codec, 0x20, 0, 1372 AC_VERB_SET_COEF_INDEX, 7); 1373 snd_hda_codec_write(codec, 0x20, 0, 1374 AC_VERB_SET_PROC_COEF, 1375 tmp | 0x3000); 1376 break; 1377#endif /* XXX */ 1378 } 1379 break; 1380 } 1381} 1382 1383static void alc_init_auto_hp(struct hda_codec *codec) 1384{ 1385 struct alc_spec *spec = codec->spec; 1386 struct auto_pin_cfg *cfg = &spec->autocfg; 1387 int i; 1388 1389 if (!cfg->hp_pins[0]) { 1390 if (cfg->line_out_type != AUTO_PIN_HP_OUT) 1391 return; 1392 } 1393 1394 if (!cfg->speaker_pins[0]) { 1395 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) 1396 return; 1397 memcpy(cfg->speaker_pins, cfg->line_out_pins, 1398 sizeof(cfg->speaker_pins)); 1399 cfg->speaker_outs = cfg->line_outs; 1400 } 1401 1402 if (!cfg->hp_pins[0]) { 1403 memcpy(cfg->hp_pins, cfg->line_out_pins, 1404 sizeof(cfg->hp_pins)); 1405 cfg->hp_outs = cfg->line_outs; 1406 } 1407 1408 for (i = 0; i < cfg->hp_outs; i++) { 1409 snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n", 1410 cfg->hp_pins[i]); 1411 snd_hda_codec_write_cache(codec, cfg->hp_pins[i], 0, 1412 AC_VERB_SET_UNSOLICITED_ENABLE, 1413 AC_USRSP_EN | ALC880_HP_EVENT); 1414 } 1415 spec->unsol_event = alc_sku_unsol_event; 1416} 1417 1418static void alc_init_auto_mic(struct hda_codec *codec) 1419{ 1420 struct alc_spec *spec = codec->spec; 1421 struct auto_pin_cfg *cfg = &spec->autocfg; 1422 hda_nid_t fixed, ext; 1423 int i; 1424 1425 /* there must be only two mic inputs exclusively */ 1426 for (i = 0; i < cfg->num_inputs; i++) 1427 if (cfg->inputs[i].type >= AUTO_PIN_LINE_IN) 1428 return; 1429 1430 fixed = ext = 0; 1431 for (i = 0; i < cfg->num_inputs; i++) { 1432 hda_nid_t nid = cfg->inputs[i].pin; 1433 unsigned int defcfg; 1434 defcfg = snd_hda_codec_get_pincfg(codec, nid); 1435 switch (snd_hda_get_input_pin_attr(defcfg)) { 1436 case INPUT_PIN_ATTR_INT: 1437 if (fixed) 1438 return; /* already occupied */ 1439 fixed = nid; 1440 break; 1441 case INPUT_PIN_ATTR_UNUSED: 1442 return; /* invalid entry */ 1443 default: 1444 if (ext) 1445 return; /* already occupied */ 1446 ext = nid; 1447 break; 1448 } 1449 } 1450 if (!ext || !fixed) 1451 return; 1452 if (!(get_wcaps(codec, ext) & AC_WCAP_UNSOL_CAP)) 1453 return; /* no unsol support */ 1454 snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x\n", 1455 ext, fixed); 1456 spec->ext_mic.pin = ext; 1457 spec->int_mic.pin = fixed; 1458 spec->ext_mic.mux_idx = MUX_IDX_UNDEF; /* set later */ 1459 spec->int_mic.mux_idx = MUX_IDX_UNDEF; /* set later */ 1460 spec->auto_mic = 1; 1461 snd_hda_codec_write_cache(codec, spec->ext_mic.pin, 0, 1462 AC_VERB_SET_UNSOLICITED_ENABLE, 1463 AC_USRSP_EN | ALC880_MIC_EVENT); 1464 spec->unsol_event = alc_sku_unsol_event; 1465} 1466 1467static int alc_auto_parse_customize_define(struct hda_codec *codec) 1468{ 1469 unsigned int ass, tmp, i; 1470 unsigned nid = 0; 1471 struct alc_spec *spec = codec->spec; 1472 1473 spec->cdefine.enable_pcbeep = 1; /* assume always enabled */ 1474 1475 ass = codec->subsystem_id & 0xffff; 1476 if (ass != codec->bus->pci->subsystem_device && (ass & 1)) 1477 goto do_sku; 1478 1479 nid = 0x1d; 1480 if (codec->vendor_id == 0x10ec0260) 1481 nid = 0x17; 1482 ass = snd_hda_codec_get_pincfg(codec, nid); 1483 1484 if (!(ass & 1)) { 1485 printk(KERN_INFO "hda_codec: %s: SKU not ready 0x%08x\n", 1486 codec->chip_name, ass); 1487 return -1; 1488 } 1489 1490 /* check sum */ 1491 tmp = 0; 1492 for (i = 1; i < 16; i++) { 1493 if ((ass >> i) & 1) 1494 tmp++; 1495 } 1496 if (((ass >> 16) & 0xf) != tmp) 1497 return -1; 1498 1499 spec->cdefine.port_connectivity = ass >> 30; 1500 spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20; 1501 spec->cdefine.check_sum = (ass >> 16) & 0xf; 1502 spec->cdefine.customization = ass >> 8; 1503do_sku: 1504 spec->cdefine.sku_cfg = ass; 1505 spec->cdefine.external_amp = (ass & 0x38) >> 3; 1506 spec->cdefine.platform_type = (ass & 0x4) >> 2; 1507 spec->cdefine.swap = (ass & 0x2) >> 1; 1508 spec->cdefine.override = ass & 0x1; 1509 1510 snd_printd("SKU: Nid=0x%x sku_cfg=0x%08x\n", 1511 nid, spec->cdefine.sku_cfg); 1512 snd_printd("SKU: port_connectivity=0x%x\n", 1513 spec->cdefine.port_connectivity); 1514 snd_printd("SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep); 1515 snd_printd("SKU: check_sum=0x%08x\n", spec->cdefine.check_sum); 1516 snd_printd("SKU: customization=0x%08x\n", spec->cdefine.customization); 1517 snd_printd("SKU: external_amp=0x%x\n", spec->cdefine.external_amp); 1518 snd_printd("SKU: platform_type=0x%x\n", spec->cdefine.platform_type); 1519 snd_printd("SKU: swap=0x%x\n", spec->cdefine.swap); 1520 snd_printd("SKU: override=0x%x\n", spec->cdefine.override); 1521 1522 return 0; 1523} 1524 1525/* check subsystem ID and set up device-specific initialization; 1526 * return 1 if initialized, 0 if invalid SSID 1527 */ 1528/* 32-bit subsystem ID for BIOS loading in HD Audio codec. 1529 * 31 ~ 16 : Manufacture ID 1530 * 15 ~ 8 : SKU ID 1531 * 7 ~ 0 : Assembly ID 1532 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36 1533 */ 1534static int alc_subsystem_id(struct hda_codec *codec, 1535 hda_nid_t porta, hda_nid_t porte, 1536 hda_nid_t portd, hda_nid_t porti) 1537{ 1538 unsigned int ass, tmp, i; 1539 unsigned nid; 1540 struct alc_spec *spec = codec->spec; 1541 1542 ass = codec->subsystem_id & 0xffff; 1543 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1)) 1544 goto do_sku; 1545 1546 /* invalid SSID, check the special NID pin defcfg instead */ 1547 /* 1548 * 31~30 : port connectivity 1549 * 29~21 : reserve 1550 * 20 : PCBEEP input 1551 * 19~16 : Check sum (15:1) 1552 * 15~1 : Custom 1553 * 0 : override 1554 */ 1555 nid = 0x1d; 1556 if (codec->vendor_id == 0x10ec0260) 1557 nid = 0x17; 1558 ass = snd_hda_codec_get_pincfg(codec, nid); 1559 snd_printd("realtek: No valid SSID, " 1560 "checking pincfg 0x%08x for NID 0x%x\n", 1561 ass, nid); 1562 if (!(ass & 1)) 1563 return 0; 1564 if ((ass >> 30) != 1) /* no physical connection */ 1565 return 0; 1566 1567 /* check sum */ 1568 tmp = 0; 1569 for (i = 1; i < 16; i++) { 1570 if ((ass >> i) & 1) 1571 tmp++; 1572 } 1573 if (((ass >> 16) & 0xf) != tmp) 1574 return 0; 1575do_sku: 1576 snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n", 1577 ass & 0xffff, codec->vendor_id); 1578 /* 1579 * 0 : override 1580 * 1 : Swap Jack 1581 * 2 : 0 --> Desktop, 1 --> Laptop 1582 * 3~5 : External Amplifier control 1583 * 7~6 : Reserved 1584 */ 1585 tmp = (ass & 0x38) >> 3; /* external Amp control */ 1586 switch (tmp) { 1587 case 1: 1588 spec->init_amp = ALC_INIT_GPIO1; 1589 break; 1590 case 3: 1591 spec->init_amp = ALC_INIT_GPIO2; 1592 break; 1593 case 7: 1594 spec->init_amp = ALC_INIT_GPIO3; 1595 break; 1596 case 5: 1597 spec->init_amp = ALC_INIT_DEFAULT; 1598 break; 1599 } 1600 1601 /* is laptop or Desktop and enable the function "Mute internal speaker 1602 * when the external headphone out jack is plugged" 1603 */ 1604 if (!(ass & 0x8000)) 1605 return 1; 1606 /* 1607 * 10~8 : Jack location 1608 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered 1609 * 14~13: Resvered 1610 * 15 : 1 --> enable the function "Mute internal speaker 1611 * when the external headphone out jack is plugged" 1612 */ 1613 if (!spec->autocfg.hp_pins[0]) { 1614 hda_nid_t nid; 1615 tmp = (ass >> 11) & 0x3; /* HP to chassis */ 1616 if (tmp == 0) 1617 nid = porta; 1618 else if (tmp == 1) 1619 nid = porte; 1620 else if (tmp == 2) 1621 nid = portd; 1622 else if (tmp == 3) 1623 nid = porti; 1624 else 1625 return 1; 1626 for (i = 0; i < spec->autocfg.line_outs; i++) 1627 if (spec->autocfg.line_out_pins[i] == nid) 1628 return 1; 1629 spec->autocfg.hp_pins[0] = nid; 1630 } 1631 1632 alc_init_auto_hp(codec); 1633 alc_init_auto_mic(codec); 1634 return 1; 1635} 1636 1637static void alc_ssid_check(struct hda_codec *codec, 1638 hda_nid_t porta, hda_nid_t porte, 1639 hda_nid_t portd, hda_nid_t porti) 1640{ 1641 if (!alc_subsystem_id(codec, porta, porte, portd, porti)) { 1642 struct alc_spec *spec = codec->spec; 1643 snd_printd("realtek: " 1644 "Enable default setup for auto mode as fallback\n"); 1645 spec->init_amp = ALC_INIT_DEFAULT; 1646 alc_init_auto_hp(codec); 1647 alc_init_auto_mic(codec); 1648 } 1649} 1650 1651/* 1652 * Fix-up pin default configurations and add default verbs 1653 */ 1654 1655struct alc_pincfg { 1656 hda_nid_t nid; 1657 u32 val; 1658}; 1659 1660struct alc_fixup { 1661 const struct alc_pincfg *pins; 1662 const struct hda_verb *verbs; 1663}; 1664 1665static void alc_pick_fixup(struct hda_codec *codec, 1666 const struct snd_pci_quirk *quirk, 1667 const struct alc_fixup *fix, 1668 int pre_init) 1669{ 1670 const struct alc_pincfg *cfg; 1671 1672 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk); 1673 if (!quirk) 1674 return; 1675 fix += quirk->value; 1676 cfg = fix->pins; 1677 if (pre_init && cfg) { 1678#ifdef CONFIG_SND_DEBUG_VERBOSE 1679 snd_printdd(KERN_INFO "hda_codec: %s: Apply pincfg for %s\n", 1680 codec->chip_name, quirk->name); 1681#endif 1682 for (; cfg->nid; cfg++) 1683 snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val); 1684 } 1685 if (!pre_init && fix->verbs) { 1686#ifdef CONFIG_SND_DEBUG_VERBOSE 1687 snd_printdd(KERN_INFO "hda_codec: %s: Apply fix-verbs for %s\n", 1688 codec->chip_name, quirk->name); 1689#endif 1690 add_verb(codec->spec, fix->verbs); 1691 } 1692} 1693 1694static int alc_read_coef_idx(struct hda_codec *codec, 1695 unsigned int coef_idx) 1696{ 1697 unsigned int val; 1698 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 1699 coef_idx); 1700 val = snd_hda_codec_read(codec, 0x20, 0, 1701 AC_VERB_GET_PROC_COEF, 0); 1702 return val; 1703} 1704 1705static void alc_write_coef_idx(struct hda_codec *codec, unsigned int coef_idx, 1706 unsigned int coef_val) 1707{ 1708 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 1709 coef_idx); 1710 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, 1711 coef_val); 1712} 1713 1714/* set right pin controls for digital I/O */ 1715static void alc_auto_init_digital(struct hda_codec *codec) 1716{ 1717 struct alc_spec *spec = codec->spec; 1718 int i; 1719 hda_nid_t pin; 1720 1721 for (i = 0; i < spec->autocfg.dig_outs; i++) { 1722 pin = spec->autocfg.dig_out_pins[i]; 1723 if (pin) { 1724 snd_hda_codec_write(codec, pin, 0, 1725 AC_VERB_SET_PIN_WIDGET_CONTROL, 1726 PIN_OUT); 1727 } 1728 } 1729 pin = spec->autocfg.dig_in_pin; 1730 if (pin) 1731 snd_hda_codec_write(codec, pin, 0, 1732 AC_VERB_SET_PIN_WIDGET_CONTROL, 1733 PIN_IN); 1734} 1735 1736/* parse digital I/Os and set up NIDs in BIOS auto-parse mode */ 1737static void alc_auto_parse_digital(struct hda_codec *codec) 1738{ 1739 struct alc_spec *spec = codec->spec; 1740 int i, err; 1741 hda_nid_t dig_nid; 1742 1743 /* support multiple SPDIFs; the secondary is set up as a slave */ 1744 for (i = 0; i < spec->autocfg.dig_outs; i++) { 1745 err = snd_hda_get_connections(codec, 1746 spec->autocfg.dig_out_pins[i], 1747 &dig_nid, 1); 1748 if (err < 0) 1749 continue; 1750 if (!i) { 1751 spec->multiout.dig_out_nid = dig_nid; 1752 spec->dig_out_type = spec->autocfg.dig_out_type[0]; 1753 } else { 1754 spec->multiout.slave_dig_outs = spec->slave_dig_outs; 1755 if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1) 1756 break; 1757 spec->slave_dig_outs[i - 1] = dig_nid; 1758 } 1759 } 1760 1761 if (spec->autocfg.dig_in_pin) { 1762 dig_nid = codec->start_nid; 1763 for (i = 0; i < codec->num_nodes; i++, dig_nid++) { 1764 unsigned int wcaps = get_wcaps(codec, dig_nid); 1765 if (get_wcaps_type(wcaps) != AC_WID_AUD_IN) 1766 continue; 1767 if (!(wcaps & AC_WCAP_DIGITAL)) 1768 continue; 1769 if (!(wcaps & AC_WCAP_CONN_LIST)) 1770 continue; 1771 err = get_connection_index(codec, dig_nid, 1772 spec->autocfg.dig_in_pin); 1773 if (err >= 0) { 1774 spec->dig_in_nid = dig_nid; 1775 break; 1776 } 1777 } 1778 } 1779} 1780 1781/* 1782 * ALC888 1783 */ 1784 1785/* 1786 * 2ch mode 1787 */ 1788static struct hda_verb alc888_4ST_ch2_intel_init[] = { 1789/* Mic-in jack as mic in */ 1790 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 1791 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 1792/* Line-in jack as Line in */ 1793 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 1794 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 1795/* Line-Out as Front */ 1796 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00}, 1797 { } /* end */ 1798}; 1799 1800/* 1801 * 4ch mode 1802 */ 1803static struct hda_verb alc888_4ST_ch4_intel_init[] = { 1804/* Mic-in jack as mic in */ 1805 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 1806 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 1807/* Line-in jack as Surround */ 1808 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 1809 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 1810/* Line-Out as Front */ 1811 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00}, 1812 { } /* end */ 1813}; 1814 1815/* 1816 * 6ch mode 1817 */ 1818static struct hda_verb alc888_4ST_ch6_intel_init[] = { 1819/* Mic-in jack as CLFE */ 1820 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 1821 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 1822/* Line-in jack as Surround */ 1823 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 1824 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 1825/* Line-Out as CLFE (workaround because Mic-in is not loud enough) */ 1826 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, 1827 { } /* end */ 1828}; 1829 1830/* 1831 * 8ch mode 1832 */ 1833static struct hda_verb alc888_4ST_ch8_intel_init[] = { 1834/* Mic-in jack as CLFE */ 1835 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 1836 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 1837/* Line-in jack as Surround */ 1838 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 1839 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 1840/* Line-Out as Side */ 1841 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, 1842 { } /* end */ 1843}; 1844 1845static struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = { 1846 { 2, alc888_4ST_ch2_intel_init }, 1847 { 4, alc888_4ST_ch4_intel_init }, 1848 { 6, alc888_4ST_ch6_intel_init }, 1849 { 8, alc888_4ST_ch8_intel_init }, 1850}; 1851 1852/* 1853 * ALC888 Fujitsu Siemens Amillo xa3530 1854 */ 1855 1856static struct hda_verb alc888_fujitsu_xa3530_verbs[] = { 1857/* Front Mic: set to PIN_IN (empty by default) */ 1858 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1859/* Connect Internal HP to Front */ 1860 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1861 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1862 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 1863/* Connect Bass HP to Front */ 1864 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1865 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1866 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 1867/* Connect Line-Out side jack (SPDIF) to Side */ 1868 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1869 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1870 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, 1871/* Connect Mic jack to CLFE */ 1872 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1873 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1874 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, 1875/* Connect Line-in jack to Surround */ 1876 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1877 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1878 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, 1879/* Connect HP out jack to Front */ 1880 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1881 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1882 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 1883/* Enable unsolicited event for HP jack and Line-out jack */ 1884 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 1885 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 1886 {} 1887}; 1888 1889static void alc_automute_amp(struct hda_codec *codec) 1890{ 1891 alc_automute_speaker(codec, 0); 1892} 1893 1894static void alc_automute_amp_unsol_event(struct hda_codec *codec, 1895 unsigned int res) 1896{ 1897 if (codec->vendor_id == 0x10ec0880) 1898 res >>= 28; 1899 else 1900 res >>= 26; 1901 if (res == ALC880_HP_EVENT) 1902 alc_automute_amp(codec); 1903} 1904 1905static void alc889_automute_setup(struct hda_codec *codec) 1906{ 1907 struct alc_spec *spec = codec->spec; 1908 1909 spec->autocfg.hp_pins[0] = 0x15; 1910 spec->autocfg.speaker_pins[0] = 0x14; 1911 spec->autocfg.speaker_pins[1] = 0x16; 1912 spec->autocfg.speaker_pins[2] = 0x17; 1913 spec->autocfg.speaker_pins[3] = 0x19; 1914 spec->autocfg.speaker_pins[4] = 0x1a; 1915} 1916 1917static void alc889_intel_init_hook(struct hda_codec *codec) 1918{ 1919 alc889_coef_init(codec); 1920 alc_automute_amp(codec); 1921} 1922 1923static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec) 1924{ 1925 struct alc_spec *spec = codec->spec; 1926 1927 spec->autocfg.hp_pins[0] = 0x17; /* line-out */ 1928 spec->autocfg.hp_pins[1] = 0x1b; /* hp */ 1929 spec->autocfg.speaker_pins[0] = 0x14; /* speaker */ 1930 spec->autocfg.speaker_pins[1] = 0x15; /* bass */ 1931} 1932 1933/* 1934 * ALC888 Acer Aspire 4930G model 1935 */ 1936 1937static struct hda_verb alc888_acer_aspire_4930g_verbs[] = { 1938/* Front Mic: set to PIN_IN (empty by default) */ 1939 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1940/* Unselect Front Mic by default in input mixer 3 */ 1941 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)}, 1942/* Enable unsolicited event for HP jack */ 1943 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 1944/* Connect Internal HP to front */ 1945 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1946 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1947 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 1948/* Connect HP out to front */ 1949 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1950 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1951 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 1952 { } 1953}; 1954 1955/* 1956 * ALC888 Acer Aspire 6530G model 1957 */ 1958 1959static struct hda_verb alc888_acer_aspire_6530g_verbs[] = { 1960/* Route to built-in subwoofer as well as speakers */ 1961 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1962 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 1963 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1964 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 1965/* Bias voltage on for external mic port */ 1966 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80}, 1967/* Front Mic: set to PIN_IN (empty by default) */ 1968 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1969/* Unselect Front Mic by default in input mixer 3 */ 1970 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)}, 1971/* Enable unsolicited event for HP jack */ 1972 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 1973/* Enable speaker output */ 1974 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1975 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1976 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 1977/* Enable headphone output */ 1978 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP}, 1979 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1980 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 1981 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, 1982 { } 1983}; 1984 1985/* 1986 * ALC889 Acer Aspire 8930G model 1987 */ 1988 1989static struct hda_verb alc889_acer_aspire_8930g_verbs[] = { 1990/* Front Mic: set to PIN_IN (empty by default) */ 1991 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1992/* Unselect Front Mic by default in input mixer 3 */ 1993 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)}, 1994/* Enable unsolicited event for HP jack */ 1995 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 1996/* Connect Internal Front to Front */ 1997 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1998 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1999 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 2000/* Connect Internal Rear to Rear */ 2001 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2002 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2003 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, 2004/* Connect Internal CLFE to CLFE */ 2005 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2006 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2007 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, 2008/* Connect HP out to Front */ 2009 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP}, 2010 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2011 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 2012/* Enable all DACs */ 2013/* DAC DISABLE/MUTE 1? */ 2014/* setting bits 1-5 disables DAC nids 0x02-0x06 apparently. Init=0x38 */ 2015 {0x20, AC_VERB_SET_COEF_INDEX, 0x03}, 2016 {0x20, AC_VERB_SET_PROC_COEF, 0x0000}, 2017/* DAC DISABLE/MUTE 2? */ 2018/* some bit here disables the other DACs. Init=0x4900 */ 2019 {0x20, AC_VERB_SET_COEF_INDEX, 0x08}, 2020 {0x20, AC_VERB_SET_PROC_COEF, 0x0000}, 2021/* DMIC fix 2022 * This laptop has a stereo digital microphone. The mics are only 1cm apart 2023 * which makes the stereo useless. However, either the mic or the ALC889 2024 * makes the signal become a difference/sum signal instead of standard 2025 * stereo, which is annoying. So instead we flip this bit which makes the 2026 * codec replicate the sum signal to both channels, turning it into a 2027 * normal mono mic. 2028 */ 2029/* DMIC_CONTROL? Init value = 0x0001 */ 2030 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b}, 2031 {0x20, AC_VERB_SET_PROC_COEF, 0x0003}, 2032 { } 2033}; 2034 2035static struct hda_input_mux alc888_2_capture_sources[2] = { 2036 /* Front mic only available on one ADC */ 2037 { 2038 .num_items = 4, 2039 .items = { 2040 { "Mic", 0x0 }, 2041 { "Line", 0x2 }, 2042 { "CD", 0x4 }, 2043 { "Front Mic", 0xb }, 2044 }, 2045 }, 2046 { 2047 .num_items = 3, 2048 .items = { 2049 { "Mic", 0x0 }, 2050 { "Line", 0x2 }, 2051 { "CD", 0x4 }, 2052 }, 2053 } 2054}; 2055 2056static struct hda_input_mux alc888_acer_aspire_6530_sources[2] = { 2057 /* Interal mic only available on one ADC */ 2058 { 2059 .num_items = 5, 2060 .items = { 2061 { "Ext Mic", 0x0 }, 2062 { "Line In", 0x2 }, 2063 { "CD", 0x4 }, 2064 { "Input Mix", 0xa }, 2065 { "Int Mic", 0xb }, 2066 }, 2067 }, 2068 { 2069 .num_items = 4, 2070 .items = { 2071 { "Ext Mic", 0x0 }, 2072 { "Line In", 0x2 }, 2073 { "CD", 0x4 }, 2074 { "Input Mix", 0xa }, 2075 }, 2076 } 2077}; 2078 2079static struct hda_input_mux alc889_capture_sources[3] = { 2080 /* Digital mic only available on first "ADC" */ 2081 { 2082 .num_items = 5, 2083 .items = { 2084 { "Mic", 0x0 }, 2085 { "Line", 0x2 }, 2086 { "CD", 0x4 }, 2087 { "Front Mic", 0xb }, 2088 { "Input Mix", 0xa }, 2089 }, 2090 }, 2091 { 2092 .num_items = 4, 2093 .items = { 2094 { "Mic", 0x0 }, 2095 { "Line", 0x2 }, 2096 { "CD", 0x4 }, 2097 { "Input Mix", 0xa }, 2098 }, 2099 }, 2100 { 2101 .num_items = 4, 2102 .items = { 2103 { "Mic", 0x0 }, 2104 { "Line", 0x2 }, 2105 { "CD", 0x4 }, 2106 { "Input Mix", 0xa }, 2107 }, 2108 } 2109}; 2110 2111static struct snd_kcontrol_new alc888_base_mixer[] = { 2112 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2113 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 2114 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2115 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 2116 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, 2117 HDA_OUTPUT), 2118 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 2119 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 2120 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 2121 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 2122 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 2123 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 2124 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 2125 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 2126 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 2127 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 2128 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 2129 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 2130 { } /* end */ 2131}; 2132 2133static struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = { 2134 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2135 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 2136 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2137 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 2138 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, 2139 HDA_OUTPUT), 2140 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 2141 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 2142 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 2143 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 2144 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 2145 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 2146 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 2147 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 2148 { } /* end */ 2149}; 2150 2151 2152static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec) 2153{ 2154 struct alc_spec *spec = codec->spec; 2155 2156 spec->autocfg.hp_pins[0] = 0x15; 2157 spec->autocfg.speaker_pins[0] = 0x14; 2158 spec->autocfg.speaker_pins[1] = 0x16; 2159 spec->autocfg.speaker_pins[2] = 0x17; 2160} 2161 2162static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec) 2163{ 2164 struct alc_spec *spec = codec->spec; 2165 2166 spec->autocfg.hp_pins[0] = 0x15; 2167 spec->autocfg.speaker_pins[0] = 0x14; 2168 spec->autocfg.speaker_pins[1] = 0x16; 2169 spec->autocfg.speaker_pins[2] = 0x17; 2170} 2171 2172static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec) 2173{ 2174 struct alc_spec *spec = codec->spec; 2175 2176 spec->autocfg.hp_pins[0] = 0x15; 2177 spec->autocfg.speaker_pins[0] = 0x14; 2178 spec->autocfg.speaker_pins[1] = 0x16; 2179 spec->autocfg.speaker_pins[2] = 0x1b; 2180} 2181 2182/* 2183 * ALC880 3-stack model 2184 * 2185 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e) 2186 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18, 2187 * F-Mic = 0x1b, HP = 0x19 2188 */ 2189 2190static hda_nid_t alc880_dac_nids[4] = { 2191 /* front, rear, clfe, rear_surr */ 2192 0x02, 0x05, 0x04, 0x03 2193}; 2194 2195static hda_nid_t alc880_adc_nids[3] = { 2196 /* ADC0-2 */ 2197 0x07, 0x08, 0x09, 2198}; 2199 2200/* The datasheet says the node 0x07 is connected from inputs, 2201 * but it shows zero connection in the real implementation on some devices. 2202 * Note: this is a 915GAV bug, fixed on 915GLV 2203 */ 2204static hda_nid_t alc880_adc_nids_alt[2] = { 2205 /* ADC1-2 */ 2206 0x08, 0x09, 2207}; 2208 2209#define ALC880_DIGOUT_NID 0x06 2210#define ALC880_DIGIN_NID 0x0a 2211 2212static struct hda_input_mux alc880_capture_source = { 2213 .num_items = 4, 2214 .items = { 2215 { "Mic", 0x0 }, 2216 { "Front Mic", 0x3 }, 2217 { "Line", 0x2 }, 2218 { "CD", 0x4 }, 2219 }, 2220}; 2221 2222/* channel source setting (2/6 channel selection for 3-stack) */ 2223/* 2ch mode */ 2224static struct hda_verb alc880_threestack_ch2_init[] = { 2225 /* set line-in to input, mute it */ 2226 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 2227 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 2228 /* set mic-in to input vref 80%, mute it */ 2229 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 2230 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 2231 { } /* end */ 2232}; 2233 2234/* 6ch mode */ 2235static struct hda_verb alc880_threestack_ch6_init[] = { 2236 /* set line-in to output, unmute it */ 2237 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 2238 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 2239 /* set mic-in to output, unmute it */ 2240 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 2241 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 2242 { } /* end */ 2243}; 2244 2245static struct hda_channel_mode alc880_threestack_modes[2] = { 2246 { 2, alc880_threestack_ch2_init }, 2247 { 6, alc880_threestack_ch6_init }, 2248}; 2249 2250static struct snd_kcontrol_new alc880_three_stack_mixer[] = { 2251 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2252 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 2253 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 2254 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT), 2255 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 2256 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 2257 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 2258 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 2259 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 2260 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 2261 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 2262 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 2263 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 2264 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 2265 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT), 2266 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT), 2267 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT), 2268 { 2269 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2270 .name = "Channel Mode", 2271 .info = alc_ch_mode_info, 2272 .get = alc_ch_mode_get, 2273 .put = alc_ch_mode_put, 2274 }, 2275 { } /* end */ 2276}; 2277 2278/* capture mixer elements */ 2279static int alc_cap_vol_info(struct snd_kcontrol *kcontrol, 2280 struct snd_ctl_elem_info *uinfo) 2281{ 2282 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2283 struct alc_spec *spec = codec->spec; 2284 int err; 2285 2286 mutex_lock(&codec->control_mutex); 2287 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0, 2288 HDA_INPUT); 2289 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo); 2290 mutex_unlock(&codec->control_mutex); 2291 return err; 2292} 2293 2294static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag, 2295 unsigned int size, unsigned int __user *tlv) 2296{ 2297 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2298 struct alc_spec *spec = codec->spec; 2299 int err; 2300 2301 mutex_lock(&codec->control_mutex); 2302 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0, 2303 HDA_INPUT); 2304 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv); 2305 mutex_unlock(&codec->control_mutex); 2306 return err; 2307} 2308 2309typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol, 2310 struct snd_ctl_elem_value *ucontrol); 2311 2312static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol, 2313 struct snd_ctl_elem_value *ucontrol, 2314 getput_call_t func) 2315{ 2316 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2317 struct alc_spec *spec = codec->spec; 2318 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 2319 int err; 2320 2321 mutex_lock(&codec->control_mutex); 2322 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx], 2323 3, 0, HDA_INPUT); 2324 err = func(kcontrol, ucontrol); 2325 mutex_unlock(&codec->control_mutex); 2326 return err; 2327} 2328 2329static int alc_cap_vol_get(struct snd_kcontrol *kcontrol, 2330 struct snd_ctl_elem_value *ucontrol) 2331{ 2332 return alc_cap_getput_caller(kcontrol, ucontrol, 2333 snd_hda_mixer_amp_volume_get); 2334} 2335 2336static int alc_cap_vol_put(struct snd_kcontrol *kcontrol, 2337 struct snd_ctl_elem_value *ucontrol) 2338{ 2339 return alc_cap_getput_caller(kcontrol, ucontrol, 2340 snd_hda_mixer_amp_volume_put); 2341} 2342 2343/* capture mixer elements */ 2344#define alc_cap_sw_info snd_ctl_boolean_stereo_info 2345 2346static int alc_cap_sw_get(struct snd_kcontrol *kcontrol, 2347 struct snd_ctl_elem_value *ucontrol) 2348{ 2349 return alc_cap_getput_caller(kcontrol, ucontrol, 2350 snd_hda_mixer_amp_switch_get); 2351} 2352 2353static int alc_cap_sw_put(struct snd_kcontrol *kcontrol, 2354 struct snd_ctl_elem_value *ucontrol) 2355{ 2356 return alc_cap_getput_caller(kcontrol, ucontrol, 2357 snd_hda_mixer_amp_switch_put); 2358} 2359 2360#define _DEFINE_CAPMIX(num) \ 2361 { \ 2362 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 2363 .name = "Capture Switch", \ 2364 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \ 2365 .count = num, \ 2366 .info = alc_cap_sw_info, \ 2367 .get = alc_cap_sw_get, \ 2368 .put = alc_cap_sw_put, \ 2369 }, \ 2370 { \ 2371 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 2372 .name = "Capture Volume", \ 2373 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \ 2374 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \ 2375 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \ 2376 .count = num, \ 2377 .info = alc_cap_vol_info, \ 2378 .get = alc_cap_vol_get, \ 2379 .put = alc_cap_vol_put, \ 2380 .tlv = { .c = alc_cap_vol_tlv }, \ 2381 } 2382 2383#define _DEFINE_CAPSRC(num) \ 2384 { \ 2385 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 2386 /* .name = "Capture Source", */ \ 2387 .name = "Input Source", \ 2388 .count = num, \ 2389 .info = alc_mux_enum_info, \ 2390 .get = alc_mux_enum_get, \ 2391 .put = alc_mux_enum_put, \ 2392 } 2393 2394#define DEFINE_CAPMIX(num) \ 2395static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \ 2396 _DEFINE_CAPMIX(num), \ 2397 _DEFINE_CAPSRC(num), \ 2398 { } /* end */ \ 2399} 2400 2401#define DEFINE_CAPMIX_NOSRC(num) \ 2402static struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \ 2403 _DEFINE_CAPMIX(num), \ 2404 { } /* end */ \ 2405} 2406 2407/* up to three ADCs */ 2408DEFINE_CAPMIX(1); 2409DEFINE_CAPMIX(2); 2410DEFINE_CAPMIX(3); 2411DEFINE_CAPMIX_NOSRC(1); 2412DEFINE_CAPMIX_NOSRC(2); 2413DEFINE_CAPMIX_NOSRC(3); 2414 2415/* 2416 * ALC880 5-stack model 2417 * 2418 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d), 2419 * Side = 0x02 (0xd) 2420 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16 2421 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19 2422 */ 2423 2424/* additional mixers to alc880_three_stack_mixer */ 2425static struct snd_kcontrol_new alc880_five_stack_mixer[] = { 2426 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2427 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT), 2428 { } /* end */ 2429}; 2430 2431/* channel source setting (6/8 channel selection for 5-stack) */ 2432/* 6ch mode */ 2433static struct hda_verb alc880_fivestack_ch6_init[] = { 2434 /* set line-in to input, mute it */ 2435 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 2436 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 2437 { } /* end */ 2438}; 2439 2440/* 8ch mode */ 2441static struct hda_verb alc880_fivestack_ch8_init[] = { 2442 /* set line-in to output, unmute it */ 2443 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 2444 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 2445 { } /* end */ 2446}; 2447 2448static struct hda_channel_mode alc880_fivestack_modes[2] = { 2449 { 6, alc880_fivestack_ch6_init }, 2450 { 8, alc880_fivestack_ch8_init }, 2451}; 2452 2453 2454/* 2455 * ALC880 6-stack model 2456 * 2457 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e), 2458 * Side = 0x05 (0x0f) 2459 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17, 2460 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b 2461 */ 2462 2463static hda_nid_t alc880_6st_dac_nids[4] = { 2464 /* front, rear, clfe, rear_surr */ 2465 0x02, 0x03, 0x04, 0x05 2466}; 2467 2468static struct hda_input_mux alc880_6stack_capture_source = { 2469 .num_items = 4, 2470 .items = { 2471 { "Mic", 0x0 }, 2472 { "Front Mic", 0x1 }, 2473 { "Line", 0x2 }, 2474 { "CD", 0x4 }, 2475 }, 2476}; 2477 2478/* fixed 8-channels */ 2479static struct hda_channel_mode alc880_sixstack_modes[1] = { 2480 { 8, NULL }, 2481}; 2482 2483static struct snd_kcontrol_new alc880_six_stack_mixer[] = { 2484 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2485 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 2486 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2487 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 2488 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 2489 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 2490 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 2491 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 2492 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 2493 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 2494 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 2495 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 2496 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 2497 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 2498 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 2499 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 2500 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 2501 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 2502 { 2503 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2504 .name = "Channel Mode", 2505 .info = alc_ch_mode_info, 2506 .get = alc_ch_mode_get, 2507 .put = alc_ch_mode_put, 2508 }, 2509 { } /* end */ 2510}; 2511 2512 2513/* 2514 * ALC880 W810 model 2515 * 2516 * W810 has rear IO for: 2517 * Front (DAC 02) 2518 * Surround (DAC 03) 2519 * Center/LFE (DAC 04) 2520 * Digital out (06) 2521 * 2522 * The system also has a pair of internal speakers, and a headphone jack. 2523 * These are both connected to Line2 on the codec, hence to DAC 02. 2524 * 2525 * There is a variable resistor to control the speaker or headphone 2526 * volume. This is a hardware-only device without a software API. 2527 * 2528 * Plugging headphones in will disable the internal speakers. This is 2529 * implemented in hardware, not via the driver using jack sense. In 2530 * a similar fashion, plugging into the rear socket marked "front" will 2531 * disable both the speakers and headphones. 2532 * 2533 * For input, there's a microphone jack, and an "audio in" jack. 2534 * These may not do anything useful with this driver yet, because I 2535 * haven't setup any initialization verbs for these yet... 2536 */ 2537 2538static hda_nid_t alc880_w810_dac_nids[3] = { 2539 /* front, rear/surround, clfe */ 2540 0x02, 0x03, 0x04 2541}; 2542 2543/* fixed 6 channels */ 2544static struct hda_channel_mode alc880_w810_modes[1] = { 2545 { 6, NULL } 2546}; 2547 2548/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */ 2549static struct snd_kcontrol_new alc880_w810_base_mixer[] = { 2550 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2551 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 2552 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2553 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 2554 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 2555 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 2556 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 2557 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 2558 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 2559 { } /* end */ 2560}; 2561 2562 2563/* 2564 * Z710V model 2565 * 2566 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d) 2567 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?), 2568 * Line = 0x1a 2569 */ 2570 2571static hda_nid_t alc880_z71v_dac_nids[1] = { 2572 0x02 2573}; 2574#define ALC880_Z71V_HP_DAC 0x03 2575 2576/* fixed 2 channels */ 2577static struct hda_channel_mode alc880_2_jack_modes[1] = { 2578 { 2, NULL } 2579}; 2580 2581static struct snd_kcontrol_new alc880_z71v_mixer[] = { 2582 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2583 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 2584 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2585 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT), 2586 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 2587 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 2588 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 2589 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 2590 { } /* end */ 2591}; 2592 2593 2594/* 2595 * ALC880 F1734 model 2596 * 2597 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d) 2598 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18 2599 */ 2600 2601static hda_nid_t alc880_f1734_dac_nids[1] = { 2602 0x03 2603}; 2604#define ALC880_F1734_HP_DAC 0x02 2605 2606static struct snd_kcontrol_new alc880_f1734_mixer[] = { 2607 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2608 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), 2609 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2610 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 2611 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 2612 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 2613 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 2614 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 2615 { } /* end */ 2616}; 2617 2618static struct hda_input_mux alc880_f1734_capture_source = { 2619 .num_items = 2, 2620 .items = { 2621 { "Mic", 0x1 }, 2622 { "CD", 0x4 }, 2623 }, 2624}; 2625 2626 2627/* 2628 * ALC880 ASUS model 2629 * 2630 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e) 2631 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16, 2632 * Mic = 0x18, Line = 0x1a 2633 */ 2634 2635#define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */ 2636#define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */ 2637 2638static struct snd_kcontrol_new alc880_asus_mixer[] = { 2639 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2640 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 2641 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2642 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 2643 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 2644 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 2645 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 2646 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 2647 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 2648 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 2649 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 2650 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 2651 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 2652 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 2653 { 2654 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2655 .name = "Channel Mode", 2656 .info = alc_ch_mode_info, 2657 .get = alc_ch_mode_get, 2658 .put = alc_ch_mode_put, 2659 }, 2660 { } /* end */ 2661}; 2662 2663/* 2664 * ALC880 ASUS W1V model 2665 * 2666 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e) 2667 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16, 2668 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b 2669 */ 2670 2671/* additional mixers to alc880_asus_mixer */ 2672static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = { 2673 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT), 2674 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT), 2675 { } /* end */ 2676}; 2677 2678/* TCL S700 */ 2679static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = { 2680 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2681 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 2682 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 2683 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT), 2684 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT), 2685 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT), 2686 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT), 2687 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 2688 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 2689 { } /* end */ 2690}; 2691 2692/* Uniwill */ 2693static struct snd_kcontrol_new alc880_uniwill_mixer[] = { 2694 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2695 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), 2696 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2697 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 2698 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 2699 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 2700 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 2701 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 2702 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 2703 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 2704 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 2705 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 2706 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 2707 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 2708 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 2709 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 2710 { 2711 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2712 .name = "Channel Mode", 2713 .info = alc_ch_mode_info, 2714 .get = alc_ch_mode_get, 2715 .put = alc_ch_mode_put, 2716 }, 2717 { } /* end */ 2718}; 2719 2720static struct snd_kcontrol_new alc880_fujitsu_mixer[] = { 2721 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2722 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), 2723 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2724 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 2725 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 2726 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 2727 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 2728 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 2729 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 2730 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 2731 { } /* end */ 2732}; 2733 2734static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = { 2735 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2736 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), 2737 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2738 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 2739 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 2740 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 2741 { } /* end */ 2742}; 2743 2744/* 2745 * virtual master controls 2746 */ 2747 2748/* 2749 * slave controls for virtual master 2750 */ 2751static const char *alc_slave_vols[] = { 2752 "Front Playback Volume", 2753 "Surround Playback Volume", 2754 "Center Playback Volume", 2755 "LFE Playback Volume", 2756 "Side Playback Volume", 2757 "Headphone Playback Volume", 2758 "Speaker Playback Volume", 2759 "Mono Playback Volume", 2760 "Line-Out Playback Volume", 2761 "PCM Playback Volume", 2762 NULL, 2763}; 2764 2765static const char *alc_slave_sws[] = { 2766 "Front Playback Switch", 2767 "Surround Playback Switch", 2768 "Center Playback Switch", 2769 "LFE Playback Switch", 2770 "Side Playback Switch", 2771 "Headphone Playback Switch", 2772 "Speaker Playback Switch", 2773 "Mono Playback Switch", 2774 "IEC958 Playback Switch", 2775 "Line-Out Playback Switch", 2776 "PCM Playback Switch", 2777 NULL, 2778}; 2779 2780/* 2781 * build control elements 2782 */ 2783 2784#define NID_MAPPING (-1) 2785 2786#define SUBDEV_SPEAKER_ (0 << 6) 2787#define SUBDEV_HP_ (1 << 6) 2788#define SUBDEV_LINE_ (2 << 6) 2789#define SUBDEV_SPEAKER(x) (SUBDEV_SPEAKER_ | ((x) & 0x3f)) 2790#define SUBDEV_HP(x) (SUBDEV_HP_ | ((x) & 0x3f)) 2791#define SUBDEV_LINE(x) (SUBDEV_LINE_ | ((x) & 0x3f)) 2792 2793static void alc_free_kctls(struct hda_codec *codec); 2794 2795#ifdef CONFIG_SND_HDA_INPUT_BEEP 2796/* additional beep mixers; the actual parameters are overwritten at build */ 2797static struct snd_kcontrol_new alc_beep_mixer[] = { 2798 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT), 2799 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT), 2800 { } /* end */ 2801}; 2802#endif 2803 2804static int alc_build_controls(struct hda_codec *codec) 2805{ 2806 struct alc_spec *spec = codec->spec; 2807 struct snd_kcontrol *kctl = NULL; 2808 struct snd_kcontrol_new *knew; 2809 int i, j, err; 2810 unsigned int u; 2811 hda_nid_t nid; 2812 2813 for (i = 0; i < spec->num_mixers; i++) { 2814 err = snd_hda_add_new_ctls(codec, spec->mixers[i]); 2815 if (err < 0) 2816 return err; 2817 } 2818 if (spec->cap_mixer) { 2819 err = snd_hda_add_new_ctls(codec, spec->cap_mixer); 2820 if (err < 0) 2821 return err; 2822 } 2823 if (spec->multiout.dig_out_nid) { 2824 err = snd_hda_create_spdif_out_ctls(codec, 2825 spec->multiout.dig_out_nid); 2826 if (err < 0) 2827 return err; 2828 if (!spec->no_analog) { 2829 err = snd_hda_create_spdif_share_sw(codec, 2830 &spec->multiout); 2831 if (err < 0) 2832 return err; 2833 spec->multiout.share_spdif = 1; 2834 } 2835 } 2836 if (spec->dig_in_nid) { 2837 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid); 2838 if (err < 0) 2839 return err; 2840 } 2841 2842#ifdef CONFIG_SND_HDA_INPUT_BEEP 2843 /* create beep controls if needed */ 2844 if (spec->beep_amp) { 2845 struct snd_kcontrol_new *knew; 2846 for (knew = alc_beep_mixer; knew->name; knew++) { 2847 struct snd_kcontrol *kctl; 2848 kctl = snd_ctl_new1(knew, codec); 2849 if (!kctl) 2850 return -ENOMEM; 2851 kctl->private_value = spec->beep_amp; 2852 err = snd_hda_ctl_add(codec, 0, kctl); 2853 if (err < 0) 2854 return err; 2855 } 2856 } 2857#endif 2858 2859 /* if we have no master control, let's create it */ 2860 if (!spec->no_analog && 2861 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) { 2862 unsigned int vmaster_tlv[4]; 2863 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid, 2864 HDA_OUTPUT, vmaster_tlv); 2865 err = snd_hda_add_vmaster(codec, "Master Playback Volume", 2866 vmaster_tlv, alc_slave_vols); 2867 if (err < 0) 2868 return err; 2869 } 2870 if (!spec->no_analog && 2871 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) { 2872 err = snd_hda_add_vmaster(codec, "Master Playback Switch", 2873 NULL, alc_slave_sws); 2874 if (err < 0) 2875 return err; 2876 } 2877 2878 /* assign Capture Source enums to NID */ 2879 if (spec->capsrc_nids || spec->adc_nids) { 2880 kctl = snd_hda_find_mixer_ctl(codec, "Capture Source"); 2881 if (!kctl) 2882 kctl = snd_hda_find_mixer_ctl(codec, "Input Source"); 2883 for (i = 0; kctl && i < kctl->count; i++) { 2884 hda_nid_t *nids = spec->capsrc_nids; 2885 if (!nids) 2886 nids = spec->adc_nids; 2887 err = snd_hda_add_nid(codec, kctl, i, nids[i]); 2888 if (err < 0) 2889 return err; 2890 } 2891 } 2892 if (spec->cap_mixer) { 2893 const char *kname = kctl ? kctl->id.name : NULL; 2894 for (knew = spec->cap_mixer; knew->name; knew++) { 2895 if (kname && strcmp(knew->name, kname) == 0) 2896 continue; 2897 kctl = snd_hda_find_mixer_ctl(codec, knew->name); 2898 for (i = 0; kctl && i < kctl->count; i++) { 2899 err = snd_hda_add_nid(codec, kctl, i, 2900 spec->adc_nids[i]); 2901 if (err < 0) 2902 return err; 2903 } 2904 } 2905 } 2906 2907 /* other nid->control mapping */ 2908 for (i = 0; i < spec->num_mixers; i++) { 2909 for (knew = spec->mixers[i]; knew->name; knew++) { 2910 if (knew->iface != NID_MAPPING) 2911 continue; 2912 kctl = snd_hda_find_mixer_ctl(codec, knew->name); 2913 if (kctl == NULL) 2914 continue; 2915 u = knew->subdevice; 2916 for (j = 0; j < 4; j++, u >>= 8) { 2917 nid = u & 0x3f; 2918 if (nid == 0) 2919 continue; 2920 switch (u & 0xc0) { 2921 case SUBDEV_SPEAKER_: 2922 nid = spec->autocfg.speaker_pins[nid]; 2923 break; 2924 case SUBDEV_LINE_: 2925 nid = spec->autocfg.line_out_pins[nid]; 2926 break; 2927 case SUBDEV_HP_: 2928 nid = spec->autocfg.hp_pins[nid]; 2929 break; 2930 default: 2931 continue; 2932 } 2933 err = snd_hda_add_nid(codec, kctl, 0, nid); 2934 if (err < 0) 2935 return err; 2936 } 2937 u = knew->private_value; 2938 for (j = 0; j < 4; j++, u >>= 8) { 2939 nid = u & 0xff; 2940 if (nid == 0) 2941 continue; 2942 err = snd_hda_add_nid(codec, kctl, 0, nid); 2943 if (err < 0) 2944 return err; 2945 } 2946 } 2947 } 2948 2949 alc_free_kctls(codec); /* no longer needed */ 2950 2951 return 0; 2952} 2953 2954 2955/* 2956 * initialize the codec volumes, etc 2957 */ 2958 2959/* 2960 * generic initialization of ADC, input mixers and output mixers 2961 */ 2962static struct hda_verb alc880_volume_init_verbs[] = { 2963 /* 2964 * Unmute ADC0-2 and set the default input to mic-in 2965 */ 2966 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 2967 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 2968 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 2969 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 2970 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 2971 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 2972 2973 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 2974 * mixer widget 2975 * Note: PASD motherboards uses the Line In 2 as the input for front 2976 * panel mic (mic 2) 2977 */ 2978 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 2979 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 2980 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 2981 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 2982 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 2983 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 2984 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, 2985 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, 2986 2987 /* 2988 * Set up output mixers (0x0c - 0x0f) 2989 */ 2990 /* set vol=0 to output mixers */ 2991 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 2992 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 2993 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 2994 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 2995 /* set up input amps for analog loopback */ 2996 /* Amp Indices: DAC = 0, mixer = 1 */ 2997 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 2998 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 2999 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3000 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 3001 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3002 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 3003 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3004 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 3005 3006 { } 3007}; 3008 3009/* 3010 * 3-stack pin configuration: 3011 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b 3012 */ 3013static struct hda_verb alc880_pin_3stack_init_verbs[] = { 3014 /* 3015 * preset connection lists of input pins 3016 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround 3017 */ 3018 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ 3019 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 3020 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */ 3021 3022 /* 3023 * Set pin mode and muting 3024 */ 3025 /* set front pin widgets 0x14 for output */ 3026 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3027 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3028 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 3029 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3030 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3031 /* Mic2 (as headphone out) for HP output */ 3032 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3033 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3034 /* Line In pin widget for input */ 3035 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3036 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3037 /* Line2 (as front mic) pin widget for input and vref at 80% */ 3038 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3039 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3040 /* CD pin widget for input */ 3041 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3042 3043 { } 3044}; 3045 3046/* 3047 * 5-stack pin configuration: 3048 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19, 3049 * line-in/side = 0x1a, f-mic = 0x1b 3050 */ 3051static struct hda_verb alc880_pin_5stack_init_verbs[] = { 3052 /* 3053 * preset connection lists of input pins 3054 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround 3055 */ 3056 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 3057 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */ 3058 3059 /* 3060 * Set pin mode and muting 3061 */ 3062 /* set pin widgets 0x14-0x17 for output */ 3063 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3064 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3065 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3066 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3067 /* unmute pins for output (no gain on this amp) */ 3068 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3069 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3070 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3071 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3072 3073 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 3074 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3075 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3076 /* Mic2 (as headphone out) for HP output */ 3077 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3078 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3079 /* Line In pin widget for input */ 3080 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3081 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3082 /* Line2 (as front mic) pin widget for input and vref at 80% */ 3083 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3084 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3085 /* CD pin widget for input */ 3086 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3087 3088 { } 3089}; 3090 3091/* 3092 * W810 pin configuration: 3093 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b 3094 */ 3095static struct hda_verb alc880_pin_w810_init_verbs[] = { 3096 /* hphone/speaker input selector: front DAC */ 3097 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0}, 3098 3099 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3100 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3101 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3102 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3103 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3104 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3105 3106 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3107 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3108 3109 { } 3110}; 3111 3112/* 3113 * Z71V pin configuration: 3114 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?) 3115 */ 3116static struct hda_verb alc880_pin_z71v_init_verbs[] = { 3117 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3118 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3119 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3120 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3121 3122 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3123 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3124 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3125 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3126 3127 { } 3128}; 3129 3130/* 3131 * 6-stack pin configuration: 3132 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18, 3133 * f-mic = 0x19, line = 0x1a, HP = 0x1b 3134 */ 3135static struct hda_verb alc880_pin_6stack_init_verbs[] = { 3136 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 3137 3138 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3139 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3140 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3141 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3142 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3143 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3144 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3145 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3146 3147 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3148 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3149 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3150 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3151 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3152 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3153 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3154 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3155 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3156 3157 { } 3158}; 3159 3160/* 3161 * Uniwill pin configuration: 3162 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19, 3163 * line = 0x1a 3164 */ 3165static struct hda_verb alc880_uniwill_init_verbs[] = { 3166 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 3167 3168 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3169 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3170 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3171 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3172 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3173 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3174 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3175 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3176 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 3177 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 3178 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 3179 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 3180 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 3181 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 3182 3183 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3184 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3185 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3186 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3187 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3188 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3189 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */ 3190 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */ 3191 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3192 3193 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 3194 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 3195 3196 { } 3197}; 3198 3199/* 3200* Uniwill P53 3201* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19, 3202 */ 3203static struct hda_verb alc880_uniwill_p53_init_verbs[] = { 3204 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 3205 3206 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3207 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3208 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3209 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3210 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3211 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3212 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 3213 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 3214 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 3215 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 3216 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 3217 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 3218 3219 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3220 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3221 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3222 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3223 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3224 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3225 3226 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 3227 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT}, 3228 3229 { } 3230}; 3231 3232static struct hda_verb alc880_beep_init_verbs[] = { 3233 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) }, 3234 { } 3235}; 3236 3237/* auto-toggle front mic */ 3238static void alc880_uniwill_mic_automute(struct hda_codec *codec) 3239{ 3240 unsigned int present; 3241 unsigned char bits; 3242 3243 present = snd_hda_jack_detect(codec, 0x18); 3244 bits = present ? HDA_AMP_MUTE : 0; 3245 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits); 3246} 3247 3248static void alc880_uniwill_setup(struct hda_codec *codec) 3249{ 3250 struct alc_spec *spec = codec->spec; 3251 3252 spec->autocfg.hp_pins[0] = 0x14; 3253 spec->autocfg.speaker_pins[0] = 0x15; 3254 spec->autocfg.speaker_pins[0] = 0x16; 3255} 3256 3257static void alc880_uniwill_init_hook(struct hda_codec *codec) 3258{ 3259 alc_automute_amp(codec); 3260 alc880_uniwill_mic_automute(codec); 3261} 3262 3263static void alc880_uniwill_unsol_event(struct hda_codec *codec, 3264 unsigned int res) 3265{ 3266 /* Looks like the unsol event is incompatible with the standard 3267 * definition. 4bit tag is placed at 28 bit! 3268 */ 3269 switch (res >> 28) { 3270 case ALC880_MIC_EVENT: 3271 alc880_uniwill_mic_automute(codec); 3272 break; 3273 default: 3274 alc_automute_amp_unsol_event(codec, res); 3275 break; 3276 } 3277} 3278 3279static void alc880_uniwill_p53_setup(struct hda_codec *codec) 3280{ 3281 struct alc_spec *spec = codec->spec; 3282 3283 spec->autocfg.hp_pins[0] = 0x14; 3284 spec->autocfg.speaker_pins[0] = 0x15; 3285} 3286 3287static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec) 3288{ 3289 unsigned int present; 3290 3291 present = snd_hda_codec_read(codec, 0x21, 0, 3292 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0); 3293 present &= HDA_AMP_VOLMASK; 3294 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0, 3295 HDA_AMP_VOLMASK, present); 3296 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0, 3297 HDA_AMP_VOLMASK, present); 3298} 3299 3300static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec, 3301 unsigned int res) 3302{ 3303 /* Looks like the unsol event is incompatible with the standard 3304 * definition. 4bit tag is placed at 28 bit! 3305 */ 3306 if ((res >> 28) == ALC880_DCVOL_EVENT) 3307 alc880_uniwill_p53_dcvol_automute(codec); 3308 else 3309 alc_automute_amp_unsol_event(codec, res); 3310} 3311 3312/* 3313 * F1734 pin configuration: 3314 * HP = 0x14, speaker-out = 0x15, mic = 0x18 3315 */ 3316static struct hda_verb alc880_pin_f1734_init_verbs[] = { 3317 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01}, 3318 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, 3319 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, 3320 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, 3321 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, 3322 3323 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3324 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3325 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3326 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3327 3328 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3329 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3330 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, 3331 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3332 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3333 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3334 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3335 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3336 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3337 3338 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT}, 3339 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT}, 3340 3341 { } 3342}; 3343 3344/* 3345 * ASUS pin configuration: 3346 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a 3347 */ 3348static struct hda_verb alc880_pin_asus_init_verbs[] = { 3349 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, 3350 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, 3351 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, 3352 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, 3353 3354 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3355 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3356 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3357 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3358 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3359 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3360 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3361 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3362 3363 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3364 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3365 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3366 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3367 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3368 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3369 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3370 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3371 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3372 3373 { } 3374}; 3375 3376/* Enable GPIO mask and set output */ 3377#define alc880_gpio1_init_verbs alc_gpio1_init_verbs 3378#define alc880_gpio2_init_verbs alc_gpio2_init_verbs 3379#define alc880_gpio3_init_verbs alc_gpio3_init_verbs 3380 3381/* Clevo m520g init */ 3382static struct hda_verb alc880_pin_clevo_init_verbs[] = { 3383 /* headphone output */ 3384 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01}, 3385 /* line-out */ 3386 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3387 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3388 /* Line-in */ 3389 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3390 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3391 /* CD */ 3392 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3393 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3394 /* Mic1 (rear panel) */ 3395 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3396 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3397 /* Mic2 (front panel) */ 3398 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3399 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3400 /* headphone */ 3401 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3402 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3403 /* change to EAPD mode */ 3404 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 3405 {0x20, AC_VERB_SET_PROC_COEF, 0x3060}, 3406 3407 { } 3408}; 3409 3410static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = { 3411 /* change to EAPD mode */ 3412 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 3413 {0x20, AC_VERB_SET_PROC_COEF, 0x3060}, 3414 3415 /* Headphone output */ 3416 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3417 /* Front output*/ 3418 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3419 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 3420 3421 /* Line In pin widget for input */ 3422 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3423 /* CD pin widget for input */ 3424 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3425 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 3426 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3427 3428 /* change to EAPD mode */ 3429 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 3430 {0x20, AC_VERB_SET_PROC_COEF, 0x3070}, 3431 3432 { } 3433}; 3434 3435/* 3436 * LG m1 express dual 3437 * 3438 * Pin assignment: 3439 * Rear Line-In/Out (blue): 0x14 3440 * Build-in Mic-In: 0x15 3441 * Speaker-out: 0x17 3442 * HP-Out (green): 0x1b 3443 * Mic-In/Out (red): 0x19 3444 * SPDIF-Out: 0x1e 3445 */ 3446 3447/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */ 3448static hda_nid_t alc880_lg_dac_nids[3] = { 3449 0x05, 0x02, 0x03 3450}; 3451 3452/* seems analog CD is not working */ 3453static struct hda_input_mux alc880_lg_capture_source = { 3454 .num_items = 3, 3455 .items = { 3456 { "Mic", 0x1 }, 3457 { "Line", 0x5 }, 3458 { "Internal Mic", 0x6 }, 3459 }, 3460}; 3461 3462/* 2,4,6 channel modes */ 3463static struct hda_verb alc880_lg_ch2_init[] = { 3464 /* set line-in and mic-in to input */ 3465 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 3466 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 3467 { } 3468}; 3469 3470static struct hda_verb alc880_lg_ch4_init[] = { 3471 /* set line-in to out and mic-in to input */ 3472 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, 3473 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 3474 { } 3475}; 3476 3477static struct hda_verb alc880_lg_ch6_init[] = { 3478 /* set line-in and mic-in to output */ 3479 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, 3480 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, 3481 { } 3482}; 3483 3484static struct hda_channel_mode alc880_lg_ch_modes[3] = { 3485 { 2, alc880_lg_ch2_init }, 3486 { 4, alc880_lg_ch4_init }, 3487 { 6, alc880_lg_ch6_init }, 3488}; 3489 3490static struct snd_kcontrol_new alc880_lg_mixer[] = { 3491 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 3492 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT), 3493 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 3494 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT), 3495 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT), 3496 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT), 3497 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT), 3498 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT), 3499 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 3500 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 3501 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT), 3502 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT), 3503 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT), 3504 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT), 3505 { 3506 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 3507 .name = "Channel Mode", 3508 .info = alc_ch_mode_info, 3509 .get = alc_ch_mode_get, 3510 .put = alc_ch_mode_put, 3511 }, 3512 { } /* end */ 3513}; 3514 3515static struct hda_verb alc880_lg_init_verbs[] = { 3516 /* set capture source to mic-in */ 3517 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 3518 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 3519 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 3520 /* mute all amp mixer inputs */ 3521 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)}, 3522 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, 3523 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, 3524 /* line-in to input */ 3525 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3526 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3527 /* built-in mic */ 3528 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3529 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3530 /* speaker-out */ 3531 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3532 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3533 /* mic-in to input */ 3534 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01}, 3535 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3536 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3537 /* HP-out */ 3538 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03}, 3539 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3540 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3541 /* jack sense */ 3542 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 3543 { } 3544}; 3545 3546/* toggle speaker-output according to the hp-jack state */ 3547static void alc880_lg_setup(struct hda_codec *codec) 3548{ 3549 struct alc_spec *spec = codec->spec; 3550 3551 spec->autocfg.hp_pins[0] = 0x1b; 3552 spec->autocfg.speaker_pins[0] = 0x17; 3553} 3554 3555/* 3556 * LG LW20 3557 * 3558 * Pin assignment: 3559 * Speaker-out: 0x14 3560 * Mic-In: 0x18 3561 * Built-in Mic-In: 0x19 3562 * Line-In: 0x1b 3563 * HP-Out: 0x1a 3564 * SPDIF-Out: 0x1e 3565 */ 3566 3567static struct hda_input_mux alc880_lg_lw_capture_source = { 3568 .num_items = 3, 3569 .items = { 3570 { "Mic", 0x0 }, 3571 { "Internal Mic", 0x1 }, 3572 { "Line In", 0x2 }, 3573 }, 3574}; 3575 3576#define alc880_lg_lw_modes alc880_threestack_modes 3577 3578static struct snd_kcontrol_new alc880_lg_lw_mixer[] = { 3579 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 3580 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 3581 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 3582 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT), 3583 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 3584 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 3585 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 3586 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 3587 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 3588 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 3589 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 3590 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 3591 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 3592 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 3593 { 3594 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 3595 .name = "Channel Mode", 3596 .info = alc_ch_mode_info, 3597 .get = alc_ch_mode_get, 3598 .put = alc_ch_mode_put, 3599 }, 3600 { } /* end */ 3601}; 3602 3603static struct hda_verb alc880_lg_lw_init_verbs[] = { 3604 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 3605 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ 3606 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */ 3607 3608 /* set capture source to mic-in */ 3609 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3610 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3611 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3612 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, 3613 /* speaker-out */ 3614 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3615 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3616 /* HP-out */ 3617 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3618 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3619 /* mic-in to input */ 3620 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3621 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3622 /* built-in mic */ 3623 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3624 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3625 /* jack sense */ 3626 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 3627 { } 3628}; 3629 3630/* toggle speaker-output according to the hp-jack state */ 3631static void alc880_lg_lw_setup(struct hda_codec *codec) 3632{ 3633 struct alc_spec *spec = codec->spec; 3634 3635 spec->autocfg.hp_pins[0] = 0x1b; 3636 spec->autocfg.speaker_pins[0] = 0x14; 3637} 3638 3639static struct snd_kcontrol_new alc880_medion_rim_mixer[] = { 3640 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 3641 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT), 3642 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 3643 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 3644 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 3645 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT), 3646 { } /* end */ 3647}; 3648 3649static struct hda_input_mux alc880_medion_rim_capture_source = { 3650 .num_items = 2, 3651 .items = { 3652 { "Mic", 0x0 }, 3653 { "Internal Mic", 0x1 }, 3654 }, 3655}; 3656 3657static struct hda_verb alc880_medion_rim_init_verbs[] = { 3658 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 3659 3660 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3661 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3662 3663 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 3664 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3665 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3666 /* Mic2 (as headphone out) for HP output */ 3667 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3668 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3669 /* Internal Speaker */ 3670 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3671 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3672 3673 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 3674 {0x20, AC_VERB_SET_PROC_COEF, 0x3060}, 3675 3676 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 3677 { } 3678}; 3679 3680/* toggle speaker-output according to the hp-jack state */ 3681static void alc880_medion_rim_automute(struct hda_codec *codec) 3682{ 3683 struct alc_spec *spec = codec->spec; 3684 alc_automute_amp(codec); 3685 /* toggle EAPD */ 3686 if (spec->jack_present) 3687 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0); 3688 else 3689 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2); 3690} 3691 3692static void alc880_medion_rim_unsol_event(struct hda_codec *codec, 3693 unsigned int res) 3694{ 3695 /* Looks like the unsol event is incompatible with the standard 3696 * definition. 4bit tag is placed at 28 bit! 3697 */ 3698 if ((res >> 28) == ALC880_HP_EVENT) 3699 alc880_medion_rim_automute(codec); 3700} 3701 3702static void alc880_medion_rim_setup(struct hda_codec *codec) 3703{ 3704 struct alc_spec *spec = codec->spec; 3705 3706 spec->autocfg.hp_pins[0] = 0x14; 3707 spec->autocfg.speaker_pins[0] = 0x1b; 3708} 3709 3710#ifdef CONFIG_SND_HDA_POWER_SAVE 3711static struct hda_amp_list alc880_loopbacks[] = { 3712 { 0x0b, HDA_INPUT, 0 }, 3713 { 0x0b, HDA_INPUT, 1 }, 3714 { 0x0b, HDA_INPUT, 2 }, 3715 { 0x0b, HDA_INPUT, 3 }, 3716 { 0x0b, HDA_INPUT, 4 }, 3717 { } /* end */ 3718}; 3719 3720static struct hda_amp_list alc880_lg_loopbacks[] = { 3721 { 0x0b, HDA_INPUT, 1 }, 3722 { 0x0b, HDA_INPUT, 6 }, 3723 { 0x0b, HDA_INPUT, 7 }, 3724 { } /* end */ 3725}; 3726#endif 3727 3728/* 3729 * Common callbacks 3730 */ 3731 3732static int alc_init(struct hda_codec *codec) 3733{ 3734 struct alc_spec *spec = codec->spec; 3735 unsigned int i; 3736 3737 alc_fix_pll(codec); 3738 alc_auto_init_amp(codec, spec->init_amp); 3739 3740 for (i = 0; i < spec->num_init_verbs; i++) 3741 snd_hda_sequence_write(codec, spec->init_verbs[i]); 3742 3743 if (spec->init_hook) 3744 spec->init_hook(codec); 3745 3746 hda_call_check_power_status(codec, 0x01); 3747 return 0; 3748} 3749 3750static void alc_unsol_event(struct hda_codec *codec, unsigned int res) 3751{ 3752 struct alc_spec *spec = codec->spec; 3753 3754 if (spec->unsol_event) 3755 spec->unsol_event(codec, res); 3756} 3757 3758#ifdef CONFIG_SND_HDA_POWER_SAVE 3759static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid) 3760{ 3761 struct alc_spec *spec = codec->spec; 3762 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid); 3763} 3764#endif 3765 3766/* 3767 * Analog playback callbacks 3768 */ 3769static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo, 3770 struct hda_codec *codec, 3771 struct snd_pcm_substream *substream) 3772{ 3773 struct alc_spec *spec = codec->spec; 3774 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream, 3775 hinfo); 3776} 3777 3778static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo, 3779 struct hda_codec *codec, 3780 unsigned int stream_tag, 3781 unsigned int format, 3782 struct snd_pcm_substream *substream) 3783{ 3784 struct alc_spec *spec = codec->spec; 3785 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, 3786 stream_tag, format, substream); 3787} 3788 3789static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, 3790 struct hda_codec *codec, 3791 struct snd_pcm_substream *substream) 3792{ 3793 struct alc_spec *spec = codec->spec; 3794 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); 3795} 3796 3797/* 3798 * Digital out 3799 */ 3800static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo, 3801 struct hda_codec *codec, 3802 struct snd_pcm_substream *substream) 3803{ 3804 struct alc_spec *spec = codec->spec; 3805 return snd_hda_multi_out_dig_open(codec, &spec->multiout); 3806} 3807 3808static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, 3809 struct hda_codec *codec, 3810 unsigned int stream_tag, 3811 unsigned int format, 3812 struct snd_pcm_substream *substream) 3813{ 3814 struct alc_spec *spec = codec->spec; 3815 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, 3816 stream_tag, format, substream); 3817} 3818 3819static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, 3820 struct hda_codec *codec, 3821 struct snd_pcm_substream *substream) 3822{ 3823 struct alc_spec *spec = codec->spec; 3824 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout); 3825} 3826 3827static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, 3828 struct hda_codec *codec, 3829 struct snd_pcm_substream *substream) 3830{ 3831 struct alc_spec *spec = codec->spec; 3832 return snd_hda_multi_out_dig_close(codec, &spec->multiout); 3833} 3834 3835/* 3836 * Analog capture 3837 */ 3838static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo, 3839 struct hda_codec *codec, 3840 unsigned int stream_tag, 3841 unsigned int format, 3842 struct snd_pcm_substream *substream) 3843{ 3844 struct alc_spec *spec = codec->spec; 3845 3846 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1], 3847 stream_tag, 0, format); 3848 return 0; 3849} 3850 3851static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, 3852 struct hda_codec *codec, 3853 struct snd_pcm_substream *substream) 3854{ 3855 struct alc_spec *spec = codec->spec; 3856 3857 snd_hda_codec_cleanup_stream(codec, 3858 spec->adc_nids[substream->number + 1]); 3859 return 0; 3860} 3861 3862/* analog capture with dynamic dual-adc changes */ 3863static int dualmic_capture_pcm_prepare(struct hda_pcm_stream *hinfo, 3864 struct hda_codec *codec, 3865 unsigned int stream_tag, 3866 unsigned int format, 3867 struct snd_pcm_substream *substream) 3868{ 3869 struct alc_spec *spec = codec->spec; 3870 spec->cur_adc = spec->adc_nids[spec->cur_adc_idx]; 3871 spec->cur_adc_stream_tag = stream_tag; 3872 spec->cur_adc_format = format; 3873 snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format); 3874 return 0; 3875} 3876 3877static int dualmic_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, 3878 struct hda_codec *codec, 3879 struct snd_pcm_substream *substream) 3880{ 3881 struct alc_spec *spec = codec->spec; 3882 snd_hda_codec_cleanup_stream(codec, spec->cur_adc); 3883 spec->cur_adc = 0; 3884 return 0; 3885} 3886 3887static struct hda_pcm_stream dualmic_pcm_analog_capture = { 3888 .substreams = 1, 3889 .channels_min = 2, 3890 .channels_max = 2, 3891 .nid = 0, /* fill later */ 3892 .ops = { 3893 .prepare = dualmic_capture_pcm_prepare, 3894 .cleanup = dualmic_capture_pcm_cleanup 3895 }, 3896}; 3897 3898/* 3899 */ 3900static struct hda_pcm_stream alc880_pcm_analog_playback = { 3901 .substreams = 1, 3902 .channels_min = 2, 3903 .channels_max = 8, 3904 /* NID is set in alc_build_pcms */ 3905 .ops = { 3906 .open = alc880_playback_pcm_open, 3907 .prepare = alc880_playback_pcm_prepare, 3908 .cleanup = alc880_playback_pcm_cleanup 3909 }, 3910}; 3911 3912static struct hda_pcm_stream alc880_pcm_analog_capture = { 3913 .substreams = 1, 3914 .channels_min = 2, 3915 .channels_max = 2, 3916 /* NID is set in alc_build_pcms */ 3917}; 3918 3919static struct hda_pcm_stream alc880_pcm_analog_alt_playback = { 3920 .substreams = 1, 3921 .channels_min = 2, 3922 .channels_max = 2, 3923 /* NID is set in alc_build_pcms */ 3924}; 3925 3926static struct hda_pcm_stream alc880_pcm_analog_alt_capture = { 3927 .substreams = 2, /* can be overridden */ 3928 .channels_min = 2, 3929 .channels_max = 2, 3930 /* NID is set in alc_build_pcms */ 3931 .ops = { 3932 .prepare = alc880_alt_capture_pcm_prepare, 3933 .cleanup = alc880_alt_capture_pcm_cleanup 3934 }, 3935}; 3936 3937static struct hda_pcm_stream alc880_pcm_digital_playback = { 3938 .substreams = 1, 3939 .channels_min = 2, 3940 .channels_max = 2, 3941 /* NID is set in alc_build_pcms */ 3942 .ops = { 3943 .open = alc880_dig_playback_pcm_open, 3944 .close = alc880_dig_playback_pcm_close, 3945 .prepare = alc880_dig_playback_pcm_prepare, 3946 .cleanup = alc880_dig_playback_pcm_cleanup 3947 }, 3948}; 3949 3950static struct hda_pcm_stream alc880_pcm_digital_capture = { 3951 .substreams = 1, 3952 .channels_min = 2, 3953 .channels_max = 2, 3954 /* NID is set in alc_build_pcms */ 3955}; 3956 3957/* Used by alc_build_pcms to flag that a PCM has no playback stream */ 3958static struct hda_pcm_stream alc_pcm_null_stream = { 3959 .substreams = 0, 3960 .channels_min = 0, 3961 .channels_max = 0, 3962}; 3963 3964static int alc_build_pcms(struct hda_codec *codec) 3965{ 3966 struct alc_spec *spec = codec->spec; 3967 struct hda_pcm *info = spec->pcm_rec; 3968 int i; 3969 3970 codec->num_pcms = 1; 3971 codec->pcm_info = info; 3972 3973 if (spec->no_analog) 3974 goto skip_analog; 3975 3976 snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog), 3977 "%s Analog", codec->chip_name); 3978 info->name = spec->stream_name_analog; 3979 3980 if (spec->stream_analog_playback) { 3981 if (snd_BUG_ON(!spec->multiout.dac_nids)) 3982 return -EINVAL; 3983 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback); 3984 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0]; 3985 } 3986 if (spec->stream_analog_capture) { 3987 if (snd_BUG_ON(!spec->adc_nids)) 3988 return -EINVAL; 3989 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture); 3990 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0]; 3991 } 3992 3993 if (spec->channel_mode) { 3994 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0; 3995 for (i = 0; i < spec->num_channel_mode; i++) { 3996 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) { 3997 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels; 3998 } 3999 } 4000 } 4001 4002 skip_analog: 4003 /* SPDIF for stream index #1 */ 4004 if (spec->multiout.dig_out_nid || spec->dig_in_nid) { 4005 snprintf(spec->stream_name_digital, 4006 sizeof(spec->stream_name_digital), 4007 "%s Digital", codec->chip_name); 4008 codec->num_pcms = 2; 4009 codec->slave_dig_outs = spec->multiout.slave_dig_outs; 4010 info = spec->pcm_rec + 1; 4011 info->name = spec->stream_name_digital; 4012 if (spec->dig_out_type) 4013 info->pcm_type = spec->dig_out_type; 4014 else 4015 info->pcm_type = HDA_PCM_TYPE_SPDIF; 4016 if (spec->multiout.dig_out_nid && 4017 spec->stream_digital_playback) { 4018 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback); 4019 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid; 4020 } 4021 if (spec->dig_in_nid && 4022 spec->stream_digital_capture) { 4023 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture); 4024 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid; 4025 } 4026 /* FIXME: do we need this for all Realtek codec models? */ 4027 codec->spdif_status_reset = 1; 4028 } 4029 4030 if (spec->no_analog) 4031 return 0; 4032 4033 /* If the use of more than one ADC is requested for the current 4034 * model, configure a second analog capture-only PCM. 4035 */ 4036 /* Additional Analaog capture for index #2 */ 4037 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) || 4038 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) { 4039 codec->num_pcms = 3; 4040 info = spec->pcm_rec + 2; 4041 info->name = spec->stream_name_analog; 4042 if (spec->alt_dac_nid) { 4043 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = 4044 *spec->stream_analog_alt_playback; 4045 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 4046 spec->alt_dac_nid; 4047 } else { 4048 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = 4049 alc_pcm_null_stream; 4050 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0; 4051 } 4052 if (spec->num_adc_nids > 1) { 4053 info->stream[SNDRV_PCM_STREAM_CAPTURE] = 4054 *spec->stream_analog_alt_capture; 4055 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 4056 spec->adc_nids[1]; 4057 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = 4058 spec->num_adc_nids - 1; 4059 } else { 4060 info->stream[SNDRV_PCM_STREAM_CAPTURE] = 4061 alc_pcm_null_stream; 4062 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0; 4063 } 4064 } 4065 4066 return 0; 4067} 4068 4069static inline void alc_shutup(struct hda_codec *codec) 4070{ 4071 snd_hda_shutup_pins(codec); 4072} 4073 4074static void alc_free_kctls(struct hda_codec *codec) 4075{ 4076 struct alc_spec *spec = codec->spec; 4077 4078 if (spec->kctls.list) { 4079 struct snd_kcontrol_new *kctl = spec->kctls.list; 4080 int i; 4081 for (i = 0; i < spec->kctls.used; i++) 4082 kfree(kctl[i].name); 4083 } 4084 snd_array_free(&spec->kctls); 4085} 4086 4087static void alc_free(struct hda_codec *codec) 4088{ 4089 struct alc_spec *spec = codec->spec; 4090 4091 if (!spec) 4092 return; 4093 4094 alc_shutup(codec); 4095 alc_free_kctls(codec); 4096 kfree(spec); 4097 snd_hda_detach_beep_device(codec); 4098} 4099 4100#ifdef CONFIG_SND_HDA_POWER_SAVE 4101static void alc_power_eapd(struct hda_codec *codec) 4102{ 4103 /* We currently only handle front, HP */ 4104 switch (codec->vendor_id) { 4105 case 0x10ec0260: 4106 set_eapd(codec, 0x0f, 0); 4107 set_eapd(codec, 0x10, 0); 4108 break; 4109 case 0x10ec0262: 4110 case 0x10ec0267: 4111 case 0x10ec0268: 4112 case 0x10ec0269: 4113 case 0x10ec0270: 4114 case 0x10ec0272: 4115 case 0x10ec0660: 4116 case 0x10ec0662: 4117 case 0x10ec0663: 4118 case 0x10ec0862: 4119 case 0x10ec0889: 4120 set_eapd(codec, 0x14, 0); 4121 set_eapd(codec, 0x15, 0); 4122 break; 4123 } 4124} 4125 4126static int alc_suspend(struct hda_codec *codec, pm_message_t state) 4127{ 4128 struct alc_spec *spec = codec->spec; 4129 alc_shutup(codec); 4130 if (spec && spec->power_hook) 4131 spec->power_hook(codec); 4132 return 0; 4133} 4134#endif 4135 4136#ifdef SND_HDA_NEEDS_RESUME 4137static int alc_resume(struct hda_codec *codec) 4138{ 4139 codec->patch_ops.init(codec); 4140 snd_hda_codec_resume_amp(codec); 4141 snd_hda_codec_resume_cache(codec); 4142 hda_call_check_power_status(codec, 0x01); 4143 return 0; 4144} 4145#endif 4146 4147/* 4148 */ 4149static struct hda_codec_ops alc_patch_ops = { 4150 .build_controls = alc_build_controls, 4151 .build_pcms = alc_build_pcms, 4152 .init = alc_init, 4153 .free = alc_free, 4154 .unsol_event = alc_unsol_event, 4155#ifdef SND_HDA_NEEDS_RESUME 4156 .resume = alc_resume, 4157#endif 4158#ifdef CONFIG_SND_HDA_POWER_SAVE 4159 .suspend = alc_suspend, 4160 .check_power_status = alc_check_power_status, 4161#endif 4162 .reboot_notify = alc_shutup, 4163}; 4164 4165/* replace the codec chip_name with the given string */ 4166static int alc_codec_rename(struct hda_codec *codec, const char *name) 4167{ 4168 kfree(codec->chip_name); 4169 codec->chip_name = kstrdup(name, GFP_KERNEL); 4170 if (!codec->chip_name) { 4171 alc_free(codec); 4172 return -ENOMEM; 4173 } 4174 return 0; 4175} 4176 4177/* 4178 * Test configuration for debugging 4179 * 4180 * Almost all inputs/outputs are enabled. I/O pins can be configured via 4181 * enum controls. 4182 */ 4183#ifdef CONFIG_SND_DEBUG 4184static hda_nid_t alc880_test_dac_nids[4] = { 4185 0x02, 0x03, 0x04, 0x05 4186}; 4187 4188static struct hda_input_mux alc880_test_capture_source = { 4189 .num_items = 7, 4190 .items = { 4191 { "In-1", 0x0 }, 4192 { "In-2", 0x1 }, 4193 { "In-3", 0x2 }, 4194 { "In-4", 0x3 }, 4195 { "CD", 0x4 }, 4196 { "Front", 0x5 }, 4197 { "Surround", 0x6 }, 4198 }, 4199}; 4200 4201static struct hda_channel_mode alc880_test_modes[4] = { 4202 { 2, NULL }, 4203 { 4, NULL }, 4204 { 6, NULL }, 4205 { 8, NULL }, 4206}; 4207 4208static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol, 4209 struct snd_ctl_elem_info *uinfo) 4210{ 4211 static char *texts[] = { 4212 "N/A", "Line Out", "HP Out", 4213 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%" 4214 }; 4215 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 4216 uinfo->count = 1; 4217 uinfo->value.enumerated.items = 8; 4218 if (uinfo->value.enumerated.item >= 8) 4219 uinfo->value.enumerated.item = 7; 4220 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); 4221 return 0; 4222} 4223 4224static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol, 4225 struct snd_ctl_elem_value *ucontrol) 4226{ 4227 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 4228 hda_nid_t nid = (hda_nid_t)kcontrol->private_value; 4229 unsigned int pin_ctl, item = 0; 4230 4231 pin_ctl = snd_hda_codec_read(codec, nid, 0, 4232 AC_VERB_GET_PIN_WIDGET_CONTROL, 0); 4233 if (pin_ctl & AC_PINCTL_OUT_EN) { 4234 if (pin_ctl & AC_PINCTL_HP_EN) 4235 item = 2; 4236 else 4237 item = 1; 4238 } else if (pin_ctl & AC_PINCTL_IN_EN) { 4239 switch (pin_ctl & AC_PINCTL_VREFEN) { 4240 case AC_PINCTL_VREF_HIZ: item = 3; break; 4241 case AC_PINCTL_VREF_50: item = 4; break; 4242 case AC_PINCTL_VREF_GRD: item = 5; break; 4243 case AC_PINCTL_VREF_80: item = 6; break; 4244 case AC_PINCTL_VREF_100: item = 7; break; 4245 } 4246 } 4247 ucontrol->value.enumerated.item[0] = item; 4248 return 0; 4249} 4250 4251static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol, 4252 struct snd_ctl_elem_value *ucontrol) 4253{ 4254 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 4255 hda_nid_t nid = (hda_nid_t)kcontrol->private_value; 4256 static unsigned int ctls[] = { 4257 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN, 4258 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ, 4259 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50, 4260 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD, 4261 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80, 4262 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100, 4263 }; 4264 unsigned int old_ctl, new_ctl; 4265 4266 old_ctl = snd_hda_codec_read(codec, nid, 0, 4267 AC_VERB_GET_PIN_WIDGET_CONTROL, 0); 4268 new_ctl = ctls[ucontrol->value.enumerated.item[0]]; 4269 if (old_ctl != new_ctl) { 4270 int val; 4271 snd_hda_codec_write_cache(codec, nid, 0, 4272 AC_VERB_SET_PIN_WIDGET_CONTROL, 4273 new_ctl); 4274 val = ucontrol->value.enumerated.item[0] >= 3 ? 4275 HDA_AMP_MUTE : 0; 4276 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, 4277 HDA_AMP_MUTE, val); 4278 return 1; 4279 } 4280 return 0; 4281} 4282 4283static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol, 4284 struct snd_ctl_elem_info *uinfo) 4285{ 4286 static char *texts[] = { 4287 "Front", "Surround", "CLFE", "Side" 4288 }; 4289 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 4290 uinfo->count = 1; 4291 uinfo->value.enumerated.items = 4; 4292 if (uinfo->value.enumerated.item >= 4) 4293 uinfo->value.enumerated.item = 3; 4294 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); 4295 return 0; 4296} 4297 4298static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol, 4299 struct snd_ctl_elem_value *ucontrol) 4300{ 4301 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 4302 hda_nid_t nid = (hda_nid_t)kcontrol->private_value; 4303 unsigned int sel; 4304 4305 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0); 4306 ucontrol->value.enumerated.item[0] = sel & 3; 4307 return 0; 4308} 4309 4310static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol, 4311 struct snd_ctl_elem_value *ucontrol) 4312{ 4313 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 4314 hda_nid_t nid = (hda_nid_t)kcontrol->private_value; 4315 unsigned int sel; 4316 4317 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3; 4318 if (ucontrol->value.enumerated.item[0] != sel) { 4319 sel = ucontrol->value.enumerated.item[0] & 3; 4320 snd_hda_codec_write_cache(codec, nid, 0, 4321 AC_VERB_SET_CONNECT_SEL, sel); 4322 return 1; 4323 } 4324 return 0; 4325} 4326 4327#define PIN_CTL_TEST(xname,nid) { \ 4328 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 4329 .name = xname, \ 4330 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \ 4331 .info = alc_test_pin_ctl_info, \ 4332 .get = alc_test_pin_ctl_get, \ 4333 .put = alc_test_pin_ctl_put, \ 4334 .private_value = nid \ 4335 } 4336 4337#define PIN_SRC_TEST(xname,nid) { \ 4338 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 4339 .name = xname, \ 4340 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \ 4341 .info = alc_test_pin_src_info, \ 4342 .get = alc_test_pin_src_get, \ 4343 .put = alc_test_pin_src_put, \ 4344 .private_value = nid \ 4345 } 4346 4347static struct snd_kcontrol_new alc880_test_mixer[] = { 4348 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 4349 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 4350 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT), 4351 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 4352 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 4353 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 4354 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT), 4355 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 4356 PIN_CTL_TEST("Front Pin Mode", 0x14), 4357 PIN_CTL_TEST("Surround Pin Mode", 0x15), 4358 PIN_CTL_TEST("CLFE Pin Mode", 0x16), 4359 PIN_CTL_TEST("Side Pin Mode", 0x17), 4360 PIN_CTL_TEST("In-1 Pin Mode", 0x18), 4361 PIN_CTL_TEST("In-2 Pin Mode", 0x19), 4362 PIN_CTL_TEST("In-3 Pin Mode", 0x1a), 4363 PIN_CTL_TEST("In-4 Pin Mode", 0x1b), 4364 PIN_SRC_TEST("In-1 Pin Source", 0x18), 4365 PIN_SRC_TEST("In-2 Pin Source", 0x19), 4366 PIN_SRC_TEST("In-3 Pin Source", 0x1a), 4367 PIN_SRC_TEST("In-4 Pin Source", 0x1b), 4368 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT), 4369 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT), 4370 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT), 4371 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT), 4372 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT), 4373 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT), 4374 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT), 4375 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT), 4376 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT), 4377 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT), 4378 { 4379 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 4380 .name = "Channel Mode", 4381 .info = alc_ch_mode_info, 4382 .get = alc_ch_mode_get, 4383 .put = alc_ch_mode_put, 4384 }, 4385 { } /* end */ 4386}; 4387 4388static struct hda_verb alc880_test_init_verbs[] = { 4389 /* Unmute inputs of 0x0c - 0x0f */ 4390 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4391 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4392 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4393 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4394 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4395 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4396 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4397 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4398 /* Vol output for 0x0c-0x0f */ 4399 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4400 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4401 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4402 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4403 /* Set output pins 0x14-0x17 */ 4404 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4405 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4406 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4407 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4408 /* Unmute output pins 0x14-0x17 */ 4409 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4410 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4411 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4412 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4413 /* Set input pins 0x18-0x1c */ 4414 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 4415 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 4416 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 4417 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 4418 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 4419 /* Mute input pins 0x18-0x1b */ 4420 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 4421 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 4422 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 4423 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 4424 /* ADC set up */ 4425 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4426 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 4427 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4428 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 4429 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4430 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 4431 /* Analog input/passthru */ 4432 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4433 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4434 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 4435 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 4436 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 4437 { } 4438}; 4439#endif 4440 4441/* 4442 */ 4443 4444static const char *alc880_models[ALC880_MODEL_LAST] = { 4445 [ALC880_3ST] = "3stack", 4446 [ALC880_TCL_S700] = "tcl", 4447 [ALC880_3ST_DIG] = "3stack-digout", 4448 [ALC880_CLEVO] = "clevo", 4449 [ALC880_5ST] = "5stack", 4450 [ALC880_5ST_DIG] = "5stack-digout", 4451 [ALC880_W810] = "w810", 4452 [ALC880_Z71V] = "z71v", 4453 [ALC880_6ST] = "6stack", 4454 [ALC880_6ST_DIG] = "6stack-digout", 4455 [ALC880_ASUS] = "asus", 4456 [ALC880_ASUS_W1V] = "asus-w1v", 4457 [ALC880_ASUS_DIG] = "asus-dig", 4458 [ALC880_ASUS_DIG2] = "asus-dig2", 4459 [ALC880_UNIWILL_DIG] = "uniwill", 4460 [ALC880_UNIWILL_P53] = "uniwill-p53", 4461 [ALC880_FUJITSU] = "fujitsu", 4462 [ALC880_F1734] = "F1734", 4463 [ALC880_LG] = "lg", 4464 [ALC880_LG_LW] = "lg-lw", 4465 [ALC880_MEDION_RIM] = "medion", 4466#ifdef CONFIG_SND_DEBUG 4467 [ALC880_TEST] = "test", 4468#endif 4469 [ALC880_AUTO] = "auto", 4470}; 4471 4472static struct snd_pci_quirk alc880_cfg_tbl[] = { 4473 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810), 4474 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG), 4475 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST), 4476 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG), 4477 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG), 4478 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG), 4479 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG), 4480 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG), 4481 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST), 4482 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG), 4483 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST), 4484 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V), 4485 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG), 4486 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG), 4487 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG), 4488 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG), 4489 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG), 4490 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V), 4491 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */ 4492 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG), 4493 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG), 4494 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG), 4495 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG), 4496 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST), 4497 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST), 4498 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */ 4499 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST), 4500 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST), 4501 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST), 4502 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST), 4503 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST), 4504 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG), 4505 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG), 4506 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG), 4507 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG), 4508 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO), 4509 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO), 4510 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2), 4511 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG), 4512 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG), 4513 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734), 4514 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL), 4515 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53), 4516 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810), 4517 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM), 4518 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG), 4519 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG), 4520 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734), 4521 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU), 4522 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_F1734), 4523 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU), 4524 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW), 4525 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG), 4526 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG), 4527 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW), 4528 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700), 4529 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */ 4530 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG), 4531 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG), 4532 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG), 4533 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG), 4534 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG), 4535 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG), 4536 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG), 4537 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG), 4538 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG), 4539 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG), 4540 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG), 4541 /* default Intel */ 4542 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST), 4543 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG), 4544 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG), 4545 {} 4546}; 4547 4548/* 4549 * ALC880 codec presets 4550 */ 4551static struct alc_config_preset alc880_presets[] = { 4552 [ALC880_3ST] = { 4553 .mixers = { alc880_three_stack_mixer }, 4554 .init_verbs = { alc880_volume_init_verbs, 4555 alc880_pin_3stack_init_verbs }, 4556 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 4557 .dac_nids = alc880_dac_nids, 4558 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), 4559 .channel_mode = alc880_threestack_modes, 4560 .need_dac_fix = 1, 4561 .input_mux = &alc880_capture_source, 4562 }, 4563 [ALC880_3ST_DIG] = { 4564 .mixers = { alc880_three_stack_mixer }, 4565 .init_verbs = { alc880_volume_init_verbs, 4566 alc880_pin_3stack_init_verbs }, 4567 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 4568 .dac_nids = alc880_dac_nids, 4569 .dig_out_nid = ALC880_DIGOUT_NID, 4570 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), 4571 .channel_mode = alc880_threestack_modes, 4572 .need_dac_fix = 1, 4573 .input_mux = &alc880_capture_source, 4574 }, 4575 [ALC880_TCL_S700] = { 4576 .mixers = { alc880_tcl_s700_mixer }, 4577 .init_verbs = { alc880_volume_init_verbs, 4578 alc880_pin_tcl_S700_init_verbs, 4579 alc880_gpio2_init_verbs }, 4580 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 4581 .dac_nids = alc880_dac_nids, 4582 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */ 4583 .num_adc_nids = 1, /* single ADC */ 4584 .hp_nid = 0x03, 4585 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), 4586 .channel_mode = alc880_2_jack_modes, 4587 .input_mux = &alc880_capture_source, 4588 }, 4589 [ALC880_5ST] = { 4590 .mixers = { alc880_three_stack_mixer, 4591 alc880_five_stack_mixer}, 4592 .init_verbs = { alc880_volume_init_verbs, 4593 alc880_pin_5stack_init_verbs }, 4594 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 4595 .dac_nids = alc880_dac_nids, 4596 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes), 4597 .channel_mode = alc880_fivestack_modes, 4598 .input_mux = &alc880_capture_source, 4599 }, 4600 [ALC880_5ST_DIG] = { 4601 .mixers = { alc880_three_stack_mixer, 4602 alc880_five_stack_mixer }, 4603 .init_verbs = { alc880_volume_init_verbs, 4604 alc880_pin_5stack_init_verbs }, 4605 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 4606 .dac_nids = alc880_dac_nids, 4607 .dig_out_nid = ALC880_DIGOUT_NID, 4608 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes), 4609 .channel_mode = alc880_fivestack_modes, 4610 .input_mux = &alc880_capture_source, 4611 }, 4612 [ALC880_6ST] = { 4613 .mixers = { alc880_six_stack_mixer }, 4614 .init_verbs = { alc880_volume_init_verbs, 4615 alc880_pin_6stack_init_verbs }, 4616 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids), 4617 .dac_nids = alc880_6st_dac_nids, 4618 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes), 4619 .channel_mode = alc880_sixstack_modes, 4620 .input_mux = &alc880_6stack_capture_source, 4621 }, 4622 [ALC880_6ST_DIG] = { 4623 .mixers = { alc880_six_stack_mixer }, 4624 .init_verbs = { alc880_volume_init_verbs, 4625 alc880_pin_6stack_init_verbs }, 4626 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids), 4627 .dac_nids = alc880_6st_dac_nids, 4628 .dig_out_nid = ALC880_DIGOUT_NID, 4629 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes), 4630 .channel_mode = alc880_sixstack_modes, 4631 .input_mux = &alc880_6stack_capture_source, 4632 }, 4633 [ALC880_W810] = { 4634 .mixers = { alc880_w810_base_mixer }, 4635 .init_verbs = { alc880_volume_init_verbs, 4636 alc880_pin_w810_init_verbs, 4637 alc880_gpio2_init_verbs }, 4638 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids), 4639 .dac_nids = alc880_w810_dac_nids, 4640 .dig_out_nid = ALC880_DIGOUT_NID, 4641 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes), 4642 .channel_mode = alc880_w810_modes, 4643 .input_mux = &alc880_capture_source, 4644 }, 4645 [ALC880_Z71V] = { 4646 .mixers = { alc880_z71v_mixer }, 4647 .init_verbs = { alc880_volume_init_verbs, 4648 alc880_pin_z71v_init_verbs }, 4649 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids), 4650 .dac_nids = alc880_z71v_dac_nids, 4651 .dig_out_nid = ALC880_DIGOUT_NID, 4652 .hp_nid = 0x03, 4653 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), 4654 .channel_mode = alc880_2_jack_modes, 4655 .input_mux = &alc880_capture_source, 4656 }, 4657 [ALC880_F1734] = { 4658 .mixers = { alc880_f1734_mixer }, 4659 .init_verbs = { alc880_volume_init_verbs, 4660 alc880_pin_f1734_init_verbs }, 4661 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids), 4662 .dac_nids = alc880_f1734_dac_nids, 4663 .hp_nid = 0x02, 4664 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), 4665 .channel_mode = alc880_2_jack_modes, 4666 .input_mux = &alc880_f1734_capture_source, 4667 .unsol_event = alc880_uniwill_p53_unsol_event, 4668 .setup = alc880_uniwill_p53_setup, 4669 .init_hook = alc_automute_amp, 4670 }, 4671 [ALC880_ASUS] = { 4672 .mixers = { alc880_asus_mixer }, 4673 .init_verbs = { alc880_volume_init_verbs, 4674 alc880_pin_asus_init_verbs, 4675 alc880_gpio1_init_verbs }, 4676 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 4677 .dac_nids = alc880_asus_dac_nids, 4678 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), 4679 .channel_mode = alc880_asus_modes, 4680 .need_dac_fix = 1, 4681 .input_mux = &alc880_capture_source, 4682 }, 4683 [ALC880_ASUS_DIG] = { 4684 .mixers = { alc880_asus_mixer }, 4685 .init_verbs = { alc880_volume_init_verbs, 4686 alc880_pin_asus_init_verbs, 4687 alc880_gpio1_init_verbs }, 4688 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 4689 .dac_nids = alc880_asus_dac_nids, 4690 .dig_out_nid = ALC880_DIGOUT_NID, 4691 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), 4692 .channel_mode = alc880_asus_modes, 4693 .need_dac_fix = 1, 4694 .input_mux = &alc880_capture_source, 4695 }, 4696 [ALC880_ASUS_DIG2] = { 4697 .mixers = { alc880_asus_mixer }, 4698 .init_verbs = { alc880_volume_init_verbs, 4699 alc880_pin_asus_init_verbs, 4700 alc880_gpio2_init_verbs }, /* use GPIO2 */ 4701 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 4702 .dac_nids = alc880_asus_dac_nids, 4703 .dig_out_nid = ALC880_DIGOUT_NID, 4704 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), 4705 .channel_mode = alc880_asus_modes, 4706 .need_dac_fix = 1, 4707 .input_mux = &alc880_capture_source, 4708 }, 4709 [ALC880_ASUS_W1V] = { 4710 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer }, 4711 .init_verbs = { alc880_volume_init_verbs, 4712 alc880_pin_asus_init_verbs, 4713 alc880_gpio1_init_verbs }, 4714 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 4715 .dac_nids = alc880_asus_dac_nids, 4716 .dig_out_nid = ALC880_DIGOUT_NID, 4717 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), 4718 .channel_mode = alc880_asus_modes, 4719 .need_dac_fix = 1, 4720 .input_mux = &alc880_capture_source, 4721 }, 4722 [ALC880_UNIWILL_DIG] = { 4723 .mixers = { alc880_asus_mixer }, 4724 .init_verbs = { alc880_volume_init_verbs, 4725 alc880_pin_asus_init_verbs }, 4726 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 4727 .dac_nids = alc880_asus_dac_nids, 4728 .dig_out_nid = ALC880_DIGOUT_NID, 4729 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), 4730 .channel_mode = alc880_asus_modes, 4731 .need_dac_fix = 1, 4732 .input_mux = &alc880_capture_source, 4733 }, 4734 [ALC880_UNIWILL] = { 4735 .mixers = { alc880_uniwill_mixer }, 4736 .init_verbs = { alc880_volume_init_verbs, 4737 alc880_uniwill_init_verbs }, 4738 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 4739 .dac_nids = alc880_asus_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 .unsol_event = alc880_uniwill_unsol_event, 4746 .setup = alc880_uniwill_setup, 4747 .init_hook = alc880_uniwill_init_hook, 4748 }, 4749 [ALC880_UNIWILL_P53] = { 4750 .mixers = { alc880_uniwill_p53_mixer }, 4751 .init_verbs = { alc880_volume_init_verbs, 4752 alc880_uniwill_p53_init_verbs }, 4753 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 4754 .dac_nids = alc880_asus_dac_nids, 4755 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes), 4756 .channel_mode = alc880_threestack_modes, 4757 .input_mux = &alc880_capture_source, 4758 .unsol_event = alc880_uniwill_p53_unsol_event, 4759 .setup = alc880_uniwill_p53_setup, 4760 .init_hook = alc_automute_amp, 4761 }, 4762 [ALC880_FUJITSU] = { 4763 .mixers = { alc880_fujitsu_mixer }, 4764 .init_verbs = { alc880_volume_init_verbs, 4765 alc880_uniwill_p53_init_verbs, 4766 alc880_beep_init_verbs }, 4767 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 4768 .dac_nids = alc880_dac_nids, 4769 .dig_out_nid = ALC880_DIGOUT_NID, 4770 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), 4771 .channel_mode = alc880_2_jack_modes, 4772 .input_mux = &alc880_capture_source, 4773 .unsol_event = alc880_uniwill_p53_unsol_event, 4774 .setup = alc880_uniwill_p53_setup, 4775 .init_hook = alc_automute_amp, 4776 }, 4777 [ALC880_CLEVO] = { 4778 .mixers = { alc880_three_stack_mixer }, 4779 .init_verbs = { alc880_volume_init_verbs, 4780 alc880_pin_clevo_init_verbs }, 4781 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 4782 .dac_nids = alc880_dac_nids, 4783 .hp_nid = 0x03, 4784 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), 4785 .channel_mode = alc880_threestack_modes, 4786 .need_dac_fix = 1, 4787 .input_mux = &alc880_capture_source, 4788 }, 4789 [ALC880_LG] = { 4790 .mixers = { alc880_lg_mixer }, 4791 .init_verbs = { alc880_volume_init_verbs, 4792 alc880_lg_init_verbs }, 4793 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids), 4794 .dac_nids = alc880_lg_dac_nids, 4795 .dig_out_nid = ALC880_DIGOUT_NID, 4796 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes), 4797 .channel_mode = alc880_lg_ch_modes, 4798 .need_dac_fix = 1, 4799 .input_mux = &alc880_lg_capture_source, 4800 .unsol_event = alc_automute_amp_unsol_event, 4801 .setup = alc880_lg_setup, 4802 .init_hook = alc_automute_amp, 4803#ifdef CONFIG_SND_HDA_POWER_SAVE 4804 .loopbacks = alc880_lg_loopbacks, 4805#endif 4806 }, 4807 [ALC880_LG_LW] = { 4808 .mixers = { alc880_lg_lw_mixer }, 4809 .init_verbs = { alc880_volume_init_verbs, 4810 alc880_lg_lw_init_verbs }, 4811 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 4812 .dac_nids = alc880_dac_nids, 4813 .dig_out_nid = ALC880_DIGOUT_NID, 4814 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes), 4815 .channel_mode = alc880_lg_lw_modes, 4816 .input_mux = &alc880_lg_lw_capture_source, 4817 .unsol_event = alc_automute_amp_unsol_event, 4818 .setup = alc880_lg_lw_setup, 4819 .init_hook = alc_automute_amp, 4820 }, 4821 [ALC880_MEDION_RIM] = { 4822 .mixers = { alc880_medion_rim_mixer }, 4823 .init_verbs = { alc880_volume_init_verbs, 4824 alc880_medion_rim_init_verbs, 4825 alc_gpio2_init_verbs }, 4826 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 4827 .dac_nids = alc880_dac_nids, 4828 .dig_out_nid = ALC880_DIGOUT_NID, 4829 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), 4830 .channel_mode = alc880_2_jack_modes, 4831 .input_mux = &alc880_medion_rim_capture_source, 4832 .unsol_event = alc880_medion_rim_unsol_event, 4833 .setup = alc880_medion_rim_setup, 4834 .init_hook = alc880_medion_rim_automute, 4835 }, 4836#ifdef CONFIG_SND_DEBUG 4837 [ALC880_TEST] = { 4838 .mixers = { alc880_test_mixer }, 4839 .init_verbs = { alc880_test_init_verbs }, 4840 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids), 4841 .dac_nids = alc880_test_dac_nids, 4842 .dig_out_nid = ALC880_DIGOUT_NID, 4843 .num_channel_mode = ARRAY_SIZE(alc880_test_modes), 4844 .channel_mode = alc880_test_modes, 4845 .input_mux = &alc880_test_capture_source, 4846 }, 4847#endif 4848}; 4849 4850/* 4851 * Automatic parse of I/O pins from the BIOS configuration 4852 */ 4853 4854enum { 4855 ALC_CTL_WIDGET_VOL, 4856 ALC_CTL_WIDGET_MUTE, 4857 ALC_CTL_BIND_MUTE, 4858}; 4859static struct snd_kcontrol_new alc880_control_templates[] = { 4860 HDA_CODEC_VOLUME(NULL, 0, 0, 0), 4861 HDA_CODEC_MUTE(NULL, 0, 0, 0), 4862 HDA_BIND_MUTE(NULL, 0, 0, 0), 4863}; 4864 4865/* add dynamic controls */ 4866static int add_control(struct alc_spec *spec, int type, const char *name, 4867 int cidx, unsigned long val) 4868{ 4869 struct snd_kcontrol_new *knew; 4870 4871 snd_array_init(&spec->kctls, sizeof(*knew), 32); 4872 knew = snd_array_new(&spec->kctls); 4873 if (!knew) 4874 return -ENOMEM; 4875 *knew = alc880_control_templates[type]; 4876 knew->name = kstrdup(name, GFP_KERNEL); 4877 if (!knew->name) 4878 return -ENOMEM; 4879 knew->index = cidx; 4880 if (get_amp_nid_(val)) 4881 knew->subdevice = HDA_SUBDEV_AMP_FLAG; 4882 knew->private_value = val; 4883 return 0; 4884} 4885 4886static int add_control_with_pfx(struct alc_spec *spec, int type, 4887 const char *pfx, const char *dir, 4888 const char *sfx, int cidx, unsigned long val) 4889{ 4890 char name[32]; 4891 snprintf(name, sizeof(name), "%s %s %s", pfx, dir, sfx); 4892 return add_control(spec, type, name, cidx, val); 4893} 4894 4895#define add_pb_vol_ctrl(spec, type, pfx, val) \ 4896 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", 0, val) 4897#define add_pb_sw_ctrl(spec, type, pfx, val) \ 4898 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", 0, val) 4899#define __add_pb_vol_ctrl(spec, type, pfx, cidx, val) \ 4900 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", cidx, val) 4901#define __add_pb_sw_ctrl(spec, type, pfx, cidx, val) \ 4902 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", cidx, val) 4903 4904#define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17) 4905#define alc880_fixed_pin_idx(nid) ((nid) - 0x14) 4906#define alc880_is_multi_pin(nid) ((nid) >= 0x18) 4907#define alc880_multi_pin_idx(nid) ((nid) - 0x18) 4908#define alc880_idx_to_dac(nid) ((nid) + 0x02) 4909#define alc880_dac_to_idx(nid) ((nid) - 0x02) 4910#define alc880_idx_to_mixer(nid) ((nid) + 0x0c) 4911#define alc880_idx_to_selector(nid) ((nid) + 0x10) 4912#define ALC880_PIN_CD_NID 0x1c 4913 4914/* fill in the dac_nids table from the parsed pin configuration */ 4915static int alc880_auto_fill_dac_nids(struct alc_spec *spec, 4916 const struct auto_pin_cfg *cfg) 4917{ 4918 hda_nid_t nid; 4919 int assigned[4]; 4920 int i, j; 4921 4922 memset(assigned, 0, sizeof(assigned)); 4923 spec->multiout.dac_nids = spec->private_dac_nids; 4924 4925 /* check the pins hardwired to audio widget */ 4926 for (i = 0; i < cfg->line_outs; i++) { 4927 nid = cfg->line_out_pins[i]; 4928 if (alc880_is_fixed_pin(nid)) { 4929 int idx = alc880_fixed_pin_idx(nid); 4930 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx); 4931 assigned[idx] = 1; 4932 } 4933 } 4934 /* left pins can be connect to any audio widget */ 4935 for (i = 0; i < cfg->line_outs; i++) { 4936 nid = cfg->line_out_pins[i]; 4937 if (alc880_is_fixed_pin(nid)) 4938 continue; 4939 /* search for an empty channel */ 4940 for (j = 0; j < cfg->line_outs; j++) { 4941 if (!assigned[j]) { 4942 spec->multiout.dac_nids[i] = 4943 alc880_idx_to_dac(j); 4944 assigned[j] = 1; 4945 break; 4946 } 4947 } 4948 } 4949 spec->multiout.num_dacs = cfg->line_outs; 4950 return 0; 4951} 4952 4953/* add playback controls from the parsed DAC table */ 4954static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec, 4955 const struct auto_pin_cfg *cfg) 4956{ 4957 static const char *chname[4] = { 4958 "Front", "Surround", NULL /*CLFE*/, "Side" 4959 }; 4960 hda_nid_t nid; 4961 int i, err; 4962 4963 for (i = 0; i < cfg->line_outs; i++) { 4964 if (!spec->multiout.dac_nids[i]) 4965 continue; 4966 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i])); 4967 if (i == 2) { 4968 /* Center/LFE */ 4969 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, 4970 "Center", 4971 HDA_COMPOSE_AMP_VAL(nid, 1, 0, 4972 HDA_OUTPUT)); 4973 if (err < 0) 4974 return err; 4975 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, 4976 "LFE", 4977 HDA_COMPOSE_AMP_VAL(nid, 2, 0, 4978 HDA_OUTPUT)); 4979 if (err < 0) 4980 return err; 4981 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, 4982 "Center", 4983 HDA_COMPOSE_AMP_VAL(nid, 1, 2, 4984 HDA_INPUT)); 4985 if (err < 0) 4986 return err; 4987 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, 4988 "LFE", 4989 HDA_COMPOSE_AMP_VAL(nid, 2, 2, 4990 HDA_INPUT)); 4991 if (err < 0) 4992 return err; 4993 } else { 4994 const char *pfx; 4995 if (cfg->line_outs == 1 && 4996 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) 4997 pfx = "Speaker"; 4998 else 4999 pfx = chname[i]; 5000 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, 5001 HDA_COMPOSE_AMP_VAL(nid, 3, 0, 5002 HDA_OUTPUT)); 5003 if (err < 0) 5004 return err; 5005 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx, 5006 HDA_COMPOSE_AMP_VAL(nid, 3, 2, 5007 HDA_INPUT)); 5008 if (err < 0) 5009 return err; 5010 } 5011 } 5012 return 0; 5013} 5014 5015/* add playback controls for speaker and HP outputs */ 5016static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin, 5017 const char *pfx) 5018{ 5019 hda_nid_t nid; 5020 int err; 5021 5022 if (!pin) 5023 return 0; 5024 5025 if (alc880_is_fixed_pin(pin)) { 5026 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); 5027 /* specify the DAC as the extra output */ 5028 if (!spec->multiout.hp_nid) 5029 spec->multiout.hp_nid = nid; 5030 else 5031 spec->multiout.extra_out_nid[0] = nid; 5032 /* control HP volume/switch on the output mixer amp */ 5033 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin)); 5034 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, 5035 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); 5036 if (err < 0) 5037 return err; 5038 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx, 5039 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT)); 5040 if (err < 0) 5041 return err; 5042 } else if (alc880_is_multi_pin(pin)) { 5043 /* set manual connection */ 5044 /* we have only a switch on HP-out PIN */ 5045 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, 5046 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); 5047 if (err < 0) 5048 return err; 5049 } 5050 return 0; 5051} 5052 5053/* create input playback/capture controls for the given pin */ 5054static int new_analog_input(struct alc_spec *spec, hda_nid_t pin, 5055 const char *ctlname, int ctlidx, 5056 int idx, hda_nid_t mix_nid) 5057{ 5058 int err; 5059 5060 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname, ctlidx, 5061 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT)); 5062 if (err < 0) 5063 return err; 5064 err = __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname, ctlidx, 5065 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT)); 5066 if (err < 0) 5067 return err; 5068 return 0; 5069} 5070 5071static int alc_is_input_pin(struct hda_codec *codec, hda_nid_t nid) 5072{ 5073 unsigned int pincap = snd_hda_query_pin_caps(codec, nid); 5074 return (pincap & AC_PINCAP_IN) != 0; 5075} 5076 5077/* create playback/capture controls for input pins */ 5078static int alc_auto_create_input_ctls(struct hda_codec *codec, 5079 const struct auto_pin_cfg *cfg, 5080 hda_nid_t mixer, 5081 hda_nid_t cap1, hda_nid_t cap2) 5082{ 5083 struct alc_spec *spec = codec->spec; 5084 struct hda_input_mux *imux = &spec->private_imux[0]; 5085 int i, err, idx, type, type_idx = 0; 5086 5087 for (i = 0; i < cfg->num_inputs; i++) { 5088 hda_nid_t pin; 5089 const char *label; 5090 5091 pin = cfg->inputs[i].pin; 5092 if (!alc_is_input_pin(codec, pin)) 5093 continue; 5094 5095 type = cfg->inputs[i].type; 5096 if (i > 0 && type == cfg->inputs[i - 1].type) 5097 type_idx++; 5098 else 5099 type_idx = 0; 5100 label = hda_get_autocfg_input_label(codec, cfg, i); 5101 if (mixer) { 5102 idx = get_connection_index(codec, mixer, pin); 5103 if (idx >= 0) { 5104 err = new_analog_input(spec, pin, 5105 label, type_idx, 5106 idx, mixer); 5107 if (err < 0) 5108 return err; 5109 } 5110 } 5111 5112 if (!cap1) 5113 continue; 5114 idx = get_connection_index(codec, cap1, pin); 5115 if (idx < 0 && cap2) 5116 idx = get_connection_index(codec, cap2, pin); 5117 if (idx >= 0) 5118 snd_hda_add_imux_item(imux, label, idx, NULL); 5119 } 5120 return 0; 5121} 5122 5123static int alc880_auto_create_input_ctls(struct hda_codec *codec, 5124 const struct auto_pin_cfg *cfg) 5125{ 5126 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x08, 0x09); 5127} 5128 5129static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid, 5130 unsigned int pin_type) 5131{ 5132 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 5133 pin_type); 5134 /* unmute pin */ 5135 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, 5136 AMP_OUT_UNMUTE); 5137} 5138 5139static void alc880_auto_set_output_and_unmute(struct hda_codec *codec, 5140 hda_nid_t nid, int pin_type, 5141 int dac_idx) 5142{ 5143 alc_set_pin_output(codec, nid, pin_type); 5144 /* need the manual connection? */ 5145 if (alc880_is_multi_pin(nid)) { 5146 struct alc_spec *spec = codec->spec; 5147 int idx = alc880_multi_pin_idx(nid); 5148 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0, 5149 AC_VERB_SET_CONNECT_SEL, 5150 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx])); 5151 } 5152} 5153 5154static int get_pin_type(int line_out_type) 5155{ 5156 if (line_out_type == AUTO_PIN_HP_OUT) 5157 return PIN_HP; 5158 else 5159 return PIN_OUT; 5160} 5161 5162static void alc880_auto_init_multi_out(struct hda_codec *codec) 5163{ 5164 struct alc_spec *spec = codec->spec; 5165 int i; 5166 5167 for (i = 0; i < spec->autocfg.line_outs; i++) { 5168 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 5169 int pin_type = get_pin_type(spec->autocfg.line_out_type); 5170 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i); 5171 } 5172} 5173 5174static void alc880_auto_init_extra_out(struct hda_codec *codec) 5175{ 5176 struct alc_spec *spec = codec->spec; 5177 hda_nid_t pin; 5178 5179 pin = spec->autocfg.speaker_pins[0]; 5180 if (pin) /* connect to front */ 5181 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0); 5182 pin = spec->autocfg.hp_pins[0]; 5183 if (pin) /* connect to front */ 5184 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); 5185} 5186 5187static void alc880_auto_init_analog_input(struct hda_codec *codec) 5188{ 5189 struct alc_spec *spec = codec->spec; 5190 struct auto_pin_cfg *cfg = &spec->autocfg; 5191 int i; 5192 5193 for (i = 0; i < cfg->num_inputs; i++) { 5194 hda_nid_t nid = cfg->inputs[i].pin; 5195 if (alc_is_input_pin(codec, nid)) { 5196 alc_set_input_pin(codec, nid, cfg->inputs[i].type); 5197 if (nid != ALC880_PIN_CD_NID && 5198 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)) 5199 snd_hda_codec_write(codec, nid, 0, 5200 AC_VERB_SET_AMP_GAIN_MUTE, 5201 AMP_OUT_MUTE); 5202 } 5203 } 5204} 5205 5206static void alc880_auto_init_input_src(struct hda_codec *codec) 5207{ 5208 struct alc_spec *spec = codec->spec; 5209 int c; 5210 5211 for (c = 0; c < spec->num_adc_nids; c++) { 5212 unsigned int mux_idx; 5213 const struct hda_input_mux *imux; 5214 mux_idx = c >= spec->num_mux_defs ? 0 : c; 5215 imux = &spec->input_mux[mux_idx]; 5216 if (!imux->num_items && mux_idx > 0) 5217 imux = &spec->input_mux[0]; 5218 if (imux) 5219 snd_hda_codec_write(codec, spec->adc_nids[c], 0, 5220 AC_VERB_SET_CONNECT_SEL, 5221 imux->items[0].index); 5222 } 5223} 5224 5225/* parse the BIOS configuration and set up the alc_spec */ 5226/* return 1 if successful, 0 if the proper config is not found, 5227 * or a negative error code 5228 */ 5229static int alc880_parse_auto_config(struct hda_codec *codec) 5230{ 5231 struct alc_spec *spec = codec->spec; 5232 int err; 5233 static hda_nid_t alc880_ignore[] = { 0x1d, 0 }; 5234 5235 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 5236 alc880_ignore); 5237 if (err < 0) 5238 return err; 5239 if (!spec->autocfg.line_outs) 5240 return 0; /* can't find valid BIOS pin config */ 5241 5242 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); 5243 if (err < 0) 5244 return err; 5245 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg); 5246 if (err < 0) 5247 return err; 5248 err = alc880_auto_create_extra_out(spec, 5249 spec->autocfg.speaker_pins[0], 5250 "Speaker"); 5251 if (err < 0) 5252 return err; 5253 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0], 5254 "Headphone"); 5255 if (err < 0) 5256 return err; 5257 err = alc880_auto_create_input_ctls(codec, &spec->autocfg); 5258 if (err < 0) 5259 return err; 5260 5261 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 5262 5263 alc_auto_parse_digital(codec); 5264 5265 if (spec->kctls.list) 5266 add_mixer(spec, spec->kctls.list); 5267 5268 add_verb(spec, alc880_volume_init_verbs); 5269 5270 spec->num_mux_defs = 1; 5271 spec->input_mux = &spec->private_imux[0]; 5272 5273 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); 5274 5275 return 1; 5276} 5277 5278/* additional initialization for auto-configuration model */ 5279static void alc880_auto_init(struct hda_codec *codec) 5280{ 5281 struct alc_spec *spec = codec->spec; 5282 alc880_auto_init_multi_out(codec); 5283 alc880_auto_init_extra_out(codec); 5284 alc880_auto_init_analog_input(codec); 5285 alc880_auto_init_input_src(codec); 5286 alc_auto_init_digital(codec); 5287 if (spec->unsol_event) 5288 alc_inithook(codec); 5289} 5290 5291/* check the ADC/MUX contains all input pins; some ADC/MUX contains only 5292 * one of two digital mic pins, e.g. on ALC272 5293 */ 5294static void fixup_automic_adc(struct hda_codec *codec) 5295{ 5296 struct alc_spec *spec = codec->spec; 5297 int i; 5298 5299 for (i = 0; i < spec->num_adc_nids; i++) { 5300 hda_nid_t cap = spec->capsrc_nids ? 5301 spec->capsrc_nids[i] : spec->adc_nids[i]; 5302 int iidx, eidx; 5303 5304 iidx = get_connection_index(codec, cap, spec->int_mic.pin); 5305 if (iidx < 0) 5306 continue; 5307 eidx = get_connection_index(codec, cap, spec->ext_mic.pin); 5308 if (eidx < 0) 5309 continue; 5310 spec->int_mic.mux_idx = iidx; 5311 spec->ext_mic.mux_idx = eidx; 5312 if (spec->capsrc_nids) 5313 spec->capsrc_nids += i; 5314 spec->adc_nids += i; 5315 spec->num_adc_nids = 1; 5316 return; 5317 } 5318 snd_printd(KERN_INFO "hda_codec: %s: " 5319 "No ADC/MUX containing both 0x%x and 0x%x pins\n", 5320 codec->chip_name, spec->int_mic.pin, spec->ext_mic.pin); 5321 spec->auto_mic = 0; /* disable auto-mic to be sure */ 5322} 5323 5324/* select or unmute the given capsrc route */ 5325static void select_or_unmute_capsrc(struct hda_codec *codec, hda_nid_t cap, 5326 int idx) 5327{ 5328 if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) { 5329 snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx, 5330 HDA_AMP_MUTE, 0); 5331 } else { 5332 snd_hda_codec_write_cache(codec, cap, 0, 5333 AC_VERB_SET_CONNECT_SEL, idx); 5334 } 5335} 5336 5337/* set the default connection to that pin */ 5338static int init_capsrc_for_pin(struct hda_codec *codec, hda_nid_t pin) 5339{ 5340 struct alc_spec *spec = codec->spec; 5341 int i; 5342 5343 for (i = 0; i < spec->num_adc_nids; i++) { 5344 hda_nid_t cap = spec->capsrc_nids ? 5345 spec->capsrc_nids[i] : spec->adc_nids[i]; 5346 int idx; 5347 5348 idx = get_connection_index(codec, cap, pin); 5349 if (idx < 0) 5350 continue; 5351 select_or_unmute_capsrc(codec, cap, idx); 5352 return i; /* return the found index */ 5353 } 5354 return -1; /* not found */ 5355} 5356 5357/* choose the ADC/MUX containing the input pin and initialize the setup */ 5358static void fixup_single_adc(struct hda_codec *codec) 5359{ 5360 struct alc_spec *spec = codec->spec; 5361 struct auto_pin_cfg *cfg = &spec->autocfg; 5362 int i; 5363 5364 /* search for the input pin; there must be only one */ 5365 if (cfg->num_inputs != 1) 5366 return; 5367 i = init_capsrc_for_pin(codec, cfg->inputs[0].pin); 5368 if (i >= 0) { 5369 /* use only this ADC */ 5370 if (spec->capsrc_nids) 5371 spec->capsrc_nids += i; 5372 spec->adc_nids += i; 5373 spec->num_adc_nids = 1; 5374 } 5375} 5376 5377/* initialize dual adcs */ 5378static void fixup_dual_adc_switch(struct hda_codec *codec) 5379{ 5380 struct alc_spec *spec = codec->spec; 5381 init_capsrc_for_pin(codec, spec->ext_mic.pin); 5382 init_capsrc_for_pin(codec, spec->int_mic.pin); 5383} 5384 5385static void set_capture_mixer(struct hda_codec *codec) 5386{ 5387 struct alc_spec *spec = codec->spec; 5388 static struct snd_kcontrol_new *caps[2][3] = { 5389 { alc_capture_mixer_nosrc1, 5390 alc_capture_mixer_nosrc2, 5391 alc_capture_mixer_nosrc3 }, 5392 { alc_capture_mixer1, 5393 alc_capture_mixer2, 5394 alc_capture_mixer3 }, 5395 }; 5396 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) { 5397 int mux = 0; 5398 int num_adcs = spec->num_adc_nids; 5399 if (spec->dual_adc_switch) 5400 fixup_dual_adc_switch(codec); 5401 else if (spec->auto_mic) 5402 fixup_automic_adc(codec); 5403 else if (spec->input_mux) { 5404 if (spec->input_mux->num_items > 1) 5405 mux = 1; 5406 else if (spec->input_mux->num_items == 1) 5407 fixup_single_adc(codec); 5408 } 5409 if (spec->dual_adc_switch) 5410 num_adcs = 1; 5411 spec->cap_mixer = caps[mux][num_adcs - 1]; 5412 } 5413} 5414 5415/* fill adc_nids (and capsrc_nids) containing all active input pins */ 5416static void fillup_priv_adc_nids(struct hda_codec *codec, hda_nid_t *nids, 5417 int num_nids) 5418{ 5419 struct alc_spec *spec = codec->spec; 5420 struct auto_pin_cfg *cfg = &spec->autocfg; 5421 int n; 5422 hda_nid_t fallback_adc = 0, fallback_cap = 0; 5423 5424 for (n = 0; n < num_nids; n++) { 5425 hda_nid_t adc, cap; 5426 hda_nid_t conn[HDA_MAX_NUM_INPUTS]; 5427 int nconns, i, j; 5428 5429 adc = nids[n]; 5430 if (get_wcaps_type(get_wcaps(codec, adc)) != AC_WID_AUD_IN) 5431 continue; 5432 cap = adc; 5433 nconns = snd_hda_get_connections(codec, cap, conn, 5434 ARRAY_SIZE(conn)); 5435 if (nconns == 1) { 5436 cap = conn[0]; 5437 nconns = snd_hda_get_connections(codec, cap, conn, 5438 ARRAY_SIZE(conn)); 5439 } 5440 if (nconns <= 0) 5441 continue; 5442 if (!fallback_adc) { 5443 fallback_adc = adc; 5444 fallback_cap = cap; 5445 } 5446 for (i = 0; i < cfg->num_inputs; i++) { 5447 hda_nid_t nid = cfg->inputs[i].pin; 5448 for (j = 0; j < nconns; j++) { 5449 if (conn[j] == nid) 5450 break; 5451 } 5452 if (j >= nconns) 5453 break; 5454 } 5455 if (i >= cfg->num_inputs) { 5456 int num_adcs = spec->num_adc_nids; 5457 spec->private_adc_nids[num_adcs] = adc; 5458 spec->private_capsrc_nids[num_adcs] = cap; 5459 spec->num_adc_nids++; 5460 spec->adc_nids = spec->private_adc_nids; 5461 if (adc != cap) 5462 spec->capsrc_nids = spec->private_capsrc_nids; 5463 } 5464 } 5465 if (!spec->num_adc_nids) { 5466 printk(KERN_WARNING "hda_codec: %s: no valid ADC found;" 5467 " using fallback 0x%x\n", 5468 codec->chip_name, fallback_adc); 5469 spec->private_adc_nids[0] = fallback_adc; 5470 spec->adc_nids = spec->private_adc_nids; 5471 if (fallback_adc != fallback_cap) { 5472 spec->private_capsrc_nids[0] = fallback_cap; 5473 spec->capsrc_nids = spec->private_adc_nids; 5474 } 5475 } 5476} 5477 5478#ifdef CONFIG_SND_HDA_INPUT_BEEP 5479#define set_beep_amp(spec, nid, idx, dir) \ 5480 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir)) 5481 5482static struct snd_pci_quirk beep_white_list[] = { 5483 SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1), 5484 SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1), 5485 SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1), 5486 {} 5487}; 5488 5489static inline int has_cdefine_beep(struct hda_codec *codec) 5490{ 5491 struct alc_spec *spec = codec->spec; 5492 const struct snd_pci_quirk *q; 5493 q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list); 5494 if (q) 5495 return q->value; 5496 return spec->cdefine.enable_pcbeep; 5497} 5498#else 5499#define set_beep_amp(spec, nid, idx, dir) /* NOP */ 5500#define has_cdefine_beep(codec) 0 5501#endif 5502 5503/* 5504 * OK, here we have finally the patch for ALC880 5505 */ 5506 5507static int patch_alc880(struct hda_codec *codec) 5508{ 5509 struct alc_spec *spec; 5510 int board_config; 5511 int err; 5512 5513 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 5514 if (spec == NULL) 5515 return -ENOMEM; 5516 5517 codec->spec = spec; 5518 5519 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST, 5520 alc880_models, 5521 alc880_cfg_tbl); 5522 if (board_config < 0) { 5523 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 5524 codec->chip_name); 5525 board_config = ALC880_AUTO; 5526 } 5527 5528 if (board_config == ALC880_AUTO) { 5529 /* automatic parse from the BIOS config */ 5530 err = alc880_parse_auto_config(codec); 5531 if (err < 0) { 5532 alc_free(codec); 5533 return err; 5534 } else if (!err) { 5535 printk(KERN_INFO 5536 "hda_codec: Cannot set up configuration " 5537 "from BIOS. Using 3-stack mode...\n"); 5538 board_config = ALC880_3ST; 5539 } 5540 } 5541 5542 err = snd_hda_attach_beep_device(codec, 0x1); 5543 if (err < 0) { 5544 alc_free(codec); 5545 return err; 5546 } 5547 5548 if (board_config != ALC880_AUTO) 5549 setup_preset(codec, &alc880_presets[board_config]); 5550 5551 spec->stream_analog_playback = &alc880_pcm_analog_playback; 5552 spec->stream_analog_capture = &alc880_pcm_analog_capture; 5553 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture; 5554 5555 spec->stream_digital_playback = &alc880_pcm_digital_playback; 5556 spec->stream_digital_capture = &alc880_pcm_digital_capture; 5557 5558 if (!spec->adc_nids && spec->input_mux) { 5559 /* check whether NID 0x07 is valid */ 5560 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]); 5561 /* get type */ 5562 wcap = get_wcaps_type(wcap); 5563 if (wcap != AC_WID_AUD_IN) { 5564 spec->adc_nids = alc880_adc_nids_alt; 5565 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt); 5566 } else { 5567 spec->adc_nids = alc880_adc_nids; 5568 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids); 5569 } 5570 } 5571 set_capture_mixer(codec); 5572 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 5573 5574 spec->vmaster_nid = 0x0c; 5575 5576 codec->patch_ops = alc_patch_ops; 5577 if (board_config == ALC880_AUTO) 5578 spec->init_hook = alc880_auto_init; 5579#ifdef CONFIG_SND_HDA_POWER_SAVE 5580 if (!spec->loopback.amplist) 5581 spec->loopback.amplist = alc880_loopbacks; 5582#endif 5583 5584 return 0; 5585} 5586 5587 5588/* 5589 * ALC260 support 5590 */ 5591 5592static hda_nid_t alc260_dac_nids[1] = { 5593 /* front */ 5594 0x02, 5595}; 5596 5597static hda_nid_t alc260_adc_nids[1] = { 5598 /* ADC0 */ 5599 0x04, 5600}; 5601 5602static hda_nid_t alc260_adc_nids_alt[1] = { 5603 /* ADC1 */ 5604 0x05, 5605}; 5606 5607/* NIDs used when simultaneous access to both ADCs makes sense. Note that 5608 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC. 5609 */ 5610static hda_nid_t alc260_dual_adc_nids[2] = { 5611 /* ADC0, ADC1 */ 5612 0x04, 0x05 5613}; 5614 5615#define ALC260_DIGOUT_NID 0x03 5616#define ALC260_DIGIN_NID 0x06 5617 5618static struct hda_input_mux alc260_capture_source = { 5619 .num_items = 4, 5620 .items = { 5621 { "Mic", 0x0 }, 5622 { "Front Mic", 0x1 }, 5623 { "Line", 0x2 }, 5624 { "CD", 0x4 }, 5625 }, 5626}; 5627 5628/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack, 5629 * headphone jack and the internal CD lines since these are the only pins at 5630 * which audio can appear. For flexibility, also allow the option of 5631 * recording the mixer output on the second ADC (ADC0 doesn't have a 5632 * connection to the mixer output). 5633 */ 5634static struct hda_input_mux alc260_fujitsu_capture_sources[2] = { 5635 { 5636 .num_items = 3, 5637 .items = { 5638 { "Mic/Line", 0x0 }, 5639 { "CD", 0x4 }, 5640 { "Headphone", 0x2 }, 5641 }, 5642 }, 5643 { 5644 .num_items = 4, 5645 .items = { 5646 { "Mic/Line", 0x0 }, 5647 { "CD", 0x4 }, 5648 { "Headphone", 0x2 }, 5649 { "Mixer", 0x5 }, 5650 }, 5651 }, 5652 5653}; 5654 5655/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to 5656 * the Fujitsu S702x, but jacks are marked differently. 5657 */ 5658static struct hda_input_mux alc260_acer_capture_sources[2] = { 5659 { 5660 .num_items = 4, 5661 .items = { 5662 { "Mic", 0x0 }, 5663 { "Line", 0x2 }, 5664 { "CD", 0x4 }, 5665 { "Headphone", 0x5 }, 5666 }, 5667 }, 5668 { 5669 .num_items = 5, 5670 .items = { 5671 { "Mic", 0x0 }, 5672 { "Line", 0x2 }, 5673 { "CD", 0x4 }, 5674 { "Headphone", 0x6 }, 5675 { "Mixer", 0x5 }, 5676 }, 5677 }, 5678}; 5679 5680/* Maxdata Favorit 100XS */ 5681static struct hda_input_mux alc260_favorit100_capture_sources[2] = { 5682 { 5683 .num_items = 2, 5684 .items = { 5685 { "Line/Mic", 0x0 }, 5686 { "CD", 0x4 }, 5687 }, 5688 }, 5689 { 5690 .num_items = 3, 5691 .items = { 5692 { "Line/Mic", 0x0 }, 5693 { "CD", 0x4 }, 5694 { "Mixer", 0x5 }, 5695 }, 5696 }, 5697}; 5698 5699/* 5700 * This is just place-holder, so there's something for alc_build_pcms to look 5701 * at when it calculates the maximum number of channels. ALC260 has no mixer 5702 * element which allows changing the channel mode, so the verb list is 5703 * never used. 5704 */ 5705static struct hda_channel_mode alc260_modes[1] = { 5706 { 2, NULL }, 5707}; 5708 5709 5710/* Mixer combinations 5711 * 5712 * basic: base_output + input + pc_beep + capture 5713 * HP: base_output + input + capture_alt 5714 * HP_3013: hp_3013 + input + capture 5715 * fujitsu: fujitsu + capture 5716 * acer: acer + capture 5717 */ 5718 5719static struct snd_kcontrol_new alc260_base_output_mixer[] = { 5720 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT), 5721 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT), 5722 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT), 5723 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT), 5724 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), 5725 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT), 5726 { } /* end */ 5727}; 5728 5729static struct snd_kcontrol_new alc260_input_mixer[] = { 5730 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), 5731 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), 5732 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), 5733 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT), 5734 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), 5735 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT), 5736 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT), 5737 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT), 5738 { } /* end */ 5739}; 5740 5741/* update HP, line and mono out pins according to the master switch */ 5742static void alc260_hp_master_update(struct hda_codec *codec, 5743 hda_nid_t hp, hda_nid_t line, 5744 hda_nid_t mono) 5745{ 5746 struct alc_spec *spec = codec->spec; 5747 unsigned int val = spec->master_sw ? PIN_HP : 0; 5748 /* change HP and line-out pins */ 5749 snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 5750 val); 5751 snd_hda_codec_write(codec, line, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 5752 val); 5753 /* mono (speaker) depending on the HP jack sense */ 5754 val = (val && !spec->jack_present) ? PIN_OUT : 0; 5755 snd_hda_codec_write(codec, mono, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 5756 val); 5757} 5758 5759static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol, 5760 struct snd_ctl_elem_value *ucontrol) 5761{ 5762 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 5763 struct alc_spec *spec = codec->spec; 5764 *ucontrol->value.integer.value = spec->master_sw; 5765 return 0; 5766} 5767 5768static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol, 5769 struct snd_ctl_elem_value *ucontrol) 5770{ 5771 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 5772 struct alc_spec *spec = codec->spec; 5773 int val = !!*ucontrol->value.integer.value; 5774 hda_nid_t hp, line, mono; 5775 5776 if (val == spec->master_sw) 5777 return 0; 5778 spec->master_sw = val; 5779 hp = (kcontrol->private_value >> 16) & 0xff; 5780 line = (kcontrol->private_value >> 8) & 0xff; 5781 mono = kcontrol->private_value & 0xff; 5782 alc260_hp_master_update(codec, hp, line, mono); 5783 return 1; 5784} 5785 5786static struct snd_kcontrol_new alc260_hp_output_mixer[] = { 5787 { 5788 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 5789 .name = "Master Playback Switch", 5790 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11, 5791 .info = snd_ctl_boolean_mono_info, 5792 .get = alc260_hp_master_sw_get, 5793 .put = alc260_hp_master_sw_put, 5794 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11 5795 }, 5796 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT), 5797 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT), 5798 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT), 5799 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT), 5800 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, 5801 HDA_OUTPUT), 5802 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT), 5803 { } /* end */ 5804}; 5805 5806static struct hda_verb alc260_hp_unsol_verbs[] = { 5807 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 5808 {}, 5809}; 5810 5811static void alc260_hp_automute(struct hda_codec *codec) 5812{ 5813 struct alc_spec *spec = codec->spec; 5814 5815 spec->jack_present = snd_hda_jack_detect(codec, 0x10); 5816 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11); 5817} 5818 5819static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res) 5820{ 5821 if ((res >> 26) == ALC880_HP_EVENT) 5822 alc260_hp_automute(codec); 5823} 5824 5825static struct snd_kcontrol_new alc260_hp_3013_mixer[] = { 5826 { 5827 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 5828 .name = "Master Playback Switch", 5829 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11, 5830 .info = snd_ctl_boolean_mono_info, 5831 .get = alc260_hp_master_sw_get, 5832 .put = alc260_hp_master_sw_put, 5833 .private_value = (0x15 << 16) | (0x10 << 8) | 0x11 5834 }, 5835 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT), 5836 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT), 5837 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT), 5838 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT), 5839 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT), 5840 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 5841 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), 5842 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT), 5843 { } /* end */ 5844}; 5845 5846static struct hda_bind_ctls alc260_dc7600_bind_master_vol = { 5847 .ops = &snd_hda_bind_vol, 5848 .values = { 5849 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT), 5850 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT), 5851 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT), 5852 0 5853 }, 5854}; 5855 5856static struct hda_bind_ctls alc260_dc7600_bind_switch = { 5857 .ops = &snd_hda_bind_sw, 5858 .values = { 5859 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT), 5860 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT), 5861 0 5862 }, 5863}; 5864 5865static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = { 5866 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol), 5867 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch), 5868 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT), 5869 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT), 5870 { } /* end */ 5871}; 5872 5873static struct hda_verb alc260_hp_3013_unsol_verbs[] = { 5874 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 5875 {}, 5876}; 5877 5878static void alc260_hp_3013_automute(struct hda_codec *codec) 5879{ 5880 struct alc_spec *spec = codec->spec; 5881 5882 spec->jack_present = snd_hda_jack_detect(codec, 0x15); 5883 alc260_hp_master_update(codec, 0x15, 0x10, 0x11); 5884} 5885 5886static void alc260_hp_3013_unsol_event(struct hda_codec *codec, 5887 unsigned int res) 5888{ 5889 if ((res >> 26) == ALC880_HP_EVENT) 5890 alc260_hp_3013_automute(codec); 5891} 5892 5893static void alc260_hp_3012_automute(struct hda_codec *codec) 5894{ 5895 unsigned int bits = snd_hda_jack_detect(codec, 0x10) ? 0 : PIN_OUT; 5896 5897 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 5898 bits); 5899 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 5900 bits); 5901 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 5902 bits); 5903} 5904 5905static void alc260_hp_3012_unsol_event(struct hda_codec *codec, 5906 unsigned int res) 5907{ 5908 if ((res >> 26) == ALC880_HP_EVENT) 5909 alc260_hp_3012_automute(codec); 5910} 5911 5912/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12, 5913 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10. 5914 */ 5915static struct snd_kcontrol_new alc260_fujitsu_mixer[] = { 5916 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT), 5917 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT), 5918 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT), 5919 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), 5920 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), 5921 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT), 5922 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT), 5923 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN), 5924 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT), 5925 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT), 5926 { } /* end */ 5927}; 5928 5929/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current 5930 * versions of the ALC260 don't act on requests to enable mic bias from NID 5931 * 0x0f (used to drive the headphone jack in these laptops). The ALC260 5932 * datasheet doesn't mention this restriction. At this stage it's not clear 5933 * whether this behaviour is intentional or is a hardware bug in chip 5934 * revisions available in early 2006. Therefore for now allow the 5935 * "Headphone Jack Mode" control to span all choices, but if it turns out 5936 * that the lack of mic bias for this NID is intentional we could change the 5937 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS. 5938 * 5939 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006 5940 * don't appear to make the mic bias available from the "line" jack, even 5941 * though the NID used for this jack (0x14) can supply it. The theory is 5942 * that perhaps Acer have included blocking capacitors between the ALC260 5943 * and the output jack. If this turns out to be the case for all such 5944 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT 5945 * to ALC_PIN_DIR_INOUT_NOMICBIAS. 5946 * 5947 * The C20x Tablet series have a mono internal speaker which is controlled 5948 * via the chip's Mono sum widget and pin complex, so include the necessary 5949 * controls for such models. On models without a "mono speaker" the control 5950 * won't do anything. 5951 */ 5952static struct snd_kcontrol_new alc260_acer_mixer[] = { 5953 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), 5954 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT), 5955 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT), 5956 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, 5957 HDA_OUTPUT), 5958 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, 5959 HDA_INPUT), 5960 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), 5961 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), 5962 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), 5963 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT), 5964 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN), 5965 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), 5966 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT), 5967 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT), 5968 { } /* end */ 5969}; 5970 5971/* Maxdata Favorit 100XS: one output and one input (0x12) jack 5972 */ 5973static struct snd_kcontrol_new alc260_favorit100_mixer[] = { 5974 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), 5975 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT), 5976 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT), 5977 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT), 5978 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT), 5979 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN), 5980 { } /* end */ 5981}; 5982 5983/* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12, 5984 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17. 5985 */ 5986static struct snd_kcontrol_new alc260_will_mixer[] = { 5987 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), 5988 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT), 5989 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), 5990 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT), 5991 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN), 5992 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), 5993 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT), 5994 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT), 5995 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), 5996 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), 5997 { } /* end */ 5998}; 5999 6000/* Replacer 672V ALC260 pin usage: Mic jack = 0x12, 6001 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f. 6002 */ 6003static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = { 6004 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), 6005 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT), 6006 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), 6007 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT), 6008 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN), 6009 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT), 6010 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT), 6011 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), 6012 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT), 6013 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT), 6014 { } /* end */ 6015}; 6016 6017/* 6018 * initialization verbs 6019 */ 6020static struct hda_verb alc260_init_verbs[] = { 6021 /* Line In pin widget for input */ 6022 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 6023 /* CD pin widget for input */ 6024 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 6025 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 6026 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 6027 /* Mic2 (front panel) pin widget for input and vref at 80% */ 6028 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 6029 /* LINE-2 is used for line-out in rear */ 6030 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6031 /* select line-out */ 6032 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00}, 6033 /* LINE-OUT pin */ 6034 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6035 /* enable HP */ 6036 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6037 /* enable Mono */ 6038 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6039 /* mute capture amp left and right */ 6040 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6041 /* set connection select to line in (default select for this ADC) */ 6042 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02}, 6043 /* mute capture amp left and right */ 6044 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6045 /* set connection select to line in (default select for this ADC) */ 6046 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02}, 6047 /* set vol=0 Line-Out mixer amp left and right */ 6048 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6049 /* unmute pin widget amp left and right (no gain on this amp) */ 6050 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6051 /* set vol=0 HP mixer amp left and right */ 6052 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6053 /* unmute pin widget amp left and right (no gain on this amp) */ 6054 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6055 /* set vol=0 Mono mixer amp left and right */ 6056 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6057 /* unmute pin widget amp left and right (no gain on this amp) */ 6058 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6059 /* unmute LINE-2 out pin */ 6060 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6061 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & 6062 * Line In 2 = 0x03 6063 */ 6064 /* mute analog inputs */ 6065 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6066 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6067 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 6068 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 6069 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 6070 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */ 6071 /* mute Front out path */ 6072 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6073 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6074 /* mute Headphone out path */ 6075 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6076 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6077 /* mute Mono out path */ 6078 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6079 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6080 { } 6081}; 6082 6083#if 0 /* should be identical with alc260_init_verbs? */ 6084static struct hda_verb alc260_hp_init_verbs[] = { 6085 /* Headphone and output */ 6086 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 6087 /* mono output */ 6088 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 6089 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 6090 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 6091 /* Mic2 (front panel) pin widget for input and vref at 80% */ 6092 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 6093 /* Line In pin widget for input */ 6094 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 6095 /* Line-2 pin widget for output */ 6096 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 6097 /* CD pin widget for input */ 6098 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 6099 /* unmute amp left and right */ 6100 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000}, 6101 /* set connection select to line in (default select for this ADC) */ 6102 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02}, 6103 /* unmute Line-Out mixer amp left and right (volume = 0) */ 6104 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 6105 /* mute pin widget amp left and right (no gain on this amp) */ 6106 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 6107 /* unmute HP mixer amp left and right (volume = 0) */ 6108 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 6109 /* mute pin widget amp left and right (no gain on this amp) */ 6110 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 6111 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & 6112 * Line In 2 = 0x03 6113 */ 6114 /* mute analog inputs */ 6115 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6116 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6117 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 6118 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 6119 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 6120 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */ 6121 /* Unmute Front out path */ 6122 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 6123 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 6124 /* Unmute Headphone out path */ 6125 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 6126 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 6127 /* Unmute Mono out path */ 6128 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 6129 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 6130 { } 6131}; 6132#endif 6133 6134static struct hda_verb alc260_hp_3013_init_verbs[] = { 6135 /* Line out and output */ 6136 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 6137 /* mono output */ 6138 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 6139 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 6140 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 6141 /* Mic2 (front panel) pin widget for input and vref at 80% */ 6142 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 6143 /* Line In pin widget for input */ 6144 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 6145 /* Headphone pin widget for output */ 6146 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 6147 /* CD pin widget for input */ 6148 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 6149 /* unmute amp left and right */ 6150 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000}, 6151 /* set connection select to line in (default select for this ADC) */ 6152 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02}, 6153 /* unmute Line-Out mixer amp left and right (volume = 0) */ 6154 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 6155 /* mute pin widget amp left and right (no gain on this amp) */ 6156 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 6157 /* unmute HP mixer amp left and right (volume = 0) */ 6158 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 6159 /* mute pin widget amp left and right (no gain on this amp) */ 6160 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 6161 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & 6162 * Line In 2 = 0x03 6163 */ 6164 /* mute analog inputs */ 6165 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6166 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6167 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 6168 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 6169 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 6170 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */ 6171 /* Unmute Front out path */ 6172 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 6173 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 6174 /* Unmute Headphone out path */ 6175 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 6176 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 6177 /* Unmute Mono out path */ 6178 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 6179 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 6180 { } 6181}; 6182 6183/* Initialisation sequence for ALC260 as configured in Fujitsu S702x 6184 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD 6185 * audio = 0x16, internal speaker = 0x10. 6186 */ 6187static struct hda_verb alc260_fujitsu_init_verbs[] = { 6188 /* Disable all GPIOs */ 6189 {0x01, AC_VERB_SET_GPIO_MASK, 0}, 6190 /* Internal speaker is connected to headphone pin */ 6191 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6192 /* Headphone/Line-out jack connects to Line1 pin; make it an output */ 6193 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6194 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */ 6195 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 6196 /* Ensure all other unused pins are disabled and muted. */ 6197 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6198 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6199 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6200 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6201 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6202 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6203 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6204 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6205 6206 /* Disable digital (SPDIF) pins */ 6207 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0}, 6208 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0}, 6209 6210 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus 6211 * when acting as an output. 6212 */ 6213 {0x0d, AC_VERB_SET_CONNECT_SEL, 0}, 6214 6215 /* Start with output sum widgets muted and their output gains at min */ 6216 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6217 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6218 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6219 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6220 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6221 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6222 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6223 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6224 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6225 6226 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */ 6227 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6228 /* Unmute Line1 pin widget output buffer since it starts as an output. 6229 * If the pin mode is changed by the user the pin mode control will 6230 * take care of enabling the pin's input/output buffers as needed. 6231 * Therefore there's no need to enable the input buffer at this 6232 * stage. 6233 */ 6234 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6235 /* Unmute input buffer of pin widget used for Line-in (no equiv 6236 * mixer ctrl) 6237 */ 6238 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6239 6240 /* Mute capture amp left and right */ 6241 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6242 /* Set ADC connection select to match default mixer setting - line 6243 * in (on mic1 pin) 6244 */ 6245 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, 6246 6247 /* Do the same for the second ADC: mute capture input amp and 6248 * set ADC connection to line in (on mic1 pin) 6249 */ 6250 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6251 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, 6252 6253 /* Mute all inputs to mixer widget (even unconnected ones) */ 6254 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */ 6255 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */ 6256 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */ 6257 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */ 6258 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */ 6259 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */ 6260 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */ 6261 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */ 6262 6263 { } 6264}; 6265 6266/* Initialisation sequence for ALC260 as configured in Acer TravelMate and 6267 * similar laptops (adapted from Fujitsu init verbs). 6268 */ 6269static struct hda_verb alc260_acer_init_verbs[] = { 6270 /* On TravelMate laptops, GPIO 0 enables the internal speaker and 6271 * the headphone jack. Turn this on and rely on the standard mute 6272 * methods whenever the user wants to turn these outputs off. 6273 */ 6274 {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, 6275 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, 6276 {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, 6277 /* Internal speaker/Headphone jack is connected to Line-out pin */ 6278 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6279 /* Internal microphone/Mic jack is connected to Mic1 pin */ 6280 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, 6281 /* Line In jack is connected to Line1 pin */ 6282 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 6283 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */ 6284 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6285 /* Ensure all other unused pins are disabled and muted. */ 6286 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6287 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6288 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6289 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6290 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6291 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6292 /* Disable digital (SPDIF) pins */ 6293 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0}, 6294 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0}, 6295 6296 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum 6297 * bus when acting as outputs. 6298 */ 6299 {0x0b, AC_VERB_SET_CONNECT_SEL, 0}, 6300 {0x0d, AC_VERB_SET_CONNECT_SEL, 0}, 6301 6302 /* Start with output sum widgets muted and their output gains at min */ 6303 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6304 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6305 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6306 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6307 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6308 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6309 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6310 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6311 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6312 6313 /* Unmute Line-out pin widget amp left and right 6314 * (no equiv mixer ctrl) 6315 */ 6316 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6317 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */ 6318 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6319 /* Unmute Mic1 and Line1 pin widget input buffers since they start as 6320 * inputs. If the pin mode is changed by the user the pin mode control 6321 * will take care of enabling the pin's input/output buffers as needed. 6322 * Therefore there's no need to enable the input buffer at this 6323 * stage. 6324 */ 6325 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6326 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6327 6328 /* Mute capture amp left and right */ 6329 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6330 /* Set ADC connection select to match default mixer setting - mic 6331 * (on mic1 pin) 6332 */ 6333 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, 6334 6335 /* Do similar with the second ADC: mute capture input amp and 6336 * set ADC connection to mic to match ALSA's default state. 6337 */ 6338 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6339 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, 6340 6341 /* Mute all inputs to mixer widget (even unconnected ones) */ 6342 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */ 6343 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */ 6344 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */ 6345 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */ 6346 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */ 6347 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */ 6348 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */ 6349 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */ 6350 6351 { } 6352}; 6353 6354/* Initialisation sequence for Maxdata Favorit 100XS 6355 * (adapted from Acer init verbs). 6356 */ 6357static struct hda_verb alc260_favorit100_init_verbs[] = { 6358 /* GPIO 0 enables the output jack. 6359 * Turn this on and rely on the standard mute 6360 * methods whenever the user wants to turn these outputs off. 6361 */ 6362 {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, 6363 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, 6364 {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, 6365 /* Line/Mic input jack is connected to Mic1 pin */ 6366 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, 6367 /* Ensure all other unused pins are disabled and muted. */ 6368 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6369 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6370 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6371 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6372 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6373 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6374 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6375 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6376 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6377 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6378 /* Disable digital (SPDIF) pins */ 6379 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0}, 6380 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0}, 6381 6382 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum 6383 * bus when acting as outputs. 6384 */ 6385 {0x0b, AC_VERB_SET_CONNECT_SEL, 0}, 6386 {0x0d, AC_VERB_SET_CONNECT_SEL, 0}, 6387 6388 /* Start with output sum widgets muted and their output gains at min */ 6389 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6390 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6391 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6392 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6393 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6394 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6395 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6396 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6397 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6398 6399 /* Unmute Line-out pin widget amp left and right 6400 * (no equiv mixer ctrl) 6401 */ 6402 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6403 /* Unmute Mic1 and Line1 pin widget input buffers since they start as 6404 * inputs. If the pin mode is changed by the user the pin mode control 6405 * will take care of enabling the pin's input/output buffers as needed. 6406 * Therefore there's no need to enable the input buffer at this 6407 * stage. 6408 */ 6409 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6410 6411 /* Mute capture amp left and right */ 6412 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6413 /* Set ADC connection select to match default mixer setting - mic 6414 * (on mic1 pin) 6415 */ 6416 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, 6417 6418 /* Do similar with the second ADC: mute capture input amp and 6419 * set ADC connection to mic to match ALSA's default state. 6420 */ 6421 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6422 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, 6423 6424 /* Mute all inputs to mixer widget (even unconnected ones) */ 6425 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */ 6426 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */ 6427 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */ 6428 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */ 6429 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */ 6430 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */ 6431 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */ 6432 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */ 6433 6434 { } 6435}; 6436 6437static struct hda_verb alc260_will_verbs[] = { 6438 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6439 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00}, 6440 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00}, 6441 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02}, 6442 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07}, 6443 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040}, 6444 {} 6445}; 6446 6447static struct hda_verb alc260_replacer_672v_verbs[] = { 6448 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02}, 6449 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07}, 6450 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050}, 6451 6452 {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, 6453 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, 6454 {0x01, AC_VERB_SET_GPIO_DATA, 0x00}, 6455 6456 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 6457 {} 6458}; 6459 6460/* toggle speaker-output according to the hp-jack state */ 6461static void alc260_replacer_672v_automute(struct hda_codec *codec) 6462{ 6463 unsigned int present; 6464 6465 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */ 6466 present = snd_hda_jack_detect(codec, 0x0f); 6467 if (present) { 6468 snd_hda_codec_write_cache(codec, 0x01, 0, 6469 AC_VERB_SET_GPIO_DATA, 1); 6470 snd_hda_codec_write_cache(codec, 0x0f, 0, 6471 AC_VERB_SET_PIN_WIDGET_CONTROL, 6472 PIN_HP); 6473 } else { 6474 snd_hda_codec_write_cache(codec, 0x01, 0, 6475 AC_VERB_SET_GPIO_DATA, 0); 6476 snd_hda_codec_write_cache(codec, 0x0f, 0, 6477 AC_VERB_SET_PIN_WIDGET_CONTROL, 6478 PIN_OUT); 6479 } 6480} 6481 6482static void alc260_replacer_672v_unsol_event(struct hda_codec *codec, 6483 unsigned int res) 6484{ 6485 if ((res >> 26) == ALC880_HP_EVENT) 6486 alc260_replacer_672v_automute(codec); 6487} 6488 6489static struct hda_verb alc260_hp_dc7600_verbs[] = { 6490 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01}, 6491 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 6492 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6493 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6494 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6495 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6496 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 6497 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 6498 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 6499 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 6500 {} 6501}; 6502 6503/* Test configuration for debugging, modelled after the ALC880 test 6504 * configuration. 6505 */ 6506#ifdef CONFIG_SND_DEBUG 6507static hda_nid_t alc260_test_dac_nids[1] = { 6508 0x02, 6509}; 6510static hda_nid_t alc260_test_adc_nids[2] = { 6511 0x04, 0x05, 6512}; 6513/* For testing the ALC260, each input MUX needs its own definition since 6514 * the signal assignments are different. This assumes that the first ADC 6515 * is NID 0x04. 6516 */ 6517static struct hda_input_mux alc260_test_capture_sources[2] = { 6518 { 6519 .num_items = 7, 6520 .items = { 6521 { "MIC1 pin", 0x0 }, 6522 { "MIC2 pin", 0x1 }, 6523 { "LINE1 pin", 0x2 }, 6524 { "LINE2 pin", 0x3 }, 6525 { "CD pin", 0x4 }, 6526 { "LINE-OUT pin", 0x5 }, 6527 { "HP-OUT pin", 0x6 }, 6528 }, 6529 }, 6530 { 6531 .num_items = 8, 6532 .items = { 6533 { "MIC1 pin", 0x0 }, 6534 { "MIC2 pin", 0x1 }, 6535 { "LINE1 pin", 0x2 }, 6536 { "LINE2 pin", 0x3 }, 6537 { "CD pin", 0x4 }, 6538 { "Mixer", 0x5 }, 6539 { "LINE-OUT pin", 0x6 }, 6540 { "HP-OUT pin", 0x7 }, 6541 }, 6542 }, 6543}; 6544static struct snd_kcontrol_new alc260_test_mixer[] = { 6545 /* Output driver widgets */ 6546 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), 6547 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT), 6548 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT), 6549 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT), 6550 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT), 6551 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT), 6552 6553 /* Modes for retasking pin widgets 6554 * Note: the ALC260 doesn't seem to act on requests to enable mic 6555 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't 6556 * mention this restriction. At this stage it's not clear whether 6557 * this behaviour is intentional or is a hardware bug in chip 6558 * revisions available at least up until early 2006. Therefore for 6559 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all 6560 * choices, but if it turns out that the lack of mic bias for these 6561 * NIDs is intentional we could change their modes from 6562 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS. 6563 */ 6564 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT), 6565 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT), 6566 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT), 6567 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT), 6568 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT), 6569 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT), 6570 6571 /* Loopback mixer controls */ 6572 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT), 6573 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT), 6574 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT), 6575 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT), 6576 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT), 6577 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT), 6578 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT), 6579 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT), 6580 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), 6581 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), 6582 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT), 6583 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT), 6584 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT), 6585 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT), 6586 6587 /* Controls for GPIO pins, assuming they are configured as outputs */ 6588 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01), 6589 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02), 6590 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04), 6591 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08), 6592 6593 /* Switches to allow the digital IO pins to be enabled. The datasheet 6594 * is ambigious as to which NID is which; testing on laptops which 6595 * make this output available should provide clarification. 6596 */ 6597 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01), 6598 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01), 6599 6600 /* A switch allowing EAPD to be enabled. Some laptops seem to use 6601 * this output to turn on an external amplifier. 6602 */ 6603 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02), 6604 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02), 6605 6606 { } /* end */ 6607}; 6608static struct hda_verb alc260_test_init_verbs[] = { 6609 /* Enable all GPIOs as outputs with an initial value of 0 */ 6610 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f}, 6611 {0x01, AC_VERB_SET_GPIO_DATA, 0x00}, 6612 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f}, 6613 6614 /* Enable retasking pins as output, initially without power amp */ 6615 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6616 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6617 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6618 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6619 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6620 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6621 6622 /* Disable digital (SPDIF) pins initially, but users can enable 6623 * them via a mixer switch. In the case of SPDIF-out, this initverb 6624 * payload also sets the generation to 0, output to be in "consumer" 6625 * PCM format, copyright asserted, no pre-emphasis and no validity 6626 * control. 6627 */ 6628 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0}, 6629 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0}, 6630 6631 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the 6632 * OUT1 sum bus when acting as an output. 6633 */ 6634 {0x0b, AC_VERB_SET_CONNECT_SEL, 0}, 6635 {0x0c, AC_VERB_SET_CONNECT_SEL, 0}, 6636 {0x0d, AC_VERB_SET_CONNECT_SEL, 0}, 6637 {0x0e, AC_VERB_SET_CONNECT_SEL, 0}, 6638 6639 /* Start with output sum widgets muted and their output gains at min */ 6640 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6641 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6642 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6643 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6644 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6645 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6646 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6647 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6648 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6649 6650 /* Unmute retasking pin widget output buffers since the default 6651 * state appears to be output. As the pin mode is changed by the 6652 * user the pin mode control will take care of enabling the pin's 6653 * input/output buffers as needed. 6654 */ 6655 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6656 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6657 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6658 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6659 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6660 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6661 /* Also unmute the mono-out pin widget */ 6662 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6663 6664 /* Mute capture amp left and right */ 6665 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6666 /* Set ADC connection select to match default mixer setting (mic1 6667 * pin) 6668 */ 6669 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, 6670 6671 /* Do the same for the second ADC: mute capture input amp and 6672 * set ADC connection to mic1 pin 6673 */ 6674 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6675 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, 6676 6677 /* Mute all inputs to mixer widget (even unconnected ones) */ 6678 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */ 6679 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */ 6680 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */ 6681 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */ 6682 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */ 6683 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */ 6684 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */ 6685 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */ 6686 6687 { } 6688}; 6689#endif 6690 6691#define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback 6692#define alc260_pcm_analog_capture alc880_pcm_analog_capture 6693 6694#define alc260_pcm_digital_playback alc880_pcm_digital_playback 6695#define alc260_pcm_digital_capture alc880_pcm_digital_capture 6696 6697/* 6698 * for BIOS auto-configuration 6699 */ 6700 6701static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid, 6702 const char *pfx, int *vol_bits) 6703{ 6704 hda_nid_t nid_vol; 6705 unsigned long vol_val, sw_val; 6706 int err; 6707 6708 if (nid >= 0x0f && nid < 0x11) { 6709 nid_vol = nid - 0x7; 6710 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT); 6711 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT); 6712 } else if (nid == 0x11) { 6713 nid_vol = nid - 0x7; 6714 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT); 6715 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT); 6716 } else if (nid >= 0x12 && nid <= 0x15) { 6717 nid_vol = 0x08; 6718 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT); 6719 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT); 6720 } else 6721 return 0; /* N/A */ 6722 6723 if (!(*vol_bits & (1 << nid_vol))) { 6724 /* first control for the volume widget */ 6725 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, vol_val); 6726 if (err < 0) 6727 return err; 6728 *vol_bits |= (1 << nid_vol); 6729 } 6730 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, sw_val); 6731 if (err < 0) 6732 return err; 6733 return 1; 6734} 6735 6736/* add playback controls from the parsed DAC table */ 6737static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec, 6738 const struct auto_pin_cfg *cfg) 6739{ 6740 hda_nid_t nid; 6741 int err; 6742 int vols = 0; 6743 6744 spec->multiout.num_dacs = 1; 6745 spec->multiout.dac_nids = spec->private_dac_nids; 6746 spec->multiout.dac_nids[0] = 0x02; 6747 6748 nid = cfg->line_out_pins[0]; 6749 if (nid) { 6750 const char *pfx; 6751 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0]) 6752 pfx = "Master"; 6753 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) 6754 pfx = "Speaker"; 6755 else 6756 pfx = "Front"; 6757 err = alc260_add_playback_controls(spec, nid, pfx, &vols); 6758 if (err < 0) 6759 return err; 6760 } 6761 6762 nid = cfg->speaker_pins[0]; 6763 if (nid) { 6764 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols); 6765 if (err < 0) 6766 return err; 6767 } 6768 6769 nid = cfg->hp_pins[0]; 6770 if (nid) { 6771 err = alc260_add_playback_controls(spec, nid, "Headphone", 6772 &vols); 6773 if (err < 0) 6774 return err; 6775 } 6776 return 0; 6777} 6778 6779/* create playback/capture controls for input pins */ 6780static int alc260_auto_create_input_ctls(struct hda_codec *codec, 6781 const struct auto_pin_cfg *cfg) 6782{ 6783 return alc_auto_create_input_ctls(codec, cfg, 0x07, 0x04, 0x05); 6784} 6785 6786static void alc260_auto_set_output_and_unmute(struct hda_codec *codec, 6787 hda_nid_t nid, int pin_type, 6788 int sel_idx) 6789{ 6790 alc_set_pin_output(codec, nid, pin_type); 6791 /* need the manual connection? */ 6792 if (nid >= 0x12) { 6793 int idx = nid - 0x12; 6794 snd_hda_codec_write(codec, idx + 0x0b, 0, 6795 AC_VERB_SET_CONNECT_SEL, sel_idx); 6796 } 6797} 6798 6799static void alc260_auto_init_multi_out(struct hda_codec *codec) 6800{ 6801 struct alc_spec *spec = codec->spec; 6802 hda_nid_t nid; 6803 6804 nid = spec->autocfg.line_out_pins[0]; 6805 if (nid) { 6806 int pin_type = get_pin_type(spec->autocfg.line_out_type); 6807 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0); 6808 } 6809 6810 nid = spec->autocfg.speaker_pins[0]; 6811 if (nid) 6812 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0); 6813 6814 nid = spec->autocfg.hp_pins[0]; 6815 if (nid) 6816 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0); 6817} 6818 6819#define ALC260_PIN_CD_NID 0x16 6820static void alc260_auto_init_analog_input(struct hda_codec *codec) 6821{ 6822 struct alc_spec *spec = codec->spec; 6823 struct auto_pin_cfg *cfg = &spec->autocfg; 6824 int i; 6825 6826 for (i = 0; i < cfg->num_inputs; i++) { 6827 hda_nid_t nid = cfg->inputs[i].pin; 6828 if (nid >= 0x12) { 6829 alc_set_input_pin(codec, nid, cfg->inputs[i].type); 6830 if (nid != ALC260_PIN_CD_NID && 6831 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)) 6832 snd_hda_codec_write(codec, nid, 0, 6833 AC_VERB_SET_AMP_GAIN_MUTE, 6834 AMP_OUT_MUTE); 6835 } 6836 } 6837} 6838 6839#define alc260_auto_init_input_src alc880_auto_init_input_src 6840 6841/* 6842 * generic initialization of ADC, input mixers and output mixers 6843 */ 6844static struct hda_verb alc260_volume_init_verbs[] = { 6845 /* 6846 * Unmute ADC0-1 and set the default input to mic-in 6847 */ 6848 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, 6849 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6850 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, 6851 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6852 6853 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 6854 * mixer widget 6855 * Note: PASD motherboards uses the Line In 2 as the input for 6856 * front panel mic (mic 2) 6857 */ 6858 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 6859 /* mute analog inputs */ 6860 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6861 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6862 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 6863 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 6864 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 6865 6866 /* 6867 * Set up output mixers (0x08 - 0x0a) 6868 */ 6869 /* set vol=0 to output mixers */ 6870 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6871 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6872 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6873 /* set up input amps for analog loopback */ 6874 /* Amp Indices: DAC = 0, mixer = 1 */ 6875 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6876 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 6877 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6878 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 6879 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6880 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 6881 6882 { } 6883}; 6884 6885static int alc260_parse_auto_config(struct hda_codec *codec) 6886{ 6887 struct alc_spec *spec = codec->spec; 6888 int err; 6889 static hda_nid_t alc260_ignore[] = { 0x17, 0 }; 6890 6891 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 6892 alc260_ignore); 6893 if (err < 0) 6894 return err; 6895 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg); 6896 if (err < 0) 6897 return err; 6898 if (!spec->kctls.list) 6899 return 0; /* can't find valid BIOS pin config */ 6900 err = alc260_auto_create_input_ctls(codec, &spec->autocfg); 6901 if (err < 0) 6902 return err; 6903 6904 spec->multiout.max_channels = 2; 6905 6906 if (spec->autocfg.dig_outs) 6907 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID; 6908 if (spec->kctls.list) 6909 add_mixer(spec, spec->kctls.list); 6910 6911 add_verb(spec, alc260_volume_init_verbs); 6912 6913 spec->num_mux_defs = 1; 6914 spec->input_mux = &spec->private_imux[0]; 6915 6916 alc_ssid_check(codec, 0x10, 0x15, 0x0f, 0); 6917 6918 return 1; 6919} 6920 6921/* additional initialization for auto-configuration model */ 6922static void alc260_auto_init(struct hda_codec *codec) 6923{ 6924 struct alc_spec *spec = codec->spec; 6925 alc260_auto_init_multi_out(codec); 6926 alc260_auto_init_analog_input(codec); 6927 alc260_auto_init_input_src(codec); 6928 alc_auto_init_digital(codec); 6929 if (spec->unsol_event) 6930 alc_inithook(codec); 6931} 6932 6933#ifdef CONFIG_SND_HDA_POWER_SAVE 6934static struct hda_amp_list alc260_loopbacks[] = { 6935 { 0x07, HDA_INPUT, 0 }, 6936 { 0x07, HDA_INPUT, 1 }, 6937 { 0x07, HDA_INPUT, 2 }, 6938 { 0x07, HDA_INPUT, 3 }, 6939 { 0x07, HDA_INPUT, 4 }, 6940 { } /* end */ 6941}; 6942#endif 6943 6944/* 6945 * Pin config fixes 6946 */ 6947enum { 6948 PINFIX_HP_DC5750, 6949}; 6950 6951static const struct alc_fixup alc260_fixups[] = { 6952 [PINFIX_HP_DC5750] = { 6953 .pins = (const struct alc_pincfg[]) { 6954 { 0x11, 0x90130110 }, /* speaker */ 6955 { } 6956 } 6957 }, 6958}; 6959 6960static struct snd_pci_quirk alc260_fixup_tbl[] = { 6961 SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", PINFIX_HP_DC5750), 6962 {} 6963}; 6964 6965/* 6966 * ALC260 configurations 6967 */ 6968static const char *alc260_models[ALC260_MODEL_LAST] = { 6969 [ALC260_BASIC] = "basic", 6970 [ALC260_HP] = "hp", 6971 [ALC260_HP_3013] = "hp-3013", 6972 [ALC260_HP_DC7600] = "hp-dc7600", 6973 [ALC260_FUJITSU_S702X] = "fujitsu", 6974 [ALC260_ACER] = "acer", 6975 [ALC260_WILL] = "will", 6976 [ALC260_REPLACER_672V] = "replacer", 6977 [ALC260_FAVORIT100] = "favorit100", 6978#ifdef CONFIG_SND_DEBUG 6979 [ALC260_TEST] = "test", 6980#endif 6981 [ALC260_AUTO] = "auto", 6982}; 6983 6984static struct snd_pci_quirk alc260_cfg_tbl[] = { 6985 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER), 6986 SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL), 6987 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER), 6988 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100), 6989 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013), 6990 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_AUTO), /* no quirk */ 6991 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013), 6992 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013), 6993 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600), 6994 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013), 6995 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP), 6996 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP), 6997 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP), 6998 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC), 6999 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC), 7000 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC), 7001 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X), 7002 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC), 7003 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V), 7004 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL), 7005 {} 7006}; 7007 7008static struct alc_config_preset alc260_presets[] = { 7009 [ALC260_BASIC] = { 7010 .mixers = { alc260_base_output_mixer, 7011 alc260_input_mixer }, 7012 .init_verbs = { alc260_init_verbs }, 7013 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 7014 .dac_nids = alc260_dac_nids, 7015 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids), 7016 .adc_nids = alc260_dual_adc_nids, 7017 .num_channel_mode = ARRAY_SIZE(alc260_modes), 7018 .channel_mode = alc260_modes, 7019 .input_mux = &alc260_capture_source, 7020 }, 7021 [ALC260_HP] = { 7022 .mixers = { alc260_hp_output_mixer, 7023 alc260_input_mixer }, 7024 .init_verbs = { alc260_init_verbs, 7025 alc260_hp_unsol_verbs }, 7026 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 7027 .dac_nids = alc260_dac_nids, 7028 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt), 7029 .adc_nids = alc260_adc_nids_alt, 7030 .num_channel_mode = ARRAY_SIZE(alc260_modes), 7031 .channel_mode = alc260_modes, 7032 .input_mux = &alc260_capture_source, 7033 .unsol_event = alc260_hp_unsol_event, 7034 .init_hook = alc260_hp_automute, 7035 }, 7036 [ALC260_HP_DC7600] = { 7037 .mixers = { alc260_hp_dc7600_mixer, 7038 alc260_input_mixer }, 7039 .init_verbs = { alc260_init_verbs, 7040 alc260_hp_dc7600_verbs }, 7041 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 7042 .dac_nids = alc260_dac_nids, 7043 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt), 7044 .adc_nids = alc260_adc_nids_alt, 7045 .num_channel_mode = ARRAY_SIZE(alc260_modes), 7046 .channel_mode = alc260_modes, 7047 .input_mux = &alc260_capture_source, 7048 .unsol_event = alc260_hp_3012_unsol_event, 7049 .init_hook = alc260_hp_3012_automute, 7050 }, 7051 [ALC260_HP_3013] = { 7052 .mixers = { alc260_hp_3013_mixer, 7053 alc260_input_mixer }, 7054 .init_verbs = { alc260_hp_3013_init_verbs, 7055 alc260_hp_3013_unsol_verbs }, 7056 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 7057 .dac_nids = alc260_dac_nids, 7058 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt), 7059 .adc_nids = alc260_adc_nids_alt, 7060 .num_channel_mode = ARRAY_SIZE(alc260_modes), 7061 .channel_mode = alc260_modes, 7062 .input_mux = &alc260_capture_source, 7063 .unsol_event = alc260_hp_3013_unsol_event, 7064 .init_hook = alc260_hp_3013_automute, 7065 }, 7066 [ALC260_FUJITSU_S702X] = { 7067 .mixers = { alc260_fujitsu_mixer }, 7068 .init_verbs = { alc260_fujitsu_init_verbs }, 7069 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 7070 .dac_nids = alc260_dac_nids, 7071 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids), 7072 .adc_nids = alc260_dual_adc_nids, 7073 .num_channel_mode = ARRAY_SIZE(alc260_modes), 7074 .channel_mode = alc260_modes, 7075 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources), 7076 .input_mux = alc260_fujitsu_capture_sources, 7077 }, 7078 [ALC260_ACER] = { 7079 .mixers = { alc260_acer_mixer }, 7080 .init_verbs = { alc260_acer_init_verbs }, 7081 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 7082 .dac_nids = alc260_dac_nids, 7083 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids), 7084 .adc_nids = alc260_dual_adc_nids, 7085 .num_channel_mode = ARRAY_SIZE(alc260_modes), 7086 .channel_mode = alc260_modes, 7087 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources), 7088 .input_mux = alc260_acer_capture_sources, 7089 }, 7090 [ALC260_FAVORIT100] = { 7091 .mixers = { alc260_favorit100_mixer }, 7092 .init_verbs = { alc260_favorit100_init_verbs }, 7093 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 7094 .dac_nids = alc260_dac_nids, 7095 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids), 7096 .adc_nids = alc260_dual_adc_nids, 7097 .num_channel_mode = ARRAY_SIZE(alc260_modes), 7098 .channel_mode = alc260_modes, 7099 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources), 7100 .input_mux = alc260_favorit100_capture_sources, 7101 }, 7102 [ALC260_WILL] = { 7103 .mixers = { alc260_will_mixer }, 7104 .init_verbs = { alc260_init_verbs, alc260_will_verbs }, 7105 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 7106 .dac_nids = alc260_dac_nids, 7107 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids), 7108 .adc_nids = alc260_adc_nids, 7109 .dig_out_nid = ALC260_DIGOUT_NID, 7110 .num_channel_mode = ARRAY_SIZE(alc260_modes), 7111 .channel_mode = alc260_modes, 7112 .input_mux = &alc260_capture_source, 7113 }, 7114 [ALC260_REPLACER_672V] = { 7115 .mixers = { alc260_replacer_672v_mixer }, 7116 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs }, 7117 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 7118 .dac_nids = alc260_dac_nids, 7119 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids), 7120 .adc_nids = alc260_adc_nids, 7121 .dig_out_nid = ALC260_DIGOUT_NID, 7122 .num_channel_mode = ARRAY_SIZE(alc260_modes), 7123 .channel_mode = alc260_modes, 7124 .input_mux = &alc260_capture_source, 7125 .unsol_event = alc260_replacer_672v_unsol_event, 7126 .init_hook = alc260_replacer_672v_automute, 7127 }, 7128#ifdef CONFIG_SND_DEBUG 7129 [ALC260_TEST] = { 7130 .mixers = { alc260_test_mixer }, 7131 .init_verbs = { alc260_test_init_verbs }, 7132 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids), 7133 .dac_nids = alc260_test_dac_nids, 7134 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids), 7135 .adc_nids = alc260_test_adc_nids, 7136 .num_channel_mode = ARRAY_SIZE(alc260_modes), 7137 .channel_mode = alc260_modes, 7138 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources), 7139 .input_mux = alc260_test_capture_sources, 7140 }, 7141#endif 7142}; 7143 7144static int patch_alc260(struct hda_codec *codec) 7145{ 7146 struct alc_spec *spec; 7147 int err, board_config; 7148 7149 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 7150 if (spec == NULL) 7151 return -ENOMEM; 7152 7153 codec->spec = spec; 7154 7155 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST, 7156 alc260_models, 7157 alc260_cfg_tbl); 7158 if (board_config < 0) { 7159 snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 7160 codec->chip_name); 7161 board_config = ALC260_AUTO; 7162 } 7163 7164 if (board_config == ALC260_AUTO) 7165 alc_pick_fixup(codec, alc260_fixup_tbl, alc260_fixups, 1); 7166 7167 if (board_config == ALC260_AUTO) { 7168 /* automatic parse from the BIOS config */ 7169 err = alc260_parse_auto_config(codec); 7170 if (err < 0) { 7171 alc_free(codec); 7172 return err; 7173 } else if (!err) { 7174 printk(KERN_INFO 7175 "hda_codec: Cannot set up configuration " 7176 "from BIOS. Using base mode...\n"); 7177 board_config = ALC260_BASIC; 7178 } 7179 } 7180 7181 err = snd_hda_attach_beep_device(codec, 0x1); 7182 if (err < 0) { 7183 alc_free(codec); 7184 return err; 7185 } 7186 7187 if (board_config != ALC260_AUTO) 7188 setup_preset(codec, &alc260_presets[board_config]); 7189 7190 spec->stream_analog_playback = &alc260_pcm_analog_playback; 7191 spec->stream_analog_capture = &alc260_pcm_analog_capture; 7192 spec->stream_analog_alt_capture = &alc260_pcm_analog_capture; 7193 7194 spec->stream_digital_playback = &alc260_pcm_digital_playback; 7195 spec->stream_digital_capture = &alc260_pcm_digital_capture; 7196 7197 if (!spec->adc_nids && spec->input_mux) { 7198 /* check whether NID 0x04 is valid */ 7199 unsigned int wcap = get_wcaps(codec, 0x04); 7200 wcap = get_wcaps_type(wcap); 7201 /* get type */ 7202 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) { 7203 spec->adc_nids = alc260_adc_nids_alt; 7204 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt); 7205 } else { 7206 spec->adc_nids = alc260_adc_nids; 7207 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids); 7208 } 7209 } 7210 set_capture_mixer(codec); 7211 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT); 7212 7213 if (board_config == ALC260_AUTO) 7214 alc_pick_fixup(codec, alc260_fixup_tbl, alc260_fixups, 0); 7215 7216 spec->vmaster_nid = 0x08; 7217 7218 codec->patch_ops = alc_patch_ops; 7219 if (board_config == ALC260_AUTO) 7220 spec->init_hook = alc260_auto_init; 7221#ifdef CONFIG_SND_HDA_POWER_SAVE 7222 if (!spec->loopback.amplist) 7223 spec->loopback.amplist = alc260_loopbacks; 7224#endif 7225 7226 return 0; 7227} 7228 7229 7230/* 7231 * ALC882/883/885/888/889 support 7232 * 7233 * ALC882 is almost identical with ALC880 but has cleaner and more flexible 7234 * configuration. Each pin widget can choose any input DACs and a mixer. 7235 * Each ADC is connected from a mixer of all inputs. This makes possible 7236 * 6-channel independent captures. 7237 * 7238 * In addition, an independent DAC for the multi-playback (not used in this 7239 * driver yet). 7240 */ 7241#define ALC882_DIGOUT_NID 0x06 7242#define ALC882_DIGIN_NID 0x0a 7243#define ALC883_DIGOUT_NID ALC882_DIGOUT_NID 7244#define ALC883_DIGIN_NID ALC882_DIGIN_NID 7245#define ALC1200_DIGOUT_NID 0x10 7246 7247 7248static struct hda_channel_mode alc882_ch_modes[1] = { 7249 { 8, NULL } 7250}; 7251 7252/* DACs */ 7253static hda_nid_t alc882_dac_nids[4] = { 7254 /* front, rear, clfe, rear_surr */ 7255 0x02, 0x03, 0x04, 0x05 7256}; 7257#define alc883_dac_nids alc882_dac_nids 7258 7259/* ADCs */ 7260#define alc882_adc_nids alc880_adc_nids 7261#define alc882_adc_nids_alt alc880_adc_nids_alt 7262#define alc883_adc_nids alc882_adc_nids_alt 7263static hda_nid_t alc883_adc_nids_alt[1] = { 0x08 }; 7264static hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 }; 7265#define alc889_adc_nids alc880_adc_nids 7266 7267static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 }; 7268static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 }; 7269#define alc883_capsrc_nids alc882_capsrc_nids_alt 7270static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 }; 7271#define alc889_capsrc_nids alc882_capsrc_nids 7272 7273/* input MUX */ 7274/* FIXME: should be a matrix-type input source selection */ 7275 7276static struct hda_input_mux alc882_capture_source = { 7277 .num_items = 4, 7278 .items = { 7279 { "Mic", 0x0 }, 7280 { "Front Mic", 0x1 }, 7281 { "Line", 0x2 }, 7282 { "CD", 0x4 }, 7283 }, 7284}; 7285 7286#define alc883_capture_source alc882_capture_source 7287 7288static struct hda_input_mux alc889_capture_source = { 7289 .num_items = 3, 7290 .items = { 7291 { "Front Mic", 0x0 }, 7292 { "Mic", 0x3 }, 7293 { "Line", 0x2 }, 7294 }, 7295}; 7296 7297static struct hda_input_mux mb5_capture_source = { 7298 .num_items = 3, 7299 .items = { 7300 { "Mic", 0x1 }, 7301 { "Line", 0x7 }, 7302 { "CD", 0x4 }, 7303 }, 7304}; 7305 7306static struct hda_input_mux macmini3_capture_source = { 7307 .num_items = 2, 7308 .items = { 7309 { "Line", 0x2 }, 7310 { "CD", 0x4 }, 7311 }, 7312}; 7313 7314static struct hda_input_mux alc883_3stack_6ch_intel = { 7315 .num_items = 4, 7316 .items = { 7317 { "Mic", 0x1 }, 7318 { "Front Mic", 0x0 }, 7319 { "Line", 0x2 }, 7320 { "CD", 0x4 }, 7321 }, 7322}; 7323 7324static struct hda_input_mux alc883_lenovo_101e_capture_source = { 7325 .num_items = 2, 7326 .items = { 7327 { "Mic", 0x1 }, 7328 { "Line", 0x2 }, 7329 }, 7330}; 7331 7332static struct hda_input_mux alc883_lenovo_nb0763_capture_source = { 7333 .num_items = 4, 7334 .items = { 7335 { "Mic", 0x0 }, 7336 { "Int Mic", 0x1 }, 7337 { "Line", 0x2 }, 7338 { "CD", 0x4 }, 7339 }, 7340}; 7341 7342static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = { 7343 .num_items = 2, 7344 .items = { 7345 { "Mic", 0x0 }, 7346 { "Int Mic", 0x1 }, 7347 }, 7348}; 7349 7350static struct hda_input_mux alc883_lenovo_sky_capture_source = { 7351 .num_items = 3, 7352 .items = { 7353 { "Mic", 0x0 }, 7354 { "Front Mic", 0x1 }, 7355 { "Line", 0x4 }, 7356 }, 7357}; 7358 7359static struct hda_input_mux alc883_asus_eee1601_capture_source = { 7360 .num_items = 2, 7361 .items = { 7362 { "Mic", 0x0 }, 7363 { "Line", 0x2 }, 7364 }, 7365}; 7366 7367static struct hda_input_mux alc889A_mb31_capture_source = { 7368 .num_items = 2, 7369 .items = { 7370 { "Mic", 0x0 }, 7371 /* Front Mic (0x01) unused */ 7372 { "Line", 0x2 }, 7373 /* Line 2 (0x03) unused */ 7374 /* CD (0x04) unused? */ 7375 }, 7376}; 7377 7378static struct hda_input_mux alc889A_imac91_capture_source = { 7379 .num_items = 2, 7380 .items = { 7381 { "Mic", 0x01 }, 7382 { "Line", 0x2 }, /* Not sure! */ 7383 }, 7384}; 7385 7386/* 7387 * 2ch mode 7388 */ 7389static struct hda_channel_mode alc883_3ST_2ch_modes[1] = { 7390 { 2, NULL } 7391}; 7392 7393/* 7394 * 2ch mode 7395 */ 7396static struct hda_verb alc882_3ST_ch2_init[] = { 7397 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 7398 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7399 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 7400 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7401 { } /* end */ 7402}; 7403 7404/* 7405 * 4ch mode 7406 */ 7407static struct hda_verb alc882_3ST_ch4_init[] = { 7408 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 7409 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7410 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7411 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7412 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7413 { } /* end */ 7414}; 7415 7416/* 7417 * 6ch mode 7418 */ 7419static struct hda_verb alc882_3ST_ch6_init[] = { 7420 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7421 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7422 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, 7423 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7424 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7425 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7426 { } /* end */ 7427}; 7428 7429static struct hda_channel_mode alc882_3ST_6ch_modes[3] = { 7430 { 2, alc882_3ST_ch2_init }, 7431 { 4, alc882_3ST_ch4_init }, 7432 { 6, alc882_3ST_ch6_init }, 7433}; 7434 7435#define alc883_3ST_6ch_modes alc882_3ST_6ch_modes 7436 7437/* 7438 * 2ch mode 7439 */ 7440static struct hda_verb alc883_3ST_ch2_clevo_init[] = { 7441 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, 7442 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 7443 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7444 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 7445 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7446 { } /* end */ 7447}; 7448 7449/* 7450 * 4ch mode 7451 */ 7452static struct hda_verb alc883_3ST_ch4_clevo_init[] = { 7453 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7454 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 7455 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7456 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7457 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7458 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7459 { } /* end */ 7460}; 7461 7462/* 7463 * 6ch mode 7464 */ 7465static struct hda_verb alc883_3ST_ch6_clevo_init[] = { 7466 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7467 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7468 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7469 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, 7470 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7471 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7472 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7473 { } /* end */ 7474}; 7475 7476static struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = { 7477 { 2, alc883_3ST_ch2_clevo_init }, 7478 { 4, alc883_3ST_ch4_clevo_init }, 7479 { 6, alc883_3ST_ch6_clevo_init }, 7480}; 7481 7482 7483/* 7484 * 6ch mode 7485 */ 7486static struct hda_verb alc882_sixstack_ch6_init[] = { 7487 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 7488 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7489 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7490 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7491 { } /* end */ 7492}; 7493 7494/* 7495 * 8ch mode 7496 */ 7497static struct hda_verb alc882_sixstack_ch8_init[] = { 7498 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7499 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7500 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7501 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7502 { } /* end */ 7503}; 7504 7505static struct hda_channel_mode alc882_sixstack_modes[2] = { 7506 { 6, alc882_sixstack_ch6_init }, 7507 { 8, alc882_sixstack_ch8_init }, 7508}; 7509 7510 7511/* Macbook Air 2,1 */ 7512 7513static struct hda_channel_mode alc885_mba21_ch_modes[1] = { 7514 { 2, NULL }, 7515}; 7516 7517/* 7518 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic 7519 */ 7520 7521/* 7522 * 2ch mode 7523 */ 7524static struct hda_verb alc885_mbp_ch2_init[] = { 7525 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 7526 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7527 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7528 { } /* end */ 7529}; 7530 7531/* 7532 * 4ch mode 7533 */ 7534static struct hda_verb alc885_mbp_ch4_init[] = { 7535 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7536 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7537 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7538 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7539 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 7540 { } /* end */ 7541}; 7542 7543static struct hda_channel_mode alc885_mbp_4ch_modes[2] = { 7544 { 2, alc885_mbp_ch2_init }, 7545 { 4, alc885_mbp_ch4_init }, 7546}; 7547 7548/* 7549 * 2ch 7550 * Speakers/Woofer/HP = Front 7551 * LineIn = Input 7552 */ 7553static struct hda_verb alc885_mb5_ch2_init[] = { 7554 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 7555 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 7556 { } /* end */ 7557}; 7558 7559/* 7560 * 6ch mode 7561 * Speakers/HP = Front 7562 * Woofer = LFE 7563 * LineIn = Surround 7564 */ 7565static struct hda_verb alc885_mb5_ch6_init[] = { 7566 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 7567 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7568 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 7569 { } /* end */ 7570}; 7571 7572static struct hda_channel_mode alc885_mb5_6ch_modes[2] = { 7573 { 2, alc885_mb5_ch2_init }, 7574 { 6, alc885_mb5_ch6_init }, 7575}; 7576 7577#define alc885_macmini3_6ch_modes alc885_mb5_6ch_modes 7578 7579/* 7580 * 2ch mode 7581 */ 7582static struct hda_verb alc883_4ST_ch2_init[] = { 7583 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7584 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7585 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 7586 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7587 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 7588 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7589 { } /* end */ 7590}; 7591 7592/* 7593 * 4ch mode 7594 */ 7595static struct hda_verb alc883_4ST_ch4_init[] = { 7596 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7597 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7598 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 7599 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7600 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7601 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7602 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7603 { } /* end */ 7604}; 7605 7606/* 7607 * 6ch mode 7608 */ 7609static struct hda_verb alc883_4ST_ch6_init[] = { 7610 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7611 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7612 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7613 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7614 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, 7615 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7616 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7617 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7618 { } /* end */ 7619}; 7620 7621/* 7622 * 8ch mode 7623 */ 7624static struct hda_verb alc883_4ST_ch8_init[] = { 7625 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7626 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7627 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 }, 7628 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7629 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7630 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, 7631 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7632 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7633 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7634 { } /* end */ 7635}; 7636 7637static struct hda_channel_mode alc883_4ST_8ch_modes[4] = { 7638 { 2, alc883_4ST_ch2_init }, 7639 { 4, alc883_4ST_ch4_init }, 7640 { 6, alc883_4ST_ch6_init }, 7641 { 8, alc883_4ST_ch8_init }, 7642}; 7643 7644 7645/* 7646 * 2ch mode 7647 */ 7648static struct hda_verb alc883_3ST_ch2_intel_init[] = { 7649 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 7650 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7651 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 7652 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7653 { } /* end */ 7654}; 7655 7656/* 7657 * 4ch mode 7658 */ 7659static struct hda_verb alc883_3ST_ch4_intel_init[] = { 7660 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 7661 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7662 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7663 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7664 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7665 { } /* end */ 7666}; 7667 7668/* 7669 * 6ch mode 7670 */ 7671static struct hda_verb alc883_3ST_ch6_intel_init[] = { 7672 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7673 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7674 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 }, 7675 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7676 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7677 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7678 { } /* end */ 7679}; 7680 7681static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = { 7682 { 2, alc883_3ST_ch2_intel_init }, 7683 { 4, alc883_3ST_ch4_intel_init }, 7684 { 6, alc883_3ST_ch6_intel_init }, 7685}; 7686 7687/* 7688 * 2ch mode 7689 */ 7690static struct hda_verb alc889_ch2_intel_init[] = { 7691 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 }, 7692 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 }, 7693 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 }, 7694 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00 }, 7695 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 7696 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7697 { } /* end */ 7698}; 7699 7700/* 7701 * 6ch mode 7702 */ 7703static struct hda_verb alc889_ch6_intel_init[] = { 7704 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 }, 7705 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7706 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 }, 7707 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 }, 7708 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 7709 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7710 { } /* end */ 7711}; 7712 7713/* 7714 * 8ch mode 7715 */ 7716static struct hda_verb alc889_ch8_intel_init[] = { 7717 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 }, 7718 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7719 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 }, 7720 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 }, 7721 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x03 }, 7722 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7723 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7724 { } /* end */ 7725}; 7726 7727static struct hda_channel_mode alc889_8ch_intel_modes[3] = { 7728 { 2, alc889_ch2_intel_init }, 7729 { 6, alc889_ch6_intel_init }, 7730 { 8, alc889_ch8_intel_init }, 7731}; 7732 7733/* 7734 * 6ch mode 7735 */ 7736static struct hda_verb alc883_sixstack_ch6_init[] = { 7737 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 7738 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7739 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7740 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7741 { } /* end */ 7742}; 7743 7744/* 7745 * 8ch mode 7746 */ 7747static struct hda_verb alc883_sixstack_ch8_init[] = { 7748 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7749 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7750 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7751 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7752 { } /* end */ 7753}; 7754 7755static struct hda_channel_mode alc883_sixstack_modes[2] = { 7756 { 6, alc883_sixstack_ch6_init }, 7757 { 8, alc883_sixstack_ch8_init }, 7758}; 7759 7760 7761/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 7762 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b 7763 */ 7764static struct snd_kcontrol_new alc882_base_mixer[] = { 7765 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7766 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 7767 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 7768 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 7769 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 7770 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 7771 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 7772 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 7773 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 7774 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 7775 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 7776 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 7777 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 7778 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 7779 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 7780 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7781 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 7782 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7783 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 7784 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 7785 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 7786 { } /* end */ 7787}; 7788 7789/* Macbook Air 2,1 same control for HP and internal Speaker */ 7790 7791static struct snd_kcontrol_new alc885_mba21_mixer[] = { 7792 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 7793 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT), 7794 { } 7795}; 7796 7797 7798static struct snd_kcontrol_new alc885_mbp3_mixer[] = { 7799 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 7800 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT), 7801 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT), 7802 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0e, 0x02, HDA_INPUT), 7803 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT), 7804 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 7805 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 7806 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT), 7807 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT), 7808 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT), 7809 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT), 7810 { } /* end */ 7811}; 7812 7813static struct snd_kcontrol_new alc885_mb5_mixer[] = { 7814 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 7815 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT), 7816 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT), 7817 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT), 7818 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT), 7819 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT), 7820 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT), 7821 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT), 7822 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT), 7823 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT), 7824 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 7825 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 7826 HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT), 7827 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0x00, HDA_INPUT), 7828 { } /* end */ 7829}; 7830 7831static struct snd_kcontrol_new alc885_macmini3_mixer[] = { 7832 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 7833 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT), 7834 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT), 7835 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT), 7836 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT), 7837 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT), 7838 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT), 7839 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT), 7840 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT), 7841 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT), 7842 HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT), 7843 { } /* end */ 7844}; 7845 7846static struct snd_kcontrol_new alc885_imac91_mixer[] = { 7847 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 7848 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT), 7849 { } /* end */ 7850}; 7851 7852 7853static struct snd_kcontrol_new alc882_w2jc_mixer[] = { 7854 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7855 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 7856 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 7857 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 7858 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 7859 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 7860 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7861 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 7862 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7863 { } /* end */ 7864}; 7865 7866static struct snd_kcontrol_new alc882_targa_mixer[] = { 7867 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7868 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 7869 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 7870 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 7871 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 7872 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 7873 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 7874 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7875 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7876 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 7877 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 7878 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 7879 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 7880 { } /* end */ 7881}; 7882 7883/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ??? 7884 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c 7885 */ 7886static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = { 7887 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7888 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 7889 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 7890 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT), 7891 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 7892 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 7893 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 7894 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 7895 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT), 7896 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT), 7897 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7898 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7899 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 7900 { } /* end */ 7901}; 7902 7903static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = { 7904 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7905 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 7906 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 7907 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 7908 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 7909 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 7910 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 7911 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7912 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 7913 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7914 { } /* end */ 7915}; 7916 7917static struct snd_kcontrol_new alc882_chmode_mixer[] = { 7918 { 7919 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 7920 .name = "Channel Mode", 7921 .info = alc_ch_mode_info, 7922 .get = alc_ch_mode_get, 7923 .put = alc_ch_mode_put, 7924 }, 7925 { } /* end */ 7926}; 7927 7928static struct hda_verb alc882_base_init_verbs[] = { 7929 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 7930 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7931 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7932 /* Rear mixer */ 7933 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7934 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7935 /* CLFE mixer */ 7936 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7937 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7938 /* Side mixer */ 7939 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7940 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7941 7942 /* Front Pin: output 0 (0x0c) */ 7943 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 7944 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7945 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 7946 /* Rear Pin: output 1 (0x0d) */ 7947 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 7948 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7949 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 7950 /* CLFE Pin: output 2 (0x0e) */ 7951 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 7952 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7953 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, 7954 /* Side Pin: output 3 (0x0f) */ 7955 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 7956 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7957 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, 7958 /* Mic (rear) pin: input vref at 80% */ 7959 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 7960 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 7961 /* Front Mic pin: input vref at 80% */ 7962 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 7963 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 7964 /* Line In pin: input */ 7965 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 7966 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 7967 /* Line-2 In: Headphone output (output 0 - 0x0c) */ 7968 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 7969 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7970 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 7971 /* CD pin widget for input */ 7972 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 7973 7974 /* FIXME: use matrix-type input source selection */ 7975 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 7976 /* Input mixer2 */ 7977 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7978 /* Input mixer3 */ 7979 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7980 /* ADC2: mute amp left and right */ 7981 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7982 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 7983 /* ADC3: mute amp left and right */ 7984 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7985 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 7986 7987 { } 7988}; 7989 7990static struct hda_verb alc882_adc1_init_verbs[] = { 7991 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 7992 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7993 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 7994 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 7995 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 7996 /* ADC1: mute amp left and right */ 7997 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7998 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 7999 { } 8000}; 8001 8002static struct hda_verb alc882_eapd_verbs[] = { 8003 /* change to EAPD mode */ 8004 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 8005 {0x20, AC_VERB_SET_PROC_COEF, 0x3060}, 8006 { } 8007}; 8008 8009static struct hda_verb alc889_eapd_verbs[] = { 8010 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 8011 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, 8012 { } 8013}; 8014 8015static struct hda_verb alc_hp15_unsol_verbs[] = { 8016 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 8017 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8018 {} 8019}; 8020 8021static struct hda_verb alc885_init_verbs[] = { 8022 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 8023 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8024 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8025 /* Rear mixer */ 8026 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8027 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8028 /* CLFE mixer */ 8029 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8030 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8031 /* Side mixer */ 8032 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8033 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8034 8035 /* Front HP Pin: output 0 (0x0c) */ 8036 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8037 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8038 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 8039 /* Front Pin: output 0 (0x0c) */ 8040 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8041 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8042 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 8043 /* Rear Pin: output 1 (0x0d) */ 8044 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8045 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8046 {0x19, AC_VERB_SET_CONNECT_SEL, 0x01}, 8047 /* CLFE Pin: output 2 (0x0e) */ 8048 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8049 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8050 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, 8051 /* Side Pin: output 3 (0x0f) */ 8052 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8053 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8054 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, 8055 /* Mic (rear) pin: input vref at 80% */ 8056 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 8057 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8058 /* Front Mic pin: input vref at 80% */ 8059 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 8060 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8061 /* Line In pin: input */ 8062 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 8063 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8064 8065 /* Mixer elements: 0x18, , 0x1a, 0x1b */ 8066 /* Input mixer1 */ 8067 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8068 /* Input mixer2 */ 8069 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8070 /* Input mixer3 */ 8071 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8072 /* ADC2: mute amp left and right */ 8073 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8074 /* ADC3: mute amp left and right */ 8075 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8076 8077 { } 8078}; 8079 8080static struct hda_verb alc885_init_input_verbs[] = { 8081 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8082 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 8083 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 8084 { } 8085}; 8086 8087 8088/* Unmute Selector 24h and set the default input to front mic */ 8089static struct hda_verb alc889_init_input_verbs[] = { 8090 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00}, 8091 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8092 { } 8093}; 8094 8095 8096#define alc883_init_verbs alc882_base_init_verbs 8097 8098/* Mac Pro test */ 8099static struct snd_kcontrol_new alc882_macpro_mixer[] = { 8100 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8101 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8102 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT), 8103 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT), 8104 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT), 8105 /* FIXME: this looks suspicious... 8106 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x02, HDA_INPUT), 8107 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x02, HDA_INPUT), 8108 */ 8109 { } /* end */ 8110}; 8111 8112static struct hda_verb alc882_macpro_init_verbs[] = { 8113 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 8114 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8115 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8116 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8117 /* Front Pin: output 0 (0x0c) */ 8118 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8119 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8120 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 8121 /* Front Mic pin: input vref at 80% */ 8122 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 8123 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8124 /* Speaker: output */ 8125 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8126 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8127 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04}, 8128 /* Headphone output (output 0 - 0x0c) */ 8129 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8130 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8131 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00}, 8132 8133 /* FIXME: use matrix-type input source selection */ 8134 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 8135 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 8136 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8137 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8138 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 8139 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8140 /* Input mixer2 */ 8141 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8142 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8143 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 8144 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8145 /* Input mixer3 */ 8146 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8147 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8148 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 8149 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8150 /* ADC1: mute amp left and right */ 8151 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8152 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 8153 /* ADC2: mute amp left and right */ 8154 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8155 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 8156 /* ADC3: mute amp left and right */ 8157 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8158 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 8159 8160 { } 8161}; 8162 8163/* Macbook 5,1 */ 8164static struct hda_verb alc885_mb5_init_verbs[] = { 8165 /* DACs */ 8166 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8167 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8168 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8169 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8170 /* Front mixer */ 8171 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8172 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8173 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8174 /* Surround mixer */ 8175 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8176 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8177 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8178 /* LFE mixer */ 8179 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8180 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8181 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8182 /* HP mixer */ 8183 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8184 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8185 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8186 /* Front Pin (0x0c) */ 8187 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01}, 8188 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8189 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00}, 8190 /* LFE Pin (0x0e) */ 8191 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01}, 8192 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8193 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, 8194 /* HP Pin (0x0f) */ 8195 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8196 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8197 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03}, 8198 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 8199 /* Front Mic pin: input vref at 80% */ 8200 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 8201 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8202 /* Line In pin */ 8203 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 8204 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8205 8206 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0x1)}, 8207 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x7)}, 8208 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x4)}, 8209 { } 8210}; 8211 8212/* Macmini 3,1 */ 8213static struct hda_verb alc885_macmini3_init_verbs[] = { 8214 /* DACs */ 8215 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8216 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8217 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8218 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8219 /* Front mixer */ 8220 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8221 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8222 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8223 /* Surround mixer */ 8224 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8225 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8226 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8227 /* LFE mixer */ 8228 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8229 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8230 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8231 /* HP mixer */ 8232 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8233 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8234 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8235 /* Front Pin (0x0c) */ 8236 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01}, 8237 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8238 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00}, 8239 /* LFE Pin (0x0e) */ 8240 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01}, 8241 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8242 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, 8243 /* HP Pin (0x0f) */ 8244 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8245 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8246 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03}, 8247 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 8248 /* Line In pin */ 8249 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 8250 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8251 8252 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8253 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8254 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 8255 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8256 { } 8257}; 8258 8259 8260static struct hda_verb alc885_mba21_init_verbs[] = { 8261 /*Internal and HP Speaker Mixer*/ 8262 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8263 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8264 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8265 /*Internal Speaker Pin (0x0c)*/ 8266 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) }, 8267 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8268 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00}, 8269 /* HP Pin: output 0 (0x0e) */ 8270 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, 8271 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8272 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 8273 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)}, 8274 /* Line in (is hp when jack connected)*/ 8275 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50}, 8276 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8277 8278 { } 8279 }; 8280 8281 8282/* Macbook Pro rev3 */ 8283static struct hda_verb alc885_mbp3_init_verbs[] = { 8284 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 8285 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8286 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8287 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8288 /* Rear mixer */ 8289 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8290 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8291 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8292 /* HP mixer */ 8293 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8294 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8295 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8296 /* Front Pin: output 0 (0x0c) */ 8297 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8298 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8299 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 8300 /* HP Pin: output 0 (0x0e) */ 8301 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, 8302 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8303 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02}, 8304 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 8305 /* Mic (rear) pin: input vref at 80% */ 8306 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 8307 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8308 /* Front Mic pin: input vref at 80% */ 8309 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 8310 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8311 /* Line In pin: use output 1 when in LineOut mode */ 8312 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 8313 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8314 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, 8315 8316 /* FIXME: use matrix-type input source selection */ 8317 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 8318 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 8319 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8320 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8321 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 8322 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8323 /* Input mixer2 */ 8324 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8325 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8326 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 8327 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8328 /* Input mixer3 */ 8329 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8330 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8331 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 8332 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8333 /* ADC1: mute amp left and right */ 8334 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8335 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 8336 /* ADC2: mute amp left and right */ 8337 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8338 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 8339 /* ADC3: mute amp left and right */ 8340 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8341 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 8342 8343 { } 8344}; 8345 8346/* iMac 9,1 */ 8347static struct hda_verb alc885_imac91_init_verbs[] = { 8348 /* Internal Speaker Pin (0x0c) */ 8349 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) }, 8350 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8351 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00}, 8352 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) }, 8353 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8354 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00}, 8355 /* HP Pin: Rear */ 8356 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8357 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8358 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 8359 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)}, 8360 /* Line in Rear */ 8361 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50}, 8362 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8363 /* Front Mic pin: input vref at 80% */ 8364 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 8365 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8366 /* Rear mixer */ 8367 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8368 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8369 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8370 /* Line-Out mixer: unmute input/output amp left and right (volume = 0) */ 8371 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8372 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8373 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8374 /* 0x24 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */ 8375 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8376 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8377 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 8378 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8379 /* 0x23 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */ 8380 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8381 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8382 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 8383 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8384 /* 0x22 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */ 8385 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8386 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8387 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 8388 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8389 /* 0x07 [Audio Input] wcaps 0x10011b: Stereo Amp-In */ 8390 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8391 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 8392 /* 0x08 [Audio Input] wcaps 0x10011b: Stereo Amp-In */ 8393 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8394 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 8395 /* 0x09 [Audio Input] wcaps 0x10011b: Stereo Amp-In */ 8396 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8397 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 8398 { } 8399}; 8400 8401/* iMac 24 mixer. */ 8402static struct snd_kcontrol_new alc885_imac24_mixer[] = { 8403 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 8404 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT), 8405 { } /* end */ 8406}; 8407 8408/* iMac 24 init verbs. */ 8409static struct hda_verb alc885_imac24_init_verbs[] = { 8410 /* Internal speakers: output 0 (0x0c) */ 8411 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8412 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8413 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00}, 8414 /* Internal speakers: output 0 (0x0c) */ 8415 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8416 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8417 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00}, 8418 /* Headphone: output 0 (0x0c) */ 8419 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8420 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8421 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 8422 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 8423 /* Front Mic: input vref at 80% */ 8424 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 8425 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8426 { } 8427}; 8428 8429/* Toggle speaker-output according to the hp-jack state */ 8430static void alc885_imac24_setup(struct hda_codec *codec) 8431{ 8432 struct alc_spec *spec = codec->spec; 8433 8434 spec->autocfg.hp_pins[0] = 0x14; 8435 spec->autocfg.speaker_pins[0] = 0x18; 8436 spec->autocfg.speaker_pins[1] = 0x1a; 8437} 8438 8439#define alc885_mb5_setup alc885_imac24_setup 8440#define alc885_macmini3_setup alc885_imac24_setup 8441 8442/* Macbook Air 2,1 */ 8443static void alc885_mba21_setup(struct hda_codec *codec) 8444{ 8445 struct alc_spec *spec = codec->spec; 8446 8447 spec->autocfg.hp_pins[0] = 0x14; 8448 spec->autocfg.speaker_pins[0] = 0x18; 8449} 8450 8451 8452 8453static void alc885_mbp3_setup(struct hda_codec *codec) 8454{ 8455 struct alc_spec *spec = codec->spec; 8456 8457 spec->autocfg.hp_pins[0] = 0x15; 8458 spec->autocfg.speaker_pins[0] = 0x14; 8459} 8460 8461static void alc885_imac91_setup(struct hda_codec *codec) 8462{ 8463 struct alc_spec *spec = codec->spec; 8464 8465 spec->autocfg.hp_pins[0] = 0x14; 8466 spec->autocfg.speaker_pins[0] = 0x18; 8467 spec->autocfg.speaker_pins[1] = 0x1a; 8468} 8469 8470static struct hda_verb alc882_targa_verbs[] = { 8471 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8472 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8473 8474 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8475 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8476 8477 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ 8478 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */ 8479 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 8480 8481 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 8482 { } /* end */ 8483}; 8484 8485/* toggle speaker-output according to the hp-jack state */ 8486static void alc882_targa_automute(struct hda_codec *codec) 8487{ 8488 struct alc_spec *spec = codec->spec; 8489 alc_automute_amp(codec); 8490 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA, 8491 spec->jack_present ? 1 : 3); 8492} 8493 8494static void alc882_targa_setup(struct hda_codec *codec) 8495{ 8496 struct alc_spec *spec = codec->spec; 8497 8498 spec->autocfg.hp_pins[0] = 0x14; 8499 spec->autocfg.speaker_pins[0] = 0x1b; 8500} 8501 8502static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res) 8503{ 8504 if ((res >> 26) == ALC880_HP_EVENT) 8505 alc882_targa_automute(codec); 8506} 8507 8508static struct hda_verb alc882_asus_a7j_verbs[] = { 8509 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8510 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8511 8512 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8513 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8514 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8515 8516 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */ 8517 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 8518 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */ 8519 8520 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ 8521 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */ 8522 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 8523 { } /* end */ 8524}; 8525 8526static struct hda_verb alc882_asus_a7m_verbs[] = { 8527 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8528 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8529 8530 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8531 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8532 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8533 8534 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */ 8535 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 8536 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */ 8537 8538 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ 8539 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */ 8540 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 8541 { } /* end */ 8542}; 8543 8544static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted) 8545{ 8546 unsigned int gpiostate, gpiomask, gpiodir; 8547 8548 gpiostate = snd_hda_codec_read(codec, codec->afg, 0, 8549 AC_VERB_GET_GPIO_DATA, 0); 8550 8551 if (!muted) 8552 gpiostate |= (1 << pin); 8553 else 8554 gpiostate &= ~(1 << pin); 8555 8556 gpiomask = snd_hda_codec_read(codec, codec->afg, 0, 8557 AC_VERB_GET_GPIO_MASK, 0); 8558 gpiomask |= (1 << pin); 8559 8560 gpiodir = snd_hda_codec_read(codec, codec->afg, 0, 8561 AC_VERB_GET_GPIO_DIRECTION, 0); 8562 gpiodir |= (1 << pin); 8563 8564 8565 snd_hda_codec_write(codec, codec->afg, 0, 8566 AC_VERB_SET_GPIO_MASK, gpiomask); 8567 snd_hda_codec_write(codec, codec->afg, 0, 8568 AC_VERB_SET_GPIO_DIRECTION, gpiodir); 8569 8570 msleep(1); 8571 8572 snd_hda_codec_write(codec, codec->afg, 0, 8573 AC_VERB_SET_GPIO_DATA, gpiostate); 8574} 8575 8576/* set up GPIO at initialization */ 8577static void alc885_macpro_init_hook(struct hda_codec *codec) 8578{ 8579 alc882_gpio_mute(codec, 0, 0); 8580 alc882_gpio_mute(codec, 1, 0); 8581} 8582 8583/* set up GPIO and update auto-muting at initialization */ 8584static void alc885_imac24_init_hook(struct hda_codec *codec) 8585{ 8586 alc885_macpro_init_hook(codec); 8587 alc_automute_amp(codec); 8588} 8589 8590/* 8591 * generic initialization of ADC, input mixers and output mixers 8592 */ 8593static struct hda_verb alc883_auto_init_verbs[] = { 8594 /* 8595 * Unmute ADC0-2 and set the default input to mic-in 8596 */ 8597 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 8598 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8599 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 8600 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8601 8602 /* 8603 * Set up output mixers (0x0c - 0x0f) 8604 */ 8605 /* set vol=0 to output mixers */ 8606 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8607 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8608 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8609 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8610 /* set up input amps for analog loopback */ 8611 /* Amp Indices: DAC = 0, mixer = 1 */ 8612 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8613 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8614 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8615 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8616 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8617 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8618 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8619 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8620 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8621 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8622 8623 /* FIXME: use matrix-type input source selection */ 8624 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 8625 /* Input mixer2 */ 8626 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8627 /* Input mixer3 */ 8628 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8629 { } 8630}; 8631 8632/* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */ 8633static struct hda_verb alc889A_mb31_ch2_init[] = { 8634 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */ 8635 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */ 8636 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */ 8637 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */ 8638 { } /* end */ 8639}; 8640 8641/* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */ 8642static struct hda_verb alc889A_mb31_ch4_init[] = { 8643 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */ 8644 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */ 8645 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */ 8646 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */ 8647 { } /* end */ 8648}; 8649 8650/* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */ 8651static struct hda_verb alc889A_mb31_ch5_init[] = { 8652 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */ 8653 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */ 8654 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */ 8655 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */ 8656 { } /* end */ 8657}; 8658 8659/* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */ 8660static struct hda_verb alc889A_mb31_ch6_init[] = { 8661 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */ 8662 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */ 8663 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */ 8664 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */ 8665 { } /* end */ 8666}; 8667 8668static struct hda_channel_mode alc889A_mb31_6ch_modes[4] = { 8669 { 2, alc889A_mb31_ch2_init }, 8670 { 4, alc889A_mb31_ch4_init }, 8671 { 5, alc889A_mb31_ch5_init }, 8672 { 6, alc889A_mb31_ch6_init }, 8673}; 8674 8675static struct hda_verb alc883_medion_eapd_verbs[] = { 8676 /* eanable EAPD on medion laptop */ 8677 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 8678 {0x20, AC_VERB_SET_PROC_COEF, 0x3070}, 8679 { } 8680}; 8681 8682#define alc883_base_mixer alc882_base_mixer 8683 8684static struct snd_kcontrol_new alc883_mitac_mixer[] = { 8685 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8686 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8687 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 8688 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 8689 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 8690 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 8691 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 8692 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8693 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8694 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8695 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8696 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 8697 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8698 { } /* end */ 8699}; 8700 8701static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = { 8702 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8703 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), 8704 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 8705 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 8706 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8707 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8708 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8709 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8710 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 8711 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8712 { } /* end */ 8713}; 8714 8715static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = { 8716 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8717 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), 8718 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 8719 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 8720 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8721 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8722 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8723 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8724 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 8725 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8726 { } /* end */ 8727}; 8728 8729static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = { 8730 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8731 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8732 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 8733 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 8734 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 8735 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8736 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8737 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8738 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8739 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8740 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8741 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 8742 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8743 { } /* end */ 8744}; 8745 8746static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = { 8747 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8748 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8749 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 8750 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 8751 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 8752 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 8753 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 8754 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 8755 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 8756 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 8757 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 8758 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8759 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8760 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8761 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8762 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8763 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8764 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 8765 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8766 { } /* end */ 8767}; 8768 8769static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = { 8770 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8771 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8772 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 8773 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 8774 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, 8775 HDA_OUTPUT), 8776 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 8777 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 8778 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 8779 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 8780 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 8781 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 8782 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8783 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8784 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8785 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT), 8786 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8787 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8788 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT), 8789 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8790 { } /* end */ 8791}; 8792 8793static struct snd_kcontrol_new alc885_8ch_intel_mixer[] = { 8794 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8795 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8796 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 8797 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 8798 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, 8799 HDA_OUTPUT), 8800 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 8801 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 8802 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 8803 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 8804 HDA_BIND_MUTE("Speaker Playback Switch", 0x0f, 2, HDA_INPUT), 8805 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 8806 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8807 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8808 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT), 8809 HDA_CODEC_VOLUME("Mic Boost", 0x1b, 0, HDA_INPUT), 8810 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT), 8811 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8812 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT), 8813 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8814 { } /* end */ 8815}; 8816 8817static struct snd_kcontrol_new alc883_fivestack_mixer[] = { 8818 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8819 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8820 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 8821 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 8822 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 8823 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 8824 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 8825 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 8826 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 8827 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 8828 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 8829 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8830 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8831 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8832 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8833 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8834 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8835 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 8836 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8837 { } /* end */ 8838}; 8839 8840static struct snd_kcontrol_new alc883_targa_mixer[] = { 8841 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8842 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8843 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 8844 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 8845 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 8846 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 8847 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 8848 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 8849 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 8850 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 8851 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 8852 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 8853 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8854 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8855 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8856 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8857 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8858 { } /* end */ 8859}; 8860 8861static struct snd_kcontrol_new alc883_targa_2ch_mixer[] = { 8862 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8863 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8864 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 8865 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 8866 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 8867 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 8868 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8869 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8870 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8871 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8872 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 8873 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8874 { } /* end */ 8875}; 8876 8877static struct snd_kcontrol_new alc883_targa_8ch_mixer[] = { 8878 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 8879 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 8880 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8881 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 8882 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8883 { } /* end */ 8884}; 8885 8886static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = { 8887 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8888 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8889 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 8890 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 8891 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 8892 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8893 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8894 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8895 { } /* end */ 8896}; 8897 8898static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = { 8899 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8900 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT), 8901 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 8902 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 8903 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 8904 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8905 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8906 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8907 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8908 { } /* end */ 8909}; 8910 8911static struct snd_kcontrol_new alc883_medion_md2_mixer[] = { 8912 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8913 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 8914 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT), 8915 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 8916 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 8917 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8918 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8919 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8920 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8921 { } /* end */ 8922}; 8923 8924static struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = { 8925 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8926 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8927 HDA_CODEC_MUTE("Speaker Playback Switch", 0x15, 0x0, HDA_OUTPUT), 8928 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT), 8929 HDA_CODEC_VOLUME("Line Playback Volume", 0x08, 0x0, HDA_INPUT), 8930 HDA_CODEC_MUTE("Line Playback Switch", 0x08, 0x0, HDA_INPUT), 8931 { } /* end */ 8932}; 8933 8934static struct hda_verb alc883_medion_wim2160_verbs[] = { 8935 /* Unmute front mixer */ 8936 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8937 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8938 8939 /* Set speaker pin to front mixer */ 8940 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 8941 8942 /* Init headphone pin */ 8943 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8944 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8945 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00}, 8946 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 8947 8948 { } /* end */ 8949}; 8950 8951/* toggle speaker-output according to the hp-jack state */ 8952static void alc883_medion_wim2160_setup(struct hda_codec *codec) 8953{ 8954 struct alc_spec *spec = codec->spec; 8955 8956 spec->autocfg.hp_pins[0] = 0x1a; 8957 spec->autocfg.speaker_pins[0] = 0x15; 8958} 8959 8960static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = { 8961 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8962 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8963 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 8964 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8965 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8966 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8967 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8968 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8969 { } /* end */ 8970}; 8971 8972static struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = { 8973 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8974 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 8975 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8976 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8977 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 8978 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 8979 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8980 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8981 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8982 { } /* end */ 8983}; 8984 8985static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = { 8986 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8987 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8988 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT), 8989 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT), 8990 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 8991 0x0d, 1, 0x0, HDA_OUTPUT), 8992 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT), 8993 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT), 8994 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT), 8995 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 8996 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 8997 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 8998 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 8999 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 9000 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 9001 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9002 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 9003 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9004 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 9005 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 9006 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 9007 { } /* end */ 9008}; 9009 9010static struct snd_kcontrol_new alc889A_mb31_mixer[] = { 9011 /* Output mixers */ 9012 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 9013 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT), 9014 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT), 9015 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT), 9016 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00, 9017 HDA_OUTPUT), 9018 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT), 9019 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT), 9020 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT), 9021 /* Output switches */ 9022 HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT), 9023 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT), 9024 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT), 9025 /* Boost mixers */ 9026 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT), 9027 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT), 9028 /* Input mixers */ 9029 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT), 9030 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT), 9031 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 9032 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 9033 { } /* end */ 9034}; 9035 9036static struct snd_kcontrol_new alc883_vaiott_mixer[] = { 9037 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9038 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 9039 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 9040 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 9041 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT), 9042 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 9043 { } /* end */ 9044}; 9045 9046static struct hda_bind_ctls alc883_bind_cap_vol = { 9047 .ops = &snd_hda_bind_vol, 9048 .values = { 9049 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT), 9050 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT), 9051 0 9052 }, 9053}; 9054 9055static struct hda_bind_ctls alc883_bind_cap_switch = { 9056 .ops = &snd_hda_bind_sw, 9057 .values = { 9058 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT), 9059 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT), 9060 0 9061 }, 9062}; 9063 9064static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = { 9065 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9066 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 9067 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 9068 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 9069 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 9070 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9071 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 9072 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9073 { } /* end */ 9074}; 9075 9076static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = { 9077 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol), 9078 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch), 9079 { 9080 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 9081 /* .name = "Capture Source", */ 9082 .name = "Input Source", 9083 .count = 1, 9084 .info = alc_mux_enum_info, 9085 .get = alc_mux_enum_get, 9086 .put = alc_mux_enum_put, 9087 }, 9088 { } /* end */ 9089}; 9090 9091static struct snd_kcontrol_new alc883_chmode_mixer[] = { 9092 { 9093 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 9094 .name = "Channel Mode", 9095 .info = alc_ch_mode_info, 9096 .get = alc_ch_mode_get, 9097 .put = alc_ch_mode_put, 9098 }, 9099 { } /* end */ 9100}; 9101 9102/* toggle speaker-output according to the hp-jack state */ 9103static void alc883_mitac_setup(struct hda_codec *codec) 9104{ 9105 struct alc_spec *spec = codec->spec; 9106 9107 spec->autocfg.hp_pins[0] = 0x15; 9108 spec->autocfg.speaker_pins[0] = 0x14; 9109 spec->autocfg.speaker_pins[1] = 0x17; 9110} 9111 9112/* auto-toggle front mic */ 9113/* 9114static void alc883_mitac_mic_automute(struct hda_codec *codec) 9115{ 9116 unsigned char bits = snd_hda_jack_detect(codec, 0x18) ? HDA_AMP_MUTE : 0; 9117 9118 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits); 9119} 9120*/ 9121 9122static struct hda_verb alc883_mitac_verbs[] = { 9123 /* HP */ 9124 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9125 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9126 /* Subwoofer */ 9127 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02}, 9128 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9129 9130 /* enable unsolicited event */ 9131 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9132 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */ 9133 9134 { } /* end */ 9135}; 9136 9137static struct hda_verb alc883_clevo_m540r_verbs[] = { 9138 /* HP */ 9139 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9140 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9141 /* Int speaker */ 9142 /*{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},*/ 9143 9144 /* enable unsolicited event */ 9145 /* 9146 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9147 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, 9148 */ 9149 9150 { } /* end */ 9151}; 9152 9153static struct hda_verb alc883_clevo_m720_verbs[] = { 9154 /* HP */ 9155 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9156 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9157 /* Int speaker */ 9158 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01}, 9159 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9160 9161 /* enable unsolicited event */ 9162 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9163 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, 9164 9165 { } /* end */ 9166}; 9167 9168static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = { 9169 /* HP */ 9170 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 9171 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9172 /* Subwoofer */ 9173 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 9174 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9175 9176 /* enable unsolicited event */ 9177 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9178 9179 { } /* end */ 9180}; 9181 9182static struct hda_verb alc883_targa_verbs[] = { 9183 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9184 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9185 9186 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9187 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9188 9189/* Connect Line-Out side jack (SPDIF) to Side */ 9190 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9191 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9192 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, 9193/* Connect Mic jack to CLFE */ 9194 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9195 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9196 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, 9197/* Connect Line-in jack to Surround */ 9198 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9199 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9200 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, 9201/* Connect HP out jack to Front */ 9202 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9203 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9204 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 9205 9206 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9207 9208 { } /* end */ 9209}; 9210 9211static struct hda_verb alc883_lenovo_101e_verbs[] = { 9212 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9213 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN}, 9214 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN}, 9215 { } /* end */ 9216}; 9217 9218static struct hda_verb alc883_lenovo_nb0763_verbs[] = { 9219 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9220 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9221 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9222 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9223 { } /* end */ 9224}; 9225 9226static struct hda_verb alc888_lenovo_ms7195_verbs[] = { 9227 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9228 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9229 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9230 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN}, 9231 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9232 { } /* end */ 9233}; 9234 9235static struct hda_verb alc883_haier_w66_verbs[] = { 9236 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9237 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9238 9239 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9240 9241 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 9242 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9243 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9244 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9245 { } /* end */ 9246}; 9247 9248static struct hda_verb alc888_lenovo_sky_verbs[] = { 9249 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9250 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9251 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9252 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9253 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9254 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9255 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00}, 9256 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9257 { } /* end */ 9258}; 9259 9260static struct hda_verb alc888_6st_dell_verbs[] = { 9261 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9262 { } 9263}; 9264 9265static struct hda_verb alc883_vaiott_verbs[] = { 9266 /* HP */ 9267 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9268 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9269 9270 /* enable unsolicited event */ 9271 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9272 9273 { } /* end */ 9274}; 9275 9276static void alc888_3st_hp_setup(struct hda_codec *codec) 9277{ 9278 struct alc_spec *spec = codec->spec; 9279 9280 spec->autocfg.hp_pins[0] = 0x1b; 9281 spec->autocfg.speaker_pins[0] = 0x14; 9282 spec->autocfg.speaker_pins[1] = 0x16; 9283 spec->autocfg.speaker_pins[2] = 0x18; 9284} 9285 9286static struct hda_verb alc888_3st_hp_verbs[] = { 9287 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */ 9288 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */ 9289 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */ 9290 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9291 { } /* end */ 9292}; 9293 9294/* 9295 * 2ch mode 9296 */ 9297static struct hda_verb alc888_3st_hp_2ch_init[] = { 9298 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 9299 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 9300 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 9301 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 9302 { } /* end */ 9303}; 9304 9305/* 9306 * 4ch mode 9307 */ 9308static struct hda_verb alc888_3st_hp_4ch_init[] = { 9309 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 9310 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 9311 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 9312 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 9313 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 }, 9314 { } /* end */ 9315}; 9316 9317/* 9318 * 6ch mode 9319 */ 9320static struct hda_verb alc888_3st_hp_6ch_init[] = { 9321 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 9322 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 9323 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, 9324 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 9325 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 9326 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 }, 9327 { } /* end */ 9328}; 9329 9330static struct hda_channel_mode alc888_3st_hp_modes[3] = { 9331 { 2, alc888_3st_hp_2ch_init }, 9332 { 4, alc888_3st_hp_4ch_init }, 9333 { 6, alc888_3st_hp_6ch_init }, 9334}; 9335 9336/* toggle front-jack and RCA according to the hp-jack state */ 9337static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec) 9338{ 9339 unsigned int present = snd_hda_jack_detect(codec, 0x1b); 9340 9341 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 9342 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 9343 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 9344 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 9345} 9346 9347/* toggle RCA according to the front-jack state */ 9348static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec) 9349{ 9350 unsigned int present = snd_hda_jack_detect(codec, 0x14); 9351 9352 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 9353 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 9354} 9355 9356static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec, 9357 unsigned int res) 9358{ 9359 if ((res >> 26) == ALC880_HP_EVENT) 9360 alc888_lenovo_ms7195_front_automute(codec); 9361 if ((res >> 26) == ALC880_FRONT_EVENT) 9362 alc888_lenovo_ms7195_rca_automute(codec); 9363} 9364 9365static struct hda_verb alc883_medion_md2_verbs[] = { 9366 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9367 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9368 9369 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9370 9371 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9372 { } /* end */ 9373}; 9374 9375/* toggle speaker-output according to the hp-jack state */ 9376static void alc883_medion_md2_setup(struct hda_codec *codec) 9377{ 9378 struct alc_spec *spec = codec->spec; 9379 9380 spec->autocfg.hp_pins[0] = 0x14; 9381 spec->autocfg.speaker_pins[0] = 0x15; 9382} 9383 9384/* toggle speaker-output according to the hp-jack state */ 9385#define alc883_targa_init_hook alc882_targa_init_hook 9386#define alc883_targa_unsol_event alc882_targa_unsol_event 9387 9388static void alc883_clevo_m720_mic_automute(struct hda_codec *codec) 9389{ 9390 unsigned int present; 9391 9392 present = snd_hda_jack_detect(codec, 0x18); 9393 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, 9394 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 9395} 9396 9397static void alc883_clevo_m720_setup(struct hda_codec *codec) 9398{ 9399 struct alc_spec *spec = codec->spec; 9400 9401 spec->autocfg.hp_pins[0] = 0x15; 9402 spec->autocfg.speaker_pins[0] = 0x14; 9403} 9404 9405static void alc883_clevo_m720_init_hook(struct hda_codec *codec) 9406{ 9407 alc_automute_amp(codec); 9408 alc883_clevo_m720_mic_automute(codec); 9409} 9410 9411static void alc883_clevo_m720_unsol_event(struct hda_codec *codec, 9412 unsigned int res) 9413{ 9414 switch (res >> 26) { 9415 case ALC880_MIC_EVENT: 9416 alc883_clevo_m720_mic_automute(codec); 9417 break; 9418 default: 9419 alc_automute_amp_unsol_event(codec, res); 9420 break; 9421 } 9422} 9423 9424/* toggle speaker-output according to the hp-jack state */ 9425static void alc883_2ch_fujitsu_pi2515_setup(struct hda_codec *codec) 9426{ 9427 struct alc_spec *spec = codec->spec; 9428 9429 spec->autocfg.hp_pins[0] = 0x14; 9430 spec->autocfg.speaker_pins[0] = 0x15; 9431} 9432 9433static void alc883_haier_w66_setup(struct hda_codec *codec) 9434{ 9435 struct alc_spec *spec = codec->spec; 9436 9437 spec->autocfg.hp_pins[0] = 0x1b; 9438 spec->autocfg.speaker_pins[0] = 0x14; 9439} 9440 9441static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec) 9442{ 9443 int bits = snd_hda_jack_detect(codec, 0x14) ? HDA_AMP_MUTE : 0; 9444 9445 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 9446 HDA_AMP_MUTE, bits); 9447} 9448 9449static void alc883_lenovo_101e_all_automute(struct hda_codec *codec) 9450{ 9451 int bits = snd_hda_jack_detect(codec, 0x1b) ? HDA_AMP_MUTE : 0; 9452 9453 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 9454 HDA_AMP_MUTE, bits); 9455 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 9456 HDA_AMP_MUTE, bits); 9457} 9458 9459static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec, 9460 unsigned int res) 9461{ 9462 if ((res >> 26) == ALC880_HP_EVENT) 9463 alc883_lenovo_101e_all_automute(codec); 9464 if ((res >> 26) == ALC880_FRONT_EVENT) 9465 alc883_lenovo_101e_ispeaker_automute(codec); 9466} 9467 9468/* toggle speaker-output according to the hp-jack state */ 9469static void alc883_acer_aspire_setup(struct hda_codec *codec) 9470{ 9471 struct alc_spec *spec = codec->spec; 9472 9473 spec->autocfg.hp_pins[0] = 0x14; 9474 spec->autocfg.speaker_pins[0] = 0x15; 9475 spec->autocfg.speaker_pins[1] = 0x16; 9476} 9477 9478static struct hda_verb alc883_acer_eapd_verbs[] = { 9479 /* HP Pin: output 0 (0x0c) */ 9480 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9481 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9482 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 9483 /* Front Pin: output 0 (0x0c) */ 9484 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9485 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9486 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9487 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, 9488 /* eanable EAPD on medion laptop */ 9489 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 9490 {0x20, AC_VERB_SET_PROC_COEF, 0x3050}, 9491 /* enable unsolicited event */ 9492 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9493 { } 9494}; 9495 9496static struct hda_verb alc888_acer_aspire_7730G_verbs[] = { 9497 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9498 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02}, 9499 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9500 { } /* end */ 9501}; 9502 9503static void alc888_6st_dell_setup(struct hda_codec *codec) 9504{ 9505 struct alc_spec *spec = codec->spec; 9506 9507 spec->autocfg.hp_pins[0] = 0x1b; 9508 spec->autocfg.speaker_pins[0] = 0x14; 9509 spec->autocfg.speaker_pins[1] = 0x15; 9510 spec->autocfg.speaker_pins[2] = 0x16; 9511 spec->autocfg.speaker_pins[3] = 0x17; 9512} 9513 9514static void alc888_lenovo_sky_setup(struct hda_codec *codec) 9515{ 9516 struct alc_spec *spec = codec->spec; 9517 9518 spec->autocfg.hp_pins[0] = 0x1b; 9519 spec->autocfg.speaker_pins[0] = 0x14; 9520 spec->autocfg.speaker_pins[1] = 0x15; 9521 spec->autocfg.speaker_pins[2] = 0x16; 9522 spec->autocfg.speaker_pins[3] = 0x17; 9523 spec->autocfg.speaker_pins[4] = 0x1a; 9524} 9525 9526static void alc883_vaiott_setup(struct hda_codec *codec) 9527{ 9528 struct alc_spec *spec = codec->spec; 9529 9530 spec->autocfg.hp_pins[0] = 0x15; 9531 spec->autocfg.speaker_pins[0] = 0x14; 9532 spec->autocfg.speaker_pins[1] = 0x17; 9533} 9534 9535static struct hda_verb alc888_asus_m90v_verbs[] = { 9536 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 9537 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 9538 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9539 /* enable unsolicited event */ 9540 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9541 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, 9542 { } /* end */ 9543}; 9544 9545static void alc883_mode2_setup(struct hda_codec *codec) 9546{ 9547 struct alc_spec *spec = codec->spec; 9548 9549 spec->autocfg.hp_pins[0] = 0x1b; 9550 spec->autocfg.speaker_pins[0] = 0x14; 9551 spec->autocfg.speaker_pins[1] = 0x15; 9552 spec->autocfg.speaker_pins[2] = 0x16; 9553 spec->ext_mic.pin = 0x18; 9554 spec->int_mic.pin = 0x19; 9555 spec->ext_mic.mux_idx = 0; 9556 spec->int_mic.mux_idx = 1; 9557 spec->auto_mic = 1; 9558} 9559 9560static struct hda_verb alc888_asus_eee1601_verbs[] = { 9561 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9562 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9563 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 9564 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9565 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 9566 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b}, 9567 {0x20, AC_VERB_SET_PROC_COEF, 0x0838}, 9568 /* enable unsolicited event */ 9569 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9570 { } /* end */ 9571}; 9572 9573static void alc883_eee1601_inithook(struct hda_codec *codec) 9574{ 9575 struct alc_spec *spec = codec->spec; 9576 9577 spec->autocfg.hp_pins[0] = 0x14; 9578 spec->autocfg.speaker_pins[0] = 0x1b; 9579 alc_automute_pin(codec); 9580} 9581 9582static struct hda_verb alc889A_mb31_verbs[] = { 9583 /* Init rear pin (used as headphone output) */ 9584 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */ 9585 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */ 9586 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9587 /* Init line pin (used as output in 4ch and 6ch mode) */ 9588 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */ 9589 /* Init line 2 pin (used as headphone out by default) */ 9590 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */ 9591 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */ 9592 { } /* end */ 9593}; 9594 9595/* Mute speakers according to the headphone jack state */ 9596static void alc889A_mb31_automute(struct hda_codec *codec) 9597{ 9598 unsigned int present; 9599 9600 /* Mute only in 2ch or 4ch mode */ 9601 if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0) 9602 == 0x00) { 9603 present = snd_hda_jack_detect(codec, 0x15); 9604 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 9605 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 9606 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0, 9607 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 9608 } 9609} 9610 9611static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res) 9612{ 9613 if ((res >> 26) == ALC880_HP_EVENT) 9614 alc889A_mb31_automute(codec); 9615} 9616 9617 9618#ifdef CONFIG_SND_HDA_POWER_SAVE 9619#define alc882_loopbacks alc880_loopbacks 9620#endif 9621 9622/* pcm configuration: identical with ALC880 */ 9623#define alc882_pcm_analog_playback alc880_pcm_analog_playback 9624#define alc882_pcm_analog_capture alc880_pcm_analog_capture 9625#define alc882_pcm_digital_playback alc880_pcm_digital_playback 9626#define alc882_pcm_digital_capture alc880_pcm_digital_capture 9627 9628static hda_nid_t alc883_slave_dig_outs[] = { 9629 ALC1200_DIGOUT_NID, 0, 9630}; 9631 9632static hda_nid_t alc1200_slave_dig_outs[] = { 9633 ALC883_DIGOUT_NID, 0, 9634}; 9635 9636/* 9637 * configuration and preset 9638 */ 9639static const char *alc882_models[ALC882_MODEL_LAST] = { 9640 [ALC882_3ST_DIG] = "3stack-dig", 9641 [ALC882_6ST_DIG] = "6stack-dig", 9642 [ALC882_ARIMA] = "arima", 9643 [ALC882_W2JC] = "w2jc", 9644 [ALC882_TARGA] = "targa", 9645 [ALC882_ASUS_A7J] = "asus-a7j", 9646 [ALC882_ASUS_A7M] = "asus-a7m", 9647 [ALC885_MACPRO] = "macpro", 9648 [ALC885_MB5] = "mb5", 9649 [ALC885_MACMINI3] = "macmini3", 9650 [ALC885_MBA21] = "mba21", 9651 [ALC885_MBP3] = "mbp3", 9652 [ALC885_IMAC24] = "imac24", 9653 [ALC885_IMAC91] = "imac91", 9654 [ALC883_3ST_2ch_DIG] = "3stack-2ch-dig", 9655 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig", 9656 [ALC883_3ST_6ch] = "3stack-6ch", 9657 [ALC883_6ST_DIG] = "alc883-6stack-dig", 9658 [ALC883_TARGA_DIG] = "targa-dig", 9659 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig", 9660 [ALC883_TARGA_8ch_DIG] = "targa-8ch-dig", 9661 [ALC883_ACER] = "acer", 9662 [ALC883_ACER_ASPIRE] = "acer-aspire", 9663 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g", 9664 [ALC888_ACER_ASPIRE_6530G] = "acer-aspire-6530g", 9665 [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g", 9666 [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g", 9667 [ALC883_MEDION] = "medion", 9668 [ALC883_MEDION_MD2] = "medion-md2", 9669 [ALC883_MEDION_WIM2160] = "medion-wim2160", 9670 [ALC883_LAPTOP_EAPD] = "laptop-eapd", 9671 [ALC883_LENOVO_101E_2ch] = "lenovo-101e", 9672 [ALC883_LENOVO_NB0763] = "lenovo-nb0763", 9673 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig", 9674 [ALC888_LENOVO_SKY] = "lenovo-sky", 9675 [ALC883_HAIER_W66] = "haier-w66", 9676 [ALC888_3ST_HP] = "3stack-hp", 9677 [ALC888_6ST_DELL] = "6stack-dell", 9678 [ALC883_MITAC] = "mitac", 9679 [ALC883_CLEVO_M540R] = "clevo-m540r", 9680 [ALC883_CLEVO_M720] = "clevo-m720", 9681 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515", 9682 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530", 9683 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel", 9684 [ALC889A_INTEL] = "intel-alc889a", 9685 [ALC889_INTEL] = "intel-x58", 9686 [ALC1200_ASUS_P5Q] = "asus-p5q", 9687 [ALC889A_MB31] = "mb31", 9688 [ALC883_SONY_VAIO_TT] = "sony-vaio-tt", 9689 [ALC882_AUTO] = "auto", 9690}; 9691 9692static struct snd_pci_quirk alc882_cfg_tbl[] = { 9693 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG), 9694 9695 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE), 9696 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE), 9697 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE), 9698 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE), 9699 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE), 9700 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE), 9701 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G", 9702 ALC888_ACER_ASPIRE_4930G), 9703 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G", 9704 ALC888_ACER_ASPIRE_4930G), 9705 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G", 9706 ALC888_ACER_ASPIRE_8930G), 9707 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G", 9708 ALC888_ACER_ASPIRE_8930G), 9709 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC882_AUTO), 9710 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC882_AUTO), 9711 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G", 9712 ALC888_ACER_ASPIRE_6530G), 9713 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G", 9714 ALC888_ACER_ASPIRE_6530G), 9715 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G", 9716 ALC888_ACER_ASPIRE_7730G), 9717 /* default Acer -- disabled as it causes more problems. 9718 * model=auto should work fine now 9719 */ 9720 /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */ 9721 9722 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL), 9723 9724 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG), 9725 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP), 9726 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP), 9727 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG), 9728 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP), 9729 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP), 9730 9731 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J), 9732 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J), 9733 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M), 9734 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V), 9735 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC), 9736 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG), 9737 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG), 9738 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG), 9739 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG), 9740 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q), 9741 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601), 9742 9743 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT), 9744 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG), 9745 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG), 9746 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC), 9747 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC), 9748 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD), 9749 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL), 9750 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch), 9751 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG), 9752 9753 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG), 9754 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG), 9755 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG), 9756 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */ 9757 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC882_AUTO), 9758 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG), 9759 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG), 9760 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG), 9761 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG), 9762 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG), 9763 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG), 9764 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG), 9765 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG), 9766 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG), 9767 SND_PCI_QUIRK(0x1462, 0x42cd, "MSI", ALC883_TARGA_DIG), 9768 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG), 9769 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG), 9770 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG), 9771 SND_PCI_QUIRK(0x1462, 0x4570, "MSI Wind Top AE2220", ALC883_TARGA_DIG), 9772 SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG), 9773 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG), 9774 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG), 9775 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG), 9776 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG), 9777 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG), 9778 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG), 9779 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG), 9780 SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG), 9781 SND_PCI_QUIRK(0x1462, 0x7437, "MSI NetOn AP1900", ALC883_TARGA_DIG), 9782 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG), 9783 SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG), 9784 9785 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG), 9786 SND_PCI_QUIRK(0x1558, 0x0571, "Clevo laptop M570U", ALC883_3ST_6ch_DIG), 9787 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720), 9788 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720), 9789 SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R), 9790 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD), 9791 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch), 9792 /* SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), */ 9793 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION), 9794 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx", 9795 ALC883_FUJITSU_PI2515), 9796 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx", 9797 ALC888_FUJITSU_XA3530), 9798 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch), 9799 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763), 9800 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763), 9801 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763), 9802 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY), 9803 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2), 9804 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG), 9805 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG), 9806 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66), 9807 9808 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL), 9809 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL), 9810 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC), 9811 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL), 9812 SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL), 9813 SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL), 9814 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC882_6ST_DIG), 9815 9816 {} 9817}; 9818 9819/* codec SSID table for Intel Mac */ 9820static struct snd_pci_quirk alc882_ssid_cfg_tbl[] = { 9821 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3), 9822 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3), 9823 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3), 9824 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_MACPRO), 9825 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24), 9826 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24), 9827 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3), 9828 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889A_MB31), 9829 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_ASUS_A7M), 9830 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC885_MBP3), 9831 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC885_MBA21), 9832 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31), 9833 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3), 9834 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24), 9835 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC885_IMAC91), 9836 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5), 9837 SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC885_MB5), 9838 /* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2, 9839 * so apparently no perfect solution yet 9840 */ 9841 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5), 9842 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5), 9843 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC885_MACMINI3), 9844 {} /* terminator */ 9845}; 9846 9847static struct alc_config_preset alc882_presets[] = { 9848 [ALC882_3ST_DIG] = { 9849 .mixers = { alc882_base_mixer }, 9850 .init_verbs = { alc882_base_init_verbs, 9851 alc882_adc1_init_verbs }, 9852 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 9853 .dac_nids = alc882_dac_nids, 9854 .dig_out_nid = ALC882_DIGOUT_NID, 9855 .dig_in_nid = ALC882_DIGIN_NID, 9856 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes), 9857 .channel_mode = alc882_ch_modes, 9858 .need_dac_fix = 1, 9859 .input_mux = &alc882_capture_source, 9860 }, 9861 [ALC882_6ST_DIG] = { 9862 .mixers = { alc882_base_mixer, alc882_chmode_mixer }, 9863 .init_verbs = { alc882_base_init_verbs, 9864 alc882_adc1_init_verbs }, 9865 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 9866 .dac_nids = alc882_dac_nids, 9867 .dig_out_nid = ALC882_DIGOUT_NID, 9868 .dig_in_nid = ALC882_DIGIN_NID, 9869 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes), 9870 .channel_mode = alc882_sixstack_modes, 9871 .input_mux = &alc882_capture_source, 9872 }, 9873 [ALC882_ARIMA] = { 9874 .mixers = { alc882_base_mixer, alc882_chmode_mixer }, 9875 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs, 9876 alc882_eapd_verbs }, 9877 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 9878 .dac_nids = alc882_dac_nids, 9879 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes), 9880 .channel_mode = alc882_sixstack_modes, 9881 .input_mux = &alc882_capture_source, 9882 }, 9883 [ALC882_W2JC] = { 9884 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer }, 9885 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs, 9886 alc882_eapd_verbs, alc880_gpio1_init_verbs }, 9887 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 9888 .dac_nids = alc882_dac_nids, 9889 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), 9890 .channel_mode = alc880_threestack_modes, 9891 .need_dac_fix = 1, 9892 .input_mux = &alc882_capture_source, 9893 .dig_out_nid = ALC882_DIGOUT_NID, 9894 }, 9895 [ALC885_MBA21] = { 9896 .mixers = { alc885_mba21_mixer }, 9897 .init_verbs = { alc885_mba21_init_verbs, alc880_gpio1_init_verbs }, 9898 .num_dacs = 2, 9899 .dac_nids = alc882_dac_nids, 9900 .channel_mode = alc885_mba21_ch_modes, 9901 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes), 9902 .input_mux = &alc882_capture_source, 9903 .unsol_event = alc_automute_amp_unsol_event, 9904 .setup = alc885_mba21_setup, 9905 .init_hook = alc_automute_amp, 9906 }, 9907 [ALC885_MBP3] = { 9908 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer }, 9909 .init_verbs = { alc885_mbp3_init_verbs, 9910 alc880_gpio1_init_verbs }, 9911 .num_dacs = 2, 9912 .dac_nids = alc882_dac_nids, 9913 .hp_nid = 0x04, 9914 .channel_mode = alc885_mbp_4ch_modes, 9915 .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes), 9916 .input_mux = &alc882_capture_source, 9917 .dig_out_nid = ALC882_DIGOUT_NID, 9918 .dig_in_nid = ALC882_DIGIN_NID, 9919 .unsol_event = alc_automute_amp_unsol_event, 9920 .setup = alc885_mbp3_setup, 9921 .init_hook = alc_automute_amp, 9922 }, 9923 [ALC885_MB5] = { 9924 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer }, 9925 .init_verbs = { alc885_mb5_init_verbs, 9926 alc880_gpio1_init_verbs }, 9927 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 9928 .dac_nids = alc882_dac_nids, 9929 .channel_mode = alc885_mb5_6ch_modes, 9930 .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes), 9931 .input_mux = &mb5_capture_source, 9932 .dig_out_nid = ALC882_DIGOUT_NID, 9933 .dig_in_nid = ALC882_DIGIN_NID, 9934 .unsol_event = alc_automute_amp_unsol_event, 9935 .setup = alc885_mb5_setup, 9936 .init_hook = alc_automute_amp, 9937 }, 9938 [ALC885_MACMINI3] = { 9939 .mixers = { alc885_macmini3_mixer, alc882_chmode_mixer }, 9940 .init_verbs = { alc885_macmini3_init_verbs, 9941 alc880_gpio1_init_verbs }, 9942 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 9943 .dac_nids = alc882_dac_nids, 9944 .channel_mode = alc885_macmini3_6ch_modes, 9945 .num_channel_mode = ARRAY_SIZE(alc885_macmini3_6ch_modes), 9946 .input_mux = &macmini3_capture_source, 9947 .dig_out_nid = ALC882_DIGOUT_NID, 9948 .dig_in_nid = ALC882_DIGIN_NID, 9949 .unsol_event = alc_automute_amp_unsol_event, 9950 .setup = alc885_macmini3_setup, 9951 .init_hook = alc_automute_amp, 9952 }, 9953 [ALC885_MACPRO] = { 9954 .mixers = { alc882_macpro_mixer }, 9955 .init_verbs = { alc882_macpro_init_verbs }, 9956 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 9957 .dac_nids = alc882_dac_nids, 9958 .dig_out_nid = ALC882_DIGOUT_NID, 9959 .dig_in_nid = ALC882_DIGIN_NID, 9960 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes), 9961 .channel_mode = alc882_ch_modes, 9962 .input_mux = &alc882_capture_source, 9963 .init_hook = alc885_macpro_init_hook, 9964 }, 9965 [ALC885_IMAC24] = { 9966 .mixers = { alc885_imac24_mixer }, 9967 .init_verbs = { alc885_imac24_init_verbs }, 9968 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 9969 .dac_nids = alc882_dac_nids, 9970 .dig_out_nid = ALC882_DIGOUT_NID, 9971 .dig_in_nid = ALC882_DIGIN_NID, 9972 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes), 9973 .channel_mode = alc882_ch_modes, 9974 .input_mux = &alc882_capture_source, 9975 .unsol_event = alc_automute_amp_unsol_event, 9976 .setup = alc885_imac24_setup, 9977 .init_hook = alc885_imac24_init_hook, 9978 }, 9979 [ALC885_IMAC91] = { 9980 .mixers = {alc885_imac91_mixer}, 9981 .init_verbs = { alc885_imac91_init_verbs, 9982 alc880_gpio1_init_verbs }, 9983 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 9984 .dac_nids = alc882_dac_nids, 9985 .channel_mode = alc885_mba21_ch_modes, 9986 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes), 9987 .input_mux = &alc889A_imac91_capture_source, 9988 .dig_out_nid = ALC882_DIGOUT_NID, 9989 .dig_in_nid = ALC882_DIGIN_NID, 9990 .unsol_event = alc_automute_amp_unsol_event, 9991 .setup = alc885_imac91_setup, 9992 .init_hook = alc_automute_amp, 9993 }, 9994 [ALC882_TARGA] = { 9995 .mixers = { alc882_targa_mixer, alc882_chmode_mixer }, 9996 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs, 9997 alc880_gpio3_init_verbs, alc882_targa_verbs}, 9998 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 9999 .dac_nids = alc882_dac_nids, 10000 .dig_out_nid = ALC882_DIGOUT_NID, 10001 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids), 10002 .adc_nids = alc882_adc_nids, 10003 .capsrc_nids = alc882_capsrc_nids, 10004 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes), 10005 .channel_mode = alc882_3ST_6ch_modes, 10006 .need_dac_fix = 1, 10007 .input_mux = &alc882_capture_source, 10008 .unsol_event = alc882_targa_unsol_event, 10009 .setup = alc882_targa_setup, 10010 .init_hook = alc882_targa_automute, 10011 }, 10012 [ALC882_ASUS_A7J] = { 10013 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer }, 10014 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs, 10015 alc882_asus_a7j_verbs}, 10016 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 10017 .dac_nids = alc882_dac_nids, 10018 .dig_out_nid = ALC882_DIGOUT_NID, 10019 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids), 10020 .adc_nids = alc882_adc_nids, 10021 .capsrc_nids = alc882_capsrc_nids, 10022 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes), 10023 .channel_mode = alc882_3ST_6ch_modes, 10024 .need_dac_fix = 1, 10025 .input_mux = &alc882_capture_source, 10026 }, 10027 [ALC882_ASUS_A7M] = { 10028 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer }, 10029 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs, 10030 alc882_eapd_verbs, alc880_gpio1_init_verbs, 10031 alc882_asus_a7m_verbs }, 10032 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 10033 .dac_nids = alc882_dac_nids, 10034 .dig_out_nid = ALC882_DIGOUT_NID, 10035 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), 10036 .channel_mode = alc880_threestack_modes, 10037 .need_dac_fix = 1, 10038 .input_mux = &alc882_capture_source, 10039 }, 10040 [ALC883_3ST_2ch_DIG] = { 10041 .mixers = { alc883_3ST_2ch_mixer }, 10042 .init_verbs = { alc883_init_verbs }, 10043 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10044 .dac_nids = alc883_dac_nids, 10045 .dig_out_nid = ALC883_DIGOUT_NID, 10046 .dig_in_nid = ALC883_DIGIN_NID, 10047 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10048 .channel_mode = alc883_3ST_2ch_modes, 10049 .input_mux = &alc883_capture_source, 10050 }, 10051 [ALC883_3ST_6ch_DIG] = { 10052 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, 10053 .init_verbs = { alc883_init_verbs }, 10054 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10055 .dac_nids = alc883_dac_nids, 10056 .dig_out_nid = ALC883_DIGOUT_NID, 10057 .dig_in_nid = ALC883_DIGIN_NID, 10058 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 10059 .channel_mode = alc883_3ST_6ch_modes, 10060 .need_dac_fix = 1, 10061 .input_mux = &alc883_capture_source, 10062 }, 10063 [ALC883_3ST_6ch] = { 10064 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, 10065 .init_verbs = { alc883_init_verbs }, 10066 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10067 .dac_nids = alc883_dac_nids, 10068 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 10069 .channel_mode = alc883_3ST_6ch_modes, 10070 .need_dac_fix = 1, 10071 .input_mux = &alc883_capture_source, 10072 }, 10073 [ALC883_3ST_6ch_INTEL] = { 10074 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer }, 10075 .init_verbs = { alc883_init_verbs }, 10076 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10077 .dac_nids = alc883_dac_nids, 10078 .dig_out_nid = ALC883_DIGOUT_NID, 10079 .dig_in_nid = ALC883_DIGIN_NID, 10080 .slave_dig_outs = alc883_slave_dig_outs, 10081 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes), 10082 .channel_mode = alc883_3ST_6ch_intel_modes, 10083 .need_dac_fix = 1, 10084 .input_mux = &alc883_3stack_6ch_intel, 10085 }, 10086 [ALC889A_INTEL] = { 10087 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer }, 10088 .init_verbs = { alc885_init_verbs, alc885_init_input_verbs, 10089 alc_hp15_unsol_verbs }, 10090 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10091 .dac_nids = alc883_dac_nids, 10092 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids), 10093 .adc_nids = alc889_adc_nids, 10094 .dig_out_nid = ALC883_DIGOUT_NID, 10095 .dig_in_nid = ALC883_DIGIN_NID, 10096 .slave_dig_outs = alc883_slave_dig_outs, 10097 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes), 10098 .channel_mode = alc889_8ch_intel_modes, 10099 .capsrc_nids = alc889_capsrc_nids, 10100 .input_mux = &alc889_capture_source, 10101 .setup = alc889_automute_setup, 10102 .init_hook = alc_automute_amp, 10103 .unsol_event = alc_automute_amp_unsol_event, 10104 .need_dac_fix = 1, 10105 }, 10106 [ALC889_INTEL] = { 10107 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer }, 10108 .init_verbs = { alc885_init_verbs, alc889_init_input_verbs, 10109 alc889_eapd_verbs, alc_hp15_unsol_verbs}, 10110 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10111 .dac_nids = alc883_dac_nids, 10112 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids), 10113 .adc_nids = alc889_adc_nids, 10114 .dig_out_nid = ALC883_DIGOUT_NID, 10115 .dig_in_nid = ALC883_DIGIN_NID, 10116 .slave_dig_outs = alc883_slave_dig_outs, 10117 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes), 10118 .channel_mode = alc889_8ch_intel_modes, 10119 .capsrc_nids = alc889_capsrc_nids, 10120 .input_mux = &alc889_capture_source, 10121 .setup = alc889_automute_setup, 10122 .init_hook = alc889_intel_init_hook, 10123 .unsol_event = alc_automute_amp_unsol_event, 10124 .need_dac_fix = 1, 10125 }, 10126 [ALC883_6ST_DIG] = { 10127 .mixers = { alc883_base_mixer, alc883_chmode_mixer }, 10128 .init_verbs = { alc883_init_verbs }, 10129 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10130 .dac_nids = alc883_dac_nids, 10131 .dig_out_nid = ALC883_DIGOUT_NID, 10132 .dig_in_nid = ALC883_DIGIN_NID, 10133 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), 10134 .channel_mode = alc883_sixstack_modes, 10135 .input_mux = &alc883_capture_source, 10136 }, 10137 [ALC883_TARGA_DIG] = { 10138 .mixers = { alc883_targa_mixer, alc883_chmode_mixer }, 10139 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs, 10140 alc883_targa_verbs}, 10141 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10142 .dac_nids = alc883_dac_nids, 10143 .dig_out_nid = ALC883_DIGOUT_NID, 10144 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 10145 .channel_mode = alc883_3ST_6ch_modes, 10146 .need_dac_fix = 1, 10147 .input_mux = &alc883_capture_source, 10148 .unsol_event = alc883_targa_unsol_event, 10149 .setup = alc882_targa_setup, 10150 .init_hook = alc882_targa_automute, 10151 }, 10152 [ALC883_TARGA_2ch_DIG] = { 10153 .mixers = { alc883_targa_2ch_mixer}, 10154 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs, 10155 alc883_targa_verbs}, 10156 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10157 .dac_nids = alc883_dac_nids, 10158 .adc_nids = alc883_adc_nids_alt, 10159 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt), 10160 .capsrc_nids = alc883_capsrc_nids, 10161 .dig_out_nid = ALC883_DIGOUT_NID, 10162 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10163 .channel_mode = alc883_3ST_2ch_modes, 10164 .input_mux = &alc883_capture_source, 10165 .unsol_event = alc883_targa_unsol_event, 10166 .setup = alc882_targa_setup, 10167 .init_hook = alc882_targa_automute, 10168 }, 10169 [ALC883_TARGA_8ch_DIG] = { 10170 .mixers = { alc883_targa_mixer, alc883_targa_8ch_mixer, 10171 alc883_chmode_mixer }, 10172 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs, 10173 alc883_targa_verbs }, 10174 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10175 .dac_nids = alc883_dac_nids, 10176 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev), 10177 .adc_nids = alc883_adc_nids_rev, 10178 .capsrc_nids = alc883_capsrc_nids_rev, 10179 .dig_out_nid = ALC883_DIGOUT_NID, 10180 .dig_in_nid = ALC883_DIGIN_NID, 10181 .num_channel_mode = ARRAY_SIZE(alc883_4ST_8ch_modes), 10182 .channel_mode = alc883_4ST_8ch_modes, 10183 .need_dac_fix = 1, 10184 .input_mux = &alc883_capture_source, 10185 .unsol_event = alc883_targa_unsol_event, 10186 .setup = alc882_targa_setup, 10187 .init_hook = alc882_targa_automute, 10188 }, 10189 [ALC883_ACER] = { 10190 .mixers = { alc883_base_mixer }, 10191 /* On TravelMate laptops, GPIO 0 enables the internal speaker 10192 * and the headphone jack. Turn this on and rely on the 10193 * standard mute methods whenever the user wants to turn 10194 * these outputs off. 10195 */ 10196 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs }, 10197 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10198 .dac_nids = alc883_dac_nids, 10199 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10200 .channel_mode = alc883_3ST_2ch_modes, 10201 .input_mux = &alc883_capture_source, 10202 }, 10203 [ALC883_ACER_ASPIRE] = { 10204 .mixers = { alc883_acer_aspire_mixer }, 10205 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs }, 10206 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10207 .dac_nids = alc883_dac_nids, 10208 .dig_out_nid = ALC883_DIGOUT_NID, 10209 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10210 .channel_mode = alc883_3ST_2ch_modes, 10211 .input_mux = &alc883_capture_source, 10212 .unsol_event = alc_automute_amp_unsol_event, 10213 .setup = alc883_acer_aspire_setup, 10214 .init_hook = alc_automute_amp, 10215 }, 10216 [ALC888_ACER_ASPIRE_4930G] = { 10217 .mixers = { alc888_base_mixer, 10218 alc883_chmode_mixer }, 10219 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs, 10220 alc888_acer_aspire_4930g_verbs }, 10221 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10222 .dac_nids = alc883_dac_nids, 10223 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev), 10224 .adc_nids = alc883_adc_nids_rev, 10225 .capsrc_nids = alc883_capsrc_nids_rev, 10226 .dig_out_nid = ALC883_DIGOUT_NID, 10227 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 10228 .channel_mode = alc883_3ST_6ch_modes, 10229 .need_dac_fix = 1, 10230 .const_channel_count = 6, 10231 .num_mux_defs = 10232 ARRAY_SIZE(alc888_2_capture_sources), 10233 .input_mux = alc888_2_capture_sources, 10234 .unsol_event = alc_automute_amp_unsol_event, 10235 .setup = alc888_acer_aspire_4930g_setup, 10236 .init_hook = alc_automute_amp, 10237 }, 10238 [ALC888_ACER_ASPIRE_6530G] = { 10239 .mixers = { alc888_acer_aspire_6530_mixer }, 10240 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs, 10241 alc888_acer_aspire_6530g_verbs }, 10242 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10243 .dac_nids = alc883_dac_nids, 10244 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev), 10245 .adc_nids = alc883_adc_nids_rev, 10246 .capsrc_nids = alc883_capsrc_nids_rev, 10247 .dig_out_nid = ALC883_DIGOUT_NID, 10248 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10249 .channel_mode = alc883_3ST_2ch_modes, 10250 .num_mux_defs = 10251 ARRAY_SIZE(alc888_2_capture_sources), 10252 .input_mux = alc888_acer_aspire_6530_sources, 10253 .unsol_event = alc_automute_amp_unsol_event, 10254 .setup = alc888_acer_aspire_6530g_setup, 10255 .init_hook = alc_automute_amp, 10256 }, 10257 [ALC888_ACER_ASPIRE_8930G] = { 10258 .mixers = { alc889_acer_aspire_8930g_mixer, 10259 alc883_chmode_mixer }, 10260 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs, 10261 alc889_acer_aspire_8930g_verbs, 10262 alc889_eapd_verbs}, 10263 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10264 .dac_nids = alc883_dac_nids, 10265 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids), 10266 .adc_nids = alc889_adc_nids, 10267 .capsrc_nids = alc889_capsrc_nids, 10268 .dig_out_nid = ALC883_DIGOUT_NID, 10269 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 10270 .channel_mode = alc883_3ST_6ch_modes, 10271 .need_dac_fix = 1, 10272 .const_channel_count = 6, 10273 .num_mux_defs = 10274 ARRAY_SIZE(alc889_capture_sources), 10275 .input_mux = alc889_capture_sources, 10276 .unsol_event = alc_automute_amp_unsol_event, 10277 .setup = alc889_acer_aspire_8930g_setup, 10278 .init_hook = alc_automute_amp, 10279#ifdef CONFIG_SND_HDA_POWER_SAVE 10280 .power_hook = alc_power_eapd, 10281#endif 10282 }, 10283 [ALC888_ACER_ASPIRE_7730G] = { 10284 .mixers = { alc883_3ST_6ch_mixer, 10285 alc883_chmode_mixer }, 10286 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs, 10287 alc888_acer_aspire_7730G_verbs }, 10288 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10289 .dac_nids = alc883_dac_nids, 10290 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev), 10291 .adc_nids = alc883_adc_nids_rev, 10292 .capsrc_nids = alc883_capsrc_nids_rev, 10293 .dig_out_nid = ALC883_DIGOUT_NID, 10294 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 10295 .channel_mode = alc883_3ST_6ch_modes, 10296 .need_dac_fix = 1, 10297 .const_channel_count = 6, 10298 .input_mux = &alc883_capture_source, 10299 .unsol_event = alc_automute_amp_unsol_event, 10300 .setup = alc888_acer_aspire_6530g_setup, 10301 .init_hook = alc_automute_amp, 10302 }, 10303 [ALC883_MEDION] = { 10304 .mixers = { alc883_fivestack_mixer, 10305 alc883_chmode_mixer }, 10306 .init_verbs = { alc883_init_verbs, 10307 alc883_medion_eapd_verbs }, 10308 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10309 .dac_nids = alc883_dac_nids, 10310 .adc_nids = alc883_adc_nids_alt, 10311 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt), 10312 .capsrc_nids = alc883_capsrc_nids, 10313 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), 10314 .channel_mode = alc883_sixstack_modes, 10315 .input_mux = &alc883_capture_source, 10316 }, 10317 [ALC883_MEDION_MD2] = { 10318 .mixers = { alc883_medion_md2_mixer}, 10319 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs}, 10320 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10321 .dac_nids = alc883_dac_nids, 10322 .dig_out_nid = ALC883_DIGOUT_NID, 10323 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10324 .channel_mode = alc883_3ST_2ch_modes, 10325 .input_mux = &alc883_capture_source, 10326 .unsol_event = alc_automute_amp_unsol_event, 10327 .setup = alc883_medion_md2_setup, 10328 .init_hook = alc_automute_amp, 10329 }, 10330 [ALC883_MEDION_WIM2160] = { 10331 .mixers = { alc883_medion_wim2160_mixer }, 10332 .init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs }, 10333 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10334 .dac_nids = alc883_dac_nids, 10335 .dig_out_nid = ALC883_DIGOUT_NID, 10336 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 10337 .adc_nids = alc883_adc_nids, 10338 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10339 .channel_mode = alc883_3ST_2ch_modes, 10340 .input_mux = &alc883_capture_source, 10341 .unsol_event = alc_automute_amp_unsol_event, 10342 .setup = alc883_medion_wim2160_setup, 10343 .init_hook = alc_automute_amp, 10344 }, 10345 [ALC883_LAPTOP_EAPD] = { 10346 .mixers = { alc883_base_mixer }, 10347 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs }, 10348 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10349 .dac_nids = alc883_dac_nids, 10350 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10351 .channel_mode = alc883_3ST_2ch_modes, 10352 .input_mux = &alc883_capture_source, 10353 }, 10354 [ALC883_CLEVO_M540R] = { 10355 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, 10356 .init_verbs = { alc883_init_verbs, alc883_clevo_m540r_verbs }, 10357 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10358 .dac_nids = alc883_dac_nids, 10359 .dig_out_nid = ALC883_DIGOUT_NID, 10360 .dig_in_nid = ALC883_DIGIN_NID, 10361 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_clevo_modes), 10362 .channel_mode = alc883_3ST_6ch_clevo_modes, 10363 .need_dac_fix = 1, 10364 .input_mux = &alc883_capture_source, 10365 /* This machine has the hardware HP auto-muting, thus 10366 * we need no software mute via unsol event 10367 */ 10368 }, 10369 [ALC883_CLEVO_M720] = { 10370 .mixers = { alc883_clevo_m720_mixer }, 10371 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs }, 10372 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10373 .dac_nids = alc883_dac_nids, 10374 .dig_out_nid = ALC883_DIGOUT_NID, 10375 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10376 .channel_mode = alc883_3ST_2ch_modes, 10377 .input_mux = &alc883_capture_source, 10378 .unsol_event = alc883_clevo_m720_unsol_event, 10379 .setup = alc883_clevo_m720_setup, 10380 .init_hook = alc883_clevo_m720_init_hook, 10381 }, 10382 [ALC883_LENOVO_101E_2ch] = { 10383 .mixers = { alc883_lenovo_101e_2ch_mixer}, 10384 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs}, 10385 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10386 .dac_nids = alc883_dac_nids, 10387 .adc_nids = alc883_adc_nids_alt, 10388 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt), 10389 .capsrc_nids = alc883_capsrc_nids, 10390 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10391 .channel_mode = alc883_3ST_2ch_modes, 10392 .input_mux = &alc883_lenovo_101e_capture_source, 10393 .unsol_event = alc883_lenovo_101e_unsol_event, 10394 .init_hook = alc883_lenovo_101e_all_automute, 10395 }, 10396 [ALC883_LENOVO_NB0763] = { 10397 .mixers = { alc883_lenovo_nb0763_mixer }, 10398 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs}, 10399 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10400 .dac_nids = alc883_dac_nids, 10401 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10402 .channel_mode = alc883_3ST_2ch_modes, 10403 .need_dac_fix = 1, 10404 .input_mux = &alc883_lenovo_nb0763_capture_source, 10405 .unsol_event = alc_automute_amp_unsol_event, 10406 .setup = alc883_medion_md2_setup, 10407 .init_hook = alc_automute_amp, 10408 }, 10409 [ALC888_LENOVO_MS7195_DIG] = { 10410 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, 10411 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs}, 10412 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10413 .dac_nids = alc883_dac_nids, 10414 .dig_out_nid = ALC883_DIGOUT_NID, 10415 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 10416 .channel_mode = alc883_3ST_6ch_modes, 10417 .need_dac_fix = 1, 10418 .input_mux = &alc883_capture_source, 10419 .unsol_event = alc883_lenovo_ms7195_unsol_event, 10420 .init_hook = alc888_lenovo_ms7195_front_automute, 10421 }, 10422 [ALC883_HAIER_W66] = { 10423 .mixers = { alc883_targa_2ch_mixer}, 10424 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs}, 10425 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10426 .dac_nids = alc883_dac_nids, 10427 .dig_out_nid = ALC883_DIGOUT_NID, 10428 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10429 .channel_mode = alc883_3ST_2ch_modes, 10430 .input_mux = &alc883_capture_source, 10431 .unsol_event = alc_automute_amp_unsol_event, 10432 .setup = alc883_haier_w66_setup, 10433 .init_hook = alc_automute_amp, 10434 }, 10435 [ALC888_3ST_HP] = { 10436 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, 10437 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs }, 10438 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10439 .dac_nids = alc883_dac_nids, 10440 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes), 10441 .channel_mode = alc888_3st_hp_modes, 10442 .need_dac_fix = 1, 10443 .input_mux = &alc883_capture_source, 10444 .unsol_event = alc_automute_amp_unsol_event, 10445 .setup = alc888_3st_hp_setup, 10446 .init_hook = alc_automute_amp, 10447 }, 10448 [ALC888_6ST_DELL] = { 10449 .mixers = { alc883_base_mixer, alc883_chmode_mixer }, 10450 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs }, 10451 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10452 .dac_nids = alc883_dac_nids, 10453 .dig_out_nid = ALC883_DIGOUT_NID, 10454 .dig_in_nid = ALC883_DIGIN_NID, 10455 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), 10456 .channel_mode = alc883_sixstack_modes, 10457 .input_mux = &alc883_capture_source, 10458 .unsol_event = alc_automute_amp_unsol_event, 10459 .setup = alc888_6st_dell_setup, 10460 .init_hook = alc_automute_amp, 10461 }, 10462 [ALC883_MITAC] = { 10463 .mixers = { alc883_mitac_mixer }, 10464 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs }, 10465 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10466 .dac_nids = alc883_dac_nids, 10467 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10468 .channel_mode = alc883_3ST_2ch_modes, 10469 .input_mux = &alc883_capture_source, 10470 .unsol_event = alc_automute_amp_unsol_event, 10471 .setup = alc883_mitac_setup, 10472 .init_hook = alc_automute_amp, 10473 }, 10474 [ALC883_FUJITSU_PI2515] = { 10475 .mixers = { alc883_2ch_fujitsu_pi2515_mixer }, 10476 .init_verbs = { alc883_init_verbs, 10477 alc883_2ch_fujitsu_pi2515_verbs}, 10478 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10479 .dac_nids = alc883_dac_nids, 10480 .dig_out_nid = ALC883_DIGOUT_NID, 10481 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10482 .channel_mode = alc883_3ST_2ch_modes, 10483 .input_mux = &alc883_fujitsu_pi2515_capture_source, 10484 .unsol_event = alc_automute_amp_unsol_event, 10485 .setup = alc883_2ch_fujitsu_pi2515_setup, 10486 .init_hook = alc_automute_amp, 10487 }, 10488 [ALC888_FUJITSU_XA3530] = { 10489 .mixers = { alc888_base_mixer, alc883_chmode_mixer }, 10490 .init_verbs = { alc883_init_verbs, 10491 alc888_fujitsu_xa3530_verbs }, 10492 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10493 .dac_nids = alc883_dac_nids, 10494 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev), 10495 .adc_nids = alc883_adc_nids_rev, 10496 .capsrc_nids = alc883_capsrc_nids_rev, 10497 .dig_out_nid = ALC883_DIGOUT_NID, 10498 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes), 10499 .channel_mode = alc888_4ST_8ch_intel_modes, 10500 .num_mux_defs = 10501 ARRAY_SIZE(alc888_2_capture_sources), 10502 .input_mux = alc888_2_capture_sources, 10503 .unsol_event = alc_automute_amp_unsol_event, 10504 .setup = alc888_fujitsu_xa3530_setup, 10505 .init_hook = alc_automute_amp, 10506 }, 10507 [ALC888_LENOVO_SKY] = { 10508 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer }, 10509 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs}, 10510 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10511 .dac_nids = alc883_dac_nids, 10512 .dig_out_nid = ALC883_DIGOUT_NID, 10513 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), 10514 .channel_mode = alc883_sixstack_modes, 10515 .need_dac_fix = 1, 10516 .input_mux = &alc883_lenovo_sky_capture_source, 10517 .unsol_event = alc_automute_amp_unsol_event, 10518 .setup = alc888_lenovo_sky_setup, 10519 .init_hook = alc_automute_amp, 10520 }, 10521 [ALC888_ASUS_M90V] = { 10522 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, 10523 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs }, 10524 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10525 .dac_nids = alc883_dac_nids, 10526 .dig_out_nid = ALC883_DIGOUT_NID, 10527 .dig_in_nid = ALC883_DIGIN_NID, 10528 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 10529 .channel_mode = alc883_3ST_6ch_modes, 10530 .need_dac_fix = 1, 10531 .input_mux = &alc883_fujitsu_pi2515_capture_source, 10532 .unsol_event = alc_sku_unsol_event, 10533 .setup = alc883_mode2_setup, 10534 .init_hook = alc_inithook, 10535 }, 10536 [ALC888_ASUS_EEE1601] = { 10537 .mixers = { alc883_asus_eee1601_mixer }, 10538 .cap_mixer = alc883_asus_eee1601_cap_mixer, 10539 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs }, 10540 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10541 .dac_nids = alc883_dac_nids, 10542 .dig_out_nid = ALC883_DIGOUT_NID, 10543 .dig_in_nid = ALC883_DIGIN_NID, 10544 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10545 .channel_mode = alc883_3ST_2ch_modes, 10546 .need_dac_fix = 1, 10547 .input_mux = &alc883_asus_eee1601_capture_source, 10548 .unsol_event = alc_sku_unsol_event, 10549 .init_hook = alc883_eee1601_inithook, 10550 }, 10551 [ALC1200_ASUS_P5Q] = { 10552 .mixers = { alc883_base_mixer, alc883_chmode_mixer }, 10553 .init_verbs = { alc883_init_verbs }, 10554 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10555 .dac_nids = alc883_dac_nids, 10556 .dig_out_nid = ALC1200_DIGOUT_NID, 10557 .dig_in_nid = ALC883_DIGIN_NID, 10558 .slave_dig_outs = alc1200_slave_dig_outs, 10559 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), 10560 .channel_mode = alc883_sixstack_modes, 10561 .input_mux = &alc883_capture_source, 10562 }, 10563 [ALC889A_MB31] = { 10564 .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer}, 10565 .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs, 10566 alc880_gpio1_init_verbs }, 10567 .adc_nids = alc883_adc_nids, 10568 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 10569 .capsrc_nids = alc883_capsrc_nids, 10570 .dac_nids = alc883_dac_nids, 10571 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10572 .channel_mode = alc889A_mb31_6ch_modes, 10573 .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes), 10574 .input_mux = &alc889A_mb31_capture_source, 10575 .dig_out_nid = ALC883_DIGOUT_NID, 10576 .unsol_event = alc889A_mb31_unsol_event, 10577 .init_hook = alc889A_mb31_automute, 10578 }, 10579 [ALC883_SONY_VAIO_TT] = { 10580 .mixers = { alc883_vaiott_mixer }, 10581 .init_verbs = { alc883_init_verbs, alc883_vaiott_verbs }, 10582 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10583 .dac_nids = alc883_dac_nids, 10584 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10585 .channel_mode = alc883_3ST_2ch_modes, 10586 .input_mux = &alc883_capture_source, 10587 .unsol_event = alc_automute_amp_unsol_event, 10588 .setup = alc883_vaiott_setup, 10589 .init_hook = alc_automute_amp, 10590 }, 10591}; 10592 10593 10594/* 10595 * Pin config fixes 10596 */ 10597enum { 10598 PINFIX_ABIT_AW9D_MAX, 10599 PINFIX_PB_M5210, 10600}; 10601 10602static const struct alc_fixup alc882_fixups[] = { 10603 [PINFIX_ABIT_AW9D_MAX] = { 10604 .pins = (const struct alc_pincfg[]) { 10605 { 0x15, 0x01080104 }, /* side */ 10606 { 0x16, 0x01011012 }, /* rear */ 10607 { 0x17, 0x01016011 }, /* clfe */ 10608 { } 10609 } 10610 }, 10611 [PINFIX_PB_M5210] = { 10612 .verbs = (const struct hda_verb[]) { 10613 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 }, 10614 {} 10615 } 10616 }, 10617}; 10618 10619static struct snd_pci_quirk alc882_fixup_tbl[] = { 10620 SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", PINFIX_PB_M5210), 10621 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX), 10622 {} 10623}; 10624 10625/* 10626 * BIOS auto configuration 10627 */ 10628static int alc882_auto_create_input_ctls(struct hda_codec *codec, 10629 const struct auto_pin_cfg *cfg) 10630{ 10631 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x23, 0x22); 10632} 10633 10634static void alc882_auto_set_output_and_unmute(struct hda_codec *codec, 10635 hda_nid_t nid, int pin_type, 10636 hda_nid_t dac) 10637{ 10638 int idx; 10639 10640 /* set as output */ 10641 alc_set_pin_output(codec, nid, pin_type); 10642 10643 if (dac == 0x25) 10644 idx = 4; 10645 else if (dac >= 0x02 && dac <= 0x05) 10646 idx = dac - 2; 10647 else 10648 return; 10649 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx); 10650} 10651 10652static void alc882_auto_init_multi_out(struct hda_codec *codec) 10653{ 10654 struct alc_spec *spec = codec->spec; 10655 int i; 10656 10657 for (i = 0; i <= HDA_SIDE; i++) { 10658 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 10659 int pin_type = get_pin_type(spec->autocfg.line_out_type); 10660 if (nid) 10661 alc882_auto_set_output_and_unmute(codec, nid, pin_type, 10662 spec->multiout.dac_nids[i]); 10663 } 10664} 10665 10666static void alc882_auto_init_hp_out(struct hda_codec *codec) 10667{ 10668 struct alc_spec *spec = codec->spec; 10669 hda_nid_t pin, dac; 10670 int i; 10671 10672 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) { 10673 pin = spec->autocfg.hp_pins[i]; 10674 if (!pin) 10675 break; 10676 dac = spec->multiout.hp_nid; 10677 if (!dac) 10678 dac = spec->multiout.dac_nids[0]; /* to front */ 10679 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, dac); 10680 } 10681 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) { 10682 pin = spec->autocfg.speaker_pins[i]; 10683 if (!pin) 10684 break; 10685 dac = spec->multiout.extra_out_nid[0]; 10686 if (!dac) 10687 dac = spec->multiout.dac_nids[0]; /* to front */ 10688 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac); 10689 } 10690} 10691 10692static void alc882_auto_init_analog_input(struct hda_codec *codec) 10693{ 10694 struct alc_spec *spec = codec->spec; 10695 struct auto_pin_cfg *cfg = &spec->autocfg; 10696 int i; 10697 10698 for (i = 0; i < cfg->num_inputs; i++) { 10699 hda_nid_t nid = cfg->inputs[i].pin; 10700 alc_set_input_pin(codec, nid, cfg->inputs[i].type); 10701 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP) 10702 snd_hda_codec_write(codec, nid, 0, 10703 AC_VERB_SET_AMP_GAIN_MUTE, 10704 AMP_OUT_MUTE); 10705 } 10706} 10707 10708static void alc882_auto_init_input_src(struct hda_codec *codec) 10709{ 10710 struct alc_spec *spec = codec->spec; 10711 int c; 10712 10713 for (c = 0; c < spec->num_adc_nids; c++) { 10714 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS]; 10715 hda_nid_t nid = spec->capsrc_nids[c]; 10716 unsigned int mux_idx; 10717 const struct hda_input_mux *imux; 10718 int conns, mute, idx, item; 10719 10720 conns = snd_hda_get_connections(codec, nid, conn_list, 10721 ARRAY_SIZE(conn_list)); 10722 if (conns < 0) 10723 continue; 10724 mux_idx = c >= spec->num_mux_defs ? 0 : c; 10725 imux = &spec->input_mux[mux_idx]; 10726 if (!imux->num_items && mux_idx > 0) 10727 imux = &spec->input_mux[0]; 10728 for (idx = 0; idx < conns; idx++) { 10729 /* if the current connection is the selected one, 10730 * unmute it as default - otherwise mute it 10731 */ 10732 mute = AMP_IN_MUTE(idx); 10733 for (item = 0; item < imux->num_items; item++) { 10734 if (imux->items[item].index == idx) { 10735 if (spec->cur_mux[c] == item) 10736 mute = AMP_IN_UNMUTE(idx); 10737 break; 10738 } 10739 } 10740 /* check if we have a selector or mixer 10741 * we could check for the widget type instead, but 10742 * just check for Amp-In presence (in case of mixer 10743 * without amp-in there is something wrong, this 10744 * function shouldn't be used or capsrc nid is wrong) 10745 */ 10746 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) 10747 snd_hda_codec_write(codec, nid, 0, 10748 AC_VERB_SET_AMP_GAIN_MUTE, 10749 mute); 10750 else if (mute != AMP_IN_MUTE(idx)) 10751 snd_hda_codec_write(codec, nid, 0, 10752 AC_VERB_SET_CONNECT_SEL, 10753 idx); 10754 } 10755 } 10756} 10757 10758/* add mic boosts if needed */ 10759static int alc_auto_add_mic_boost(struct hda_codec *codec) 10760{ 10761 struct alc_spec *spec = codec->spec; 10762 struct auto_pin_cfg *cfg = &spec->autocfg; 10763 int i, err; 10764 hda_nid_t nid; 10765 10766 for (i = 0; i < cfg->num_inputs; i++) { 10767 if (cfg->inputs[i].type > AUTO_PIN_MIC) 10768 break; 10769 nid = cfg->inputs[i].pin; 10770 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) { 10771 char label[32]; 10772 snprintf(label, sizeof(label), "%s Boost", 10773 hda_get_autocfg_input_label(codec, cfg, i)); 10774 err = add_control(spec, ALC_CTL_WIDGET_VOL, label, 0, 10775 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT)); 10776 if (err < 0) 10777 return err; 10778 } 10779 } 10780 return 0; 10781} 10782 10783/* almost identical with ALC880 parser... */ 10784static int alc882_parse_auto_config(struct hda_codec *codec) 10785{ 10786 struct alc_spec *spec = codec->spec; 10787 static hda_nid_t alc882_ignore[] = { 0x1d, 0 }; 10788 int err; 10789 10790 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 10791 alc882_ignore); 10792 if (err < 0) 10793 return err; 10794 if (!spec->autocfg.line_outs) 10795 return 0; /* can't find valid BIOS pin config */ 10796 10797 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); 10798 if (err < 0) 10799 return err; 10800 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg); 10801 if (err < 0) 10802 return err; 10803 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0], 10804 "Headphone"); 10805 if (err < 0) 10806 return err; 10807 err = alc880_auto_create_extra_out(spec, 10808 spec->autocfg.speaker_pins[0], 10809 "Speaker"); 10810 if (err < 0) 10811 return err; 10812 err = alc882_auto_create_input_ctls(codec, &spec->autocfg); 10813 if (err < 0) 10814 return err; 10815 10816 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 10817 10818 alc_auto_parse_digital(codec); 10819 10820 if (spec->kctls.list) 10821 add_mixer(spec, spec->kctls.list); 10822 10823 add_verb(spec, alc883_auto_init_verbs); 10824 /* if ADC 0x07 is available, initialize it, too */ 10825 if (get_wcaps_type(get_wcaps(codec, 0x07)) == AC_WID_AUD_IN) 10826 add_verb(spec, alc882_adc1_init_verbs); 10827 10828 spec->num_mux_defs = 1; 10829 spec->input_mux = &spec->private_imux[0]; 10830 10831 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); 10832 10833 err = alc_auto_add_mic_boost(codec); 10834 if (err < 0) 10835 return err; 10836 10837 return 1; /* config found */ 10838} 10839 10840/* additional initialization for auto-configuration model */ 10841static void alc882_auto_init(struct hda_codec *codec) 10842{ 10843 struct alc_spec *spec = codec->spec; 10844 alc882_auto_init_multi_out(codec); 10845 alc882_auto_init_hp_out(codec); 10846 alc882_auto_init_analog_input(codec); 10847 alc882_auto_init_input_src(codec); 10848 alc_auto_init_digital(codec); 10849 if (spec->unsol_event) 10850 alc_inithook(codec); 10851} 10852 10853static int patch_alc882(struct hda_codec *codec) 10854{ 10855 struct alc_spec *spec; 10856 int err, board_config; 10857 10858 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 10859 if (spec == NULL) 10860 return -ENOMEM; 10861 10862 codec->spec = spec; 10863 10864 alc_auto_parse_customize_define(codec); 10865 10866 switch (codec->vendor_id) { 10867 case 0x10ec0882: 10868 case 0x10ec0885: 10869 break; 10870 default: 10871 /* ALC883 and variants */ 10872 alc_fix_pll_init(codec, 0x20, 0x0a, 10); 10873 break; 10874 } 10875 10876 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST, 10877 alc882_models, 10878 alc882_cfg_tbl); 10879 10880 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) 10881 board_config = snd_hda_check_board_codec_sid_config(codec, 10882 ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl); 10883 10884 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) { 10885 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 10886 codec->chip_name); 10887 board_config = ALC882_AUTO; 10888 } 10889 10890 if (board_config == ALC882_AUTO) 10891 alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups, 1); 10892 10893 if (board_config == ALC882_AUTO) { 10894 /* automatic parse from the BIOS config */ 10895 err = alc882_parse_auto_config(codec); 10896 if (err < 0) { 10897 alc_free(codec); 10898 return err; 10899 } else if (!err) { 10900 printk(KERN_INFO 10901 "hda_codec: Cannot set up configuration " 10902 "from BIOS. Using base mode...\n"); 10903 board_config = ALC882_3ST_DIG; 10904 } 10905 } 10906 10907 if (has_cdefine_beep(codec)) { 10908 err = snd_hda_attach_beep_device(codec, 0x1); 10909 if (err < 0) { 10910 alc_free(codec); 10911 return err; 10912 } 10913 } 10914 10915 if (board_config != ALC882_AUTO) 10916 setup_preset(codec, &alc882_presets[board_config]); 10917 10918 spec->stream_analog_playback = &alc882_pcm_analog_playback; 10919 spec->stream_analog_capture = &alc882_pcm_analog_capture; 10920 /* FIXME: setup DAC5 */ 10921 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/ 10922 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture; 10923 10924 spec->stream_digital_playback = &alc882_pcm_digital_playback; 10925 spec->stream_digital_capture = &alc882_pcm_digital_capture; 10926 10927 if (!spec->adc_nids && spec->input_mux) { 10928 int i, j; 10929 spec->num_adc_nids = 0; 10930 for (i = 0; i < ARRAY_SIZE(alc882_adc_nids); i++) { 10931 const struct hda_input_mux *imux = spec->input_mux; 10932 hda_nid_t cap; 10933 hda_nid_t items[16]; 10934 hda_nid_t nid = alc882_adc_nids[i]; 10935 unsigned int wcap = get_wcaps(codec, nid); 10936 /* get type */ 10937 wcap = get_wcaps_type(wcap); 10938 if (wcap != AC_WID_AUD_IN) 10939 continue; 10940 spec->private_adc_nids[spec->num_adc_nids] = nid; 10941 err = snd_hda_get_connections(codec, nid, &cap, 1); 10942 if (err < 0) 10943 continue; 10944 err = snd_hda_get_connections(codec, cap, items, 10945 ARRAY_SIZE(items)); 10946 if (err < 0) 10947 continue; 10948 for (j = 0; j < imux->num_items; j++) 10949 if (imux->items[j].index >= err) 10950 break; 10951 if (j < imux->num_items) 10952 continue; 10953 spec->private_capsrc_nids[spec->num_adc_nids] = cap; 10954 spec->num_adc_nids++; 10955 } 10956 spec->adc_nids = spec->private_adc_nids; 10957 spec->capsrc_nids = spec->private_capsrc_nids; 10958 } 10959 10960 set_capture_mixer(codec); 10961 10962 if (has_cdefine_beep(codec)) 10963 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 10964 10965 if (board_config == ALC882_AUTO) 10966 alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups, 0); 10967 10968 spec->vmaster_nid = 0x0c; 10969 10970 codec->patch_ops = alc_patch_ops; 10971 if (board_config == ALC882_AUTO) 10972 spec->init_hook = alc882_auto_init; 10973#ifdef CONFIG_SND_HDA_POWER_SAVE 10974 if (!spec->loopback.amplist) 10975 spec->loopback.amplist = alc882_loopbacks; 10976#endif 10977 10978 return 0; 10979} 10980 10981 10982/* 10983 * ALC262 support 10984 */ 10985 10986#define ALC262_DIGOUT_NID ALC880_DIGOUT_NID 10987#define ALC262_DIGIN_NID ALC880_DIGIN_NID 10988 10989#define alc262_dac_nids alc260_dac_nids 10990#define alc262_adc_nids alc882_adc_nids 10991#define alc262_adc_nids_alt alc882_adc_nids_alt 10992#define alc262_capsrc_nids alc882_capsrc_nids 10993#define alc262_capsrc_nids_alt alc882_capsrc_nids_alt 10994 10995#define alc262_modes alc260_modes 10996#define alc262_capture_source alc882_capture_source 10997 10998static hda_nid_t alc262_dmic_adc_nids[1] = { 10999 /* ADC0 */ 11000 0x09 11001}; 11002 11003static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 }; 11004 11005static struct snd_kcontrol_new alc262_base_mixer[] = { 11006 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11007 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 11008 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 11009 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 11010 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 11011 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 11012 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11013 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11014 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 11015 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 11016 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 11017 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 11018 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT), 11019 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 11020 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 11021 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT), 11022 { } /* end */ 11023}; 11024 11025/* update HP, line and mono-out pins according to the master switch */ 11026static void alc262_hp_master_update(struct hda_codec *codec) 11027{ 11028 struct alc_spec *spec = codec->spec; 11029 int val = spec->master_sw; 11030 11031 /* HP & line-out */ 11032 snd_hda_codec_write_cache(codec, 0x1b, 0, 11033 AC_VERB_SET_PIN_WIDGET_CONTROL, 11034 val ? PIN_HP : 0); 11035 snd_hda_codec_write_cache(codec, 0x15, 0, 11036 AC_VERB_SET_PIN_WIDGET_CONTROL, 11037 val ? PIN_HP : 0); 11038 /* mono (speaker) depending on the HP jack sense */ 11039 val = val && !spec->jack_present; 11040 snd_hda_codec_write_cache(codec, 0x16, 0, 11041 AC_VERB_SET_PIN_WIDGET_CONTROL, 11042 val ? PIN_OUT : 0); 11043} 11044 11045static void alc262_hp_bpc_automute(struct hda_codec *codec) 11046{ 11047 struct alc_spec *spec = codec->spec; 11048 11049 spec->jack_present = snd_hda_jack_detect(codec, 0x1b); 11050 alc262_hp_master_update(codec); 11051} 11052 11053static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res) 11054{ 11055 if ((res >> 26) != ALC880_HP_EVENT) 11056 return; 11057 alc262_hp_bpc_automute(codec); 11058} 11059 11060static void alc262_hp_wildwest_automute(struct hda_codec *codec) 11061{ 11062 struct alc_spec *spec = codec->spec; 11063 11064 spec->jack_present = snd_hda_jack_detect(codec, 0x15); 11065 alc262_hp_master_update(codec); 11066} 11067 11068static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec, 11069 unsigned int res) 11070{ 11071 if ((res >> 26) != ALC880_HP_EVENT) 11072 return; 11073 alc262_hp_wildwest_automute(codec); 11074} 11075 11076#define alc262_hp_master_sw_get alc260_hp_master_sw_get 11077 11078static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol, 11079 struct snd_ctl_elem_value *ucontrol) 11080{ 11081 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 11082 struct alc_spec *spec = codec->spec; 11083 int val = !!*ucontrol->value.integer.value; 11084 11085 if (val == spec->master_sw) 11086 return 0; 11087 spec->master_sw = val; 11088 alc262_hp_master_update(codec); 11089 return 1; 11090} 11091 11092#define ALC262_HP_MASTER_SWITCH \ 11093 { \ 11094 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 11095 .name = "Master Playback Switch", \ 11096 .info = snd_ctl_boolean_mono_info, \ 11097 .get = alc262_hp_master_sw_get, \ 11098 .put = alc262_hp_master_sw_put, \ 11099 }, \ 11100 { \ 11101 .iface = NID_MAPPING, \ 11102 .name = "Master Playback Switch", \ 11103 .private_value = 0x15 | (0x16 << 8) | (0x1b << 16), \ 11104 } 11105 11106 11107static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = { 11108 ALC262_HP_MASTER_SWITCH, 11109 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11110 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT), 11111 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 11112 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0, 11113 HDA_OUTPUT), 11114 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0, 11115 HDA_OUTPUT), 11116 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11117 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11118 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 11119 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 11120 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 11121 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 11122 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 11123 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 11124 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 11125 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 11126 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT), 11127 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT), 11128 { } /* end */ 11129}; 11130 11131static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = { 11132 ALC262_HP_MASTER_SWITCH, 11133 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11134 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 11135 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 11136 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 11137 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0, 11138 HDA_OUTPUT), 11139 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0, 11140 HDA_OUTPUT), 11141 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT), 11142 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT), 11143 HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT), 11144 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT), 11145 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT), 11146 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 11147 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 11148 { } /* end */ 11149}; 11150 11151static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = { 11152 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11153 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11154 HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT), 11155 { } /* end */ 11156}; 11157 11158/* mute/unmute internal speaker according to the hp jack and mute state */ 11159static void alc262_hp_t5735_setup(struct hda_codec *codec) 11160{ 11161 struct alc_spec *spec = codec->spec; 11162 11163 spec->autocfg.hp_pins[0] = 0x15; 11164 spec->autocfg.speaker_pins[0] = 0x14; 11165} 11166 11167static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = { 11168 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11169 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 11170 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 11171 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 11172 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11173 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11174 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 11175 { } /* end */ 11176}; 11177 11178static struct hda_verb alc262_hp_t5735_verbs[] = { 11179 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 11180 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11181 11182 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 11183 { } 11184}; 11185 11186static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = { 11187 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11188 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 11189 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT), 11190 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT), 11191 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT), 11192 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT), 11193 { } /* end */ 11194}; 11195 11196static struct hda_verb alc262_hp_rp5700_verbs[] = { 11197 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 11198 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 11199 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 11200 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 11201 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 11202 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 11203 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 11204 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 11205 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))}, 11206 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))}, 11207 {} 11208}; 11209 11210static struct hda_input_mux alc262_hp_rp5700_capture_source = { 11211 .num_items = 1, 11212 .items = { 11213 { "Line", 0x1 }, 11214 }, 11215}; 11216 11217/* bind hp and internal speaker mute (with plug check) as master switch */ 11218static void alc262_hippo_master_update(struct hda_codec *codec) 11219{ 11220 struct alc_spec *spec = codec->spec; 11221 hda_nid_t hp_nid = spec->autocfg.hp_pins[0]; 11222 hda_nid_t line_nid = spec->autocfg.line_out_pins[0]; 11223 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0]; 11224 unsigned int mute; 11225 11226 /* HP */ 11227 mute = spec->master_sw ? 0 : HDA_AMP_MUTE; 11228 snd_hda_codec_amp_stereo(codec, hp_nid, HDA_OUTPUT, 0, 11229 HDA_AMP_MUTE, mute); 11230 /* mute internal speaker per jack sense */ 11231 if (spec->jack_present) 11232 mute = HDA_AMP_MUTE; 11233 if (line_nid) 11234 snd_hda_codec_amp_stereo(codec, line_nid, HDA_OUTPUT, 0, 11235 HDA_AMP_MUTE, mute); 11236 if (speaker_nid && speaker_nid != line_nid) 11237 snd_hda_codec_amp_stereo(codec, speaker_nid, HDA_OUTPUT, 0, 11238 HDA_AMP_MUTE, mute); 11239} 11240 11241#define alc262_hippo_master_sw_get alc262_hp_master_sw_get 11242 11243static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol, 11244 struct snd_ctl_elem_value *ucontrol) 11245{ 11246 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 11247 struct alc_spec *spec = codec->spec; 11248 int val = !!*ucontrol->value.integer.value; 11249 11250 if (val == spec->master_sw) 11251 return 0; 11252 spec->master_sw = val; 11253 alc262_hippo_master_update(codec); 11254 return 1; 11255} 11256 11257#define ALC262_HIPPO_MASTER_SWITCH \ 11258 { \ 11259 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 11260 .name = "Master Playback Switch", \ 11261 .info = snd_ctl_boolean_mono_info, \ 11262 .get = alc262_hippo_master_sw_get, \ 11263 .put = alc262_hippo_master_sw_put, \ 11264 }, \ 11265 { \ 11266 .iface = NID_MAPPING, \ 11267 .name = "Master Playback Switch", \ 11268 .subdevice = SUBDEV_HP(0) | (SUBDEV_LINE(0) << 8) | \ 11269 (SUBDEV_SPEAKER(0) << 16), \ 11270 } 11271 11272static struct snd_kcontrol_new alc262_hippo_mixer[] = { 11273 ALC262_HIPPO_MASTER_SWITCH, 11274 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11275 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 11276 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 11277 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 11278 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 11279 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11280 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11281 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 11282 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 11283 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 11284 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 11285 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 11286 { } /* end */ 11287}; 11288 11289static struct snd_kcontrol_new alc262_hippo1_mixer[] = { 11290 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11291 ALC262_HIPPO_MASTER_SWITCH, 11292 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 11293 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 11294 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 11295 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 11296 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11297 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11298 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 11299 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 11300 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 11301 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 11302 { } /* end */ 11303}; 11304 11305/* mute/unmute internal speaker according to the hp jack and mute state */ 11306static void alc262_hippo_automute(struct hda_codec *codec) 11307{ 11308 struct alc_spec *spec = codec->spec; 11309 hda_nid_t hp_nid = spec->autocfg.hp_pins[0]; 11310 11311 spec->jack_present = snd_hda_jack_detect(codec, hp_nid); 11312 alc262_hippo_master_update(codec); 11313} 11314 11315static void alc262_hippo_unsol_event(struct hda_codec *codec, unsigned int res) 11316{ 11317 if ((res >> 26) != ALC880_HP_EVENT) 11318 return; 11319 alc262_hippo_automute(codec); 11320} 11321 11322static void alc262_hippo_setup(struct hda_codec *codec) 11323{ 11324 struct alc_spec *spec = codec->spec; 11325 11326 spec->autocfg.hp_pins[0] = 0x15; 11327 spec->autocfg.speaker_pins[0] = 0x14; 11328} 11329 11330static void alc262_hippo1_setup(struct hda_codec *codec) 11331{ 11332 struct alc_spec *spec = codec->spec; 11333 11334 spec->autocfg.hp_pins[0] = 0x1b; 11335 spec->autocfg.speaker_pins[0] = 0x14; 11336} 11337 11338 11339static struct snd_kcontrol_new alc262_sony_mixer[] = { 11340 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11341 ALC262_HIPPO_MASTER_SWITCH, 11342 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11343 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11344 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 11345 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 11346 { } /* end */ 11347}; 11348 11349static struct snd_kcontrol_new alc262_benq_t31_mixer[] = { 11350 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11351 ALC262_HIPPO_MASTER_SWITCH, 11352 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 11353 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11354 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11355 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 11356 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 11357 { } /* end */ 11358}; 11359 11360static struct snd_kcontrol_new alc262_tyan_mixer[] = { 11361 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11362 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT), 11363 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT), 11364 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT), 11365 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 11366 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 11367 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11368 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11369 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 11370 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 11371 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 11372 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 11373 { } /* end */ 11374}; 11375 11376static struct hda_verb alc262_tyan_verbs[] = { 11377 /* Headphone automute */ 11378 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 11379 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11380 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 11381 11382 /* P11 AUX_IN, white 4-pin connector */ 11383 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 11384 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1}, 11385 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93}, 11386 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19}, 11387 11388 {} 11389}; 11390 11391/* unsolicited event for HP jack sensing */ 11392static void alc262_tyan_setup(struct hda_codec *codec) 11393{ 11394 struct alc_spec *spec = codec->spec; 11395 11396 spec->autocfg.hp_pins[0] = 0x1b; 11397 spec->autocfg.speaker_pins[0] = 0x15; 11398} 11399 11400 11401#define alc262_capture_mixer alc882_capture_mixer 11402#define alc262_capture_alt_mixer alc882_capture_alt_mixer 11403 11404/* 11405 * generic initialization of ADC, input mixers and output mixers 11406 */ 11407static struct hda_verb alc262_init_verbs[] = { 11408 /* 11409 * Unmute ADC0-2 and set the default input to mic-in 11410 */ 11411 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 11412 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11413 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 11414 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11415 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 11416 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11417 11418 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 11419 * mixer widget 11420 * Note: PASD motherboards uses the Line In 2 as the input for 11421 * front panel mic (mic 2) 11422 */ 11423 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 11424 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 11425 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 11426 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 11427 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 11428 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 11429 11430 /* 11431 * Set up output mixers (0x0c - 0x0e) 11432 */ 11433 /* set vol=0 to output mixers */ 11434 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 11435 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 11436 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 11437 /* set up input amps for analog loopback */ 11438 /* Amp Indices: DAC = 0, mixer = 1 */ 11439 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11440 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11441 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11442 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11443 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11444 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11445 11446 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 11447 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 11448 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 11449 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 11450 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 11451 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 11452 11453 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 11454 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 11455 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 11456 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 11457 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 11458 11459 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 11460 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 11461 11462 /* FIXME: use matrix-type input source selection */ 11463 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 11464 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 11465 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 11466 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 11467 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 11468 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 11469 /* Input mixer2 */ 11470 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 11471 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 11472 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 11473 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 11474 /* Input mixer3 */ 11475 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 11476 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 11477 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 11478 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 11479 11480 { } 11481}; 11482 11483static struct hda_verb alc262_eapd_verbs[] = { 11484 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 11485 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, 11486 { } 11487}; 11488 11489static struct hda_verb alc262_hippo1_unsol_verbs[] = { 11490 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 11491 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 11492 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 11493 11494 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 11495 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11496 {} 11497}; 11498 11499static struct hda_verb alc262_sony_unsol_verbs[] = { 11500 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 11501 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 11502 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic 11503 11504 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 11505 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11506 {} 11507}; 11508 11509static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = { 11510 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11511 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 11512 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 11513 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11514 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11515 { } /* end */ 11516}; 11517 11518static struct hda_verb alc262_toshiba_s06_verbs[] = { 11519 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 11520 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 11521 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11522 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 11523 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09}, 11524 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 11525 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 11526 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 11527 {} 11528}; 11529 11530static void alc262_toshiba_s06_setup(struct hda_codec *codec) 11531{ 11532 struct alc_spec *spec = codec->spec; 11533 11534 spec->autocfg.hp_pins[0] = 0x15; 11535 spec->autocfg.speaker_pins[0] = 0x14; 11536 spec->ext_mic.pin = 0x18; 11537 spec->ext_mic.mux_idx = 0; 11538 spec->int_mic.pin = 0x12; 11539 spec->int_mic.mux_idx = 9; 11540 spec->auto_mic = 1; 11541} 11542 11543/* 11544 * nec model 11545 * 0x15 = headphone 11546 * 0x16 = internal speaker 11547 * 0x18 = external mic 11548 */ 11549 11550static struct snd_kcontrol_new alc262_nec_mixer[] = { 11551 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 11552 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT), 11553 11554 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11555 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11556 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 11557 11558 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 11559 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 11560 { } /* end */ 11561}; 11562 11563static struct hda_verb alc262_nec_verbs[] = { 11564 /* Unmute Speaker */ 11565 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 11566 11567 /* Headphone */ 11568 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 11569 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 11570 11571 /* External mic to headphone */ 11572 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11573 /* External mic to speaker */ 11574 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11575 {} 11576}; 11577 11578/* 11579 * fujitsu model 11580 * 0x14 = headphone/spdif-out, 0x15 = internal speaker, 11581 * 0x1b = port replicator headphone out 11582 */ 11583 11584#define ALC_HP_EVENT 0x37 11585 11586static struct hda_verb alc262_fujitsu_unsol_verbs[] = { 11587 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, 11588 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11589 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, 11590 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11591 {} 11592}; 11593 11594static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = { 11595 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, 11596 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11597 {} 11598}; 11599 11600static struct hda_verb alc262_lenovo_3000_init_verbs[] = { 11601 /* Front Mic pin: input vref at 50% */ 11602 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, 11603 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 11604 {} 11605}; 11606 11607static struct hda_input_mux alc262_fujitsu_capture_source = { 11608 .num_items = 3, 11609 .items = { 11610 { "Mic", 0x0 }, 11611 { "Int Mic", 0x1 }, 11612 { "CD", 0x4 }, 11613 }, 11614}; 11615 11616static struct hda_input_mux alc262_HP_capture_source = { 11617 .num_items = 5, 11618 .items = { 11619 { "Mic", 0x0 }, 11620 { "Front Mic", 0x1 }, 11621 { "Line", 0x2 }, 11622 { "CD", 0x4 }, 11623 { "AUX IN", 0x6 }, 11624 }, 11625}; 11626 11627static struct hda_input_mux alc262_HP_D7000_capture_source = { 11628 .num_items = 4, 11629 .items = { 11630 { "Mic", 0x0 }, 11631 { "Front Mic", 0x2 }, 11632 { "Line", 0x1 }, 11633 { "CD", 0x4 }, 11634 }, 11635}; 11636 11637/* mute/unmute internal speaker according to the hp jacks and mute state */ 11638static void alc262_fujitsu_automute(struct hda_codec *codec, int force) 11639{ 11640 struct alc_spec *spec = codec->spec; 11641 unsigned int mute; 11642 11643 if (force || !spec->sense_updated) { 11644 spec->jack_present = snd_hda_jack_detect(codec, 0x14) || 11645 snd_hda_jack_detect(codec, 0x1b); 11646 spec->sense_updated = 1; 11647 } 11648 /* unmute internal speaker only if both HPs are unplugged and 11649 * master switch is on 11650 */ 11651 if (spec->jack_present) 11652 mute = HDA_AMP_MUTE; 11653 else 11654 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0); 11655 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 11656 HDA_AMP_MUTE, mute); 11657} 11658 11659/* unsolicited event for HP jack sensing */ 11660static void alc262_fujitsu_unsol_event(struct hda_codec *codec, 11661 unsigned int res) 11662{ 11663 if ((res >> 26) != ALC_HP_EVENT) 11664 return; 11665 alc262_fujitsu_automute(codec, 1); 11666} 11667 11668static void alc262_fujitsu_init_hook(struct hda_codec *codec) 11669{ 11670 alc262_fujitsu_automute(codec, 1); 11671} 11672 11673/* bind volumes of both NID 0x0c and 0x0d */ 11674static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = { 11675 .ops = &snd_hda_bind_vol, 11676 .values = { 11677 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT), 11678 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT), 11679 0 11680 }, 11681}; 11682 11683/* mute/unmute internal speaker according to the hp jack and mute state */ 11684static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force) 11685{ 11686 struct alc_spec *spec = codec->spec; 11687 unsigned int mute; 11688 11689 if (force || !spec->sense_updated) { 11690 spec->jack_present = snd_hda_jack_detect(codec, 0x1b); 11691 spec->sense_updated = 1; 11692 } 11693 if (spec->jack_present) { 11694 /* mute internal speaker */ 11695 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 11696 HDA_AMP_MUTE, HDA_AMP_MUTE); 11697 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0, 11698 HDA_AMP_MUTE, HDA_AMP_MUTE); 11699 } else { 11700 /* unmute internal speaker if necessary */ 11701 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0); 11702 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 11703 HDA_AMP_MUTE, mute); 11704 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0, 11705 HDA_AMP_MUTE, mute); 11706 } 11707} 11708 11709/* unsolicited event for HP jack sensing */ 11710static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec, 11711 unsigned int res) 11712{ 11713 if ((res >> 26) != ALC_HP_EVENT) 11714 return; 11715 alc262_lenovo_3000_automute(codec, 1); 11716} 11717 11718static int amp_stereo_mute_update(struct hda_codec *codec, hda_nid_t nid, 11719 int dir, int idx, long *valp) 11720{ 11721 int i, change = 0; 11722 11723 for (i = 0; i < 2; i++, valp++) 11724 change |= snd_hda_codec_amp_update(codec, nid, i, dir, idx, 11725 HDA_AMP_MUTE, 11726 *valp ? 0 : HDA_AMP_MUTE); 11727 return change; 11728} 11729 11730/* bind hp and internal speaker mute (with plug check) */ 11731static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol, 11732 struct snd_ctl_elem_value *ucontrol) 11733{ 11734 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 11735 long *valp = ucontrol->value.integer.value; 11736 int change; 11737 11738 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp); 11739 change |= amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp); 11740 if (change) 11741 alc262_fujitsu_automute(codec, 0); 11742 return change; 11743} 11744 11745static struct snd_kcontrol_new alc262_fujitsu_mixer[] = { 11746 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol), 11747 { 11748 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 11749 .name = "Master Playback Switch", 11750 .subdevice = HDA_SUBDEV_AMP_FLAG, 11751 .info = snd_hda_mixer_amp_switch_info, 11752 .get = snd_hda_mixer_amp_switch_get, 11753 .put = alc262_fujitsu_master_sw_put, 11754 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 11755 }, 11756 { 11757 .iface = NID_MAPPING, 11758 .name = "Master Playback Switch", 11759 .private_value = 0x1b, 11760 }, 11761 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 11762 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 11763 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 11764 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11765 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11766 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 11767 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 11768 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 11769 { } /* end */ 11770}; 11771 11772/* bind hp and internal speaker mute (with plug check) */ 11773static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol, 11774 struct snd_ctl_elem_value *ucontrol) 11775{ 11776 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 11777 long *valp = ucontrol->value.integer.value; 11778 int change; 11779 11780 change = amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp); 11781 if (change) 11782 alc262_lenovo_3000_automute(codec, 0); 11783 return change; 11784} 11785 11786static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = { 11787 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol), 11788 { 11789 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 11790 .name = "Master Playback Switch", 11791 .subdevice = HDA_SUBDEV_AMP_FLAG, 11792 .info = snd_hda_mixer_amp_switch_info, 11793 .get = snd_hda_mixer_amp_switch_get, 11794 .put = alc262_lenovo_3000_master_sw_put, 11795 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT), 11796 }, 11797 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 11798 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 11799 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 11800 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11801 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11802 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 11803 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 11804 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 11805 { } /* end */ 11806}; 11807 11808static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = { 11809 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol), 11810 ALC262_HIPPO_MASTER_SWITCH, 11811 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11812 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11813 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 11814 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 11815 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 11816 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 11817 { } /* end */ 11818}; 11819 11820/* additional init verbs for Benq laptops */ 11821static struct hda_verb alc262_EAPD_verbs[] = { 11822 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 11823 {0x20, AC_VERB_SET_PROC_COEF, 0x3070}, 11824 {} 11825}; 11826 11827static struct hda_verb alc262_benq_t31_EAPD_verbs[] = { 11828 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 11829 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 11830 11831 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 11832 {0x20, AC_VERB_SET_PROC_COEF, 0x3050}, 11833 {} 11834}; 11835 11836/* Samsung Q1 Ultra Vista model setup */ 11837static struct snd_kcontrol_new alc262_ultra_mixer[] = { 11838 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11839 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT), 11840 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 11841 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 11842 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT), 11843 HDA_CODEC_VOLUME("Headphone Mic Boost", 0x15, 0, HDA_INPUT), 11844 { } /* end */ 11845}; 11846 11847static struct hda_verb alc262_ultra_verbs[] = { 11848 /* output mixer */ 11849 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 11850 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 11851 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 11852 /* speaker */ 11853 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 11854 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 11855 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11856 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 11857 /* HP */ 11858 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11859 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 11860 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11861 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 11862 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 11863 /* internal mic */ 11864 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 11865 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 11866 /* ADC, choose mic */ 11867 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 11868 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 11869 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11870 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 11871 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 11872 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 11873 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, 11874 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, 11875 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, 11876 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)}, 11877 {} 11878}; 11879 11880/* mute/unmute internal speaker according to the hp jack and mute state */ 11881static void alc262_ultra_automute(struct hda_codec *codec) 11882{ 11883 struct alc_spec *spec = codec->spec; 11884 unsigned int mute; 11885 11886 mute = 0; 11887 /* auto-mute only when HP is used as HP */ 11888 if (!spec->cur_mux[0]) { 11889 spec->jack_present = snd_hda_jack_detect(codec, 0x15); 11890 if (spec->jack_present) 11891 mute = HDA_AMP_MUTE; 11892 } 11893 /* mute/unmute internal speaker */ 11894 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 11895 HDA_AMP_MUTE, mute); 11896 /* mute/unmute HP */ 11897 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 11898 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE); 11899} 11900 11901/* unsolicited event for HP jack sensing */ 11902static void alc262_ultra_unsol_event(struct hda_codec *codec, 11903 unsigned int res) 11904{ 11905 if ((res >> 26) != ALC880_HP_EVENT) 11906 return; 11907 alc262_ultra_automute(codec); 11908} 11909 11910static struct hda_input_mux alc262_ultra_capture_source = { 11911 .num_items = 2, 11912 .items = { 11913 { "Mic", 0x1 }, 11914 { "Headphone", 0x7 }, 11915 }, 11916}; 11917 11918static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol, 11919 struct snd_ctl_elem_value *ucontrol) 11920{ 11921 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 11922 struct alc_spec *spec = codec->spec; 11923 int ret; 11924 11925 ret = alc_mux_enum_put(kcontrol, ucontrol); 11926 if (!ret) 11927 return 0; 11928 /* reprogram the HP pin as mic or HP according to the input source */ 11929 snd_hda_codec_write_cache(codec, 0x15, 0, 11930 AC_VERB_SET_PIN_WIDGET_CONTROL, 11931 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP); 11932 alc262_ultra_automute(codec); /* mute/unmute HP */ 11933 return ret; 11934} 11935 11936static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = { 11937 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT), 11938 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT), 11939 { 11940 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 11941 .name = "Capture Source", 11942 .info = alc_mux_enum_info, 11943 .get = alc_mux_enum_get, 11944 .put = alc262_ultra_mux_enum_put, 11945 }, 11946 { 11947 .iface = NID_MAPPING, 11948 .name = "Capture Source", 11949 .private_value = 0x15, 11950 }, 11951 { } /* end */ 11952}; 11953 11954/* We use two mixers depending on the output pin; 0x16 is a mono output 11955 * and thus it's bound with a different mixer. 11956 * This function returns which mixer amp should be used. 11957 */ 11958static int alc262_check_volbit(hda_nid_t nid) 11959{ 11960 if (!nid) 11961 return 0; 11962 else if (nid == 0x16) 11963 return 2; 11964 else 11965 return 1; 11966} 11967 11968static int alc262_add_out_vol_ctl(struct alc_spec *spec, hda_nid_t nid, 11969 const char *pfx, int *vbits, int idx) 11970{ 11971 unsigned long val; 11972 int vbit; 11973 11974 vbit = alc262_check_volbit(nid); 11975 if (!vbit) 11976 return 0; 11977 if (*vbits & vbit) /* a volume control for this mixer already there */ 11978 return 0; 11979 *vbits |= vbit; 11980 if (vbit == 2) 11981 val = HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT); 11982 else 11983 val = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT); 11984 return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx, val); 11985} 11986 11987static int alc262_add_out_sw_ctl(struct alc_spec *spec, hda_nid_t nid, 11988 const char *pfx, int idx) 11989{ 11990 unsigned long val; 11991 11992 if (!nid) 11993 return 0; 11994 if (nid == 0x16) 11995 val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT); 11996 else 11997 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT); 11998 return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx, val); 11999} 12000 12001/* add playback controls from the parsed DAC table */ 12002static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, 12003 const struct auto_pin_cfg *cfg) 12004{ 12005 const char *pfx; 12006 int vbits; 12007 int i, err; 12008 12009 spec->multiout.num_dacs = 1; /* only use one dac */ 12010 spec->multiout.dac_nids = spec->private_dac_nids; 12011 spec->multiout.dac_nids[0] = 2; 12012 12013 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0]) 12014 pfx = "Master"; 12015 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) 12016 pfx = "Speaker"; 12017 else if (cfg->line_out_type == AUTO_PIN_HP_OUT) 12018 pfx = "Headphone"; 12019 else 12020 pfx = "Front"; 12021 for (i = 0; i < 2; i++) { 12022 err = alc262_add_out_sw_ctl(spec, cfg->line_out_pins[i], pfx, i); 12023 if (err < 0) 12024 return err; 12025 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { 12026 err = alc262_add_out_sw_ctl(spec, cfg->speaker_pins[i], 12027 "Speaker", i); 12028 if (err < 0) 12029 return err; 12030 } 12031 if (cfg->line_out_type != AUTO_PIN_HP_OUT) { 12032 err = alc262_add_out_sw_ctl(spec, cfg->hp_pins[i], 12033 "Headphone", i); 12034 if (err < 0) 12035 return err; 12036 } 12037 } 12038 12039 vbits = alc262_check_volbit(cfg->line_out_pins[0]) | 12040 alc262_check_volbit(cfg->speaker_pins[0]) | 12041 alc262_check_volbit(cfg->hp_pins[0]); 12042 if (vbits == 1 || vbits == 2) 12043 pfx = "Master"; /* only one mixer is used */ 12044 vbits = 0; 12045 for (i = 0; i < 2; i++) { 12046 err = alc262_add_out_vol_ctl(spec, cfg->line_out_pins[i], pfx, 12047 &vbits, i); 12048 if (err < 0) 12049 return err; 12050 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { 12051 err = alc262_add_out_vol_ctl(spec, cfg->speaker_pins[i], 12052 "Speaker", &vbits, i); 12053 if (err < 0) 12054 return err; 12055 } 12056 if (cfg->line_out_type != AUTO_PIN_HP_OUT) { 12057 err = alc262_add_out_vol_ctl(spec, cfg->hp_pins[i], 12058 "Headphone", &vbits, i); 12059 if (err < 0) 12060 return err; 12061 } 12062 } 12063 return 0; 12064} 12065 12066#define alc262_auto_create_input_ctls \ 12067 alc882_auto_create_input_ctls 12068 12069/* 12070 * generic initialization of ADC, input mixers and output mixers 12071 */ 12072static struct hda_verb alc262_volume_init_verbs[] = { 12073 /* 12074 * Unmute ADC0-2 and set the default input to mic-in 12075 */ 12076 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 12077 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12078 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 12079 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12080 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 12081 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12082 12083 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 12084 * mixer widget 12085 * Note: PASD motherboards uses the Line In 2 as the input for 12086 * front panel mic (mic 2) 12087 */ 12088 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 12089 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 12090 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 12091 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 12092 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 12093 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 12094 12095 /* 12096 * Set up output mixers (0x0c - 0x0f) 12097 */ 12098 /* set vol=0 to output mixers */ 12099 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 12100 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 12101 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 12102 12103 /* set up input amps for analog loopback */ 12104 /* Amp Indices: DAC = 0, mixer = 1 */ 12105 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12106 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12107 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12108 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12109 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12110 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12111 12112 /* FIXME: use matrix-type input source selection */ 12113 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 12114 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 12115 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 12116 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 12117 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 12118 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 12119 /* Input mixer2 */ 12120 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 12121 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 12122 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 12123 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 12124 /* Input mixer3 */ 12125 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 12126 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 12127 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 12128 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 12129 12130 { } 12131}; 12132 12133static struct hda_verb alc262_HP_BPC_init_verbs[] = { 12134 /* 12135 * Unmute ADC0-2 and set the default input to mic-in 12136 */ 12137 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 12138 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12139 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 12140 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12141 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 12142 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12143 12144 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 12145 * mixer widget 12146 * Note: PASD motherboards uses the Line In 2 as the input for 12147 * front panel mic (mic 2) 12148 */ 12149 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 12150 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 12151 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 12152 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 12153 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 12154 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 12155 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, 12156 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, 12157 12158 /* 12159 * Set up output mixers (0x0c - 0x0e) 12160 */ 12161 /* set vol=0 to output mixers */ 12162 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 12163 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 12164 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 12165 12166 /* set up input amps for analog loopback */ 12167 /* Amp Indices: DAC = 0, mixer = 1 */ 12168 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12169 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12170 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12171 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12172 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12173 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12174 12175 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 12176 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 12177 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 12178 12179 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 12180 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 12181 12182 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 12183 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 12184 12185 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 12186 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 12187 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 12188 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 12189 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 12190 12191 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 12192 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 12193 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 12194 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 12195 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 12196 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 12197 12198 12199 /* FIXME: use matrix-type input source selection */ 12200 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */ 12201 /* Input mixer1: only unmute Mic */ 12202 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 12203 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))}, 12204 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 12205 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 12206 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 12207 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))}, 12208 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))}, 12209 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))}, 12210 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))}, 12211 /* Input mixer2 */ 12212 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 12213 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))}, 12214 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 12215 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 12216 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 12217 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))}, 12218 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))}, 12219 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))}, 12220 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))}, 12221 /* Input mixer3 */ 12222 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 12223 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))}, 12224 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 12225 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 12226 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 12227 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))}, 12228 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))}, 12229 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))}, 12230 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))}, 12231 12232 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 12233 12234 { } 12235}; 12236 12237static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = { 12238 /* 12239 * Unmute ADC0-2 and set the default input to mic-in 12240 */ 12241 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 12242 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12243 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 12244 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12245 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 12246 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12247 12248 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 12249 * mixer widget 12250 * Note: PASD motherboards uses the Line In 2 as the input for front 12251 * panel mic (mic 2) 12252 */ 12253 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 12254 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 12255 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 12256 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 12257 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 12258 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 12259 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, 12260 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, 12261 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, 12262 /* 12263 * Set up output mixers (0x0c - 0x0e) 12264 */ 12265 /* set vol=0 to output mixers */ 12266 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 12267 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 12268 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 12269 12270 /* set up input amps for analog loopback */ 12271 /* Amp Indices: DAC = 0, mixer = 1 */ 12272 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12273 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12274 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12275 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12276 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12277 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12278 12279 12280 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */ 12281 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */ 12282 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */ 12283 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */ 12284 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */ 12285 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */ 12286 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */ 12287 12288 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 12289 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 12290 12291 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 12292 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 12293 12294 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */ 12295 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 12296 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 12297 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, 12298 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 12299 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 12300 12301 /* FIXME: use matrix-type input source selection */ 12302 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 12303 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 12304 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/ 12305 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/ 12306 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/ 12307 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/ 12308 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/ 12309 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */ 12310 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/ 12311 /* Input mixer2 */ 12312 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 12313 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 12314 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, 12315 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, 12316 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, 12317 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */ 12318 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, 12319 /* Input mixer3 */ 12320 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 12321 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 12322 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, 12323 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, 12324 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, 12325 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */ 12326 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, 12327 12328 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 12329 12330 { } 12331}; 12332 12333static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = { 12334 12335 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */ 12336 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 12337 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01}, 12338 12339 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */ 12340 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */ 12341 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) }, 12342 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) }, 12343 12344 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */ 12345 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 12346 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 12347 {} 12348}; 12349 12350/* 12351 * Pin config fixes 12352 */ 12353enum { 12354 PINFIX_FSC_H270, 12355}; 12356 12357static const struct alc_fixup alc262_fixups[] = { 12358 [PINFIX_FSC_H270] = { 12359 .pins = (const struct alc_pincfg[]) { 12360 { 0x14, 0x99130110 }, /* speaker */ 12361 { 0x15, 0x0221142f }, /* front HP */ 12362 { 0x1b, 0x0121141f }, /* rear HP */ 12363 { } 12364 } 12365 }, 12366 [PINFIX_PB_M5210] = { 12367 .verbs = (const struct hda_verb[]) { 12368 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 }, 12369 {} 12370 } 12371 }, 12372}; 12373 12374static struct snd_pci_quirk alc262_fixup_tbl[] = { 12375 SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", PINFIX_FSC_H270), 12376 {} 12377}; 12378 12379 12380#ifdef CONFIG_SND_HDA_POWER_SAVE 12381#define alc262_loopbacks alc880_loopbacks 12382#endif 12383 12384/* pcm configuration: identical with ALC880 */ 12385#define alc262_pcm_analog_playback alc880_pcm_analog_playback 12386#define alc262_pcm_analog_capture alc880_pcm_analog_capture 12387#define alc262_pcm_digital_playback alc880_pcm_digital_playback 12388#define alc262_pcm_digital_capture alc880_pcm_digital_capture 12389 12390/* 12391 * BIOS auto configuration 12392 */ 12393static int alc262_parse_auto_config(struct hda_codec *codec) 12394{ 12395 struct alc_spec *spec = codec->spec; 12396 int err; 12397 static hda_nid_t alc262_ignore[] = { 0x1d, 0 }; 12398 12399 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 12400 alc262_ignore); 12401 if (err < 0) 12402 return err; 12403 if (!spec->autocfg.line_outs) { 12404 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) { 12405 spec->multiout.max_channels = 2; 12406 spec->no_analog = 1; 12407 goto dig_only; 12408 } 12409 return 0; /* can't find valid BIOS pin config */ 12410 } 12411 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg); 12412 if (err < 0) 12413 return err; 12414 err = alc262_auto_create_input_ctls(codec, &spec->autocfg); 12415 if (err < 0) 12416 return err; 12417 12418 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 12419 12420 dig_only: 12421 alc_auto_parse_digital(codec); 12422 12423 if (spec->kctls.list) 12424 add_mixer(spec, spec->kctls.list); 12425 12426 add_verb(spec, alc262_volume_init_verbs); 12427 spec->num_mux_defs = 1; 12428 spec->input_mux = &spec->private_imux[0]; 12429 12430 err = alc_auto_add_mic_boost(codec); 12431 if (err < 0) 12432 return err; 12433 12434 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); 12435 12436 return 1; 12437} 12438 12439#define alc262_auto_init_multi_out alc882_auto_init_multi_out 12440#define alc262_auto_init_hp_out alc882_auto_init_hp_out 12441#define alc262_auto_init_analog_input alc882_auto_init_analog_input 12442#define alc262_auto_init_input_src alc882_auto_init_input_src 12443 12444 12445/* init callback for auto-configuration model -- overriding the default init */ 12446static void alc262_auto_init(struct hda_codec *codec) 12447{ 12448 struct alc_spec *spec = codec->spec; 12449 alc262_auto_init_multi_out(codec); 12450 alc262_auto_init_hp_out(codec); 12451 alc262_auto_init_analog_input(codec); 12452 alc262_auto_init_input_src(codec); 12453 alc_auto_init_digital(codec); 12454 if (spec->unsol_event) 12455 alc_inithook(codec); 12456} 12457 12458/* 12459 * configuration and preset 12460 */ 12461static const char *alc262_models[ALC262_MODEL_LAST] = { 12462 [ALC262_BASIC] = "basic", 12463 [ALC262_HIPPO] = "hippo", 12464 [ALC262_HIPPO_1] = "hippo_1", 12465 [ALC262_FUJITSU] = "fujitsu", 12466 [ALC262_HP_BPC] = "hp-bpc", 12467 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000", 12468 [ALC262_HP_TC_T5735] = "hp-tc-t5735", 12469 [ALC262_HP_RP5700] = "hp-rp5700", 12470 [ALC262_BENQ_ED8] = "benq", 12471 [ALC262_BENQ_T31] = "benq-t31", 12472 [ALC262_SONY_ASSAMD] = "sony-assamd", 12473 [ALC262_TOSHIBA_S06] = "toshiba-s06", 12474 [ALC262_TOSHIBA_RX1] = "toshiba-rx1", 12475 [ALC262_ULTRA] = "ultra", 12476 [ALC262_LENOVO_3000] = "lenovo-3000", 12477 [ALC262_NEC] = "nec", 12478 [ALC262_TYAN] = "tyan", 12479 [ALC262_AUTO] = "auto", 12480}; 12481 12482static struct snd_pci_quirk alc262_cfg_tbl[] = { 12483 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO), 12484 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC), 12485 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series", 12486 ALC262_HP_BPC), 12487 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series", 12488 ALC262_HP_BPC), 12489 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series", 12490 ALC262_HP_BPC), 12491 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL), 12492 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF), 12493 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL), 12494 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF), 12495 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL), 12496 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF), 12497 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL), 12498 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF), 12499 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC), 12500 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC), 12501 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC), 12502 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735", 12503 ALC262_HP_TC_T5735), 12504 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700), 12505 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD), 12506 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO), 12507 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD), 12508 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */ 12509 SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06), 12510 SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO), 12511 SND_PCI_QUIRK(0x104d, 0x9047, "Sony VAIO Type G", ALC262_AUTO), 12512#if 0 /* disable the quirk since model=auto works better in recent versions */ 12513 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO", 12514 ALC262_SONY_ASSAMD), 12515#endif 12516 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1", 12517 ALC262_TOSHIBA_RX1), 12518 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06), 12519 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU), 12520 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU), 12521 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN), 12522 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1", 12523 ALC262_ULTRA), 12524 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO), 12525 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000), 12526 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8), 12527 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31), 12528 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1), 12529 {} 12530}; 12531 12532static struct alc_config_preset alc262_presets[] = { 12533 [ALC262_BASIC] = { 12534 .mixers = { alc262_base_mixer }, 12535 .init_verbs = { alc262_init_verbs }, 12536 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12537 .dac_nids = alc262_dac_nids, 12538 .hp_nid = 0x03, 12539 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12540 .channel_mode = alc262_modes, 12541 .input_mux = &alc262_capture_source, 12542 }, 12543 [ALC262_HIPPO] = { 12544 .mixers = { alc262_hippo_mixer }, 12545 .init_verbs = { alc262_init_verbs, alc_hp15_unsol_verbs}, 12546 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12547 .dac_nids = alc262_dac_nids, 12548 .hp_nid = 0x03, 12549 .dig_out_nid = ALC262_DIGOUT_NID, 12550 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12551 .channel_mode = alc262_modes, 12552 .input_mux = &alc262_capture_source, 12553 .unsol_event = alc262_hippo_unsol_event, 12554 .setup = alc262_hippo_setup, 12555 .init_hook = alc262_hippo_automute, 12556 }, 12557 [ALC262_HIPPO_1] = { 12558 .mixers = { alc262_hippo1_mixer }, 12559 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs}, 12560 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12561 .dac_nids = alc262_dac_nids, 12562 .hp_nid = 0x02, 12563 .dig_out_nid = ALC262_DIGOUT_NID, 12564 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12565 .channel_mode = alc262_modes, 12566 .input_mux = &alc262_capture_source, 12567 .unsol_event = alc262_hippo_unsol_event, 12568 .setup = alc262_hippo1_setup, 12569 .init_hook = alc262_hippo_automute, 12570 }, 12571 [ALC262_FUJITSU] = { 12572 .mixers = { alc262_fujitsu_mixer }, 12573 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs, 12574 alc262_fujitsu_unsol_verbs }, 12575 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12576 .dac_nids = alc262_dac_nids, 12577 .hp_nid = 0x03, 12578 .dig_out_nid = ALC262_DIGOUT_NID, 12579 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12580 .channel_mode = alc262_modes, 12581 .input_mux = &alc262_fujitsu_capture_source, 12582 .unsol_event = alc262_fujitsu_unsol_event, 12583 .init_hook = alc262_fujitsu_init_hook, 12584 }, 12585 [ALC262_HP_BPC] = { 12586 .mixers = { alc262_HP_BPC_mixer }, 12587 .init_verbs = { alc262_HP_BPC_init_verbs }, 12588 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12589 .dac_nids = alc262_dac_nids, 12590 .hp_nid = 0x03, 12591 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12592 .channel_mode = alc262_modes, 12593 .input_mux = &alc262_HP_capture_source, 12594 .unsol_event = alc262_hp_bpc_unsol_event, 12595 .init_hook = alc262_hp_bpc_automute, 12596 }, 12597 [ALC262_HP_BPC_D7000_WF] = { 12598 .mixers = { alc262_HP_BPC_WildWest_mixer }, 12599 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs }, 12600 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12601 .dac_nids = alc262_dac_nids, 12602 .hp_nid = 0x03, 12603 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12604 .channel_mode = alc262_modes, 12605 .input_mux = &alc262_HP_D7000_capture_source, 12606 .unsol_event = alc262_hp_wildwest_unsol_event, 12607 .init_hook = alc262_hp_wildwest_automute, 12608 }, 12609 [ALC262_HP_BPC_D7000_WL] = { 12610 .mixers = { alc262_HP_BPC_WildWest_mixer, 12611 alc262_HP_BPC_WildWest_option_mixer }, 12612 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs }, 12613 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12614 .dac_nids = alc262_dac_nids, 12615 .hp_nid = 0x03, 12616 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12617 .channel_mode = alc262_modes, 12618 .input_mux = &alc262_HP_D7000_capture_source, 12619 .unsol_event = alc262_hp_wildwest_unsol_event, 12620 .init_hook = alc262_hp_wildwest_automute, 12621 }, 12622 [ALC262_HP_TC_T5735] = { 12623 .mixers = { alc262_hp_t5735_mixer }, 12624 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs }, 12625 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12626 .dac_nids = alc262_dac_nids, 12627 .hp_nid = 0x03, 12628 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12629 .channel_mode = alc262_modes, 12630 .input_mux = &alc262_capture_source, 12631 .unsol_event = alc_sku_unsol_event, 12632 .setup = alc262_hp_t5735_setup, 12633 .init_hook = alc_inithook, 12634 }, 12635 [ALC262_HP_RP5700] = { 12636 .mixers = { alc262_hp_rp5700_mixer }, 12637 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs }, 12638 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12639 .dac_nids = alc262_dac_nids, 12640 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12641 .channel_mode = alc262_modes, 12642 .input_mux = &alc262_hp_rp5700_capture_source, 12643 }, 12644 [ALC262_BENQ_ED8] = { 12645 .mixers = { alc262_base_mixer }, 12646 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs }, 12647 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12648 .dac_nids = alc262_dac_nids, 12649 .hp_nid = 0x03, 12650 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12651 .channel_mode = alc262_modes, 12652 .input_mux = &alc262_capture_source, 12653 }, 12654 [ALC262_SONY_ASSAMD] = { 12655 .mixers = { alc262_sony_mixer }, 12656 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs}, 12657 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12658 .dac_nids = alc262_dac_nids, 12659 .hp_nid = 0x02, 12660 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12661 .channel_mode = alc262_modes, 12662 .input_mux = &alc262_capture_source, 12663 .unsol_event = alc262_hippo_unsol_event, 12664 .setup = alc262_hippo_setup, 12665 .init_hook = alc262_hippo_automute, 12666 }, 12667 [ALC262_BENQ_T31] = { 12668 .mixers = { alc262_benq_t31_mixer }, 12669 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, 12670 alc_hp15_unsol_verbs }, 12671 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12672 .dac_nids = alc262_dac_nids, 12673 .hp_nid = 0x03, 12674 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12675 .channel_mode = alc262_modes, 12676 .input_mux = &alc262_capture_source, 12677 .unsol_event = alc262_hippo_unsol_event, 12678 .setup = alc262_hippo_setup, 12679 .init_hook = alc262_hippo_automute, 12680 }, 12681 [ALC262_ULTRA] = { 12682 .mixers = { alc262_ultra_mixer }, 12683 .cap_mixer = alc262_ultra_capture_mixer, 12684 .init_verbs = { alc262_ultra_verbs }, 12685 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12686 .dac_nids = alc262_dac_nids, 12687 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12688 .channel_mode = alc262_modes, 12689 .input_mux = &alc262_ultra_capture_source, 12690 .adc_nids = alc262_adc_nids, /* ADC0 */ 12691 .capsrc_nids = alc262_capsrc_nids, 12692 .num_adc_nids = 1, /* single ADC */ 12693 .unsol_event = alc262_ultra_unsol_event, 12694 .init_hook = alc262_ultra_automute, 12695 }, 12696 [ALC262_LENOVO_3000] = { 12697 .mixers = { alc262_lenovo_3000_mixer }, 12698 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs, 12699 alc262_lenovo_3000_unsol_verbs, 12700 alc262_lenovo_3000_init_verbs }, 12701 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12702 .dac_nids = alc262_dac_nids, 12703 .hp_nid = 0x03, 12704 .dig_out_nid = ALC262_DIGOUT_NID, 12705 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12706 .channel_mode = alc262_modes, 12707 .input_mux = &alc262_fujitsu_capture_source, 12708 .unsol_event = alc262_lenovo_3000_unsol_event, 12709 }, 12710 [ALC262_NEC] = { 12711 .mixers = { alc262_nec_mixer }, 12712 .init_verbs = { alc262_nec_verbs }, 12713 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12714 .dac_nids = alc262_dac_nids, 12715 .hp_nid = 0x03, 12716 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12717 .channel_mode = alc262_modes, 12718 .input_mux = &alc262_capture_source, 12719 }, 12720 [ALC262_TOSHIBA_S06] = { 12721 .mixers = { alc262_toshiba_s06_mixer }, 12722 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs, 12723 alc262_eapd_verbs }, 12724 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12725 .capsrc_nids = alc262_dmic_capsrc_nids, 12726 .dac_nids = alc262_dac_nids, 12727 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */ 12728 .num_adc_nids = 1, /* single ADC */ 12729 .dig_out_nid = ALC262_DIGOUT_NID, 12730 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12731 .channel_mode = alc262_modes, 12732 .unsol_event = alc_sku_unsol_event, 12733 .setup = alc262_toshiba_s06_setup, 12734 .init_hook = alc_inithook, 12735 }, 12736 [ALC262_TOSHIBA_RX1] = { 12737 .mixers = { alc262_toshiba_rx1_mixer }, 12738 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs }, 12739 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12740 .dac_nids = alc262_dac_nids, 12741 .hp_nid = 0x03, 12742 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12743 .channel_mode = alc262_modes, 12744 .input_mux = &alc262_capture_source, 12745 .unsol_event = alc262_hippo_unsol_event, 12746 .setup = alc262_hippo_setup, 12747 .init_hook = alc262_hippo_automute, 12748 }, 12749 [ALC262_TYAN] = { 12750 .mixers = { alc262_tyan_mixer }, 12751 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs}, 12752 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12753 .dac_nids = alc262_dac_nids, 12754 .hp_nid = 0x02, 12755 .dig_out_nid = ALC262_DIGOUT_NID, 12756 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12757 .channel_mode = alc262_modes, 12758 .input_mux = &alc262_capture_source, 12759 .unsol_event = alc_automute_amp_unsol_event, 12760 .setup = alc262_tyan_setup, 12761 .init_hook = alc_automute_amp, 12762 }, 12763}; 12764 12765static int patch_alc262(struct hda_codec *codec) 12766{ 12767 struct alc_spec *spec; 12768 int board_config; 12769 int err; 12770 12771 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 12772 if (spec == NULL) 12773 return -ENOMEM; 12774 12775 codec->spec = spec; 12776#if 0 12777 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is 12778 * under-run 12779 */ 12780 { 12781 int tmp; 12782 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7); 12783 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0); 12784 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7); 12785 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80); 12786 } 12787#endif 12788 alc_auto_parse_customize_define(codec); 12789 12790 alc_fix_pll_init(codec, 0x20, 0x0a, 10); 12791 12792 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST, 12793 alc262_models, 12794 alc262_cfg_tbl); 12795 12796 if (board_config < 0) { 12797 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 12798 codec->chip_name); 12799 board_config = ALC262_AUTO; 12800 } 12801 12802 if (board_config == ALC262_AUTO) 12803 alc_pick_fixup(codec, alc262_fixup_tbl, alc262_fixups, 1); 12804 12805 if (board_config == ALC262_AUTO) { 12806 /* automatic parse from the BIOS config */ 12807 err = alc262_parse_auto_config(codec); 12808 if (err < 0) { 12809 alc_free(codec); 12810 return err; 12811 } else if (!err) { 12812 printk(KERN_INFO 12813 "hda_codec: Cannot set up configuration " 12814 "from BIOS. Using base mode...\n"); 12815 board_config = ALC262_BASIC; 12816 } 12817 } 12818 12819 if (!spec->no_analog && has_cdefine_beep(codec)) { 12820 err = snd_hda_attach_beep_device(codec, 0x1); 12821 if (err < 0) { 12822 alc_free(codec); 12823 return err; 12824 } 12825 } 12826 12827 if (board_config != ALC262_AUTO) 12828 setup_preset(codec, &alc262_presets[board_config]); 12829 12830 spec->stream_analog_playback = &alc262_pcm_analog_playback; 12831 spec->stream_analog_capture = &alc262_pcm_analog_capture; 12832 12833 spec->stream_digital_playback = &alc262_pcm_digital_playback; 12834 spec->stream_digital_capture = &alc262_pcm_digital_capture; 12835 12836 if (!spec->adc_nids && spec->input_mux) { 12837 int i; 12838 /* check whether the digital-mic has to be supported */ 12839 for (i = 0; i < spec->input_mux->num_items; i++) { 12840 if (spec->input_mux->items[i].index >= 9) 12841 break; 12842 } 12843 if (i < spec->input_mux->num_items) { 12844 /* use only ADC0 */ 12845 spec->adc_nids = alc262_dmic_adc_nids; 12846 spec->num_adc_nids = 1; 12847 spec->capsrc_nids = alc262_dmic_capsrc_nids; 12848 } else { 12849 /* all analog inputs */ 12850 /* check whether NID 0x07 is valid */ 12851 unsigned int wcap = get_wcaps(codec, 0x07); 12852 12853 /* get type */ 12854 wcap = get_wcaps_type(wcap); 12855 if (wcap != AC_WID_AUD_IN) { 12856 spec->adc_nids = alc262_adc_nids_alt; 12857 spec->num_adc_nids = 12858 ARRAY_SIZE(alc262_adc_nids_alt); 12859 spec->capsrc_nids = alc262_capsrc_nids_alt; 12860 } else { 12861 spec->adc_nids = alc262_adc_nids; 12862 spec->num_adc_nids = 12863 ARRAY_SIZE(alc262_adc_nids); 12864 spec->capsrc_nids = alc262_capsrc_nids; 12865 } 12866 } 12867 } 12868 if (!spec->cap_mixer && !spec->no_analog) 12869 set_capture_mixer(codec); 12870 if (!spec->no_analog && has_cdefine_beep(codec)) 12871 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 12872 12873 if (board_config == ALC262_AUTO) 12874 alc_pick_fixup(codec, alc262_fixup_tbl, alc262_fixups, 0); 12875 12876 spec->vmaster_nid = 0x0c; 12877 12878 codec->patch_ops = alc_patch_ops; 12879 if (board_config == ALC262_AUTO) 12880 spec->init_hook = alc262_auto_init; 12881#ifdef CONFIG_SND_HDA_POWER_SAVE 12882 if (!spec->loopback.amplist) 12883 spec->loopback.amplist = alc262_loopbacks; 12884#endif 12885 12886 return 0; 12887} 12888 12889/* 12890 * ALC268 channel source setting (2 channel) 12891 */ 12892#define ALC268_DIGOUT_NID ALC880_DIGOUT_NID 12893#define alc268_modes alc260_modes 12894 12895static hda_nid_t alc268_dac_nids[2] = { 12896 /* front, hp */ 12897 0x02, 0x03 12898}; 12899 12900static hda_nid_t alc268_adc_nids[2] = { 12901 /* ADC0-1 */ 12902 0x08, 0x07 12903}; 12904 12905static hda_nid_t alc268_adc_nids_alt[1] = { 12906 /* ADC0 */ 12907 0x08 12908}; 12909 12910static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 }; 12911 12912static struct snd_kcontrol_new alc268_base_mixer[] = { 12913 /* output mixer control */ 12914 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), 12915 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 12916 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT), 12917 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 12918 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 12919 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 12920 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT), 12921 { } 12922}; 12923 12924static struct snd_kcontrol_new alc268_toshiba_mixer[] = { 12925 /* output mixer control */ 12926 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), 12927 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT), 12928 ALC262_HIPPO_MASTER_SWITCH, 12929 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 12930 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 12931 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT), 12932 { } 12933}; 12934 12935/* bind Beep switches of both NID 0x0f and 0x10 */ 12936static struct hda_bind_ctls alc268_bind_beep_sw = { 12937 .ops = &snd_hda_bind_sw, 12938 .values = { 12939 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT), 12940 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT), 12941 0 12942 }, 12943}; 12944 12945static struct snd_kcontrol_new alc268_beep_mixer[] = { 12946 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT), 12947 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw), 12948 { } 12949}; 12950 12951static struct hda_verb alc268_eapd_verbs[] = { 12952 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 12953 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, 12954 { } 12955}; 12956 12957/* Toshiba specific */ 12958static struct hda_verb alc268_toshiba_verbs[] = { 12959 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 12960 { } /* end */ 12961}; 12962 12963/* Acer specific */ 12964/* bind volumes of both NID 0x02 and 0x03 */ 12965static struct hda_bind_ctls alc268_acer_bind_master_vol = { 12966 .ops = &snd_hda_bind_vol, 12967 .values = { 12968 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), 12969 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT), 12970 0 12971 }, 12972}; 12973 12974/* mute/unmute internal speaker according to the hp jack and mute state */ 12975static void alc268_acer_automute(struct hda_codec *codec, int force) 12976{ 12977 struct alc_spec *spec = codec->spec; 12978 unsigned int mute; 12979 12980 if (force || !spec->sense_updated) { 12981 spec->jack_present = snd_hda_jack_detect(codec, 0x14); 12982 spec->sense_updated = 1; 12983 } 12984 if (spec->jack_present) 12985 mute = HDA_AMP_MUTE; /* mute internal speaker */ 12986 else /* unmute internal speaker if necessary */ 12987 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0); 12988 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 12989 HDA_AMP_MUTE, mute); 12990} 12991 12992 12993/* bind hp and internal speaker mute (with plug check) */ 12994static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol, 12995 struct snd_ctl_elem_value *ucontrol) 12996{ 12997 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 12998 long *valp = ucontrol->value.integer.value; 12999 int change; 13000 13001 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp); 13002 if (change) 13003 alc268_acer_automute(codec, 0); 13004 return change; 13005} 13006 13007static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = { 13008 /* output mixer control */ 13009 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), 13010 { 13011 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 13012 .name = "Master Playback Switch", 13013 .subdevice = HDA_SUBDEV_AMP_FLAG, 13014 .info = snd_hda_mixer_amp_switch_info, 13015 .get = snd_hda_mixer_amp_switch_get, 13016 .put = alc268_acer_master_sw_put, 13017 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 13018 }, 13019 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT), 13020 { } 13021}; 13022 13023static struct snd_kcontrol_new alc268_acer_mixer[] = { 13024 /* output mixer control */ 13025 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), 13026 { 13027 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 13028 .name = "Master Playback Switch", 13029 .subdevice = HDA_SUBDEV_AMP_FLAG, 13030 .info = snd_hda_mixer_amp_switch_info, 13031 .get = snd_hda_mixer_amp_switch_get, 13032 .put = alc268_acer_master_sw_put, 13033 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 13034 }, 13035 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 13036 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), 13037 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT), 13038 { } 13039}; 13040 13041static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = { 13042 /* output mixer control */ 13043 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), 13044 { 13045 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 13046 .name = "Master Playback Switch", 13047 .subdevice = HDA_SUBDEV_AMP_FLAG, 13048 .info = snd_hda_mixer_amp_switch_info, 13049 .get = snd_hda_mixer_amp_switch_get, 13050 .put = alc268_acer_master_sw_put, 13051 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 13052 }, 13053 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 13054 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT), 13055 { } 13056}; 13057 13058static struct hda_verb alc268_acer_aspire_one_verbs[] = { 13059 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 13060 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 13061 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 13062 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 13063 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06}, 13064 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017}, 13065 { } 13066}; 13067 13068static struct hda_verb alc268_acer_verbs[] = { 13069 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */ 13070 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 13071 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 13072 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 13073 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 13074 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 13075 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 13076 { } 13077}; 13078 13079/* unsolicited event for HP jack sensing */ 13080#define alc268_toshiba_unsol_event alc262_hippo_unsol_event 13081#define alc268_toshiba_setup alc262_hippo_setup 13082#define alc268_toshiba_automute alc262_hippo_automute 13083 13084static void alc268_acer_unsol_event(struct hda_codec *codec, 13085 unsigned int res) 13086{ 13087 if ((res >> 26) != ALC880_HP_EVENT) 13088 return; 13089 alc268_acer_automute(codec, 1); 13090} 13091 13092static void alc268_acer_init_hook(struct hda_codec *codec) 13093{ 13094 alc268_acer_automute(codec, 1); 13095} 13096 13097/* toggle speaker-output according to the hp-jack state */ 13098static void alc268_aspire_one_speaker_automute(struct hda_codec *codec) 13099{ 13100 unsigned int present; 13101 unsigned char bits; 13102 13103 present = snd_hda_jack_detect(codec, 0x15); 13104 bits = present ? HDA_AMP_MUTE : 0; 13105 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0, 13106 HDA_AMP_MUTE, bits); 13107 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1, 13108 HDA_AMP_MUTE, bits); 13109} 13110 13111static void alc268_acer_lc_unsol_event(struct hda_codec *codec, 13112 unsigned int res) 13113{ 13114 switch (res >> 26) { 13115 case ALC880_HP_EVENT: 13116 alc268_aspire_one_speaker_automute(codec); 13117 break; 13118 case ALC880_MIC_EVENT: 13119 alc_mic_automute(codec); 13120 break; 13121 } 13122} 13123 13124static void alc268_acer_lc_setup(struct hda_codec *codec) 13125{ 13126 struct alc_spec *spec = codec->spec; 13127 spec->ext_mic.pin = 0x18; 13128 spec->ext_mic.mux_idx = 0; 13129 spec->int_mic.pin = 0x12; 13130 spec->int_mic.mux_idx = 6; 13131 spec->auto_mic = 1; 13132} 13133 13134static void alc268_acer_lc_init_hook(struct hda_codec *codec) 13135{ 13136 alc268_aspire_one_speaker_automute(codec); 13137 alc_mic_automute(codec); 13138} 13139 13140static struct snd_kcontrol_new alc268_dell_mixer[] = { 13141 /* output mixer control */ 13142 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 13143 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 13144 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 13145 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 13146 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 13147 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), 13148 { } 13149}; 13150 13151static struct hda_verb alc268_dell_verbs[] = { 13152 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 13153 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 13154 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 13155 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, 13156 { } 13157}; 13158 13159/* mute/unmute internal speaker according to the hp jack and mute state */ 13160static void alc268_dell_setup(struct hda_codec *codec) 13161{ 13162 struct alc_spec *spec = codec->spec; 13163 13164 spec->autocfg.hp_pins[0] = 0x15; 13165 spec->autocfg.speaker_pins[0] = 0x14; 13166 spec->ext_mic.pin = 0x18; 13167 spec->ext_mic.mux_idx = 0; 13168 spec->int_mic.pin = 0x19; 13169 spec->int_mic.mux_idx = 1; 13170 spec->auto_mic = 1; 13171} 13172 13173static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = { 13174 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT), 13175 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 13176 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT), 13177 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 13178 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT), 13179 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT), 13180 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT), 13181 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 13182 { } 13183}; 13184 13185static struct hda_verb alc267_quanta_il1_verbs[] = { 13186 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 13187 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, 13188 { } 13189}; 13190 13191static void alc267_quanta_il1_setup(struct hda_codec *codec) 13192{ 13193 struct alc_spec *spec = codec->spec; 13194 spec->autocfg.hp_pins[0] = 0x15; 13195 spec->autocfg.speaker_pins[0] = 0x14; 13196 spec->ext_mic.pin = 0x18; 13197 spec->ext_mic.mux_idx = 0; 13198 spec->int_mic.pin = 0x19; 13199 spec->int_mic.mux_idx = 1; 13200 spec->auto_mic = 1; 13201} 13202 13203/* 13204 * generic initialization of ADC, input mixers and output mixers 13205 */ 13206static struct hda_verb alc268_base_init_verbs[] = { 13207 /* Unmute DAC0-1 and set vol = 0 */ 13208 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 13209 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 13210 13211 /* 13212 * Set up output mixers (0x0c - 0x0e) 13213 */ 13214 /* set vol=0 to output mixers */ 13215 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13216 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00}, 13217 13218 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13219 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13220 13221 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 13222 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 13223 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 13224 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 13225 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 13226 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 13227 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 13228 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 13229 13230 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 13231 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 13232 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 13233 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 13234 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 13235 13236 /* set PCBEEP vol = 0, mute connections */ 13237 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13238 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 13239 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 13240 13241 /* Unmute Selector 23h,24h and set the default input to mic-in */ 13242 13243 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00}, 13244 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 13245 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00}, 13246 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 13247 13248 { } 13249}; 13250 13251/* 13252 * generic initialization of ADC, input mixers and output mixers 13253 */ 13254static struct hda_verb alc268_volume_init_verbs[] = { 13255 /* set output DAC */ 13256 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 13257 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 13258 13259 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 13260 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 13261 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 13262 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 13263 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 13264 13265 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13266 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13267 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13268 13269 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 13270 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 13271 13272 /* set PCBEEP vol = 0, mute connections */ 13273 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13274 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 13275 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 13276 13277 { } 13278}; 13279 13280static struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = { 13281 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT), 13282 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT), 13283 { } /* end */ 13284}; 13285 13286static struct snd_kcontrol_new alc268_capture_alt_mixer[] = { 13287 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT), 13288 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT), 13289 _DEFINE_CAPSRC(1), 13290 { } /* end */ 13291}; 13292 13293static struct snd_kcontrol_new alc268_capture_mixer[] = { 13294 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT), 13295 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT), 13296 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT), 13297 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT), 13298 _DEFINE_CAPSRC(2), 13299 { } /* end */ 13300}; 13301 13302static struct hda_input_mux alc268_capture_source = { 13303 .num_items = 4, 13304 .items = { 13305 { "Mic", 0x0 }, 13306 { "Front Mic", 0x1 }, 13307 { "Line", 0x2 }, 13308 { "CD", 0x3 }, 13309 }, 13310}; 13311 13312static struct hda_input_mux alc268_acer_capture_source = { 13313 .num_items = 3, 13314 .items = { 13315 { "Mic", 0x0 }, 13316 { "Internal Mic", 0x1 }, 13317 { "Line", 0x2 }, 13318 }, 13319}; 13320 13321static struct hda_input_mux alc268_acer_dmic_capture_source = { 13322 .num_items = 3, 13323 .items = { 13324 { "Mic", 0x0 }, 13325 { "Internal Mic", 0x6 }, 13326 { "Line", 0x2 }, 13327 }, 13328}; 13329 13330#ifdef CONFIG_SND_DEBUG 13331static struct snd_kcontrol_new alc268_test_mixer[] = { 13332 /* Volume widgets */ 13333 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT), 13334 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT), 13335 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT), 13336 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT), 13337 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT), 13338 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT), 13339 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT), 13340 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT), 13341 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT), 13342 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT), 13343 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT), 13344 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT), 13345 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT), 13346 /* The below appears problematic on some hardwares */ 13347 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/ 13348 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT), 13349 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT), 13350 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT), 13351 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT), 13352 13353 /* Modes for retasking pin widgets */ 13354 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT), 13355 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT), 13356 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT), 13357 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT), 13358 13359 /* Controls for GPIO pins, assuming they are configured as outputs */ 13360 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01), 13361 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02), 13362 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04), 13363 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08), 13364 13365 /* Switches to allow the digital SPDIF output pin to be enabled. 13366 * The ALC268 does not have an SPDIF input. 13367 */ 13368 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01), 13369 13370 /* A switch allowing EAPD to be enabled. Some laptops seem to use 13371 * this output to turn on an external amplifier. 13372 */ 13373 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02), 13374 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02), 13375 13376 { } /* end */ 13377}; 13378#endif 13379 13380/* create input playback/capture controls for the given pin */ 13381static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid, 13382 const char *ctlname, int idx) 13383{ 13384 hda_nid_t dac; 13385 int err; 13386 13387 switch (nid) { 13388 case 0x14: 13389 case 0x16: 13390 dac = 0x02; 13391 break; 13392 case 0x15: 13393 case 0x1a: /* ALC259/269 only */ 13394 case 0x1b: /* ALC259/269 only */ 13395 case 0x21: /* ALC269vb has this pin, too */ 13396 dac = 0x03; 13397 break; 13398 default: 13399 snd_printd(KERN_WARNING "hda_codec: " 13400 "ignoring pin 0x%x as unknown\n", nid); 13401 return 0; 13402 } 13403 if (spec->multiout.dac_nids[0] != dac && 13404 spec->multiout.dac_nids[1] != dac) { 13405 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname, 13406 HDA_COMPOSE_AMP_VAL(dac, 3, idx, 13407 HDA_OUTPUT)); 13408 if (err < 0) 13409 return err; 13410 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac; 13411 } 13412 13413 if (nid != 0x16) 13414 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname, 13415 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT)); 13416 else /* mono */ 13417 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname, 13418 HDA_COMPOSE_AMP_VAL(nid, 2, idx, HDA_OUTPUT)); 13419 if (err < 0) 13420 return err; 13421 return 0; 13422} 13423 13424/* add playback controls from the parsed DAC table */ 13425static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec, 13426 const struct auto_pin_cfg *cfg) 13427{ 13428 hda_nid_t nid; 13429 int err; 13430 13431 spec->multiout.dac_nids = spec->private_dac_nids; 13432 13433 nid = cfg->line_out_pins[0]; 13434 if (nid) { 13435 const char *name; 13436 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) 13437 name = "Speaker"; 13438 else 13439 name = "Front"; 13440 err = alc268_new_analog_output(spec, nid, name, 0); 13441 if (err < 0) 13442 return err; 13443 } 13444 13445 nid = cfg->speaker_pins[0]; 13446 if (nid == 0x1d) { 13447 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, "Speaker", 13448 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT)); 13449 if (err < 0) 13450 return err; 13451 } else if (nid) { 13452 err = alc268_new_analog_output(spec, nid, "Speaker", 0); 13453 if (err < 0) 13454 return err; 13455 } 13456 nid = cfg->hp_pins[0]; 13457 if (nid) { 13458 err = alc268_new_analog_output(spec, nid, "Headphone", 0); 13459 if (err < 0) 13460 return err; 13461 } 13462 13463 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2]; 13464 if (nid == 0x16) { 13465 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, "Mono", 13466 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT)); 13467 if (err < 0) 13468 return err; 13469 } 13470 return 0; 13471} 13472 13473/* create playback/capture controls for input pins */ 13474static int alc268_auto_create_input_ctls(struct hda_codec *codec, 13475 const struct auto_pin_cfg *cfg) 13476{ 13477 return alc_auto_create_input_ctls(codec, cfg, 0, 0x23, 0x24); 13478} 13479 13480static void alc268_auto_set_output_and_unmute(struct hda_codec *codec, 13481 hda_nid_t nid, int pin_type) 13482{ 13483 int idx; 13484 13485 alc_set_pin_output(codec, nid, pin_type); 13486 if (nid == 0x14 || nid == 0x16) 13487 idx = 0; 13488 else 13489 idx = 1; 13490 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx); 13491} 13492 13493static void alc268_auto_init_multi_out(struct hda_codec *codec) 13494{ 13495 struct alc_spec *spec = codec->spec; 13496 int i; 13497 13498 for (i = 0; i < spec->autocfg.line_outs; i++) { 13499 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 13500 int pin_type = get_pin_type(spec->autocfg.line_out_type); 13501 alc268_auto_set_output_and_unmute(codec, nid, pin_type); 13502 } 13503} 13504 13505static void alc268_auto_init_hp_out(struct hda_codec *codec) 13506{ 13507 struct alc_spec *spec = codec->spec; 13508 hda_nid_t pin; 13509 int i; 13510 13511 for (i = 0; i < spec->autocfg.hp_outs; i++) { 13512 pin = spec->autocfg.hp_pins[i]; 13513 alc268_auto_set_output_and_unmute(codec, pin, PIN_HP); 13514 } 13515 for (i = 0; i < spec->autocfg.speaker_outs; i++) { 13516 pin = spec->autocfg.speaker_pins[i]; 13517 alc268_auto_set_output_and_unmute(codec, pin, PIN_OUT); 13518 } 13519 if (spec->autocfg.mono_out_pin) 13520 snd_hda_codec_write(codec, spec->autocfg.mono_out_pin, 0, 13521 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); 13522} 13523 13524static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec) 13525{ 13526 struct alc_spec *spec = codec->spec; 13527 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0]; 13528 hda_nid_t hp_nid = spec->autocfg.hp_pins[0]; 13529 hda_nid_t line_nid = spec->autocfg.line_out_pins[0]; 13530 unsigned int dac_vol1, dac_vol2; 13531 13532 if (line_nid == 0x1d || speaker_nid == 0x1d) { 13533 snd_hda_codec_write(codec, speaker_nid, 0, 13534 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); 13535 /* mute mixer inputs from 0x1d */ 13536 snd_hda_codec_write(codec, 0x0f, 0, 13537 AC_VERB_SET_AMP_GAIN_MUTE, 13538 AMP_IN_UNMUTE(1)); 13539 snd_hda_codec_write(codec, 0x10, 0, 13540 AC_VERB_SET_AMP_GAIN_MUTE, 13541 AMP_IN_UNMUTE(1)); 13542 } else { 13543 /* unmute mixer inputs from 0x1d */ 13544 snd_hda_codec_write(codec, 0x0f, 0, 13545 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)); 13546 snd_hda_codec_write(codec, 0x10, 0, 13547 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)); 13548 } 13549 13550 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */ 13551 if (line_nid == 0x14) 13552 dac_vol2 = AMP_OUT_ZERO; 13553 else if (line_nid == 0x15) 13554 dac_vol1 = AMP_OUT_ZERO; 13555 if (hp_nid == 0x14) 13556 dac_vol2 = AMP_OUT_ZERO; 13557 else if (hp_nid == 0x15) 13558 dac_vol1 = AMP_OUT_ZERO; 13559 if (line_nid != 0x16 || hp_nid != 0x16 || 13560 spec->autocfg.line_out_pins[1] != 0x16 || 13561 spec->autocfg.line_out_pins[2] != 0x16) 13562 dac_vol1 = dac_vol2 = AMP_OUT_ZERO; 13563 13564 snd_hda_codec_write(codec, 0x02, 0, 13565 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1); 13566 snd_hda_codec_write(codec, 0x03, 0, 13567 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2); 13568} 13569 13570/* pcm configuration: identical with ALC880 */ 13571#define alc268_pcm_analog_playback alc880_pcm_analog_playback 13572#define alc268_pcm_analog_capture alc880_pcm_analog_capture 13573#define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture 13574#define alc268_pcm_digital_playback alc880_pcm_digital_playback 13575 13576/* 13577 * BIOS auto configuration 13578 */ 13579static int alc268_parse_auto_config(struct hda_codec *codec) 13580{ 13581 struct alc_spec *spec = codec->spec; 13582 int err; 13583 static hda_nid_t alc268_ignore[] = { 0 }; 13584 13585 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 13586 alc268_ignore); 13587 if (err < 0) 13588 return err; 13589 if (!spec->autocfg.line_outs) { 13590 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) { 13591 spec->multiout.max_channels = 2; 13592 spec->no_analog = 1; 13593 goto dig_only; 13594 } 13595 return 0; /* can't find valid BIOS pin config */ 13596 } 13597 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg); 13598 if (err < 0) 13599 return err; 13600 err = alc268_auto_create_input_ctls(codec, &spec->autocfg); 13601 if (err < 0) 13602 return err; 13603 13604 spec->multiout.max_channels = 2; 13605 13606 dig_only: 13607 /* digital only support output */ 13608 alc_auto_parse_digital(codec); 13609 if (spec->kctls.list) 13610 add_mixer(spec, spec->kctls.list); 13611 13612 if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d) 13613 add_mixer(spec, alc268_beep_mixer); 13614 13615 add_verb(spec, alc268_volume_init_verbs); 13616 spec->num_mux_defs = 2; 13617 spec->input_mux = &spec->private_imux[0]; 13618 13619 err = alc_auto_add_mic_boost(codec); 13620 if (err < 0) 13621 return err; 13622 13623 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); 13624 13625 return 1; 13626} 13627 13628#define alc268_auto_init_analog_input alc882_auto_init_analog_input 13629 13630/* init callback for auto-configuration model -- overriding the default init */ 13631static void alc268_auto_init(struct hda_codec *codec) 13632{ 13633 struct alc_spec *spec = codec->spec; 13634 alc268_auto_init_multi_out(codec); 13635 alc268_auto_init_hp_out(codec); 13636 alc268_auto_init_mono_speaker_out(codec); 13637 alc268_auto_init_analog_input(codec); 13638 alc_auto_init_digital(codec); 13639 if (spec->unsol_event) 13640 alc_inithook(codec); 13641} 13642 13643/* 13644 * configuration and preset 13645 */ 13646static const char *alc268_models[ALC268_MODEL_LAST] = { 13647 [ALC267_QUANTA_IL1] = "quanta-il1", 13648 [ALC268_3ST] = "3stack", 13649 [ALC268_TOSHIBA] = "toshiba", 13650 [ALC268_ACER] = "acer", 13651 [ALC268_ACER_DMIC] = "acer-dmic", 13652 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire", 13653 [ALC268_DELL] = "dell", 13654 [ALC268_ZEPTO] = "zepto", 13655#ifdef CONFIG_SND_DEBUG 13656 [ALC268_TEST] = "test", 13657#endif 13658 [ALC268_AUTO] = "auto", 13659}; 13660 13661static struct snd_pci_quirk alc268_cfg_tbl[] = { 13662 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER), 13663 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER), 13664 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER), 13665 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER), 13666 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER), 13667 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One", 13668 ALC268_ACER_ASPIRE_ONE), 13669 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL), 13670 SND_PCI_QUIRK_MASK(0x1028, 0xfff0, 0x02b0, 13671 "Dell Inspiron Mini9/Vostro A90", ALC268_DELL), 13672 /* almost compatible with toshiba but with optional digital outs; 13673 * auto-probing seems working fine 13674 */ 13675 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series", 13676 ALC268_AUTO), 13677 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST), 13678 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO), 13679 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA), 13680 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER), 13681 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1), 13682 {} 13683}; 13684 13685/* Toshiba laptops have no unique PCI SSID but only codec SSID */ 13686static struct snd_pci_quirk alc268_ssid_cfg_tbl[] = { 13687 SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO), 13688 SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO), 13689 SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05", 13690 ALC268_TOSHIBA), 13691 {} 13692}; 13693 13694static struct alc_config_preset alc268_presets[] = { 13695 [ALC267_QUANTA_IL1] = { 13696 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer, 13697 alc268_capture_nosrc_mixer }, 13698 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 13699 alc267_quanta_il1_verbs }, 13700 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 13701 .dac_nids = alc268_dac_nids, 13702 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 13703 .adc_nids = alc268_adc_nids_alt, 13704 .hp_nid = 0x03, 13705 .num_channel_mode = ARRAY_SIZE(alc268_modes), 13706 .channel_mode = alc268_modes, 13707 .unsol_event = alc_sku_unsol_event, 13708 .setup = alc267_quanta_il1_setup, 13709 .init_hook = alc_inithook, 13710 }, 13711 [ALC268_3ST] = { 13712 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer, 13713 alc268_beep_mixer }, 13714 .init_verbs = { alc268_base_init_verbs }, 13715 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 13716 .dac_nids = alc268_dac_nids, 13717 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 13718 .adc_nids = alc268_adc_nids_alt, 13719 .capsrc_nids = alc268_capsrc_nids, 13720 .hp_nid = 0x03, 13721 .dig_out_nid = ALC268_DIGOUT_NID, 13722 .num_channel_mode = ARRAY_SIZE(alc268_modes), 13723 .channel_mode = alc268_modes, 13724 .input_mux = &alc268_capture_source, 13725 }, 13726 [ALC268_TOSHIBA] = { 13727 .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer, 13728 alc268_beep_mixer }, 13729 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 13730 alc268_toshiba_verbs }, 13731 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 13732 .dac_nids = alc268_dac_nids, 13733 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 13734 .adc_nids = alc268_adc_nids_alt, 13735 .capsrc_nids = alc268_capsrc_nids, 13736 .hp_nid = 0x03, 13737 .num_channel_mode = ARRAY_SIZE(alc268_modes), 13738 .channel_mode = alc268_modes, 13739 .input_mux = &alc268_capture_source, 13740 .unsol_event = alc268_toshiba_unsol_event, 13741 .setup = alc268_toshiba_setup, 13742 .init_hook = alc268_toshiba_automute, 13743 }, 13744 [ALC268_ACER] = { 13745 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer, 13746 alc268_beep_mixer }, 13747 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 13748 alc268_acer_verbs }, 13749 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 13750 .dac_nids = alc268_dac_nids, 13751 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 13752 .adc_nids = alc268_adc_nids_alt, 13753 .capsrc_nids = alc268_capsrc_nids, 13754 .hp_nid = 0x02, 13755 .num_channel_mode = ARRAY_SIZE(alc268_modes), 13756 .channel_mode = alc268_modes, 13757 .input_mux = &alc268_acer_capture_source, 13758 .unsol_event = alc268_acer_unsol_event, 13759 .init_hook = alc268_acer_init_hook, 13760 }, 13761 [ALC268_ACER_DMIC] = { 13762 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer, 13763 alc268_beep_mixer }, 13764 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 13765 alc268_acer_verbs }, 13766 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 13767 .dac_nids = alc268_dac_nids, 13768 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 13769 .adc_nids = alc268_adc_nids_alt, 13770 .capsrc_nids = alc268_capsrc_nids, 13771 .hp_nid = 0x02, 13772 .num_channel_mode = ARRAY_SIZE(alc268_modes), 13773 .channel_mode = alc268_modes, 13774 .input_mux = &alc268_acer_dmic_capture_source, 13775 .unsol_event = alc268_acer_unsol_event, 13776 .init_hook = alc268_acer_init_hook, 13777 }, 13778 [ALC268_ACER_ASPIRE_ONE] = { 13779 .mixers = { alc268_acer_aspire_one_mixer, 13780 alc268_beep_mixer, 13781 alc268_capture_nosrc_mixer }, 13782 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 13783 alc268_acer_aspire_one_verbs }, 13784 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 13785 .dac_nids = alc268_dac_nids, 13786 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 13787 .adc_nids = alc268_adc_nids_alt, 13788 .capsrc_nids = alc268_capsrc_nids, 13789 .hp_nid = 0x03, 13790 .num_channel_mode = ARRAY_SIZE(alc268_modes), 13791 .channel_mode = alc268_modes, 13792 .unsol_event = alc268_acer_lc_unsol_event, 13793 .setup = alc268_acer_lc_setup, 13794 .init_hook = alc268_acer_lc_init_hook, 13795 }, 13796 [ALC268_DELL] = { 13797 .mixers = { alc268_dell_mixer, alc268_beep_mixer, 13798 alc268_capture_nosrc_mixer }, 13799 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 13800 alc268_dell_verbs }, 13801 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 13802 .dac_nids = alc268_dac_nids, 13803 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 13804 .adc_nids = alc268_adc_nids_alt, 13805 .capsrc_nids = alc268_capsrc_nids, 13806 .hp_nid = 0x02, 13807 .num_channel_mode = ARRAY_SIZE(alc268_modes), 13808 .channel_mode = alc268_modes, 13809 .unsol_event = alc_sku_unsol_event, 13810 .setup = alc268_dell_setup, 13811 .init_hook = alc_inithook, 13812 }, 13813 [ALC268_ZEPTO] = { 13814 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer, 13815 alc268_beep_mixer }, 13816 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 13817 alc268_toshiba_verbs }, 13818 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 13819 .dac_nids = alc268_dac_nids, 13820 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 13821 .adc_nids = alc268_adc_nids_alt, 13822 .capsrc_nids = alc268_capsrc_nids, 13823 .hp_nid = 0x03, 13824 .dig_out_nid = ALC268_DIGOUT_NID, 13825 .num_channel_mode = ARRAY_SIZE(alc268_modes), 13826 .channel_mode = alc268_modes, 13827 .input_mux = &alc268_capture_source, 13828 .setup = alc268_toshiba_setup, 13829 .init_hook = alc268_toshiba_automute, 13830 }, 13831#ifdef CONFIG_SND_DEBUG 13832 [ALC268_TEST] = { 13833 .mixers = { alc268_test_mixer, alc268_capture_mixer }, 13834 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 13835 alc268_volume_init_verbs }, 13836 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 13837 .dac_nids = alc268_dac_nids, 13838 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 13839 .adc_nids = alc268_adc_nids_alt, 13840 .capsrc_nids = alc268_capsrc_nids, 13841 .hp_nid = 0x03, 13842 .dig_out_nid = ALC268_DIGOUT_NID, 13843 .num_channel_mode = ARRAY_SIZE(alc268_modes), 13844 .channel_mode = alc268_modes, 13845 .input_mux = &alc268_capture_source, 13846 }, 13847#endif 13848}; 13849 13850static int patch_alc268(struct hda_codec *codec) 13851{ 13852 struct alc_spec *spec; 13853 int board_config; 13854 int i, has_beep, err; 13855 13856 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 13857 if (spec == NULL) 13858 return -ENOMEM; 13859 13860 codec->spec = spec; 13861 13862 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST, 13863 alc268_models, 13864 alc268_cfg_tbl); 13865 13866 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) 13867 board_config = snd_hda_check_board_codec_sid_config(codec, 13868 ALC268_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl); 13869 13870 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) { 13871 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 13872 codec->chip_name); 13873 board_config = ALC268_AUTO; 13874 } 13875 13876 if (board_config == ALC268_AUTO) { 13877 /* automatic parse from the BIOS config */ 13878 err = alc268_parse_auto_config(codec); 13879 if (err < 0) { 13880 alc_free(codec); 13881 return err; 13882 } else if (!err) { 13883 printk(KERN_INFO 13884 "hda_codec: Cannot set up configuration " 13885 "from BIOS. Using base mode...\n"); 13886 board_config = ALC268_3ST; 13887 } 13888 } 13889 13890 if (board_config != ALC268_AUTO) 13891 setup_preset(codec, &alc268_presets[board_config]); 13892 13893 spec->stream_analog_playback = &alc268_pcm_analog_playback; 13894 spec->stream_analog_capture = &alc268_pcm_analog_capture; 13895 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture; 13896 13897 spec->stream_digital_playback = &alc268_pcm_digital_playback; 13898 13899 has_beep = 0; 13900 for (i = 0; i < spec->num_mixers; i++) { 13901 if (spec->mixers[i] == alc268_beep_mixer) { 13902 has_beep = 1; 13903 break; 13904 } 13905 } 13906 13907 if (has_beep) { 13908 err = snd_hda_attach_beep_device(codec, 0x1); 13909 if (err < 0) { 13910 alc_free(codec); 13911 return err; 13912 } 13913 if (!query_amp_caps(codec, 0x1d, HDA_INPUT)) 13914 /* override the amp caps for beep generator */ 13915 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT, 13916 (0x0c << AC_AMPCAP_OFFSET_SHIFT) | 13917 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) | 13918 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) | 13919 (0 << AC_AMPCAP_MUTE_SHIFT)); 13920 } 13921 13922 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) { 13923 /* check whether NID 0x07 is valid */ 13924 unsigned int wcap = get_wcaps(codec, 0x07); 13925 int i; 13926 13927 spec->capsrc_nids = alc268_capsrc_nids; 13928 /* get type */ 13929 wcap = get_wcaps_type(wcap); 13930 if (spec->auto_mic || 13931 wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) { 13932 spec->adc_nids = alc268_adc_nids_alt; 13933 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt); 13934 if (spec->auto_mic) 13935 fixup_automic_adc(codec); 13936 if (spec->auto_mic || spec->input_mux->num_items == 1) 13937 add_mixer(spec, alc268_capture_nosrc_mixer); 13938 else 13939 add_mixer(spec, alc268_capture_alt_mixer); 13940 } else { 13941 spec->adc_nids = alc268_adc_nids; 13942 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids); 13943 add_mixer(spec, alc268_capture_mixer); 13944 } 13945 /* set default input source */ 13946 for (i = 0; i < spec->num_adc_nids; i++) 13947 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i], 13948 0, AC_VERB_SET_CONNECT_SEL, 13949 i < spec->num_mux_defs ? 13950 spec->input_mux[i].items[0].index : 13951 spec->input_mux->items[0].index); 13952 } 13953 13954 spec->vmaster_nid = 0x02; 13955 13956 codec->patch_ops = alc_patch_ops; 13957 if (board_config == ALC268_AUTO) 13958 spec->init_hook = alc268_auto_init; 13959 13960 return 0; 13961} 13962 13963/* 13964 * ALC269 channel source setting (2 channel) 13965 */ 13966#define ALC269_DIGOUT_NID ALC880_DIGOUT_NID 13967 13968#define alc269_dac_nids alc260_dac_nids 13969 13970static hda_nid_t alc269_adc_nids[1] = { 13971 /* ADC1 */ 13972 0x08, 13973}; 13974 13975static hda_nid_t alc269_capsrc_nids[1] = { 13976 0x23, 13977}; 13978 13979static hda_nid_t alc269vb_adc_nids[1] = { 13980 /* ADC1 */ 13981 0x09, 13982}; 13983 13984static hda_nid_t alc269vb_capsrc_nids[1] = { 13985 0x22, 13986}; 13987 13988static hda_nid_t alc269_adc_candidates[] = { 13989 0x08, 0x09, 0x07, 13990}; 13991 13992#define alc269_modes alc260_modes 13993#define alc269_capture_source alc880_lg_lw_capture_source 13994 13995static struct snd_kcontrol_new alc269_base_mixer[] = { 13996 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 13997 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 13998 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 13999 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 14000 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 14001 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 14002 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 14003 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 14004 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 14005 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 14006 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 14007 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT), 14008 { } /* end */ 14009}; 14010 14011static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = { 14012 /* output mixer control */ 14013 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), 14014 { 14015 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 14016 .name = "Master Playback Switch", 14017 .subdevice = HDA_SUBDEV_AMP_FLAG, 14018 .info = snd_hda_mixer_amp_switch_info, 14019 .get = snd_hda_mixer_amp_switch_get, 14020 .put = alc268_acer_master_sw_put, 14021 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 14022 }, 14023 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 14024 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 14025 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 14026 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 14027 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 14028 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), 14029 { } 14030}; 14031 14032static struct snd_kcontrol_new alc269_lifebook_mixer[] = { 14033 /* output mixer control */ 14034 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), 14035 { 14036 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 14037 .name = "Master Playback Switch", 14038 .subdevice = HDA_SUBDEV_AMP_FLAG, 14039 .info = snd_hda_mixer_amp_switch_info, 14040 .get = snd_hda_mixer_amp_switch_get, 14041 .put = alc268_acer_master_sw_put, 14042 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 14043 }, 14044 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 14045 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 14046 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 14047 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 14048 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 14049 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), 14050 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT), 14051 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT), 14052 HDA_CODEC_VOLUME("Dock Mic Boost", 0x1b, 0, HDA_INPUT), 14053 { } 14054}; 14055 14056static struct snd_kcontrol_new alc269_laptop_mixer[] = { 14057 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 14058 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 14059 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 14060 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 14061 { } /* end */ 14062}; 14063 14064static struct snd_kcontrol_new alc269vb_laptop_mixer[] = { 14065 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 14066 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 14067 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT), 14068 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 14069 { } /* end */ 14070}; 14071 14072static struct snd_kcontrol_new alc269_asus_mixer[] = { 14073 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT), 14074 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x0, HDA_INPUT), 14075 { } /* end */ 14076}; 14077 14078/* capture mixer elements */ 14079static struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = { 14080 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 14081 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 14082 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 14083 HDA_CODEC_VOLUME("IntMic Boost", 0x19, 0, HDA_INPUT), 14084 { } /* end */ 14085}; 14086 14087static struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = { 14088 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 14089 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 14090 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 14091 { } /* end */ 14092}; 14093 14094static struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = { 14095 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), 14096 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), 14097 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 14098 HDA_CODEC_VOLUME("IntMic Boost", 0x19, 0, HDA_INPUT), 14099 { } /* end */ 14100}; 14101 14102static struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = { 14103 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), 14104 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), 14105 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 14106 { } /* end */ 14107}; 14108 14109/* FSC amilo */ 14110#define alc269_fujitsu_mixer alc269_laptop_mixer 14111 14112static struct hda_verb alc269_quanta_fl1_verbs[] = { 14113 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 14114 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14115 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 14116 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 14117 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 14118 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14119 { } 14120}; 14121 14122static struct hda_verb alc269_lifebook_verbs[] = { 14123 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 14124 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, 14125 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14126 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 14127 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 14128 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 14129 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 14130 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 14131 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 14132 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14133 { } 14134}; 14135 14136/* toggle speaker-output according to the hp-jack state */ 14137static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec) 14138{ 14139 unsigned int present; 14140 unsigned char bits; 14141 14142 present = snd_hda_jack_detect(codec, 0x15); 14143 bits = present ? HDA_AMP_MUTE : 0; 14144 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 14145 HDA_AMP_MUTE, bits); 14146 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 14147 HDA_AMP_MUTE, bits); 14148 14149 snd_hda_codec_write(codec, 0x20, 0, 14150 AC_VERB_SET_COEF_INDEX, 0x0c); 14151 snd_hda_codec_write(codec, 0x20, 0, 14152 AC_VERB_SET_PROC_COEF, 0x680); 14153 14154 snd_hda_codec_write(codec, 0x20, 0, 14155 AC_VERB_SET_COEF_INDEX, 0x0c); 14156 snd_hda_codec_write(codec, 0x20, 0, 14157 AC_VERB_SET_PROC_COEF, 0x480); 14158} 14159 14160/* toggle speaker-output according to the hp-jacks state */ 14161static void alc269_lifebook_speaker_automute(struct hda_codec *codec) 14162{ 14163 unsigned int present; 14164 unsigned char bits; 14165 14166 /* Check laptop headphone socket */ 14167 present = snd_hda_jack_detect(codec, 0x15); 14168 14169 /* Check port replicator headphone socket */ 14170 present |= snd_hda_jack_detect(codec, 0x1a); 14171 14172 bits = present ? HDA_AMP_MUTE : 0; 14173 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 14174 HDA_AMP_MUTE, bits); 14175 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 14176 HDA_AMP_MUTE, bits); 14177 14178 snd_hda_codec_write(codec, 0x20, 0, 14179 AC_VERB_SET_COEF_INDEX, 0x0c); 14180 snd_hda_codec_write(codec, 0x20, 0, 14181 AC_VERB_SET_PROC_COEF, 0x680); 14182 14183 snd_hda_codec_write(codec, 0x20, 0, 14184 AC_VERB_SET_COEF_INDEX, 0x0c); 14185 snd_hda_codec_write(codec, 0x20, 0, 14186 AC_VERB_SET_PROC_COEF, 0x480); 14187} 14188 14189static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec) 14190{ 14191 unsigned int present_laptop; 14192 unsigned int present_dock; 14193 14194 present_laptop = snd_hda_jack_detect(codec, 0x18); 14195 present_dock = snd_hda_jack_detect(codec, 0x1b); 14196 14197 /* Laptop mic port overrides dock mic port, design decision */ 14198 if (present_dock) 14199 snd_hda_codec_write(codec, 0x23, 0, 14200 AC_VERB_SET_CONNECT_SEL, 0x3); 14201 if (present_laptop) 14202 snd_hda_codec_write(codec, 0x23, 0, 14203 AC_VERB_SET_CONNECT_SEL, 0x0); 14204 if (!present_dock && !present_laptop) 14205 snd_hda_codec_write(codec, 0x23, 0, 14206 AC_VERB_SET_CONNECT_SEL, 0x1); 14207} 14208 14209static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec, 14210 unsigned int res) 14211{ 14212 switch (res >> 26) { 14213 case ALC880_HP_EVENT: 14214 alc269_quanta_fl1_speaker_automute(codec); 14215 break; 14216 case ALC880_MIC_EVENT: 14217 alc_mic_automute(codec); 14218 break; 14219 } 14220} 14221 14222static void alc269_lifebook_unsol_event(struct hda_codec *codec, 14223 unsigned int res) 14224{ 14225 if ((res >> 26) == ALC880_HP_EVENT) 14226 alc269_lifebook_speaker_automute(codec); 14227 if ((res >> 26) == ALC880_MIC_EVENT) 14228 alc269_lifebook_mic_autoswitch(codec); 14229} 14230 14231static void alc269_quanta_fl1_setup(struct hda_codec *codec) 14232{ 14233 struct alc_spec *spec = codec->spec; 14234 spec->autocfg.hp_pins[0] = 0x15; 14235 spec->autocfg.speaker_pins[0] = 0x14; 14236 spec->ext_mic.pin = 0x18; 14237 spec->ext_mic.mux_idx = 0; 14238 spec->int_mic.pin = 0x19; 14239 spec->int_mic.mux_idx = 1; 14240 spec->auto_mic = 1; 14241} 14242 14243static void alc269_quanta_fl1_init_hook(struct hda_codec *codec) 14244{ 14245 alc269_quanta_fl1_speaker_automute(codec); 14246 alc_mic_automute(codec); 14247} 14248 14249static void alc269_lifebook_init_hook(struct hda_codec *codec) 14250{ 14251 alc269_lifebook_speaker_automute(codec); 14252 alc269_lifebook_mic_autoswitch(codec); 14253} 14254 14255static struct hda_verb alc269_laptop_dmic_init_verbs[] = { 14256 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 14257 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05}, 14258 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 }, 14259 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))}, 14260 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14261 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 14262 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 14263 {} 14264}; 14265 14266static struct hda_verb alc269_laptop_amic_init_verbs[] = { 14267 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 14268 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01}, 14269 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 }, 14270 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))}, 14271 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 14272 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 14273 {} 14274}; 14275 14276static struct hda_verb alc269vb_laptop_dmic_init_verbs[] = { 14277 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, 14278 {0x22, AC_VERB_SET_CONNECT_SEL, 0x06}, 14279 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 }, 14280 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))}, 14281 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14282 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 14283 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 14284 {} 14285}; 14286 14287static struct hda_verb alc269vb_laptop_amic_init_verbs[] = { 14288 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, 14289 {0x22, AC_VERB_SET_CONNECT_SEL, 0x01}, 14290 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 }, 14291 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))}, 14292 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14293 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 14294 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 14295 {} 14296}; 14297 14298static struct hda_verb alc271_acer_dmic_verbs[] = { 14299 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d}, 14300 {0x20, AC_VERB_SET_PROC_COEF, 0x4000}, 14301 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14302 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 14303 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 14304 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 14305 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, 14306 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 14307 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 14308 {0x22, AC_VERB_SET_CONNECT_SEL, 6}, 14309 { } 14310}; 14311 14312/* toggle speaker-output according to the hp-jack state */ 14313static void alc269_speaker_automute(struct hda_codec *codec) 14314{ 14315 struct alc_spec *spec = codec->spec; 14316 unsigned int nid = spec->autocfg.hp_pins[0]; 14317 unsigned int present; 14318 unsigned char bits; 14319 14320 present = snd_hda_jack_detect(codec, nid); 14321 bits = present ? HDA_AMP_MUTE : 0; 14322 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 14323 HDA_AMP_MUTE, bits); 14324 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 14325 HDA_AMP_MUTE, bits); 14326} 14327 14328/* unsolicited event for HP jack sensing */ 14329static void alc269_laptop_unsol_event(struct hda_codec *codec, 14330 unsigned int res) 14331{ 14332 switch (res >> 26) { 14333 case ALC880_HP_EVENT: 14334 alc269_speaker_automute(codec); 14335 break; 14336 case ALC880_MIC_EVENT: 14337 alc_mic_automute(codec); 14338 break; 14339 } 14340} 14341 14342static void alc269_laptop_amic_setup(struct hda_codec *codec) 14343{ 14344 struct alc_spec *spec = codec->spec; 14345 spec->autocfg.hp_pins[0] = 0x15; 14346 spec->autocfg.speaker_pins[0] = 0x14; 14347 spec->ext_mic.pin = 0x18; 14348 spec->ext_mic.mux_idx = 0; 14349 spec->int_mic.pin = 0x19; 14350 spec->int_mic.mux_idx = 1; 14351 spec->auto_mic = 1; 14352} 14353 14354static void alc269_laptop_dmic_setup(struct hda_codec *codec) 14355{ 14356 struct alc_spec *spec = codec->spec; 14357 spec->autocfg.hp_pins[0] = 0x15; 14358 spec->autocfg.speaker_pins[0] = 0x14; 14359 spec->ext_mic.pin = 0x18; 14360 spec->ext_mic.mux_idx = 0; 14361 spec->int_mic.pin = 0x12; 14362 spec->int_mic.mux_idx = 5; 14363 spec->auto_mic = 1; 14364} 14365 14366static void alc269vb_laptop_amic_setup(struct hda_codec *codec) 14367{ 14368 struct alc_spec *spec = codec->spec; 14369 spec->autocfg.hp_pins[0] = 0x21; 14370 spec->autocfg.speaker_pins[0] = 0x14; 14371 spec->ext_mic.pin = 0x18; 14372 spec->ext_mic.mux_idx = 0; 14373 spec->int_mic.pin = 0x19; 14374 spec->int_mic.mux_idx = 1; 14375 spec->auto_mic = 1; 14376} 14377 14378static void alc269vb_laptop_dmic_setup(struct hda_codec *codec) 14379{ 14380 struct alc_spec *spec = codec->spec; 14381 spec->autocfg.hp_pins[0] = 0x21; 14382 spec->autocfg.speaker_pins[0] = 0x14; 14383 spec->ext_mic.pin = 0x18; 14384 spec->ext_mic.mux_idx = 0; 14385 spec->int_mic.pin = 0x12; 14386 spec->int_mic.mux_idx = 6; 14387 spec->auto_mic = 1; 14388} 14389 14390static void alc269_laptop_inithook(struct hda_codec *codec) 14391{ 14392 alc269_speaker_automute(codec); 14393 alc_mic_automute(codec); 14394} 14395 14396/* 14397 * generic initialization of ADC, input mixers and output mixers 14398 */ 14399static struct hda_verb alc269_init_verbs[] = { 14400 /* 14401 * Unmute ADC0 and set the default input to mic-in 14402 */ 14403 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14404 14405 /* 14406 * Set up output mixers (0x02 - 0x03) 14407 */ 14408 /* set vol=0 to output mixers */ 14409 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 14410 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 14411 14412 /* set up input amps for analog loopback */ 14413 /* Amp Indices: DAC = 0, mixer = 1 */ 14414 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14415 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 14416 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14417 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 14418 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14419 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 14420 14421 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 14422 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 14423 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 14424 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 14425 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 14426 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14427 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14428 14429 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 14430 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 14431 14432 /* FIXME: use Mux-type input source selection */ 14433 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */ 14434 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 14435 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00}, 14436 14437 /* set EAPD */ 14438 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 14439 { } 14440}; 14441 14442static struct hda_verb alc269vb_init_verbs[] = { 14443 /* 14444 * Unmute ADC0 and set the default input to mic-in 14445 */ 14446 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14447 14448 /* 14449 * Set up output mixers (0x02 - 0x03) 14450 */ 14451 /* set vol=0 to output mixers */ 14452 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 14453 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 14454 14455 /* set up input amps for analog loopback */ 14456 /* Amp Indices: DAC = 0, mixer = 1 */ 14457 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14458 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 14459 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14460 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 14461 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14462 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 14463 14464 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 14465 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 14466 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 14467 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 14468 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 14469 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14470 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14471 14472 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 14473 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 14474 14475 /* FIXME: use Mux-type input source selection */ 14476 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */ 14477 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 14478 {0x22, AC_VERB_SET_CONNECT_SEL, 0x00}, 14479 14480 /* set EAPD */ 14481 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 14482 { } 14483}; 14484 14485#define alc269_auto_create_multi_out_ctls \ 14486 alc268_auto_create_multi_out_ctls 14487#define alc269_auto_create_input_ctls \ 14488 alc268_auto_create_input_ctls 14489 14490#ifdef CONFIG_SND_HDA_POWER_SAVE 14491#define alc269_loopbacks alc880_loopbacks 14492#endif 14493 14494/* pcm configuration: identical with ALC880 */ 14495#define alc269_pcm_analog_playback alc880_pcm_analog_playback 14496#define alc269_pcm_analog_capture alc880_pcm_analog_capture 14497#define alc269_pcm_digital_playback alc880_pcm_digital_playback 14498#define alc269_pcm_digital_capture alc880_pcm_digital_capture 14499 14500static struct hda_pcm_stream alc269_44k_pcm_analog_playback = { 14501 .substreams = 1, 14502 .channels_min = 2, 14503 .channels_max = 8, 14504 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */ 14505 /* NID is set in alc_build_pcms */ 14506 .ops = { 14507 .open = alc880_playback_pcm_open, 14508 .prepare = alc880_playback_pcm_prepare, 14509 .cleanup = alc880_playback_pcm_cleanup 14510 }, 14511}; 14512 14513static struct hda_pcm_stream alc269_44k_pcm_analog_capture = { 14514 .substreams = 1, 14515 .channels_min = 2, 14516 .channels_max = 2, 14517 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */ 14518 /* NID is set in alc_build_pcms */ 14519}; 14520 14521#ifdef CONFIG_SND_HDA_POWER_SAVE 14522static int alc269_mic2_for_mute_led(struct hda_codec *codec) 14523{ 14524 switch (codec->subsystem_id) { 14525 case 0x103c1586: 14526 return 1; 14527 } 14528 return 0; 14529} 14530 14531static int alc269_mic2_mute_check_ps(struct hda_codec *codec, hda_nid_t nid) 14532{ 14533 /* update mute-LED according to the speaker mute state */ 14534 if (nid == 0x01 || nid == 0x14) { 14535 int pinval; 14536 if (snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0) & 14537 HDA_AMP_MUTE) 14538 pinval = 0x24; 14539 else 14540 pinval = 0x20; 14541 /* mic2 vref pin is used for mute LED control */ 14542 snd_hda_codec_update_cache(codec, 0x19, 0, 14543 AC_VERB_SET_PIN_WIDGET_CONTROL, 14544 pinval); 14545 } 14546 return alc_check_power_status(codec, nid); 14547} 14548#endif /* CONFIG_SND_HDA_POWER_SAVE */ 14549 14550static int alc275_setup_dual_adc(struct hda_codec *codec) 14551{ 14552 struct alc_spec *spec = codec->spec; 14553 14554 if (codec->vendor_id != 0x10ec0275 || !spec->auto_mic) 14555 return 0; 14556 if ((spec->ext_mic.pin >= 0x18 && spec->int_mic.pin <= 0x13) || 14557 (spec->ext_mic.pin <= 0x12 && spec->int_mic.pin >= 0x18)) { 14558 if (spec->ext_mic.pin <= 0x12) { 14559 spec->private_adc_nids[0] = 0x08; 14560 spec->private_adc_nids[1] = 0x11; 14561 spec->private_capsrc_nids[0] = 0x23; 14562 spec->private_capsrc_nids[1] = 0x22; 14563 } else { 14564 spec->private_adc_nids[0] = 0x11; 14565 spec->private_adc_nids[1] = 0x08; 14566 spec->private_capsrc_nids[0] = 0x22; 14567 spec->private_capsrc_nids[1] = 0x23; 14568 } 14569 spec->adc_nids = spec->private_adc_nids; 14570 spec->capsrc_nids = spec->private_capsrc_nids; 14571 spec->num_adc_nids = 2; 14572 spec->dual_adc_switch = 1; 14573 snd_printdd("realtek: enabling dual ADC switchg (%02x:%02x)\n", 14574 spec->adc_nids[0], spec->adc_nids[1]); 14575 return 1; 14576 } 14577 return 0; 14578} 14579 14580/* different alc269-variants */ 14581enum { 14582 ALC269_TYPE_NORMAL, 14583 ALC269_TYPE_ALC259, 14584 ALC269_TYPE_ALC271X, 14585}; 14586 14587/* 14588 * BIOS auto configuration 14589 */ 14590static int alc269_parse_auto_config(struct hda_codec *codec) 14591{ 14592 struct alc_spec *spec = codec->spec; 14593 int err; 14594 static hda_nid_t alc269_ignore[] = { 0x1d, 0 }; 14595 14596 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 14597 alc269_ignore); 14598 if (err < 0) 14599 return err; 14600 14601 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg); 14602 if (err < 0) 14603 return err; 14604 if (spec->codec_variant == ALC269_TYPE_NORMAL) 14605 err = alc269_auto_create_input_ctls(codec, &spec->autocfg); 14606 else 14607 err = alc_auto_create_input_ctls(codec, &spec->autocfg, 0, 14608 0x22, 0); 14609 if (err < 0) 14610 return err; 14611 14612 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 14613 14614 alc_auto_parse_digital(codec); 14615 14616 if (spec->kctls.list) 14617 add_mixer(spec, spec->kctls.list); 14618 14619 if (spec->codec_variant != ALC269_TYPE_NORMAL) { 14620 add_verb(spec, alc269vb_init_verbs); 14621 alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21); 14622 } else { 14623 add_verb(spec, alc269_init_verbs); 14624 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); 14625 } 14626 14627 spec->num_mux_defs = 1; 14628 spec->input_mux = &spec->private_imux[0]; 14629 14630 if (!alc275_setup_dual_adc(codec)) 14631 fillup_priv_adc_nids(codec, alc269_adc_candidates, 14632 sizeof(alc269_adc_candidates)); 14633 14634 /* set default input source */ 14635 if (!spec->dual_adc_switch) 14636 select_or_unmute_capsrc(codec, spec->capsrc_nids[0], 14637 spec->input_mux->items[0].index); 14638 14639 err = alc_auto_add_mic_boost(codec); 14640 if (err < 0) 14641 return err; 14642 14643 if (!spec->cap_mixer && !spec->no_analog) 14644 set_capture_mixer(codec); 14645 14646 return 1; 14647} 14648 14649#define alc269_auto_init_multi_out alc268_auto_init_multi_out 14650#define alc269_auto_init_hp_out alc268_auto_init_hp_out 14651#define alc269_auto_init_analog_input alc882_auto_init_analog_input 14652 14653 14654/* init callback for auto-configuration model -- overriding the default init */ 14655static void alc269_auto_init(struct hda_codec *codec) 14656{ 14657 struct alc_spec *spec = codec->spec; 14658 alc269_auto_init_multi_out(codec); 14659 alc269_auto_init_hp_out(codec); 14660 alc269_auto_init_analog_input(codec); 14661 alc_auto_init_digital(codec); 14662 alc_init_jacks(codec); 14663 if (spec->unsol_event) 14664 alc_inithook(codec); 14665} 14666 14667#ifdef SND_HDA_NEEDS_RESUME 14668static void alc269_toggle_power_output(struct hda_codec *codec, int power_up) 14669{ 14670 int val = alc_read_coef_idx(codec, 0x04); 14671 if (power_up) 14672 val |= 1 << 11; 14673 else 14674 val &= ~(1 << 11); 14675 alc_write_coef_idx(codec, 0x04, val); 14676} 14677 14678#ifdef CONFIG_SND_HDA_POWER_SAVE 14679static int alc269_suspend(struct hda_codec *codec, pm_message_t state) 14680{ 14681 struct alc_spec *spec = codec->spec; 14682 14683 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) 14684 alc269_toggle_power_output(codec, 0); 14685 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) { 14686 alc269_toggle_power_output(codec, 0); 14687 msleep(150); 14688 } 14689 14690 alc_shutup(codec); 14691 if (spec && spec->power_hook) 14692 spec->power_hook(codec); 14693 return 0; 14694} 14695#endif /* CONFIG_SND_HDA_POWER_SAVE */ 14696 14697static int alc269_resume(struct hda_codec *codec) 14698{ 14699 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) { 14700 alc269_toggle_power_output(codec, 0); 14701 msleep(150); 14702 } 14703 14704 codec->patch_ops.init(codec); 14705 14706 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) { 14707 alc269_toggle_power_output(codec, 1); 14708 msleep(200); 14709 } 14710 14711 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) 14712 alc269_toggle_power_output(codec, 1); 14713 14714 snd_hda_codec_resume_amp(codec); 14715 snd_hda_codec_resume_cache(codec); 14716 hda_call_check_power_status(codec, 0x01); 14717 return 0; 14718} 14719#endif /* SND_HDA_NEEDS_RESUME */ 14720 14721enum { 14722 ALC269_FIXUP_SONY_VAIO, 14723 ALC269_FIXUP_DELL_M101Z, 14724}; 14725 14726static const struct alc_fixup alc269_fixups[] = { 14727 [ALC269_FIXUP_SONY_VAIO] = { 14728 .verbs = (const struct hda_verb[]) { 14729 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD}, 14730 {} 14731 } 14732 }, 14733 [ALC269_FIXUP_DELL_M101Z] = { 14734 .verbs = (const struct hda_verb[]) { 14735 /* Enables internal speaker */ 14736 {0x20, AC_VERB_SET_COEF_INDEX, 13}, 14737 {0x20, AC_VERB_SET_PROC_COEF, 0x4040}, 14738 {} 14739 } 14740 }, 14741}; 14742 14743static struct snd_pci_quirk alc269_fixup_tbl[] = { 14744 SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO), 14745 SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z), 14746 {} 14747}; 14748 14749 14750/* 14751 * configuration and preset 14752 */ 14753static const char *alc269_models[ALC269_MODEL_LAST] = { 14754 [ALC269_BASIC] = "basic", 14755 [ALC269_QUANTA_FL1] = "quanta", 14756 [ALC269_AMIC] = "laptop-amic", 14757 [ALC269_DMIC] = "laptop-dmic", 14758 [ALC269_FUJITSU] = "fujitsu", 14759 [ALC269_LIFEBOOK] = "lifebook", 14760 [ALC269_AUTO] = "auto", 14761}; 14762 14763static struct snd_pci_quirk alc269_cfg_tbl[] = { 14764 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1), 14765 SND_PCI_QUIRK(0x1025, 0x047c, "ACER ZGA", ALC271_ACER), 14766 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A", 14767 ALC269_AMIC), 14768 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269VB_AMIC), 14769 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269VB_AMIC), 14770 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269VB_AMIC), 14771 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_AMIC), 14772 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269VB_AMIC), 14773 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269VB_AMIC), 14774 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269VB_AMIC), 14775 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269VB_AMIC), 14776 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_AMIC), 14777 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82Jv", ALC269_AMIC), 14778 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_AMIC), 14779 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_AMIC), 14780 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_AMIC), 14781 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_AMIC), 14782 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_AMIC), 14783 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_AMIC), 14784 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_AMIC), 14785 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_AMIC), 14786 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_AMIC), 14787 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_AMIC), 14788 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_AMIC), 14789 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_AMIC), 14790 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_AMIC), 14791 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_AMIC), 14792 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_AMIC), 14793 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_AMIC), 14794 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_AMIC), 14795 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_AMIC), 14796 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_AMIC), 14797 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_AMIC), 14798 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_AMIC), 14799 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_DMIC), 14800 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_AMIC), 14801 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_AMIC), 14802 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_AMIC), 14803 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_AMIC), 14804 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901", 14805 ALC269_DMIC), 14806 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101", 14807 ALC269_DMIC), 14808 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC), 14809 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC), 14810 SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_AUTO), 14811 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK), 14812 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC), 14813 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU), 14814 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_AMIC), 14815 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_AMIC), 14816 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_DMIC), 14817 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_DMIC), 14818 {} 14819}; 14820 14821static struct alc_config_preset alc269_presets[] = { 14822 [ALC269_BASIC] = { 14823 .mixers = { alc269_base_mixer }, 14824 .init_verbs = { alc269_init_verbs }, 14825 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 14826 .dac_nids = alc269_dac_nids, 14827 .hp_nid = 0x03, 14828 .num_channel_mode = ARRAY_SIZE(alc269_modes), 14829 .channel_mode = alc269_modes, 14830 .input_mux = &alc269_capture_source, 14831 }, 14832 [ALC269_QUANTA_FL1] = { 14833 .mixers = { alc269_quanta_fl1_mixer }, 14834 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs }, 14835 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 14836 .dac_nids = alc269_dac_nids, 14837 .hp_nid = 0x03, 14838 .num_channel_mode = ARRAY_SIZE(alc269_modes), 14839 .channel_mode = alc269_modes, 14840 .input_mux = &alc269_capture_source, 14841 .unsol_event = alc269_quanta_fl1_unsol_event, 14842 .setup = alc269_quanta_fl1_setup, 14843 .init_hook = alc269_quanta_fl1_init_hook, 14844 }, 14845 [ALC269_AMIC] = { 14846 .mixers = { alc269_laptop_mixer }, 14847 .cap_mixer = alc269_laptop_analog_capture_mixer, 14848 .init_verbs = { alc269_init_verbs, 14849 alc269_laptop_amic_init_verbs }, 14850 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 14851 .dac_nids = alc269_dac_nids, 14852 .hp_nid = 0x03, 14853 .num_channel_mode = ARRAY_SIZE(alc269_modes), 14854 .channel_mode = alc269_modes, 14855 .unsol_event = alc269_laptop_unsol_event, 14856 .setup = alc269_laptop_amic_setup, 14857 .init_hook = alc269_laptop_inithook, 14858 }, 14859 [ALC269_DMIC] = { 14860 .mixers = { alc269_laptop_mixer }, 14861 .cap_mixer = alc269_laptop_digital_capture_mixer, 14862 .init_verbs = { alc269_init_verbs, 14863 alc269_laptop_dmic_init_verbs }, 14864 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 14865 .dac_nids = alc269_dac_nids, 14866 .hp_nid = 0x03, 14867 .num_channel_mode = ARRAY_SIZE(alc269_modes), 14868 .channel_mode = alc269_modes, 14869 .unsol_event = alc269_laptop_unsol_event, 14870 .setup = alc269_laptop_dmic_setup, 14871 .init_hook = alc269_laptop_inithook, 14872 }, 14873 [ALC269VB_AMIC] = { 14874 .mixers = { alc269vb_laptop_mixer }, 14875 .cap_mixer = alc269vb_laptop_analog_capture_mixer, 14876 .init_verbs = { alc269vb_init_verbs, 14877 alc269vb_laptop_amic_init_verbs }, 14878 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 14879 .dac_nids = alc269_dac_nids, 14880 .hp_nid = 0x03, 14881 .num_channel_mode = ARRAY_SIZE(alc269_modes), 14882 .channel_mode = alc269_modes, 14883 .unsol_event = alc269_laptop_unsol_event, 14884 .setup = alc269vb_laptop_amic_setup, 14885 .init_hook = alc269_laptop_inithook, 14886 }, 14887 [ALC269VB_DMIC] = { 14888 .mixers = { alc269vb_laptop_mixer }, 14889 .cap_mixer = alc269vb_laptop_digital_capture_mixer, 14890 .init_verbs = { alc269vb_init_verbs, 14891 alc269vb_laptop_dmic_init_verbs }, 14892 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 14893 .dac_nids = alc269_dac_nids, 14894 .hp_nid = 0x03, 14895 .num_channel_mode = ARRAY_SIZE(alc269_modes), 14896 .channel_mode = alc269_modes, 14897 .unsol_event = alc269_laptop_unsol_event, 14898 .setup = alc269vb_laptop_dmic_setup, 14899 .init_hook = alc269_laptop_inithook, 14900 }, 14901 [ALC269_FUJITSU] = { 14902 .mixers = { alc269_fujitsu_mixer }, 14903 .cap_mixer = alc269_laptop_digital_capture_mixer, 14904 .init_verbs = { alc269_init_verbs, 14905 alc269_laptop_dmic_init_verbs }, 14906 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 14907 .dac_nids = alc269_dac_nids, 14908 .hp_nid = 0x03, 14909 .num_channel_mode = ARRAY_SIZE(alc269_modes), 14910 .channel_mode = alc269_modes, 14911 .unsol_event = alc269_laptop_unsol_event, 14912 .setup = alc269_laptop_dmic_setup, 14913 .init_hook = alc269_laptop_inithook, 14914 }, 14915 [ALC269_LIFEBOOK] = { 14916 .mixers = { alc269_lifebook_mixer }, 14917 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs }, 14918 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 14919 .dac_nids = alc269_dac_nids, 14920 .hp_nid = 0x03, 14921 .num_channel_mode = ARRAY_SIZE(alc269_modes), 14922 .channel_mode = alc269_modes, 14923 .input_mux = &alc269_capture_source, 14924 .unsol_event = alc269_lifebook_unsol_event, 14925 .init_hook = alc269_lifebook_init_hook, 14926 }, 14927 [ALC271_ACER] = { 14928 .mixers = { alc269_asus_mixer }, 14929 .cap_mixer = alc269vb_laptop_digital_capture_mixer, 14930 .init_verbs = { alc269_init_verbs, alc271_acer_dmic_verbs }, 14931 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 14932 .dac_nids = alc269_dac_nids, 14933 .adc_nids = alc262_dmic_adc_nids, 14934 .num_adc_nids = ARRAY_SIZE(alc262_dmic_adc_nids), 14935 .capsrc_nids = alc262_dmic_capsrc_nids, 14936 .num_channel_mode = ARRAY_SIZE(alc269_modes), 14937 .channel_mode = alc269_modes, 14938 .input_mux = &alc269_capture_source, 14939 .dig_out_nid = ALC880_DIGOUT_NID, 14940 .unsol_event = alc_sku_unsol_event, 14941 .setup = alc269vb_laptop_dmic_setup, 14942 .init_hook = alc_inithook, 14943 }, 14944}; 14945 14946static int alc269_fill_coef(struct hda_codec *codec) 14947{ 14948 int val; 14949 14950 if ((alc_read_coef_idx(codec, 0) & 0x00ff) < 0x015) { 14951 alc_write_coef_idx(codec, 0xf, 0x960b); 14952 alc_write_coef_idx(codec, 0xe, 0x8817); 14953 } 14954 14955 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x016) { 14956 alc_write_coef_idx(codec, 0xf, 0x960b); 14957 alc_write_coef_idx(codec, 0xe, 0x8814); 14958 } 14959 14960 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) { 14961 val = alc_read_coef_idx(codec, 0x04); 14962 /* Power up output pin */ 14963 alc_write_coef_idx(codec, 0x04, val | (1<<11)); 14964 } 14965 14966 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) { 14967 val = alc_read_coef_idx(codec, 0xd); 14968 if ((val & 0x0c00) >> 10 != 0x1) { 14969 /* Capless ramp up clock control */ 14970 alc_write_coef_idx(codec, 0xd, val | 1<<10); 14971 } 14972 val = alc_read_coef_idx(codec, 0x17); 14973 if ((val & 0x01c0) >> 6 != 0x4) { 14974 /* Class D power on reset */ 14975 alc_write_coef_idx(codec, 0x17, val | 1<<7); 14976 } 14977 } 14978 return 0; 14979} 14980 14981static int patch_alc269(struct hda_codec *codec) 14982{ 14983 struct alc_spec *spec; 14984 int board_config; 14985 int err; 14986 14987 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 14988 if (spec == NULL) 14989 return -ENOMEM; 14990 14991 codec->spec = spec; 14992 14993 alc_auto_parse_customize_define(codec); 14994 14995 if ((alc_read_coef_idx(codec, 0) & 0x00f0) == 0x0010){ 14996 if (codec->bus->pci->subsystem_vendor == 0x1025 && 14997 spec->cdefine.platform_type == 1) { 14998 alc_codec_rename(codec, "ALC271X"); 14999 spec->codec_variant = ALC269_TYPE_ALC271X; 15000 } else { 15001 alc_codec_rename(codec, "ALC259"); 15002 spec->codec_variant = ALC269_TYPE_ALC259; 15003 } 15004 } else 15005 alc_fix_pll_init(codec, 0x20, 0x04, 15); 15006 15007 alc269_fill_coef(codec); 15008 15009 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST, 15010 alc269_models, 15011 alc269_cfg_tbl); 15012 15013 if (board_config < 0) { 15014 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 15015 codec->chip_name); 15016 board_config = ALC269_AUTO; 15017 } 15018 15019 if (board_config == ALC269_AUTO) 15020 alc_pick_fixup(codec, alc269_fixup_tbl, alc269_fixups, 1); 15021 15022 if (board_config == ALC269_AUTO) { 15023 /* automatic parse from the BIOS config */ 15024 err = alc269_parse_auto_config(codec); 15025 if (err < 0) { 15026 alc_free(codec); 15027 return err; 15028 } else if (!err) { 15029 printk(KERN_INFO 15030 "hda_codec: Cannot set up configuration " 15031 "from BIOS. Using base mode...\n"); 15032 board_config = ALC269_BASIC; 15033 } 15034 } 15035 15036 if (has_cdefine_beep(codec)) { 15037 err = snd_hda_attach_beep_device(codec, 0x1); 15038 if (err < 0) { 15039 alc_free(codec); 15040 return err; 15041 } 15042 } 15043 15044 if (board_config != ALC269_AUTO) 15045 setup_preset(codec, &alc269_presets[board_config]); 15046 15047 if (board_config == ALC269_QUANTA_FL1) { 15048 /* Due to a hardware problem on Lenovo Ideadpad, we need to 15049 * fix the sample rate of analog I/O to 44.1kHz 15050 */ 15051 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback; 15052 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture; 15053 } else if (spec->dual_adc_switch) { 15054 spec->stream_analog_playback = &alc269_pcm_analog_playback; 15055 /* switch ADC dynamically */ 15056 spec->stream_analog_capture = &dualmic_pcm_analog_capture; 15057 } else { 15058 spec->stream_analog_playback = &alc269_pcm_analog_playback; 15059 spec->stream_analog_capture = &alc269_pcm_analog_capture; 15060 } 15061 spec->stream_digital_playback = &alc269_pcm_digital_playback; 15062 spec->stream_digital_capture = &alc269_pcm_digital_capture; 15063 15064 if (!spec->adc_nids) { /* wasn't filled automatically? use default */ 15065 if (spec->codec_variant != ALC269_TYPE_NORMAL) { 15066 spec->adc_nids = alc269_adc_nids; 15067 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids); 15068 spec->capsrc_nids = alc269_capsrc_nids; 15069 } else { 15070 spec->adc_nids = alc269vb_adc_nids; 15071 spec->num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids); 15072 spec->capsrc_nids = alc269vb_capsrc_nids; 15073 } 15074 } 15075 15076 if (!spec->cap_mixer) 15077 set_capture_mixer(codec); 15078 if (has_cdefine_beep(codec)) 15079 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); 15080 15081 if (board_config == ALC269_AUTO) 15082 alc_pick_fixup(codec, alc269_fixup_tbl, alc269_fixups, 0); 15083 15084 spec->vmaster_nid = 0x02; 15085 15086 codec->patch_ops = alc_patch_ops; 15087#ifdef CONFIG_SND_HDA_POWER_SAVE 15088 codec->patch_ops.suspend = alc269_suspend; 15089#endif 15090#ifdef SND_HDA_NEEDS_RESUME 15091 codec->patch_ops.resume = alc269_resume; 15092#endif 15093 if (board_config == ALC269_AUTO) 15094 spec->init_hook = alc269_auto_init; 15095#ifdef CONFIG_SND_HDA_POWER_SAVE 15096 if (!spec->loopback.amplist) 15097 spec->loopback.amplist = alc269_loopbacks; 15098 if (alc269_mic2_for_mute_led(codec)) 15099 codec->patch_ops.check_power_status = alc269_mic2_mute_check_ps; 15100#endif 15101 15102 return 0; 15103} 15104 15105/* 15106 * ALC861 channel source setting (2/6 channel selection for 3-stack) 15107 */ 15108 15109/* 15110 * set the path ways for 2 channel output 15111 * need to set the codec line out and mic 1 pin widgets to inputs 15112 */ 15113static struct hda_verb alc861_threestack_ch2_init[] = { 15114 /* set pin widget 1Ah (line in) for input */ 15115 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 15116 /* set pin widget 18h (mic1/2) for input, for mic also enable 15117 * the vref 15118 */ 15119 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15120 15121 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, 15122#if 0 15123 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/ 15124 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/ 15125#endif 15126 { } /* end */ 15127}; 15128/* 15129 * 6ch mode 15130 * need to set the codec line out and mic 1 pin widgets to outputs 15131 */ 15132static struct hda_verb alc861_threestack_ch6_init[] = { 15133 /* set pin widget 1Ah (line in) for output (Back Surround)*/ 15134 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15135 /* set pin widget 18h (mic1) for output (CLFE)*/ 15136 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15137 15138 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15139 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15140 15141 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 }, 15142#if 0 15143 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/ 15144 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/ 15145#endif 15146 { } /* end */ 15147}; 15148 15149static struct hda_channel_mode alc861_threestack_modes[2] = { 15150 { 2, alc861_threestack_ch2_init }, 15151 { 6, alc861_threestack_ch6_init }, 15152}; 15153/* Set mic1 as input and unmute the mixer */ 15154static struct hda_verb alc861_uniwill_m31_ch2_init[] = { 15155 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15156 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/ 15157 { } /* end */ 15158}; 15159/* Set mic1 as output and mute mixer */ 15160static struct hda_verb alc861_uniwill_m31_ch4_init[] = { 15161 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15162 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/ 15163 { } /* end */ 15164}; 15165 15166static struct hda_channel_mode alc861_uniwill_m31_modes[2] = { 15167 { 2, alc861_uniwill_m31_ch2_init }, 15168 { 4, alc861_uniwill_m31_ch4_init }, 15169}; 15170 15171/* Set mic1 and line-in as input and unmute the mixer */ 15172static struct hda_verb alc861_asus_ch2_init[] = { 15173 /* set pin widget 1Ah (line in) for input */ 15174 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 15175 /* set pin widget 18h (mic1/2) for input, for mic also enable 15176 * the vref 15177 */ 15178 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15179 15180 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, 15181#if 0 15182 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/ 15183 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/ 15184#endif 15185 { } /* end */ 15186}; 15187/* Set mic1 nad line-in as output and mute mixer */ 15188static struct hda_verb alc861_asus_ch6_init[] = { 15189 /* set pin widget 1Ah (line in) for output (Back Surround)*/ 15190 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15191 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */ 15192 /* set pin widget 18h (mic1) for output (CLFE)*/ 15193 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15194 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */ 15195 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15196 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15197 15198 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 }, 15199#if 0 15200 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/ 15201 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/ 15202#endif 15203 { } /* end */ 15204}; 15205 15206static struct hda_channel_mode alc861_asus_modes[2] = { 15207 { 2, alc861_asus_ch2_init }, 15208 { 6, alc861_asus_ch6_init }, 15209}; 15210 15211/* patch-ALC861 */ 15212 15213static struct snd_kcontrol_new alc861_base_mixer[] = { 15214 /* output mixer control */ 15215 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), 15216 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), 15217 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT), 15218 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT), 15219 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), 15220 15221 /*Input mixer control */ 15222 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT), 15223 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */ 15224 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), 15225 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), 15226 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT), 15227 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT), 15228 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), 15229 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), 15230 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), 15231 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT), 15232 15233 { } /* end */ 15234}; 15235 15236static struct snd_kcontrol_new alc861_3ST_mixer[] = { 15237 /* output mixer control */ 15238 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), 15239 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), 15240 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT), 15241 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT), 15242 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */ 15243 15244 /* Input mixer control */ 15245 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT), 15246 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */ 15247 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), 15248 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), 15249 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT), 15250 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT), 15251 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), 15252 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), 15253 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), 15254 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT), 15255 15256 { 15257 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 15258 .name = "Channel Mode", 15259 .info = alc_ch_mode_info, 15260 .get = alc_ch_mode_get, 15261 .put = alc_ch_mode_put, 15262 .private_value = ARRAY_SIZE(alc861_threestack_modes), 15263 }, 15264 { } /* end */ 15265}; 15266 15267static struct snd_kcontrol_new alc861_toshiba_mixer[] = { 15268 /* output mixer control */ 15269 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT), 15270 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), 15271 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), 15272 15273 { } /* end */ 15274}; 15275 15276static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = { 15277 /* output mixer control */ 15278 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), 15279 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), 15280 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT), 15281 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT), 15282 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */ 15283 15284 /* Input mixer control */ 15285 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT), 15286 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */ 15287 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), 15288 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), 15289 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT), 15290 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT), 15291 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), 15292 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), 15293 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), 15294 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT), 15295 15296 { 15297 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 15298 .name = "Channel Mode", 15299 .info = alc_ch_mode_info, 15300 .get = alc_ch_mode_get, 15301 .put = alc_ch_mode_put, 15302 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes), 15303 }, 15304 { } /* end */ 15305}; 15306 15307static struct snd_kcontrol_new alc861_asus_mixer[] = { 15308 /* output mixer control */ 15309 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), 15310 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), 15311 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT), 15312 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT), 15313 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), 15314 15315 /* Input mixer control */ 15316 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT), 15317 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), 15318 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), 15319 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), 15320 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT), 15321 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT), 15322 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), 15323 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), 15324 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), 15325 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT), 15326 15327 { 15328 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 15329 .name = "Channel Mode", 15330 .info = alc_ch_mode_info, 15331 .get = alc_ch_mode_get, 15332 .put = alc_ch_mode_put, 15333 .private_value = ARRAY_SIZE(alc861_asus_modes), 15334 }, 15335 { } 15336}; 15337 15338/* additional mixer */ 15339static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = { 15340 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), 15341 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), 15342 { } 15343}; 15344 15345/* 15346 * generic initialization of ADC, input mixers and output mixers 15347 */ 15348static struct hda_verb alc861_base_init_verbs[] = { 15349 /* 15350 * Unmute ADC0 and set the default input to mic-in 15351 */ 15352 /* port-A for surround (rear panel) */ 15353 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15354 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15355 /* port-B for mic-in (rear panel) with vref */ 15356 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15357 /* port-C for line-in (rear panel) */ 15358 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 15359 /* port-D for Front */ 15360 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15361 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15362 /* port-E for HP out (front panel) */ 15363 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, 15364 /* route front PCM to HP */ 15365 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15366 /* port-F for mic-in (front panel) with vref */ 15367 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15368 /* port-G for CLFE (rear panel) */ 15369 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15370 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15371 /* port-H for side (rear panel) */ 15372 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15373 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15374 /* CD-in */ 15375 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 15376 /* route front mic to ADC1*/ 15377 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 15378 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15379 15380 /* Unmute DAC0~3 & spdif out*/ 15381 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15382 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15383 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15384 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15385 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15386 15387 /* Unmute Mixer 14 (mic) 1c (Line in)*/ 15388 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15389 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15390 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15391 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15392 15393 /* Unmute Stereo Mixer 15 */ 15394 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15395 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15396 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 15397 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */ 15398 15399 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15400 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15401 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15402 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15403 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15404 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15405 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15406 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15407 /* hp used DAC 3 (Front) */ 15408 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 15409 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 15410 15411 { } 15412}; 15413 15414static struct hda_verb alc861_threestack_init_verbs[] = { 15415 /* 15416 * Unmute ADC0 and set the default input to mic-in 15417 */ 15418 /* port-A for surround (rear panel) */ 15419 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 15420 /* port-B for mic-in (rear panel) with vref */ 15421 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15422 /* port-C for line-in (rear panel) */ 15423 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 15424 /* port-D for Front */ 15425 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15426 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15427 /* port-E for HP out (front panel) */ 15428 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, 15429 /* route front PCM to HP */ 15430 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15431 /* port-F for mic-in (front panel) with vref */ 15432 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15433 /* port-G for CLFE (rear panel) */ 15434 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 15435 /* port-H for side (rear panel) */ 15436 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 15437 /* CD-in */ 15438 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 15439 /* route front mic to ADC1*/ 15440 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 15441 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15442 /* Unmute DAC0~3 & spdif out*/ 15443 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15444 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15445 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15446 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15447 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15448 15449 /* Unmute Mixer 14 (mic) 1c (Line in)*/ 15450 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15451 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15452 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15453 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15454 15455 /* Unmute Stereo Mixer 15 */ 15456 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15457 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15458 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 15459 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */ 15460 15461 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15462 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15463 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15464 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15465 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15466 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15467 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15468 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15469 /* hp used DAC 3 (Front) */ 15470 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 15471 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 15472 { } 15473}; 15474 15475static struct hda_verb alc861_uniwill_m31_init_verbs[] = { 15476 /* 15477 * Unmute ADC0 and set the default input to mic-in 15478 */ 15479 /* port-A for surround (rear panel) */ 15480 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 15481 /* port-B for mic-in (rear panel) with vref */ 15482 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15483 /* port-C for line-in (rear panel) */ 15484 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 15485 /* port-D for Front */ 15486 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15487 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15488 /* port-E for HP out (front panel) */ 15489 /* this has to be set to VREF80 */ 15490 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15491 /* route front PCM to HP */ 15492 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15493 /* port-F for mic-in (front panel) with vref */ 15494 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15495 /* port-G for CLFE (rear panel) */ 15496 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 15497 /* port-H for side (rear panel) */ 15498 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 15499 /* CD-in */ 15500 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 15501 /* route front mic to ADC1*/ 15502 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 15503 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15504 /* Unmute DAC0~3 & spdif out*/ 15505 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15506 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15507 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15508 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15509 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15510 15511 /* Unmute Mixer 14 (mic) 1c (Line in)*/ 15512 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15513 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15514 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15515 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15516 15517 /* Unmute Stereo Mixer 15 */ 15518 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15519 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15520 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 15521 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */ 15522 15523 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15524 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15525 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15526 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15527 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15528 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15529 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15530 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15531 /* hp used DAC 3 (Front) */ 15532 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 15533 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 15534 { } 15535}; 15536 15537static struct hda_verb alc861_asus_init_verbs[] = { 15538 /* 15539 * Unmute ADC0 and set the default input to mic-in 15540 */ 15541 /* port-A for surround (rear panel) 15542 * according to codec#0 this is the HP jack 15543 */ 15544 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */ 15545 /* route front PCM to HP */ 15546 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 }, 15547 /* port-B for mic-in (rear panel) with vref */ 15548 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15549 /* port-C for line-in (rear panel) */ 15550 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 15551 /* port-D for Front */ 15552 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15553 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15554 /* port-E for HP out (front panel) */ 15555 /* this has to be set to VREF80 */ 15556 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15557 /* route front PCM to HP */ 15558 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15559 /* port-F for mic-in (front panel) with vref */ 15560 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15561 /* port-G for CLFE (rear panel) */ 15562 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15563 /* port-H for side (rear panel) */ 15564 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15565 /* CD-in */ 15566 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 15567 /* route front mic to ADC1*/ 15568 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 15569 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15570 /* Unmute DAC0~3 & spdif out*/ 15571 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15572 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15573 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15574 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15575 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15576 /* Unmute Mixer 14 (mic) 1c (Line in)*/ 15577 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15578 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15579 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15580 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15581 15582 /* Unmute Stereo Mixer 15 */ 15583 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15584 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15585 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 15586 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */ 15587 15588 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15589 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15590 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15591 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15592 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15593 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15594 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15595 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15596 /* hp used DAC 3 (Front) */ 15597 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 15598 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 15599 { } 15600}; 15601 15602/* additional init verbs for ASUS laptops */ 15603static struct hda_verb alc861_asus_laptop_init_verbs[] = { 15604 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */ 15605 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */ 15606 { } 15607}; 15608 15609/* 15610 * generic initialization of ADC, input mixers and output mixers 15611 */ 15612static struct hda_verb alc861_auto_init_verbs[] = { 15613 /* 15614 * Unmute ADC0 and set the default input to mic-in 15615 */ 15616 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */ 15617 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15618 15619 /* Unmute DAC0~3 & spdif out*/ 15620 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 15621 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 15622 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 15623 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 15624 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15625 15626 /* Unmute Mixer 14 (mic) 1c (Line in)*/ 15627 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15628 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15629 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15630 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15631 15632 /* Unmute Stereo Mixer 15 */ 15633 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15634 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15635 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 15636 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, 15637 15638 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 15639 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 15640 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 15641 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 15642 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 15643 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 15644 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 15645 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 15646 15647 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 15648 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 15649 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 15650 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 15651 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 15652 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 15653 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 15654 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 15655 15656 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */ 15657 15658 { } 15659}; 15660 15661static struct hda_verb alc861_toshiba_init_verbs[] = { 15662 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 15663 15664 { } 15665}; 15666 15667/* toggle speaker-output according to the hp-jack state */ 15668static void alc861_toshiba_automute(struct hda_codec *codec) 15669{ 15670 unsigned int present = snd_hda_jack_detect(codec, 0x0f); 15671 15672 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0, 15673 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 15674 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3, 15675 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE); 15676} 15677 15678static void alc861_toshiba_unsol_event(struct hda_codec *codec, 15679 unsigned int res) 15680{ 15681 if ((res >> 26) == ALC880_HP_EVENT) 15682 alc861_toshiba_automute(codec); 15683} 15684 15685/* pcm configuration: identical with ALC880 */ 15686#define alc861_pcm_analog_playback alc880_pcm_analog_playback 15687#define alc861_pcm_analog_capture alc880_pcm_analog_capture 15688#define alc861_pcm_digital_playback alc880_pcm_digital_playback 15689#define alc861_pcm_digital_capture alc880_pcm_digital_capture 15690 15691 15692#define ALC861_DIGOUT_NID 0x07 15693 15694static struct hda_channel_mode alc861_8ch_modes[1] = { 15695 { 8, NULL } 15696}; 15697 15698static hda_nid_t alc861_dac_nids[4] = { 15699 /* front, surround, clfe, side */ 15700 0x03, 0x06, 0x05, 0x04 15701}; 15702 15703static hda_nid_t alc660_dac_nids[3] = { 15704 /* front, clfe, surround */ 15705 0x03, 0x05, 0x06 15706}; 15707 15708static hda_nid_t alc861_adc_nids[1] = { 15709 /* ADC0-2 */ 15710 0x08, 15711}; 15712 15713static struct hda_input_mux alc861_capture_source = { 15714 .num_items = 5, 15715 .items = { 15716 { "Mic", 0x0 }, 15717 { "Front Mic", 0x3 }, 15718 { "Line", 0x1 }, 15719 { "CD", 0x4 }, 15720 { "Mixer", 0x5 }, 15721 }, 15722}; 15723 15724static hda_nid_t alc861_look_for_dac(struct hda_codec *codec, hda_nid_t pin) 15725{ 15726 struct alc_spec *spec = codec->spec; 15727 hda_nid_t mix, srcs[5]; 15728 int i, j, num; 15729 15730 if (snd_hda_get_connections(codec, pin, &mix, 1) != 1) 15731 return 0; 15732 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs)); 15733 if (num < 0) 15734 return 0; 15735 for (i = 0; i < num; i++) { 15736 unsigned int type; 15737 type = get_wcaps_type(get_wcaps(codec, srcs[i])); 15738 if (type != AC_WID_AUD_OUT) 15739 continue; 15740 for (j = 0; j < spec->multiout.num_dacs; j++) 15741 if (spec->multiout.dac_nids[j] == srcs[i]) 15742 break; 15743 if (j >= spec->multiout.num_dacs) 15744 return srcs[i]; 15745 } 15746 return 0; 15747} 15748 15749/* fill in the dac_nids table from the parsed pin configuration */ 15750static int alc861_auto_fill_dac_nids(struct hda_codec *codec, 15751 const struct auto_pin_cfg *cfg) 15752{ 15753 struct alc_spec *spec = codec->spec; 15754 int i; 15755 hda_nid_t nid, dac; 15756 15757 spec->multiout.dac_nids = spec->private_dac_nids; 15758 for (i = 0; i < cfg->line_outs; i++) { 15759 nid = cfg->line_out_pins[i]; 15760 dac = alc861_look_for_dac(codec, nid); 15761 if (!dac) 15762 continue; 15763 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac; 15764 } 15765 return 0; 15766} 15767 15768static int alc861_create_out_sw(struct hda_codec *codec, const char *pfx, 15769 hda_nid_t nid, unsigned int chs) 15770{ 15771 return add_pb_sw_ctrl(codec->spec, ALC_CTL_WIDGET_MUTE, pfx, 15772 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT)); 15773} 15774 15775/* add playback controls from the parsed DAC table */ 15776static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec, 15777 const struct auto_pin_cfg *cfg) 15778{ 15779 struct alc_spec *spec = codec->spec; 15780 static const char *chname[4] = { 15781 "Front", "Surround", NULL /*CLFE*/, "Side" 15782 }; 15783 hda_nid_t nid; 15784 int i, err; 15785 15786 if (cfg->line_outs == 1) { 15787 const char *pfx = NULL; 15788 if (!cfg->hp_outs) 15789 pfx = "Master"; 15790 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) 15791 pfx = "Speaker"; 15792 if (pfx) { 15793 nid = spec->multiout.dac_nids[0]; 15794 return alc861_create_out_sw(codec, pfx, nid, 3); 15795 } 15796 } 15797 15798 for (i = 0; i < cfg->line_outs; i++) { 15799 nid = spec->multiout.dac_nids[i]; 15800 if (!nid) 15801 continue; 15802 if (i == 2) { 15803 /* Center/LFE */ 15804 err = alc861_create_out_sw(codec, "Center", nid, 1); 15805 if (err < 0) 15806 return err; 15807 err = alc861_create_out_sw(codec, "LFE", nid, 2); 15808 if (err < 0) 15809 return err; 15810 } else { 15811 err = alc861_create_out_sw(codec, chname[i], nid, 3); 15812 if (err < 0) 15813 return err; 15814 } 15815 } 15816 return 0; 15817} 15818 15819static int alc861_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin) 15820{ 15821 struct alc_spec *spec = codec->spec; 15822 int err; 15823 hda_nid_t nid; 15824 15825 if (!pin) 15826 return 0; 15827 15828 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) { 15829 nid = alc861_look_for_dac(codec, pin); 15830 if (nid) { 15831 err = alc861_create_out_sw(codec, "Headphone", nid, 3); 15832 if (err < 0) 15833 return err; 15834 spec->multiout.hp_nid = nid; 15835 } 15836 } 15837 return 0; 15838} 15839 15840/* create playback/capture controls for input pins */ 15841static int alc861_auto_create_input_ctls(struct hda_codec *codec, 15842 const struct auto_pin_cfg *cfg) 15843{ 15844 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x08, 0); 15845} 15846 15847static void alc861_auto_set_output_and_unmute(struct hda_codec *codec, 15848 hda_nid_t nid, 15849 int pin_type, hda_nid_t dac) 15850{ 15851 hda_nid_t mix, srcs[5]; 15852 int i, num; 15853 15854 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 15855 pin_type); 15856 snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE, 15857 AMP_OUT_UNMUTE); 15858 if (snd_hda_get_connections(codec, nid, &mix, 1) != 1) 15859 return; 15860 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs)); 15861 if (num < 0) 15862 return; 15863 for (i = 0; i < num; i++) { 15864 unsigned int mute; 15865 if (srcs[i] == dac || srcs[i] == 0x15) 15866 mute = AMP_IN_UNMUTE(i); 15867 else 15868 mute = AMP_IN_MUTE(i); 15869 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE, 15870 mute); 15871 } 15872} 15873 15874static void alc861_auto_init_multi_out(struct hda_codec *codec) 15875{ 15876 struct alc_spec *spec = codec->spec; 15877 int i; 15878 15879 for (i = 0; i < spec->autocfg.line_outs; i++) { 15880 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 15881 int pin_type = get_pin_type(spec->autocfg.line_out_type); 15882 if (nid) 15883 alc861_auto_set_output_and_unmute(codec, nid, pin_type, 15884 spec->multiout.dac_nids[i]); 15885 } 15886} 15887 15888static void alc861_auto_init_hp_out(struct hda_codec *codec) 15889{ 15890 struct alc_spec *spec = codec->spec; 15891 15892 if (spec->autocfg.hp_outs) 15893 alc861_auto_set_output_and_unmute(codec, 15894 spec->autocfg.hp_pins[0], 15895 PIN_HP, 15896 spec->multiout.hp_nid); 15897 if (spec->autocfg.speaker_outs) 15898 alc861_auto_set_output_and_unmute(codec, 15899 spec->autocfg.speaker_pins[0], 15900 PIN_OUT, 15901 spec->multiout.dac_nids[0]); 15902} 15903 15904static void alc861_auto_init_analog_input(struct hda_codec *codec) 15905{ 15906 struct alc_spec *spec = codec->spec; 15907 struct auto_pin_cfg *cfg = &spec->autocfg; 15908 int i; 15909 15910 for (i = 0; i < cfg->num_inputs; i++) { 15911 hda_nid_t nid = cfg->inputs[i].pin; 15912 if (nid >= 0x0c && nid <= 0x11) 15913 alc_set_input_pin(codec, nid, cfg->inputs[i].type); 15914 } 15915} 15916 15917/* parse the BIOS configuration and set up the alc_spec */ 15918/* return 1 if successful, 0 if the proper config is not found, 15919 * or a negative error code 15920 */ 15921static int alc861_parse_auto_config(struct hda_codec *codec) 15922{ 15923 struct alc_spec *spec = codec->spec; 15924 int err; 15925 static hda_nid_t alc861_ignore[] = { 0x1d, 0 }; 15926 15927 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 15928 alc861_ignore); 15929 if (err < 0) 15930 return err; 15931 if (!spec->autocfg.line_outs) 15932 return 0; /* can't find valid BIOS pin config */ 15933 15934 err = alc861_auto_fill_dac_nids(codec, &spec->autocfg); 15935 if (err < 0) 15936 return err; 15937 err = alc861_auto_create_multi_out_ctls(codec, &spec->autocfg); 15938 if (err < 0) 15939 return err; 15940 err = alc861_auto_create_hp_ctls(codec, spec->autocfg.hp_pins[0]); 15941 if (err < 0) 15942 return err; 15943 err = alc861_auto_create_input_ctls(codec, &spec->autocfg); 15944 if (err < 0) 15945 return err; 15946 15947 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 15948 15949 alc_auto_parse_digital(codec); 15950 15951 if (spec->kctls.list) 15952 add_mixer(spec, spec->kctls.list); 15953 15954 add_verb(spec, alc861_auto_init_verbs); 15955 15956 spec->num_mux_defs = 1; 15957 spec->input_mux = &spec->private_imux[0]; 15958 15959 spec->adc_nids = alc861_adc_nids; 15960 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids); 15961 set_capture_mixer(codec); 15962 15963 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b, 0); 15964 15965 return 1; 15966} 15967 15968/* additional initialization for auto-configuration model */ 15969static void alc861_auto_init(struct hda_codec *codec) 15970{ 15971 struct alc_spec *spec = codec->spec; 15972 alc861_auto_init_multi_out(codec); 15973 alc861_auto_init_hp_out(codec); 15974 alc861_auto_init_analog_input(codec); 15975 alc_auto_init_digital(codec); 15976 if (spec->unsol_event) 15977 alc_inithook(codec); 15978} 15979 15980#ifdef CONFIG_SND_HDA_POWER_SAVE 15981static struct hda_amp_list alc861_loopbacks[] = { 15982 { 0x15, HDA_INPUT, 0 }, 15983 { 0x15, HDA_INPUT, 1 }, 15984 { 0x15, HDA_INPUT, 2 }, 15985 { 0x15, HDA_INPUT, 3 }, 15986 { } /* end */ 15987}; 15988#endif 15989 15990 15991/* 15992 * configuration and preset 15993 */ 15994static const char *alc861_models[ALC861_MODEL_LAST] = { 15995 [ALC861_3ST] = "3stack", 15996 [ALC660_3ST] = "3stack-660", 15997 [ALC861_3ST_DIG] = "3stack-dig", 15998 [ALC861_6ST_DIG] = "6stack-dig", 15999 [ALC861_UNIWILL_M31] = "uniwill-m31", 16000 [ALC861_TOSHIBA] = "toshiba", 16001 [ALC861_ASUS] = "asus", 16002 [ALC861_ASUS_LAPTOP] = "asus-laptop", 16003 [ALC861_AUTO] = "auto", 16004}; 16005 16006static struct snd_pci_quirk alc861_cfg_tbl[] = { 16007 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST), 16008 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP), 16009 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP), 16010 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS), 16011 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP), 16012 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG), 16013 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA), 16014 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!) 16015 * Any other models that need this preset? 16016 */ 16017 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */ 16018 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST), 16019 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST), 16020 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31), 16021 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31), 16022 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP), 16023 /* FIXME: the below seems conflict */ 16024 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */ 16025 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST), 16026 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST), 16027 {} 16028}; 16029 16030static struct alc_config_preset alc861_presets[] = { 16031 [ALC861_3ST] = { 16032 .mixers = { alc861_3ST_mixer }, 16033 .init_verbs = { alc861_threestack_init_verbs }, 16034 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 16035 .dac_nids = alc861_dac_nids, 16036 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes), 16037 .channel_mode = alc861_threestack_modes, 16038 .need_dac_fix = 1, 16039 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 16040 .adc_nids = alc861_adc_nids, 16041 .input_mux = &alc861_capture_source, 16042 }, 16043 [ALC861_3ST_DIG] = { 16044 .mixers = { alc861_base_mixer }, 16045 .init_verbs = { alc861_threestack_init_verbs }, 16046 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 16047 .dac_nids = alc861_dac_nids, 16048 .dig_out_nid = ALC861_DIGOUT_NID, 16049 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes), 16050 .channel_mode = alc861_threestack_modes, 16051 .need_dac_fix = 1, 16052 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 16053 .adc_nids = alc861_adc_nids, 16054 .input_mux = &alc861_capture_source, 16055 }, 16056 [ALC861_6ST_DIG] = { 16057 .mixers = { alc861_base_mixer }, 16058 .init_verbs = { alc861_base_init_verbs }, 16059 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 16060 .dac_nids = alc861_dac_nids, 16061 .dig_out_nid = ALC861_DIGOUT_NID, 16062 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes), 16063 .channel_mode = alc861_8ch_modes, 16064 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 16065 .adc_nids = alc861_adc_nids, 16066 .input_mux = &alc861_capture_source, 16067 }, 16068 [ALC660_3ST] = { 16069 .mixers = { alc861_3ST_mixer }, 16070 .init_verbs = { alc861_threestack_init_verbs }, 16071 .num_dacs = ARRAY_SIZE(alc660_dac_nids), 16072 .dac_nids = alc660_dac_nids, 16073 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes), 16074 .channel_mode = alc861_threestack_modes, 16075 .need_dac_fix = 1, 16076 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 16077 .adc_nids = alc861_adc_nids, 16078 .input_mux = &alc861_capture_source, 16079 }, 16080 [ALC861_UNIWILL_M31] = { 16081 .mixers = { alc861_uniwill_m31_mixer }, 16082 .init_verbs = { alc861_uniwill_m31_init_verbs }, 16083 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 16084 .dac_nids = alc861_dac_nids, 16085 .dig_out_nid = ALC861_DIGOUT_NID, 16086 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes), 16087 .channel_mode = alc861_uniwill_m31_modes, 16088 .need_dac_fix = 1, 16089 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 16090 .adc_nids = alc861_adc_nids, 16091 .input_mux = &alc861_capture_source, 16092 }, 16093 [ALC861_TOSHIBA] = { 16094 .mixers = { alc861_toshiba_mixer }, 16095 .init_verbs = { alc861_base_init_verbs, 16096 alc861_toshiba_init_verbs }, 16097 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 16098 .dac_nids = alc861_dac_nids, 16099 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 16100 .channel_mode = alc883_3ST_2ch_modes, 16101 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 16102 .adc_nids = alc861_adc_nids, 16103 .input_mux = &alc861_capture_source, 16104 .unsol_event = alc861_toshiba_unsol_event, 16105 .init_hook = alc861_toshiba_automute, 16106 }, 16107 [ALC861_ASUS] = { 16108 .mixers = { alc861_asus_mixer }, 16109 .init_verbs = { alc861_asus_init_verbs }, 16110 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 16111 .dac_nids = alc861_dac_nids, 16112 .dig_out_nid = ALC861_DIGOUT_NID, 16113 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes), 16114 .channel_mode = alc861_asus_modes, 16115 .need_dac_fix = 1, 16116 .hp_nid = 0x06, 16117 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 16118 .adc_nids = alc861_adc_nids, 16119 .input_mux = &alc861_capture_source, 16120 }, 16121 [ALC861_ASUS_LAPTOP] = { 16122 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer }, 16123 .init_verbs = { alc861_asus_init_verbs, 16124 alc861_asus_laptop_init_verbs }, 16125 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 16126 .dac_nids = alc861_dac_nids, 16127 .dig_out_nid = ALC861_DIGOUT_NID, 16128 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 16129 .channel_mode = alc883_3ST_2ch_modes, 16130 .need_dac_fix = 1, 16131 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 16132 .adc_nids = alc861_adc_nids, 16133 .input_mux = &alc861_capture_source, 16134 }, 16135}; 16136 16137/* Pin config fixes */ 16138enum { 16139 PINFIX_FSC_AMILO_PI1505, 16140}; 16141 16142static const struct alc_fixup alc861_fixups[] = { 16143 [PINFIX_FSC_AMILO_PI1505] = { 16144 .pins = (const struct alc_pincfg[]) { 16145 { 0x0b, 0x0221101f }, /* HP */ 16146 { 0x0f, 0x90170310 }, /* speaker */ 16147 { } 16148 } 16149 }, 16150}; 16151 16152static struct snd_pci_quirk alc861_fixup_tbl[] = { 16153 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505), 16154 {} 16155}; 16156 16157static int patch_alc861(struct hda_codec *codec) 16158{ 16159 struct alc_spec *spec; 16160 int board_config; 16161 int err; 16162 16163 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 16164 if (spec == NULL) 16165 return -ENOMEM; 16166 16167 codec->spec = spec; 16168 16169 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST, 16170 alc861_models, 16171 alc861_cfg_tbl); 16172 16173 if (board_config < 0) { 16174 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 16175 codec->chip_name); 16176 board_config = ALC861_AUTO; 16177 } 16178 16179 if (board_config == ALC861_AUTO) 16180 alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups, 1); 16181 16182 if (board_config == ALC861_AUTO) { 16183 /* automatic parse from the BIOS config */ 16184 err = alc861_parse_auto_config(codec); 16185 if (err < 0) { 16186 alc_free(codec); 16187 return err; 16188 } else if (!err) { 16189 printk(KERN_INFO 16190 "hda_codec: Cannot set up configuration " 16191 "from BIOS. Using base mode...\n"); 16192 board_config = ALC861_3ST_DIG; 16193 } 16194 } 16195 16196 err = snd_hda_attach_beep_device(codec, 0x23); 16197 if (err < 0) { 16198 alc_free(codec); 16199 return err; 16200 } 16201 16202 if (board_config != ALC861_AUTO) 16203 setup_preset(codec, &alc861_presets[board_config]); 16204 16205 spec->stream_analog_playback = &alc861_pcm_analog_playback; 16206 spec->stream_analog_capture = &alc861_pcm_analog_capture; 16207 16208 spec->stream_digital_playback = &alc861_pcm_digital_playback; 16209 spec->stream_digital_capture = &alc861_pcm_digital_capture; 16210 16211 if (!spec->cap_mixer) 16212 set_capture_mixer(codec); 16213 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT); 16214 16215 spec->vmaster_nid = 0x03; 16216 16217 if (board_config == ALC861_AUTO) 16218 alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups, 0); 16219 16220 codec->patch_ops = alc_patch_ops; 16221 if (board_config == ALC861_AUTO) { 16222 spec->init_hook = alc861_auto_init; 16223#ifdef CONFIG_SND_HDA_POWER_SAVE 16224 spec->power_hook = alc_power_eapd; 16225#endif 16226 } 16227#ifdef CONFIG_SND_HDA_POWER_SAVE 16228 if (!spec->loopback.amplist) 16229 spec->loopback.amplist = alc861_loopbacks; 16230#endif 16231 16232 return 0; 16233} 16234 16235/* 16236 * ALC861-VD support 16237 * 16238 * Based on ALC882 16239 * 16240 * In addition, an independent DAC 16241 */ 16242#define ALC861VD_DIGOUT_NID 0x06 16243 16244static hda_nid_t alc861vd_dac_nids[4] = { 16245 /* front, surr, clfe, side surr */ 16246 0x02, 0x03, 0x04, 0x05 16247}; 16248 16249/* dac_nids for ALC660vd are in a different order - according to 16250 * Realtek's driver. 16251 * This should probably result in a different mixer for 6stack models 16252 * of ALC660vd codecs, but for now there is only 3stack mixer 16253 * - and it is the same as in 861vd. 16254 * adc_nids in ALC660vd are (is) the same as in 861vd 16255 */ 16256static hda_nid_t alc660vd_dac_nids[3] = { 16257 /* front, rear, clfe, rear_surr */ 16258 0x02, 0x04, 0x03 16259}; 16260 16261static hda_nid_t alc861vd_adc_nids[1] = { 16262 /* ADC0 */ 16263 0x09, 16264}; 16265 16266static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 }; 16267 16268/* input MUX */ 16269/* FIXME: should be a matrix-type input source selection */ 16270static struct hda_input_mux alc861vd_capture_source = { 16271 .num_items = 4, 16272 .items = { 16273 { "Mic", 0x0 }, 16274 { "Front Mic", 0x1 }, 16275 { "Line", 0x2 }, 16276 { "CD", 0x4 }, 16277 }, 16278}; 16279 16280static struct hda_input_mux alc861vd_dallas_capture_source = { 16281 .num_items = 2, 16282 .items = { 16283 { "Ext Mic", 0x0 }, 16284 { "Int Mic", 0x1 }, 16285 }, 16286}; 16287 16288static struct hda_input_mux alc861vd_hp_capture_source = { 16289 .num_items = 2, 16290 .items = { 16291 { "Front Mic", 0x0 }, 16292 { "ATAPI Mic", 0x1 }, 16293 }, 16294}; 16295 16296/* 16297 * 2ch mode 16298 */ 16299static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = { 16300 { 2, NULL } 16301}; 16302 16303/* 16304 * 6ch mode 16305 */ 16306static struct hda_verb alc861vd_6stack_ch6_init[] = { 16307 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 16308 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 16309 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 16310 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 16311 { } /* end */ 16312}; 16313 16314/* 16315 * 8ch mode 16316 */ 16317static struct hda_verb alc861vd_6stack_ch8_init[] = { 16318 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 16319 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 16320 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 16321 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 16322 { } /* end */ 16323}; 16324 16325static struct hda_channel_mode alc861vd_6stack_modes[2] = { 16326 { 6, alc861vd_6stack_ch6_init }, 16327 { 8, alc861vd_6stack_ch8_init }, 16328}; 16329 16330static struct snd_kcontrol_new alc861vd_chmode_mixer[] = { 16331 { 16332 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 16333 .name = "Channel Mode", 16334 .info = alc_ch_mode_info, 16335 .get = alc_ch_mode_get, 16336 .put = alc_ch_mode_put, 16337 }, 16338 { } /* end */ 16339}; 16340 16341/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 16342 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b 16343 */ 16344static struct snd_kcontrol_new alc861vd_6st_mixer[] = { 16345 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 16346 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 16347 16348 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT), 16349 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 16350 16351 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, 16352 HDA_OUTPUT), 16353 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, 16354 HDA_OUTPUT), 16355 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 16356 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 16357 16358 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT), 16359 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 16360 16361 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 16362 16363 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 16364 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 16365 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 16366 16367 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 16368 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 16369 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 16370 16371 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 16372 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 16373 16374 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 16375 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 16376 16377 { } /* end */ 16378}; 16379 16380static struct snd_kcontrol_new alc861vd_3st_mixer[] = { 16381 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 16382 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 16383 16384 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 16385 16386 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 16387 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 16388 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 16389 16390 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 16391 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 16392 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 16393 16394 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 16395 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 16396 16397 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 16398 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 16399 16400 { } /* end */ 16401}; 16402 16403static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = { 16404 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 16405 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/ 16406 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 16407 16408 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 16409 16410 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 16411 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 16412 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 16413 16414 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 16415 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 16416 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 16417 16418 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 16419 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 16420 16421 { } /* end */ 16422}; 16423 16424/* Pin assignment: Speaker=0x14, HP = 0x15, 16425 * Ext Mic=0x18, Int Mic = 0x19, CD = 0x1c, PC Beep = 0x1d 16426 */ 16427static struct snd_kcontrol_new alc861vd_dallas_mixer[] = { 16428 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 16429 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT), 16430 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 16431 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT), 16432 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT), 16433 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 16434 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 16435 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 16436 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 16437 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 16438 { } /* end */ 16439}; 16440 16441/* Pin assignment: Speaker=0x14, Line-out = 0x15, 16442 * Front Mic=0x18, ATAPI Mic = 0x19, 16443 */ 16444static struct snd_kcontrol_new alc861vd_hp_mixer[] = { 16445 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 16446 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 16447 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 16448 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT), 16449 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 16450 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 16451 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 16452 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 16453 16454 { } /* end */ 16455}; 16456 16457/* 16458 * generic initialization of ADC, input mixers and output mixers 16459 */ 16460static struct hda_verb alc861vd_volume_init_verbs[] = { 16461 /* 16462 * Unmute ADC0 and set the default input to mic-in 16463 */ 16464 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 16465 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 16466 16467 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of 16468 * the analog-loopback mixer widget 16469 */ 16470 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 16471 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 16472 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 16473 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 16474 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 16475 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 16476 16477 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */ 16478 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 16479 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 16480 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 16481 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, 16482 16483 /* 16484 * Set up output mixers (0x02 - 0x05) 16485 */ 16486 /* set vol=0 to output mixers */ 16487 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 16488 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 16489 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 16490 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 16491 16492 /* set up input amps for analog loopback */ 16493 /* Amp Indices: DAC = 0, mixer = 1 */ 16494 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 16495 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 16496 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 16497 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 16498 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 16499 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 16500 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 16501 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 16502 16503 { } 16504}; 16505 16506/* 16507 * 3-stack pin configuration: 16508 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b 16509 */ 16510static struct hda_verb alc861vd_3stack_init_verbs[] = { 16511 /* 16512 * Set pin mode and muting 16513 */ 16514 /* set front pin widgets 0x14 for output */ 16515 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 16516 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 16517 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 16518 16519 /* Mic (rear) pin: input vref at 80% */ 16520 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 16521 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 16522 /* Front Mic pin: input vref at 80% */ 16523 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 16524 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 16525 /* Line In pin: input */ 16526 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 16527 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 16528 /* Line-2 In: Headphone output (output 0 - 0x0c) */ 16529 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 16530 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 16531 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 16532 /* CD pin widget for input */ 16533 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 16534 16535 { } 16536}; 16537 16538/* 16539 * 6-stack pin configuration: 16540 */ 16541static struct hda_verb alc861vd_6stack_init_verbs[] = { 16542 /* 16543 * Set pin mode and muting 16544 */ 16545 /* set front pin widgets 0x14 for output */ 16546 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 16547 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 16548 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 16549 16550 /* Rear Pin: output 1 (0x0d) */ 16551 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 16552 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 16553 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 16554 /* CLFE Pin: output 2 (0x0e) */ 16555 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 16556 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 16557 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, 16558 /* Side Pin: output 3 (0x0f) */ 16559 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 16560 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 16561 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, 16562 16563 /* Mic (rear) pin: input vref at 80% */ 16564 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 16565 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 16566 /* Front Mic pin: input vref at 80% */ 16567 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 16568 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 16569 /* Line In pin: input */ 16570 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 16571 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 16572 /* Line-2 In: Headphone output (output 0 - 0x0c) */ 16573 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 16574 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 16575 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 16576 /* CD pin widget for input */ 16577 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 16578 16579 { } 16580}; 16581 16582static struct hda_verb alc861vd_eapd_verbs[] = { 16583 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 16584 { } 16585}; 16586 16587static struct hda_verb alc660vd_eapd_verbs[] = { 16588 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 16589 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, 16590 { } 16591}; 16592 16593static struct hda_verb alc861vd_lenovo_unsol_verbs[] = { 16594 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 16595 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 16596 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, 16597 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 16598 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 16599 {} 16600}; 16601 16602static void alc861vd_lenovo_mic_automute(struct hda_codec *codec) 16603{ 16604 unsigned int present; 16605 unsigned char bits; 16606 16607 present = snd_hda_jack_detect(codec, 0x18); 16608 bits = present ? HDA_AMP_MUTE : 0; 16609 16610 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, 16611 HDA_AMP_MUTE, bits); 16612} 16613 16614static void alc861vd_lenovo_setup(struct hda_codec *codec) 16615{ 16616 struct alc_spec *spec = codec->spec; 16617 spec->autocfg.hp_pins[0] = 0x1b; 16618 spec->autocfg.speaker_pins[0] = 0x14; 16619} 16620 16621static void alc861vd_lenovo_init_hook(struct hda_codec *codec) 16622{ 16623 alc_automute_amp(codec); 16624 alc861vd_lenovo_mic_automute(codec); 16625} 16626 16627static void alc861vd_lenovo_unsol_event(struct hda_codec *codec, 16628 unsigned int res) 16629{ 16630 switch (res >> 26) { 16631 case ALC880_MIC_EVENT: 16632 alc861vd_lenovo_mic_automute(codec); 16633 break; 16634 default: 16635 alc_automute_amp_unsol_event(codec, res); 16636 break; 16637 } 16638} 16639 16640static struct hda_verb alc861vd_dallas_verbs[] = { 16641 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 16642 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 16643 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 16644 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 16645 16646 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 16647 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 16648 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 16649 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 16650 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 16651 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 16652 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 16653 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 16654 16655 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 16656 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 16657 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 16658 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 16659 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 16660 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 16661 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 16662 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 16663 16664 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, 16665 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 16666 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, 16667 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 16668 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 16669 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 16670 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 16671 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 16672 16673 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 16674 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 16675 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 16676 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 16677 16678 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 16679 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 16680 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 16681 16682 { } /* end */ 16683}; 16684 16685/* toggle speaker-output according to the hp-jack state */ 16686static void alc861vd_dallas_setup(struct hda_codec *codec) 16687{ 16688 struct alc_spec *spec = codec->spec; 16689 16690 spec->autocfg.hp_pins[0] = 0x15; 16691 spec->autocfg.speaker_pins[0] = 0x14; 16692} 16693 16694#ifdef CONFIG_SND_HDA_POWER_SAVE 16695#define alc861vd_loopbacks alc880_loopbacks 16696#endif 16697 16698/* pcm configuration: identical with ALC880 */ 16699#define alc861vd_pcm_analog_playback alc880_pcm_analog_playback 16700#define alc861vd_pcm_analog_capture alc880_pcm_analog_capture 16701#define alc861vd_pcm_digital_playback alc880_pcm_digital_playback 16702#define alc861vd_pcm_digital_capture alc880_pcm_digital_capture 16703 16704/* 16705 * configuration and preset 16706 */ 16707static const char *alc861vd_models[ALC861VD_MODEL_LAST] = { 16708 [ALC660VD_3ST] = "3stack-660", 16709 [ALC660VD_3ST_DIG] = "3stack-660-digout", 16710 [ALC660VD_ASUS_V1S] = "asus-v1s", 16711 [ALC861VD_3ST] = "3stack", 16712 [ALC861VD_3ST_DIG] = "3stack-digout", 16713 [ALC861VD_6ST_DIG] = "6stack-digout", 16714 [ALC861VD_LENOVO] = "lenovo", 16715 [ALC861VD_DALLAS] = "dallas", 16716 [ALC861VD_HP] = "hp", 16717 [ALC861VD_AUTO] = "auto", 16718}; 16719 16720static struct snd_pci_quirk alc861vd_cfg_tbl[] = { 16721 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST), 16722 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP), 16723 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST), 16724 /*SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),*/ /* auto */ 16725 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S), 16726 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG), 16727 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST), 16728 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO), 16729 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/ 16730 SND_PCI_QUIRK(0x1179, 0xff01, "Toshiba A135", ALC861VD_LENOVO), 16731 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO), 16732 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS), 16733 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG), 16734 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO), 16735 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG), 16736 {} 16737}; 16738 16739static struct alc_config_preset alc861vd_presets[] = { 16740 [ALC660VD_3ST] = { 16741 .mixers = { alc861vd_3st_mixer }, 16742 .init_verbs = { alc861vd_volume_init_verbs, 16743 alc861vd_3stack_init_verbs }, 16744 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids), 16745 .dac_nids = alc660vd_dac_nids, 16746 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 16747 .channel_mode = alc861vd_3stack_2ch_modes, 16748 .input_mux = &alc861vd_capture_source, 16749 }, 16750 [ALC660VD_3ST_DIG] = { 16751 .mixers = { alc861vd_3st_mixer }, 16752 .init_verbs = { alc861vd_volume_init_verbs, 16753 alc861vd_3stack_init_verbs }, 16754 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids), 16755 .dac_nids = alc660vd_dac_nids, 16756 .dig_out_nid = ALC861VD_DIGOUT_NID, 16757 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 16758 .channel_mode = alc861vd_3stack_2ch_modes, 16759 .input_mux = &alc861vd_capture_source, 16760 }, 16761 [ALC861VD_3ST] = { 16762 .mixers = { alc861vd_3st_mixer }, 16763 .init_verbs = { alc861vd_volume_init_verbs, 16764 alc861vd_3stack_init_verbs }, 16765 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids), 16766 .dac_nids = alc861vd_dac_nids, 16767 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 16768 .channel_mode = alc861vd_3stack_2ch_modes, 16769 .input_mux = &alc861vd_capture_source, 16770 }, 16771 [ALC861VD_3ST_DIG] = { 16772 .mixers = { alc861vd_3st_mixer }, 16773 .init_verbs = { alc861vd_volume_init_verbs, 16774 alc861vd_3stack_init_verbs }, 16775 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids), 16776 .dac_nids = alc861vd_dac_nids, 16777 .dig_out_nid = ALC861VD_DIGOUT_NID, 16778 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 16779 .channel_mode = alc861vd_3stack_2ch_modes, 16780 .input_mux = &alc861vd_capture_source, 16781 }, 16782 [ALC861VD_6ST_DIG] = { 16783 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer }, 16784 .init_verbs = { alc861vd_volume_init_verbs, 16785 alc861vd_6stack_init_verbs }, 16786 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids), 16787 .dac_nids = alc861vd_dac_nids, 16788 .dig_out_nid = ALC861VD_DIGOUT_NID, 16789 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes), 16790 .channel_mode = alc861vd_6stack_modes, 16791 .input_mux = &alc861vd_capture_source, 16792 }, 16793 [ALC861VD_LENOVO] = { 16794 .mixers = { alc861vd_lenovo_mixer }, 16795 .init_verbs = { alc861vd_volume_init_verbs, 16796 alc861vd_3stack_init_verbs, 16797 alc861vd_eapd_verbs, 16798 alc861vd_lenovo_unsol_verbs }, 16799 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids), 16800 .dac_nids = alc660vd_dac_nids, 16801 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 16802 .channel_mode = alc861vd_3stack_2ch_modes, 16803 .input_mux = &alc861vd_capture_source, 16804 .unsol_event = alc861vd_lenovo_unsol_event, 16805 .setup = alc861vd_lenovo_setup, 16806 .init_hook = alc861vd_lenovo_init_hook, 16807 }, 16808 [ALC861VD_DALLAS] = { 16809 .mixers = { alc861vd_dallas_mixer }, 16810 .init_verbs = { alc861vd_dallas_verbs }, 16811 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids), 16812 .dac_nids = alc861vd_dac_nids, 16813 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 16814 .channel_mode = alc861vd_3stack_2ch_modes, 16815 .input_mux = &alc861vd_dallas_capture_source, 16816 .unsol_event = alc_automute_amp_unsol_event, 16817 .setup = alc861vd_dallas_setup, 16818 .init_hook = alc_automute_amp, 16819 }, 16820 [ALC861VD_HP] = { 16821 .mixers = { alc861vd_hp_mixer }, 16822 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs }, 16823 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids), 16824 .dac_nids = alc861vd_dac_nids, 16825 .dig_out_nid = ALC861VD_DIGOUT_NID, 16826 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 16827 .channel_mode = alc861vd_3stack_2ch_modes, 16828 .input_mux = &alc861vd_hp_capture_source, 16829 .unsol_event = alc_automute_amp_unsol_event, 16830 .setup = alc861vd_dallas_setup, 16831 .init_hook = alc_automute_amp, 16832 }, 16833 [ALC660VD_ASUS_V1S] = { 16834 .mixers = { alc861vd_lenovo_mixer }, 16835 .init_verbs = { alc861vd_volume_init_verbs, 16836 alc861vd_3stack_init_verbs, 16837 alc861vd_eapd_verbs, 16838 alc861vd_lenovo_unsol_verbs }, 16839 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids), 16840 .dac_nids = alc660vd_dac_nids, 16841 .dig_out_nid = ALC861VD_DIGOUT_NID, 16842 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 16843 .channel_mode = alc861vd_3stack_2ch_modes, 16844 .input_mux = &alc861vd_capture_source, 16845 .unsol_event = alc861vd_lenovo_unsol_event, 16846 .setup = alc861vd_lenovo_setup, 16847 .init_hook = alc861vd_lenovo_init_hook, 16848 }, 16849}; 16850 16851/* 16852 * BIOS auto configuration 16853 */ 16854static int alc861vd_auto_create_input_ctls(struct hda_codec *codec, 16855 const struct auto_pin_cfg *cfg) 16856{ 16857 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x09, 0); 16858} 16859 16860 16861static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec, 16862 hda_nid_t nid, int pin_type, int dac_idx) 16863{ 16864 alc_set_pin_output(codec, nid, pin_type); 16865} 16866 16867static void alc861vd_auto_init_multi_out(struct hda_codec *codec) 16868{ 16869 struct alc_spec *spec = codec->spec; 16870 int i; 16871 16872 for (i = 0; i <= HDA_SIDE; i++) { 16873 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 16874 int pin_type = get_pin_type(spec->autocfg.line_out_type); 16875 if (nid) 16876 alc861vd_auto_set_output_and_unmute(codec, nid, 16877 pin_type, i); 16878 } 16879} 16880 16881 16882static void alc861vd_auto_init_hp_out(struct hda_codec *codec) 16883{ 16884 struct alc_spec *spec = codec->spec; 16885 hda_nid_t pin; 16886 16887 pin = spec->autocfg.hp_pins[0]; 16888 if (pin) /* connect to front and use dac 0 */ 16889 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); 16890 pin = spec->autocfg.speaker_pins[0]; 16891 if (pin) 16892 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0); 16893} 16894 16895#define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID 16896 16897static void alc861vd_auto_init_analog_input(struct hda_codec *codec) 16898{ 16899 struct alc_spec *spec = codec->spec; 16900 struct auto_pin_cfg *cfg = &spec->autocfg; 16901 int i; 16902 16903 for (i = 0; i < cfg->num_inputs; i++) { 16904 hda_nid_t nid = cfg->inputs[i].pin; 16905 if (alc_is_input_pin(codec, nid)) { 16906 alc_set_input_pin(codec, nid, cfg->inputs[i].type); 16907 if (nid != ALC861VD_PIN_CD_NID && 16908 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)) 16909 snd_hda_codec_write(codec, nid, 0, 16910 AC_VERB_SET_AMP_GAIN_MUTE, 16911 AMP_OUT_MUTE); 16912 } 16913 } 16914} 16915 16916#define alc861vd_auto_init_input_src alc882_auto_init_input_src 16917 16918#define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02) 16919#define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c) 16920 16921/* add playback controls from the parsed DAC table */ 16922/* Based on ALC880 version. But ALC861VD has separate, 16923 * different NIDs for mute/unmute switch and volume control */ 16924static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec, 16925 const struct auto_pin_cfg *cfg) 16926{ 16927 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"}; 16928 hda_nid_t nid_v, nid_s; 16929 int i, err; 16930 16931 for (i = 0; i < cfg->line_outs; i++) { 16932 if (!spec->multiout.dac_nids[i]) 16933 continue; 16934 nid_v = alc861vd_idx_to_mixer_vol( 16935 alc880_dac_to_idx( 16936 spec->multiout.dac_nids[i])); 16937 nid_s = alc861vd_idx_to_mixer_switch( 16938 alc880_dac_to_idx( 16939 spec->multiout.dac_nids[i])); 16940 16941 if (i == 2) { 16942 /* Center/LFE */ 16943 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, 16944 "Center", 16945 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0, 16946 HDA_OUTPUT)); 16947 if (err < 0) 16948 return err; 16949 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, 16950 "LFE", 16951 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0, 16952 HDA_OUTPUT)); 16953 if (err < 0) 16954 return err; 16955 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, 16956 "Center", 16957 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2, 16958 HDA_INPUT)); 16959 if (err < 0) 16960 return err; 16961 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, 16962 "LFE", 16963 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2, 16964 HDA_INPUT)); 16965 if (err < 0) 16966 return err; 16967 } else { 16968 const char *pfx; 16969 if (cfg->line_outs == 1 && 16970 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) { 16971 if (!cfg->hp_pins) 16972 pfx = "Speaker"; 16973 else 16974 pfx = "PCM"; 16975 } else 16976 pfx = chname[i]; 16977 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, 16978 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, 16979 HDA_OUTPUT)); 16980 if (err < 0) 16981 return err; 16982 if (cfg->line_outs == 1 && 16983 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) 16984 pfx = "Speaker"; 16985 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx, 16986 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, 16987 HDA_INPUT)); 16988 if (err < 0) 16989 return err; 16990 } 16991 } 16992 return 0; 16993} 16994 16995/* add playback controls for speaker and HP outputs */ 16996/* Based on ALC880 version. But ALC861VD has separate, 16997 * different NIDs for mute/unmute switch and volume control */ 16998static int alc861vd_auto_create_extra_out(struct alc_spec *spec, 16999 hda_nid_t pin, const char *pfx) 17000{ 17001 hda_nid_t nid_v, nid_s; 17002 int err; 17003 17004 if (!pin) 17005 return 0; 17006 17007 if (alc880_is_fixed_pin(pin)) { 17008 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); 17009 /* specify the DAC as the extra output */ 17010 if (!spec->multiout.hp_nid) 17011 spec->multiout.hp_nid = nid_v; 17012 else 17013 spec->multiout.extra_out_nid[0] = nid_v; 17014 /* control HP volume/switch on the output mixer amp */ 17015 nid_v = alc861vd_idx_to_mixer_vol( 17016 alc880_fixed_pin_idx(pin)); 17017 nid_s = alc861vd_idx_to_mixer_switch( 17018 alc880_fixed_pin_idx(pin)); 17019 17020 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, 17021 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT)); 17022 if (err < 0) 17023 return err; 17024 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx, 17025 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT)); 17026 if (err < 0) 17027 return err; 17028 } else if (alc880_is_multi_pin(pin)) { 17029 /* set manual connection */ 17030 /* we have only a switch on HP-out PIN */ 17031 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, 17032 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); 17033 if (err < 0) 17034 return err; 17035 } 17036 return 0; 17037} 17038 17039/* parse the BIOS configuration and set up the alc_spec 17040 * return 1 if successful, 0 if the proper config is not found, 17041 * or a negative error code 17042 * Based on ALC880 version - had to change it to override 17043 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */ 17044static int alc861vd_parse_auto_config(struct hda_codec *codec) 17045{ 17046 struct alc_spec *spec = codec->spec; 17047 int err; 17048 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 }; 17049 17050 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 17051 alc861vd_ignore); 17052 if (err < 0) 17053 return err; 17054 if (!spec->autocfg.line_outs) 17055 return 0; /* can't find valid BIOS pin config */ 17056 17057 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); 17058 if (err < 0) 17059 return err; 17060 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg); 17061 if (err < 0) 17062 return err; 17063 err = alc861vd_auto_create_extra_out(spec, 17064 spec->autocfg.speaker_pins[0], 17065 "Speaker"); 17066 if (err < 0) 17067 return err; 17068 err = alc861vd_auto_create_extra_out(spec, 17069 spec->autocfg.hp_pins[0], 17070 "Headphone"); 17071 if (err < 0) 17072 return err; 17073 err = alc861vd_auto_create_input_ctls(codec, &spec->autocfg); 17074 if (err < 0) 17075 return err; 17076 17077 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 17078 17079 alc_auto_parse_digital(codec); 17080 17081 if (spec->kctls.list) 17082 add_mixer(spec, spec->kctls.list); 17083 17084 add_verb(spec, alc861vd_volume_init_verbs); 17085 17086 spec->num_mux_defs = 1; 17087 spec->input_mux = &spec->private_imux[0]; 17088 17089 err = alc_auto_add_mic_boost(codec); 17090 if (err < 0) 17091 return err; 17092 17093 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); 17094 17095 return 1; 17096} 17097 17098/* additional initialization for auto-configuration model */ 17099static void alc861vd_auto_init(struct hda_codec *codec) 17100{ 17101 struct alc_spec *spec = codec->spec; 17102 alc861vd_auto_init_multi_out(codec); 17103 alc861vd_auto_init_hp_out(codec); 17104 alc861vd_auto_init_analog_input(codec); 17105 alc861vd_auto_init_input_src(codec); 17106 alc_auto_init_digital(codec); 17107 if (spec->unsol_event) 17108 alc_inithook(codec); 17109} 17110 17111enum { 17112 ALC660VD_FIX_ASUS_GPIO1 17113}; 17114 17115/* reset GPIO1 */ 17116static const struct alc_fixup alc861vd_fixups[] = { 17117 [ALC660VD_FIX_ASUS_GPIO1] = { 17118 .verbs = (const struct hda_verb[]) { 17119 {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, 17120 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, 17121 {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, 17122 { } 17123 } 17124 }, 17125}; 17126 17127static struct snd_pci_quirk alc861vd_fixup_tbl[] = { 17128 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1), 17129 {} 17130}; 17131 17132static int patch_alc861vd(struct hda_codec *codec) 17133{ 17134 struct alc_spec *spec; 17135 int err, board_config; 17136 17137 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 17138 if (spec == NULL) 17139 return -ENOMEM; 17140 17141 codec->spec = spec; 17142 17143 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST, 17144 alc861vd_models, 17145 alc861vd_cfg_tbl); 17146 17147 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) { 17148 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 17149 codec->chip_name); 17150 board_config = ALC861VD_AUTO; 17151 } 17152 17153 if (board_config == ALC861VD_AUTO) 17154 alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups, 1); 17155 17156 if (board_config == ALC861VD_AUTO) { 17157 /* automatic parse from the BIOS config */ 17158 err = alc861vd_parse_auto_config(codec); 17159 if (err < 0) { 17160 alc_free(codec); 17161 return err; 17162 } else if (!err) { 17163 printk(KERN_INFO 17164 "hda_codec: Cannot set up configuration " 17165 "from BIOS. Using base mode...\n"); 17166 board_config = ALC861VD_3ST; 17167 } 17168 } 17169 17170 err = snd_hda_attach_beep_device(codec, 0x23); 17171 if (err < 0) { 17172 alc_free(codec); 17173 return err; 17174 } 17175 17176 if (board_config != ALC861VD_AUTO) 17177 setup_preset(codec, &alc861vd_presets[board_config]); 17178 17179 if (codec->vendor_id == 0x10ec0660) { 17180 /* always turn on EAPD */ 17181 add_verb(spec, alc660vd_eapd_verbs); 17182 } 17183 17184 spec->stream_analog_playback = &alc861vd_pcm_analog_playback; 17185 spec->stream_analog_capture = &alc861vd_pcm_analog_capture; 17186 17187 spec->stream_digital_playback = &alc861vd_pcm_digital_playback; 17188 spec->stream_digital_capture = &alc861vd_pcm_digital_capture; 17189 17190 if (!spec->adc_nids) { 17191 spec->adc_nids = alc861vd_adc_nids; 17192 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids); 17193 } 17194 if (!spec->capsrc_nids) 17195 spec->capsrc_nids = alc861vd_capsrc_nids; 17196 17197 set_capture_mixer(codec); 17198 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 17199 17200 spec->vmaster_nid = 0x02; 17201 17202 if (board_config == ALC861VD_AUTO) 17203 alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups, 0); 17204 17205 codec->patch_ops = alc_patch_ops; 17206 17207 if (board_config == ALC861VD_AUTO) 17208 spec->init_hook = alc861vd_auto_init; 17209#ifdef CONFIG_SND_HDA_POWER_SAVE 17210 if (!spec->loopback.amplist) 17211 spec->loopback.amplist = alc861vd_loopbacks; 17212#endif 17213 17214 return 0; 17215} 17216 17217/* 17218 * ALC662 support 17219 * 17220 * ALC662 is almost identical with ALC880 but has cleaner and more flexible 17221 * configuration. Each pin widget can choose any input DACs and a mixer. 17222 * Each ADC is connected from a mixer of all inputs. This makes possible 17223 * 6-channel independent captures. 17224 * 17225 * In addition, an independent DAC for the multi-playback (not used in this 17226 * driver yet). 17227 */ 17228#define ALC662_DIGOUT_NID 0x06 17229#define ALC662_DIGIN_NID 0x0a 17230 17231static hda_nid_t alc662_dac_nids[4] = { 17232 /* front, rear, clfe, rear_surr */ 17233 0x02, 0x03, 0x04 17234}; 17235 17236static hda_nid_t alc272_dac_nids[2] = { 17237 0x02, 0x03 17238}; 17239 17240static hda_nid_t alc662_adc_nids[2] = { 17241 /* ADC1-2 */ 17242 0x09, 0x08 17243}; 17244 17245static hda_nid_t alc272_adc_nids[1] = { 17246 /* ADC1-2 */ 17247 0x08, 17248}; 17249 17250static hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 }; 17251static hda_nid_t alc272_capsrc_nids[1] = { 0x23 }; 17252 17253 17254/* input MUX */ 17255/* FIXME: should be a matrix-type input source selection */ 17256static struct hda_input_mux alc662_capture_source = { 17257 .num_items = 4, 17258 .items = { 17259 { "Mic", 0x0 }, 17260 { "Front Mic", 0x1 }, 17261 { "Line", 0x2 }, 17262 { "CD", 0x4 }, 17263 }, 17264}; 17265 17266static struct hda_input_mux alc662_lenovo_101e_capture_source = { 17267 .num_items = 2, 17268 .items = { 17269 { "Mic", 0x1 }, 17270 { "Line", 0x2 }, 17271 }, 17272}; 17273 17274static struct hda_input_mux alc663_capture_source = { 17275 .num_items = 3, 17276 .items = { 17277 { "Mic", 0x0 }, 17278 { "Front Mic", 0x1 }, 17279 { "Line", 0x2 }, 17280 }, 17281}; 17282 17283#if 0 /* set to 1 for testing other input sources below */ 17284static struct hda_input_mux alc272_nc10_capture_source = { 17285 .num_items = 16, 17286 .items = { 17287 { "Autoselect Mic", 0x0 }, 17288 { "Internal Mic", 0x1 }, 17289 { "In-0x02", 0x2 }, 17290 { "In-0x03", 0x3 }, 17291 { "In-0x04", 0x4 }, 17292 { "In-0x05", 0x5 }, 17293 { "In-0x06", 0x6 }, 17294 { "In-0x07", 0x7 }, 17295 { "In-0x08", 0x8 }, 17296 { "In-0x09", 0x9 }, 17297 { "In-0x0a", 0x0a }, 17298 { "In-0x0b", 0x0b }, 17299 { "In-0x0c", 0x0c }, 17300 { "In-0x0d", 0x0d }, 17301 { "In-0x0e", 0x0e }, 17302 { "In-0x0f", 0x0f }, 17303 }, 17304}; 17305#endif 17306 17307/* 17308 * 2ch mode 17309 */ 17310static struct hda_channel_mode alc662_3ST_2ch_modes[1] = { 17311 { 2, NULL } 17312}; 17313 17314/* 17315 * 2ch mode 17316 */ 17317static struct hda_verb alc662_3ST_ch2_init[] = { 17318 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 17319 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 17320 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 17321 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 17322 { } /* end */ 17323}; 17324 17325/* 17326 * 6ch mode 17327 */ 17328static struct hda_verb alc662_3ST_ch6_init[] = { 17329 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 17330 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 17331 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, 17332 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 17333 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 17334 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 17335 { } /* end */ 17336}; 17337 17338static struct hda_channel_mode alc662_3ST_6ch_modes[2] = { 17339 { 2, alc662_3ST_ch2_init }, 17340 { 6, alc662_3ST_ch6_init }, 17341}; 17342 17343/* 17344 * 2ch mode 17345 */ 17346static struct hda_verb alc662_sixstack_ch6_init[] = { 17347 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 17348 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 17349 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 17350 { } /* end */ 17351}; 17352 17353/* 17354 * 6ch mode 17355 */ 17356static struct hda_verb alc662_sixstack_ch8_init[] = { 17357 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 17358 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 17359 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 17360 { } /* end */ 17361}; 17362 17363static struct hda_channel_mode alc662_5stack_modes[2] = { 17364 { 2, alc662_sixstack_ch6_init }, 17365 { 6, alc662_sixstack_ch8_init }, 17366}; 17367 17368/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 17369 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b 17370 */ 17371 17372static struct snd_kcontrol_new alc662_base_mixer[] = { 17373 /* output mixer control */ 17374 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), 17375 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT), 17376 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT), 17377 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT), 17378 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT), 17379 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT), 17380 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT), 17381 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT), 17382 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 17383 17384 /*Input mixer control */ 17385 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT), 17386 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT), 17387 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT), 17388 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT), 17389 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT), 17390 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT), 17391 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT), 17392 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT), 17393 { } /* end */ 17394}; 17395 17396static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = { 17397 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 17398 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT), 17399 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 17400 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 17401 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 17402 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 17403 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 17404 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17405 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17406 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 17407 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 17408 { } /* end */ 17409}; 17410 17411static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = { 17412 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 17413 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT), 17414 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT), 17415 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT), 17416 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT), 17417 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT), 17418 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT), 17419 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT), 17420 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 17421 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 17422 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 17423 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 17424 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 17425 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17426 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17427 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 17428 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 17429 { } /* end */ 17430}; 17431 17432static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = { 17433 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 17434 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT), 17435 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT), 17436 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT), 17437 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 17438 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 17439 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 17440 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 17441 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 17442 { } /* end */ 17443}; 17444 17445static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = { 17446 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT), 17447 ALC262_HIPPO_MASTER_SWITCH, 17448 17449 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT), 17450 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17451 HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17452 17453 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT), 17454 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 17455 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 17456 { } /* end */ 17457}; 17458 17459static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = { 17460 ALC262_HIPPO_MASTER_SWITCH, 17461 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 17462 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT), 17463 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT), 17464 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT), 17465 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT), 17466 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 17467 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 17468 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17469 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17470 { } /* end */ 17471}; 17472 17473static struct hda_bind_ctls alc663_asus_bind_master_vol = { 17474 .ops = &snd_hda_bind_vol, 17475 .values = { 17476 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), 17477 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT), 17478 0 17479 }, 17480}; 17481 17482static struct hda_bind_ctls alc663_asus_one_bind_switch = { 17483 .ops = &snd_hda_bind_sw, 17484 .values = { 17485 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 17486 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT), 17487 0 17488 }, 17489}; 17490 17491static struct snd_kcontrol_new alc663_m51va_mixer[] = { 17492 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol), 17493 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch), 17494 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17495 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17496 { } /* end */ 17497}; 17498 17499static struct hda_bind_ctls alc663_asus_tree_bind_switch = { 17500 .ops = &snd_hda_bind_sw, 17501 .values = { 17502 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 17503 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT), 17504 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT), 17505 0 17506 }, 17507}; 17508 17509static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = { 17510 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol), 17511 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch), 17512 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17513 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17514 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 17515 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 17516 17517 { } /* end */ 17518}; 17519 17520static struct hda_bind_ctls alc663_asus_four_bind_switch = { 17521 .ops = &snd_hda_bind_sw, 17522 .values = { 17523 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 17524 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT), 17525 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT), 17526 0 17527 }, 17528}; 17529 17530static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = { 17531 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol), 17532 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch), 17533 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17534 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17535 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 17536 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 17537 { } /* end */ 17538}; 17539 17540static struct snd_kcontrol_new alc662_1bjd_mixer[] = { 17541 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 17542 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 17543 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 17544 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17545 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17546 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 17547 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 17548 { } /* end */ 17549}; 17550 17551static struct hda_bind_ctls alc663_asus_two_bind_master_vol = { 17552 .ops = &snd_hda_bind_vol, 17553 .values = { 17554 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), 17555 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT), 17556 0 17557 }, 17558}; 17559 17560static struct hda_bind_ctls alc663_asus_two_bind_switch = { 17561 .ops = &snd_hda_bind_sw, 17562 .values = { 17563 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 17564 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT), 17565 0 17566 }, 17567}; 17568 17569static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = { 17570 HDA_BIND_VOL("Master Playback Volume", 17571 &alc663_asus_two_bind_master_vol), 17572 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch), 17573 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 17574 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT), 17575 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17576 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17577 { } /* end */ 17578}; 17579 17580static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = { 17581 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol), 17582 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch), 17583 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 17584 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 17585 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17586 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17587 { } /* end */ 17588}; 17589 17590static struct snd_kcontrol_new alc663_g71v_mixer[] = { 17591 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 17592 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 17593 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT), 17594 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT), 17595 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT), 17596 17597 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17598 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17599 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 17600 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 17601 { } /* end */ 17602}; 17603 17604static struct snd_kcontrol_new alc663_g50v_mixer[] = { 17605 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 17606 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 17607 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT), 17608 17609 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17610 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17611 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 17612 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 17613 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 17614 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 17615 { } /* end */ 17616}; 17617 17618static struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = { 17619 .ops = &snd_hda_bind_sw, 17620 .values = { 17621 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 17622 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT), 17623 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT), 17624 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT), 17625 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT), 17626 0 17627 }, 17628}; 17629 17630static struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = { 17631 .ops = &snd_hda_bind_sw, 17632 .values = { 17633 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 17634 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT), 17635 0 17636 }, 17637}; 17638 17639static struct snd_kcontrol_new alc663_mode7_mixer[] = { 17640 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch), 17641 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol), 17642 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch), 17643 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 17644 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT), 17645 HDA_CODEC_VOLUME("IntMic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17646 HDA_CODEC_MUTE("IntMic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17647 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 17648 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 17649 { } /* end */ 17650}; 17651 17652static struct snd_kcontrol_new alc663_mode8_mixer[] = { 17653 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch), 17654 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol), 17655 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch), 17656 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x15, 0x0, HDA_OUTPUT), 17657 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT), 17658 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17659 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17660 { } /* end */ 17661}; 17662 17663 17664static struct snd_kcontrol_new alc662_chmode_mixer[] = { 17665 { 17666 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 17667 .name = "Channel Mode", 17668 .info = alc_ch_mode_info, 17669 .get = alc_ch_mode_get, 17670 .put = alc_ch_mode_put, 17671 }, 17672 { } /* end */ 17673}; 17674 17675static struct hda_verb alc662_init_verbs[] = { 17676 /* ADC: mute amp left and right */ 17677 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 17678 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 17679 17680 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 17681 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 17682 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 17683 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 17684 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 17685 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 17686 17687 /* Front Pin: output 0 (0x0c) */ 17688 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 17689 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17690 17691 /* Rear Pin: output 1 (0x0d) */ 17692 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 17693 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17694 17695 /* CLFE Pin: output 2 (0x0e) */ 17696 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 17697 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17698 17699 /* Mic (rear) pin: input vref at 80% */ 17700 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 17701 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 17702 /* Front Mic pin: input vref at 80% */ 17703 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 17704 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 17705 /* Line In pin: input */ 17706 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17707 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 17708 /* Line-2 In: Headphone output (output 0 - 0x0c) */ 17709 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17710 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17711 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 17712 /* CD pin widget for input */ 17713 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17714 17715 /* FIXME: use matrix-type input source selection */ 17716 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 17717 /* Input mixer */ 17718 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 17719 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 17720 17721 /* always trun on EAPD */ 17722 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 17723 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, 17724 17725 { } 17726}; 17727 17728static struct hda_verb alc663_init_verbs[] = { 17729 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 17730 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17731 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 17732 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17733 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 17734 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 17735 { } 17736}; 17737 17738static struct hda_verb alc272_init_verbs[] = { 17739 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17740 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 17741 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 17742 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17743 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 17744 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17745 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 17746 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 17747 { } 17748}; 17749 17750static struct hda_verb alc662_sue_init_verbs[] = { 17751 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT}, 17752 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT}, 17753 {} 17754}; 17755 17756static struct hda_verb alc662_eeepc_sue_init_verbs[] = { 17757 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 17758 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17759 {} 17760}; 17761 17762/* Set Unsolicited Event*/ 17763static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = { 17764 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 17765 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17766 {} 17767}; 17768 17769static struct hda_verb alc663_m51va_init_verbs[] = { 17770 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17771 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17772 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17773 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17774 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ 17775 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 17776 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)}, 17777 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 17778 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17779 {} 17780}; 17781 17782static struct hda_verb alc663_21jd_amic_init_verbs[] = { 17783 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17784 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17785 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ 17786 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 17787 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 17788 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 17789 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17790 {} 17791}; 17792 17793static struct hda_verb alc662_1bjd_amic_init_verbs[] = { 17794 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17795 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17796 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17797 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */ 17798 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 17799 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 17800 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 17801 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17802 {} 17803}; 17804 17805static struct hda_verb alc663_15jd_amic_init_verbs[] = { 17806 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17807 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17808 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ 17809 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 17810 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 17811 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 17812 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17813 {} 17814}; 17815 17816static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = { 17817 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17818 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17819 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17820 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */ 17821 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17822 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17823 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */ 17824 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 17825 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 17826 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 17827 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17828 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17829 {} 17830}; 17831 17832static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = { 17833 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17834 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17835 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17836 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ 17837 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17838 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17839 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ 17840 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 17841 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 17842 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 17843 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17844 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17845 {} 17846}; 17847 17848static struct hda_verb alc663_g71v_init_verbs[] = { 17849 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17850 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */ 17851 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */ 17852 17853 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17854 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17855 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */ 17856 17857 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT}, 17858 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT}, 17859 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT}, 17860 {} 17861}; 17862 17863static struct hda_verb alc663_g50v_init_verbs[] = { 17864 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17865 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17866 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */ 17867 17868 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 17869 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17870 {} 17871}; 17872 17873static struct hda_verb alc662_ecs_init_verbs[] = { 17874 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f}, 17875 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 17876 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 17877 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17878 {} 17879}; 17880 17881static struct hda_verb alc272_dell_zm1_init_verbs[] = { 17882 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17883 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17884 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17885 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17886 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17887 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17888 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ 17889 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 17890 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)}, 17891 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 17892 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17893 {} 17894}; 17895 17896static struct hda_verb alc272_dell_init_verbs[] = { 17897 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17898 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17899 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17900 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17901 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17902 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17903 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ 17904 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 17905 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)}, 17906 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 17907 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17908 {} 17909}; 17910 17911static struct hda_verb alc663_mode7_init_verbs[] = { 17912 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17913 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17914 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 17915 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17916 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17917 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17918 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, 17919 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17920 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17921 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ 17922 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 17923 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)}, 17924 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 17925 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17926 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17927 {} 17928}; 17929 17930static struct hda_verb alc663_mode8_init_verbs[] = { 17931 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17932 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17933 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17934 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 17935 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17936 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 17937 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17938 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17939 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17940 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17941 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ 17942 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 17943 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)}, 17944 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17945 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 17946 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17947 {} 17948}; 17949 17950static struct snd_kcontrol_new alc662_auto_capture_mixer[] = { 17951 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), 17952 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), 17953 { } /* end */ 17954}; 17955 17956static struct snd_kcontrol_new alc272_auto_capture_mixer[] = { 17957 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 17958 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 17959 { } /* end */ 17960}; 17961 17962static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec) 17963{ 17964 unsigned int present; 17965 unsigned char bits; 17966 17967 present = snd_hda_jack_detect(codec, 0x14); 17968 bits = present ? HDA_AMP_MUTE : 0; 17969 17970 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 17971 HDA_AMP_MUTE, bits); 17972} 17973 17974static void alc662_lenovo_101e_all_automute(struct hda_codec *codec) 17975{ 17976 unsigned int present; 17977 unsigned char bits; 17978 17979 present = snd_hda_jack_detect(codec, 0x1b); 17980 bits = present ? HDA_AMP_MUTE : 0; 17981 17982 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 17983 HDA_AMP_MUTE, bits); 17984 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 17985 HDA_AMP_MUTE, bits); 17986} 17987 17988static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec, 17989 unsigned int res) 17990{ 17991 if ((res >> 26) == ALC880_HP_EVENT) 17992 alc662_lenovo_101e_all_automute(codec); 17993 if ((res >> 26) == ALC880_FRONT_EVENT) 17994 alc662_lenovo_101e_ispeaker_automute(codec); 17995} 17996 17997/* unsolicited event for HP jack sensing */ 17998static void alc662_eeepc_unsol_event(struct hda_codec *codec, 17999 unsigned int res) 18000{ 18001 if ((res >> 26) == ALC880_MIC_EVENT) 18002 alc_mic_automute(codec); 18003 else 18004 alc262_hippo_unsol_event(codec, res); 18005} 18006 18007static void alc662_eeepc_setup(struct hda_codec *codec) 18008{ 18009 struct alc_spec *spec = codec->spec; 18010 18011 alc262_hippo1_setup(codec); 18012 spec->ext_mic.pin = 0x18; 18013 spec->ext_mic.mux_idx = 0; 18014 spec->int_mic.pin = 0x19; 18015 spec->int_mic.mux_idx = 1; 18016 spec->auto_mic = 1; 18017} 18018 18019static void alc662_eeepc_inithook(struct hda_codec *codec) 18020{ 18021 alc262_hippo_automute(codec); 18022 alc_mic_automute(codec); 18023} 18024 18025static void alc662_eeepc_ep20_setup(struct hda_codec *codec) 18026{ 18027 struct alc_spec *spec = codec->spec; 18028 18029 spec->autocfg.hp_pins[0] = 0x14; 18030 spec->autocfg.speaker_pins[0] = 0x1b; 18031} 18032 18033#define alc662_eeepc_ep20_inithook alc262_hippo_master_update 18034 18035static void alc663_m51va_speaker_automute(struct hda_codec *codec) 18036{ 18037 unsigned int present; 18038 unsigned char bits; 18039 18040 present = snd_hda_jack_detect(codec, 0x21); 18041 bits = present ? HDA_AMP_MUTE : 0; 18042 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 18043 HDA_AMP_MUTE, bits); 18044 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 18045 HDA_AMP_MUTE, bits); 18046} 18047 18048static void alc663_21jd_two_speaker_automute(struct hda_codec *codec) 18049{ 18050 unsigned int present; 18051 unsigned char bits; 18052 18053 present = snd_hda_jack_detect(codec, 0x21); 18054 bits = present ? HDA_AMP_MUTE : 0; 18055 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 18056 HDA_AMP_MUTE, bits); 18057 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 18058 HDA_AMP_MUTE, bits); 18059 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0, 18060 HDA_AMP_MUTE, bits); 18061 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1, 18062 HDA_AMP_MUTE, bits); 18063} 18064 18065static void alc663_15jd_two_speaker_automute(struct hda_codec *codec) 18066{ 18067 unsigned int present; 18068 unsigned char bits; 18069 18070 present = snd_hda_jack_detect(codec, 0x15); 18071 bits = present ? HDA_AMP_MUTE : 0; 18072 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 18073 HDA_AMP_MUTE, bits); 18074 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 18075 HDA_AMP_MUTE, bits); 18076 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0, 18077 HDA_AMP_MUTE, bits); 18078 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1, 18079 HDA_AMP_MUTE, bits); 18080} 18081 18082static void alc662_f5z_speaker_automute(struct hda_codec *codec) 18083{ 18084 unsigned int present; 18085 unsigned char bits; 18086 18087 present = snd_hda_jack_detect(codec, 0x1b); 18088 bits = present ? 0 : PIN_OUT; 18089 snd_hda_codec_write(codec, 0x14, 0, 18090 AC_VERB_SET_PIN_WIDGET_CONTROL, bits); 18091} 18092 18093static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec) 18094{ 18095 unsigned int present1, present2; 18096 18097 present1 = snd_hda_jack_detect(codec, 0x21); 18098 present2 = snd_hda_jack_detect(codec, 0x15); 18099 18100 if (present1 || present2) { 18101 snd_hda_codec_write_cache(codec, 0x14, 0, 18102 AC_VERB_SET_PIN_WIDGET_CONTROL, 0); 18103 } else { 18104 snd_hda_codec_write_cache(codec, 0x14, 0, 18105 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); 18106 } 18107} 18108 18109static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec) 18110{ 18111 unsigned int present1, present2; 18112 18113 present1 = snd_hda_jack_detect(codec, 0x1b); 18114 present2 = snd_hda_jack_detect(codec, 0x15); 18115 18116 if (present1 || present2) { 18117 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 18118 HDA_AMP_MUTE, HDA_AMP_MUTE); 18119 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 18120 HDA_AMP_MUTE, HDA_AMP_MUTE); 18121 } else { 18122 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 18123 HDA_AMP_MUTE, 0); 18124 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 18125 HDA_AMP_MUTE, 0); 18126 } 18127} 18128 18129static void alc663_two_hp_m7_speaker_automute(struct hda_codec *codec) 18130{ 18131 unsigned int present1, present2; 18132 18133 present1 = snd_hda_codec_read(codec, 0x1b, 0, 18134 AC_VERB_GET_PIN_SENSE, 0) 18135 & AC_PINSENSE_PRESENCE; 18136 present2 = snd_hda_codec_read(codec, 0x21, 0, 18137 AC_VERB_GET_PIN_SENSE, 0) 18138 & AC_PINSENSE_PRESENCE; 18139 18140 if (present1 || present2) { 18141 snd_hda_codec_write_cache(codec, 0x14, 0, 18142 AC_VERB_SET_PIN_WIDGET_CONTROL, 0); 18143 snd_hda_codec_write_cache(codec, 0x17, 0, 18144 AC_VERB_SET_PIN_WIDGET_CONTROL, 0); 18145 } else { 18146 snd_hda_codec_write_cache(codec, 0x14, 0, 18147 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); 18148 snd_hda_codec_write_cache(codec, 0x17, 0, 18149 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); 18150 } 18151} 18152 18153static void alc663_two_hp_m8_speaker_automute(struct hda_codec *codec) 18154{ 18155 unsigned int present1, present2; 18156 18157 present1 = snd_hda_codec_read(codec, 0x21, 0, 18158 AC_VERB_GET_PIN_SENSE, 0) 18159 & AC_PINSENSE_PRESENCE; 18160 present2 = snd_hda_codec_read(codec, 0x15, 0, 18161 AC_VERB_GET_PIN_SENSE, 0) 18162 & AC_PINSENSE_PRESENCE; 18163 18164 if (present1 || present2) { 18165 snd_hda_codec_write_cache(codec, 0x14, 0, 18166 AC_VERB_SET_PIN_WIDGET_CONTROL, 0); 18167 snd_hda_codec_write_cache(codec, 0x17, 0, 18168 AC_VERB_SET_PIN_WIDGET_CONTROL, 0); 18169 } else { 18170 snd_hda_codec_write_cache(codec, 0x14, 0, 18171 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); 18172 snd_hda_codec_write_cache(codec, 0x17, 0, 18173 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); 18174 } 18175} 18176 18177static void alc663_m51va_unsol_event(struct hda_codec *codec, 18178 unsigned int res) 18179{ 18180 switch (res >> 26) { 18181 case ALC880_HP_EVENT: 18182 alc663_m51va_speaker_automute(codec); 18183 break; 18184 case ALC880_MIC_EVENT: 18185 alc_mic_automute(codec); 18186 break; 18187 } 18188} 18189 18190static void alc663_m51va_setup(struct hda_codec *codec) 18191{ 18192 struct alc_spec *spec = codec->spec; 18193 spec->ext_mic.pin = 0x18; 18194 spec->ext_mic.mux_idx = 0; 18195 spec->int_mic.pin = 0x12; 18196 spec->int_mic.mux_idx = 9; 18197 spec->auto_mic = 1; 18198} 18199 18200static void alc663_m51va_inithook(struct hda_codec *codec) 18201{ 18202 alc663_m51va_speaker_automute(codec); 18203 alc_mic_automute(codec); 18204} 18205 18206/* ***************** Mode1 ******************************/ 18207#define alc663_mode1_unsol_event alc663_m51va_unsol_event 18208 18209static void alc663_mode1_setup(struct hda_codec *codec) 18210{ 18211 struct alc_spec *spec = codec->spec; 18212 spec->ext_mic.pin = 0x18; 18213 spec->ext_mic.mux_idx = 0; 18214 spec->int_mic.pin = 0x19; 18215 spec->int_mic.mux_idx = 1; 18216 spec->auto_mic = 1; 18217} 18218 18219#define alc663_mode1_inithook alc663_m51va_inithook 18220 18221/* ***************** Mode2 ******************************/ 18222static void alc662_mode2_unsol_event(struct hda_codec *codec, 18223 unsigned int res) 18224{ 18225 switch (res >> 26) { 18226 case ALC880_HP_EVENT: 18227 alc662_f5z_speaker_automute(codec); 18228 break; 18229 case ALC880_MIC_EVENT: 18230 alc_mic_automute(codec); 18231 break; 18232 } 18233} 18234 18235#define alc662_mode2_setup alc663_mode1_setup 18236 18237static void alc662_mode2_inithook(struct hda_codec *codec) 18238{ 18239 alc662_f5z_speaker_automute(codec); 18240 alc_mic_automute(codec); 18241} 18242/* ***************** Mode3 ******************************/ 18243static void alc663_mode3_unsol_event(struct hda_codec *codec, 18244 unsigned int res) 18245{ 18246 switch (res >> 26) { 18247 case ALC880_HP_EVENT: 18248 alc663_two_hp_m1_speaker_automute(codec); 18249 break; 18250 case ALC880_MIC_EVENT: 18251 alc_mic_automute(codec); 18252 break; 18253 } 18254} 18255 18256#define alc663_mode3_setup alc663_mode1_setup 18257 18258static void alc663_mode3_inithook(struct hda_codec *codec) 18259{ 18260 alc663_two_hp_m1_speaker_automute(codec); 18261 alc_mic_automute(codec); 18262} 18263/* ***************** Mode4 ******************************/ 18264static void alc663_mode4_unsol_event(struct hda_codec *codec, 18265 unsigned int res) 18266{ 18267 switch (res >> 26) { 18268 case ALC880_HP_EVENT: 18269 alc663_21jd_two_speaker_automute(codec); 18270 break; 18271 case ALC880_MIC_EVENT: 18272 alc_mic_automute(codec); 18273 break; 18274 } 18275} 18276 18277#define alc663_mode4_setup alc663_mode1_setup 18278 18279static void alc663_mode4_inithook(struct hda_codec *codec) 18280{ 18281 alc663_21jd_two_speaker_automute(codec); 18282 alc_mic_automute(codec); 18283} 18284/* ***************** Mode5 ******************************/ 18285static void alc663_mode5_unsol_event(struct hda_codec *codec, 18286 unsigned int res) 18287{ 18288 switch (res >> 26) { 18289 case ALC880_HP_EVENT: 18290 alc663_15jd_two_speaker_automute(codec); 18291 break; 18292 case ALC880_MIC_EVENT: 18293 alc_mic_automute(codec); 18294 break; 18295 } 18296} 18297 18298#define alc663_mode5_setup alc663_mode1_setup 18299 18300static void alc663_mode5_inithook(struct hda_codec *codec) 18301{ 18302 alc663_15jd_two_speaker_automute(codec); 18303 alc_mic_automute(codec); 18304} 18305/* ***************** Mode6 ******************************/ 18306static void alc663_mode6_unsol_event(struct hda_codec *codec, 18307 unsigned int res) 18308{ 18309 switch (res >> 26) { 18310 case ALC880_HP_EVENT: 18311 alc663_two_hp_m2_speaker_automute(codec); 18312 break; 18313 case ALC880_MIC_EVENT: 18314 alc_mic_automute(codec); 18315 break; 18316 } 18317} 18318 18319#define alc663_mode6_setup alc663_mode1_setup 18320 18321static void alc663_mode6_inithook(struct hda_codec *codec) 18322{ 18323 alc663_two_hp_m2_speaker_automute(codec); 18324 alc_mic_automute(codec); 18325} 18326 18327/* ***************** Mode7 ******************************/ 18328static void alc663_mode7_unsol_event(struct hda_codec *codec, 18329 unsigned int res) 18330{ 18331 switch (res >> 26) { 18332 case ALC880_HP_EVENT: 18333 alc663_two_hp_m7_speaker_automute(codec); 18334 break; 18335 case ALC880_MIC_EVENT: 18336 alc_mic_automute(codec); 18337 break; 18338 } 18339} 18340 18341#define alc663_mode7_setup alc663_mode1_setup 18342 18343static void alc663_mode7_inithook(struct hda_codec *codec) 18344{ 18345 alc663_two_hp_m7_speaker_automute(codec); 18346 alc_mic_automute(codec); 18347} 18348 18349/* ***************** Mode8 ******************************/ 18350static void alc663_mode8_unsol_event(struct hda_codec *codec, 18351 unsigned int res) 18352{ 18353 switch (res >> 26) { 18354 case ALC880_HP_EVENT: 18355 alc663_two_hp_m8_speaker_automute(codec); 18356 break; 18357 case ALC880_MIC_EVENT: 18358 alc_mic_automute(codec); 18359 break; 18360 } 18361} 18362 18363#define alc663_mode8_setup alc663_m51va_setup 18364 18365static void alc663_mode8_inithook(struct hda_codec *codec) 18366{ 18367 alc663_two_hp_m8_speaker_automute(codec); 18368 alc_mic_automute(codec); 18369} 18370 18371static void alc663_g71v_hp_automute(struct hda_codec *codec) 18372{ 18373 unsigned int present; 18374 unsigned char bits; 18375 18376 present = snd_hda_jack_detect(codec, 0x21); 18377 bits = present ? HDA_AMP_MUTE : 0; 18378 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 18379 HDA_AMP_MUTE, bits); 18380 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 18381 HDA_AMP_MUTE, bits); 18382} 18383 18384static void alc663_g71v_front_automute(struct hda_codec *codec) 18385{ 18386 unsigned int present; 18387 unsigned char bits; 18388 18389 present = snd_hda_jack_detect(codec, 0x15); 18390 bits = present ? HDA_AMP_MUTE : 0; 18391 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 18392 HDA_AMP_MUTE, bits); 18393} 18394 18395static void alc663_g71v_unsol_event(struct hda_codec *codec, 18396 unsigned int res) 18397{ 18398 switch (res >> 26) { 18399 case ALC880_HP_EVENT: 18400 alc663_g71v_hp_automute(codec); 18401 break; 18402 case ALC880_FRONT_EVENT: 18403 alc663_g71v_front_automute(codec); 18404 break; 18405 case ALC880_MIC_EVENT: 18406 alc_mic_automute(codec); 18407 break; 18408 } 18409} 18410 18411#define alc663_g71v_setup alc663_m51va_setup 18412 18413static void alc663_g71v_inithook(struct hda_codec *codec) 18414{ 18415 alc663_g71v_front_automute(codec); 18416 alc663_g71v_hp_automute(codec); 18417 alc_mic_automute(codec); 18418} 18419 18420static void alc663_g50v_unsol_event(struct hda_codec *codec, 18421 unsigned int res) 18422{ 18423 switch (res >> 26) { 18424 case ALC880_HP_EVENT: 18425 alc663_m51va_speaker_automute(codec); 18426 break; 18427 case ALC880_MIC_EVENT: 18428 alc_mic_automute(codec); 18429 break; 18430 } 18431} 18432 18433#define alc663_g50v_setup alc663_m51va_setup 18434 18435static void alc663_g50v_inithook(struct hda_codec *codec) 18436{ 18437 alc663_m51va_speaker_automute(codec); 18438 alc_mic_automute(codec); 18439} 18440 18441static struct snd_kcontrol_new alc662_ecs_mixer[] = { 18442 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT), 18443 ALC262_HIPPO_MASTER_SWITCH, 18444 18445 HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT), 18446 HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT), 18447 HDA_CODEC_MUTE("e-Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT), 18448 18449 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT), 18450 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 18451 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 18452 { } /* end */ 18453}; 18454 18455static struct snd_kcontrol_new alc272_nc10_mixer[] = { 18456 /* Master Playback automatically created from Speaker and Headphone */ 18457 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 18458 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 18459 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 18460 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT), 18461 18462 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 18463 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 18464 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT), 18465 18466 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 18467 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 18468 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 18469 { } /* end */ 18470}; 18471 18472#ifdef CONFIG_SND_HDA_POWER_SAVE 18473#define alc662_loopbacks alc880_loopbacks 18474#endif 18475 18476 18477/* pcm configuration: identical with ALC880 */ 18478#define alc662_pcm_analog_playback alc880_pcm_analog_playback 18479#define alc662_pcm_analog_capture alc880_pcm_analog_capture 18480#define alc662_pcm_digital_playback alc880_pcm_digital_playback 18481#define alc662_pcm_digital_capture alc880_pcm_digital_capture 18482 18483/* 18484 * configuration and preset 18485 */ 18486static const char *alc662_models[ALC662_MODEL_LAST] = { 18487 [ALC662_3ST_2ch_DIG] = "3stack-dig", 18488 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig", 18489 [ALC662_3ST_6ch] = "3stack-6ch", 18490 [ALC662_5ST_DIG] = "6stack-dig", 18491 [ALC662_LENOVO_101E] = "lenovo-101e", 18492 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701", 18493 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20", 18494 [ALC662_ECS] = "ecs", 18495 [ALC663_ASUS_M51VA] = "m51va", 18496 [ALC663_ASUS_G71V] = "g71v", 18497 [ALC663_ASUS_H13] = "h13", 18498 [ALC663_ASUS_G50V] = "g50v", 18499 [ALC663_ASUS_MODE1] = "asus-mode1", 18500 [ALC662_ASUS_MODE2] = "asus-mode2", 18501 [ALC663_ASUS_MODE3] = "asus-mode3", 18502 [ALC663_ASUS_MODE4] = "asus-mode4", 18503 [ALC663_ASUS_MODE5] = "asus-mode5", 18504 [ALC663_ASUS_MODE6] = "asus-mode6", 18505 [ALC663_ASUS_MODE7] = "asus-mode7", 18506 [ALC663_ASUS_MODE8] = "asus-mode8", 18507 [ALC272_DELL] = "dell", 18508 [ALC272_DELL_ZM1] = "dell-zm1", 18509 [ALC272_SAMSUNG_NC10] = "samsung-nc10", 18510 [ALC662_AUTO] = "auto", 18511}; 18512 18513static struct snd_pci_quirk alc662_cfg_tbl[] = { 18514 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS), 18515 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL), 18516 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1), 18517 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1), 18518 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3), 18519 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC663_ASUS_MODE1), 18520 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3), 18521 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1), 18522 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2), 18523 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1), 18524 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC663_ASUS_MODE1), 18525 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC663_ASUS_MODE1), 18526 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2), 18527 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC663_ASUS_MODE7), 18528 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC663_ASUS_MODE7), 18529 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC663_ASUS_MODE8), 18530 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC663_ASUS_MODE3), 18531 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC663_ASUS_MODE1), 18532 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2), 18533 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_ASUS_MODE2), 18534 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC663_ASUS_MODE1), 18535 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2), 18536 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6), 18537 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6), 18538 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2), 18539 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC663_ASUS_MODE1), 18540 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3), 18541 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA), 18542 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2), 18543 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2), 18544 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5), 18545 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6), 18546 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2), 18547 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1), 18548 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2), 18549 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2), 18550 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA), 18551 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/ 18552 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3), 18553 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3), 18554 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1), 18555 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC663_ASUS_MODE1), 18556 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1), 18557 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1), 18558 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1), 18559 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2), 18560 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2), 18561 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1), 18562 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1), 18563 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3), 18564 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1), 18565 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1), 18566 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V), 18567 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/ 18568 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1), 18569 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2), 18570 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA), 18571 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1), 18572 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4), 18573 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG), 18574 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701), 18575 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20), 18576 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS), 18577 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K", 18578 ALC662_3ST_6ch_DIG), 18579 SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO), 18580 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10), 18581 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L", 18582 ALC662_3ST_6ch_DIG), 18583 SND_PCI_QUIRK(0x152d, 0x2304, "Quanta WH1", ALC663_ASUS_H13), 18584 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG), 18585 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA), 18586 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E), 18587 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0", 18588 ALC662_3ST_6ch_DIG), 18589 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x", 18590 ALC663_ASUS_H13), 18591 {} 18592}; 18593 18594static struct alc_config_preset alc662_presets[] = { 18595 [ALC662_3ST_2ch_DIG] = { 18596 .mixers = { alc662_3ST_2ch_mixer }, 18597 .init_verbs = { alc662_init_verbs }, 18598 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18599 .dac_nids = alc662_dac_nids, 18600 .dig_out_nid = ALC662_DIGOUT_NID, 18601 .dig_in_nid = ALC662_DIGIN_NID, 18602 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18603 .channel_mode = alc662_3ST_2ch_modes, 18604 .input_mux = &alc662_capture_source, 18605 }, 18606 [ALC662_3ST_6ch_DIG] = { 18607 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer }, 18608 .init_verbs = { alc662_init_verbs }, 18609 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18610 .dac_nids = alc662_dac_nids, 18611 .dig_out_nid = ALC662_DIGOUT_NID, 18612 .dig_in_nid = ALC662_DIGIN_NID, 18613 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), 18614 .channel_mode = alc662_3ST_6ch_modes, 18615 .need_dac_fix = 1, 18616 .input_mux = &alc662_capture_source, 18617 }, 18618 [ALC662_3ST_6ch] = { 18619 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer }, 18620 .init_verbs = { alc662_init_verbs }, 18621 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18622 .dac_nids = alc662_dac_nids, 18623 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), 18624 .channel_mode = alc662_3ST_6ch_modes, 18625 .need_dac_fix = 1, 18626 .input_mux = &alc662_capture_source, 18627 }, 18628 [ALC662_5ST_DIG] = { 18629 .mixers = { alc662_base_mixer, alc662_chmode_mixer }, 18630 .init_verbs = { alc662_init_verbs }, 18631 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18632 .dac_nids = alc662_dac_nids, 18633 .dig_out_nid = ALC662_DIGOUT_NID, 18634 .dig_in_nid = ALC662_DIGIN_NID, 18635 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes), 18636 .channel_mode = alc662_5stack_modes, 18637 .input_mux = &alc662_capture_source, 18638 }, 18639 [ALC662_LENOVO_101E] = { 18640 .mixers = { alc662_lenovo_101e_mixer }, 18641 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs }, 18642 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18643 .dac_nids = alc662_dac_nids, 18644 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18645 .channel_mode = alc662_3ST_2ch_modes, 18646 .input_mux = &alc662_lenovo_101e_capture_source, 18647 .unsol_event = alc662_lenovo_101e_unsol_event, 18648 .init_hook = alc662_lenovo_101e_all_automute, 18649 }, 18650 [ALC662_ASUS_EEEPC_P701] = { 18651 .mixers = { alc662_eeepc_p701_mixer }, 18652 .init_verbs = { alc662_init_verbs, 18653 alc662_eeepc_sue_init_verbs }, 18654 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18655 .dac_nids = alc662_dac_nids, 18656 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18657 .channel_mode = alc662_3ST_2ch_modes, 18658 .unsol_event = alc662_eeepc_unsol_event, 18659 .setup = alc662_eeepc_setup, 18660 .init_hook = alc662_eeepc_inithook, 18661 }, 18662 [ALC662_ASUS_EEEPC_EP20] = { 18663 .mixers = { alc662_eeepc_ep20_mixer, 18664 alc662_chmode_mixer }, 18665 .init_verbs = { alc662_init_verbs, 18666 alc662_eeepc_ep20_sue_init_verbs }, 18667 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18668 .dac_nids = alc662_dac_nids, 18669 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), 18670 .channel_mode = alc662_3ST_6ch_modes, 18671 .input_mux = &alc662_lenovo_101e_capture_source, 18672 .unsol_event = alc662_eeepc_unsol_event, 18673 .setup = alc662_eeepc_ep20_setup, 18674 .init_hook = alc662_eeepc_ep20_inithook, 18675 }, 18676 [ALC662_ECS] = { 18677 .mixers = { alc662_ecs_mixer }, 18678 .init_verbs = { alc662_init_verbs, 18679 alc662_ecs_init_verbs }, 18680 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18681 .dac_nids = alc662_dac_nids, 18682 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18683 .channel_mode = alc662_3ST_2ch_modes, 18684 .unsol_event = alc662_eeepc_unsol_event, 18685 .setup = alc662_eeepc_setup, 18686 .init_hook = alc662_eeepc_inithook, 18687 }, 18688 [ALC663_ASUS_M51VA] = { 18689 .mixers = { alc663_m51va_mixer }, 18690 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs }, 18691 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18692 .dac_nids = alc662_dac_nids, 18693 .dig_out_nid = ALC662_DIGOUT_NID, 18694 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18695 .channel_mode = alc662_3ST_2ch_modes, 18696 .unsol_event = alc663_m51va_unsol_event, 18697 .setup = alc663_m51va_setup, 18698 .init_hook = alc663_m51va_inithook, 18699 }, 18700 [ALC663_ASUS_G71V] = { 18701 .mixers = { alc663_g71v_mixer }, 18702 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs }, 18703 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18704 .dac_nids = alc662_dac_nids, 18705 .dig_out_nid = ALC662_DIGOUT_NID, 18706 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18707 .channel_mode = alc662_3ST_2ch_modes, 18708 .unsol_event = alc663_g71v_unsol_event, 18709 .setup = alc663_g71v_setup, 18710 .init_hook = alc663_g71v_inithook, 18711 }, 18712 [ALC663_ASUS_H13] = { 18713 .mixers = { alc663_m51va_mixer }, 18714 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs }, 18715 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18716 .dac_nids = alc662_dac_nids, 18717 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18718 .channel_mode = alc662_3ST_2ch_modes, 18719 .unsol_event = alc663_m51va_unsol_event, 18720 .init_hook = alc663_m51va_inithook, 18721 }, 18722 [ALC663_ASUS_G50V] = { 18723 .mixers = { alc663_g50v_mixer }, 18724 .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs }, 18725 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18726 .dac_nids = alc662_dac_nids, 18727 .dig_out_nid = ALC662_DIGOUT_NID, 18728 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), 18729 .channel_mode = alc662_3ST_6ch_modes, 18730 .input_mux = &alc663_capture_source, 18731 .unsol_event = alc663_g50v_unsol_event, 18732 .setup = alc663_g50v_setup, 18733 .init_hook = alc663_g50v_inithook, 18734 }, 18735 [ALC663_ASUS_MODE1] = { 18736 .mixers = { alc663_m51va_mixer }, 18737 .cap_mixer = alc662_auto_capture_mixer, 18738 .init_verbs = { alc662_init_verbs, 18739 alc663_21jd_amic_init_verbs }, 18740 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18741 .hp_nid = 0x03, 18742 .dac_nids = alc662_dac_nids, 18743 .dig_out_nid = ALC662_DIGOUT_NID, 18744 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18745 .channel_mode = alc662_3ST_2ch_modes, 18746 .unsol_event = alc663_mode1_unsol_event, 18747 .setup = alc663_mode1_setup, 18748 .init_hook = alc663_mode1_inithook, 18749 }, 18750 [ALC662_ASUS_MODE2] = { 18751 .mixers = { alc662_1bjd_mixer }, 18752 .cap_mixer = alc662_auto_capture_mixer, 18753 .init_verbs = { alc662_init_verbs, 18754 alc662_1bjd_amic_init_verbs }, 18755 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18756 .dac_nids = alc662_dac_nids, 18757 .dig_out_nid = ALC662_DIGOUT_NID, 18758 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18759 .channel_mode = alc662_3ST_2ch_modes, 18760 .unsol_event = alc662_mode2_unsol_event, 18761 .setup = alc662_mode2_setup, 18762 .init_hook = alc662_mode2_inithook, 18763 }, 18764 [ALC663_ASUS_MODE3] = { 18765 .mixers = { alc663_two_hp_m1_mixer }, 18766 .cap_mixer = alc662_auto_capture_mixer, 18767 .init_verbs = { alc662_init_verbs, 18768 alc663_two_hp_amic_m1_init_verbs }, 18769 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18770 .hp_nid = 0x03, 18771 .dac_nids = alc662_dac_nids, 18772 .dig_out_nid = ALC662_DIGOUT_NID, 18773 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18774 .channel_mode = alc662_3ST_2ch_modes, 18775 .unsol_event = alc663_mode3_unsol_event, 18776 .setup = alc663_mode3_setup, 18777 .init_hook = alc663_mode3_inithook, 18778 }, 18779 [ALC663_ASUS_MODE4] = { 18780 .mixers = { alc663_asus_21jd_clfe_mixer }, 18781 .cap_mixer = alc662_auto_capture_mixer, 18782 .init_verbs = { alc662_init_verbs, 18783 alc663_21jd_amic_init_verbs}, 18784 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18785 .hp_nid = 0x03, 18786 .dac_nids = alc662_dac_nids, 18787 .dig_out_nid = ALC662_DIGOUT_NID, 18788 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18789 .channel_mode = alc662_3ST_2ch_modes, 18790 .unsol_event = alc663_mode4_unsol_event, 18791 .setup = alc663_mode4_setup, 18792 .init_hook = alc663_mode4_inithook, 18793 }, 18794 [ALC663_ASUS_MODE5] = { 18795 .mixers = { alc663_asus_15jd_clfe_mixer }, 18796 .cap_mixer = alc662_auto_capture_mixer, 18797 .init_verbs = { alc662_init_verbs, 18798 alc663_15jd_amic_init_verbs }, 18799 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18800 .hp_nid = 0x03, 18801 .dac_nids = alc662_dac_nids, 18802 .dig_out_nid = ALC662_DIGOUT_NID, 18803 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18804 .channel_mode = alc662_3ST_2ch_modes, 18805 .unsol_event = alc663_mode5_unsol_event, 18806 .setup = alc663_mode5_setup, 18807 .init_hook = alc663_mode5_inithook, 18808 }, 18809 [ALC663_ASUS_MODE6] = { 18810 .mixers = { alc663_two_hp_m2_mixer }, 18811 .cap_mixer = alc662_auto_capture_mixer, 18812 .init_verbs = { alc662_init_verbs, 18813 alc663_two_hp_amic_m2_init_verbs }, 18814 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18815 .hp_nid = 0x03, 18816 .dac_nids = alc662_dac_nids, 18817 .dig_out_nid = ALC662_DIGOUT_NID, 18818 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18819 .channel_mode = alc662_3ST_2ch_modes, 18820 .unsol_event = alc663_mode6_unsol_event, 18821 .setup = alc663_mode6_setup, 18822 .init_hook = alc663_mode6_inithook, 18823 }, 18824 [ALC663_ASUS_MODE7] = { 18825 .mixers = { alc663_mode7_mixer }, 18826 .cap_mixer = alc662_auto_capture_mixer, 18827 .init_verbs = { alc662_init_verbs, 18828 alc663_mode7_init_verbs }, 18829 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18830 .hp_nid = 0x03, 18831 .dac_nids = alc662_dac_nids, 18832 .dig_out_nid = ALC662_DIGOUT_NID, 18833 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18834 .channel_mode = alc662_3ST_2ch_modes, 18835 .unsol_event = alc663_mode7_unsol_event, 18836 .setup = alc663_mode7_setup, 18837 .init_hook = alc663_mode7_inithook, 18838 }, 18839 [ALC663_ASUS_MODE8] = { 18840 .mixers = { alc663_mode8_mixer }, 18841 .cap_mixer = alc662_auto_capture_mixer, 18842 .init_verbs = { alc662_init_verbs, 18843 alc663_mode8_init_verbs }, 18844 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18845 .hp_nid = 0x03, 18846 .dac_nids = alc662_dac_nids, 18847 .dig_out_nid = ALC662_DIGOUT_NID, 18848 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18849 .channel_mode = alc662_3ST_2ch_modes, 18850 .unsol_event = alc663_mode8_unsol_event, 18851 .setup = alc663_mode8_setup, 18852 .init_hook = alc663_mode8_inithook, 18853 }, 18854 [ALC272_DELL] = { 18855 .mixers = { alc663_m51va_mixer }, 18856 .cap_mixer = alc272_auto_capture_mixer, 18857 .init_verbs = { alc662_init_verbs, alc272_dell_init_verbs }, 18858 .num_dacs = ARRAY_SIZE(alc272_dac_nids), 18859 .dac_nids = alc662_dac_nids, 18860 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18861 .adc_nids = alc272_adc_nids, 18862 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids), 18863 .capsrc_nids = alc272_capsrc_nids, 18864 .channel_mode = alc662_3ST_2ch_modes, 18865 .unsol_event = alc663_m51va_unsol_event, 18866 .setup = alc663_m51va_setup, 18867 .init_hook = alc663_m51va_inithook, 18868 }, 18869 [ALC272_DELL_ZM1] = { 18870 .mixers = { alc663_m51va_mixer }, 18871 .cap_mixer = alc662_auto_capture_mixer, 18872 .init_verbs = { alc662_init_verbs, alc272_dell_zm1_init_verbs }, 18873 .num_dacs = ARRAY_SIZE(alc272_dac_nids), 18874 .dac_nids = alc662_dac_nids, 18875 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18876 .adc_nids = alc662_adc_nids, 18877 .num_adc_nids = 1, 18878 .capsrc_nids = alc662_capsrc_nids, 18879 .channel_mode = alc662_3ST_2ch_modes, 18880 .unsol_event = alc663_m51va_unsol_event, 18881 .setup = alc663_m51va_setup, 18882 .init_hook = alc663_m51va_inithook, 18883 }, 18884 [ALC272_SAMSUNG_NC10] = { 18885 .mixers = { alc272_nc10_mixer }, 18886 .init_verbs = { alc662_init_verbs, 18887 alc663_21jd_amic_init_verbs }, 18888 .num_dacs = ARRAY_SIZE(alc272_dac_nids), 18889 .dac_nids = alc272_dac_nids, 18890 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18891 .channel_mode = alc662_3ST_2ch_modes, 18892 /*.input_mux = &alc272_nc10_capture_source,*/ 18893 .unsol_event = alc663_mode4_unsol_event, 18894 .setup = alc663_mode4_setup, 18895 .init_hook = alc663_mode4_inithook, 18896 }, 18897}; 18898 18899 18900/* 18901 * BIOS auto configuration 18902 */ 18903 18904/* convert from MIX nid to DAC */ 18905static inline hda_nid_t alc662_mix_to_dac(hda_nid_t nid) 18906{ 18907 if (nid == 0x0f) 18908 return 0x02; 18909 else if (nid >= 0x0c && nid <= 0x0e) 18910 return nid - 0x0c + 0x02; 18911 else 18912 return 0; 18913} 18914 18915/* get MIX nid connected to the given pin targeted to DAC */ 18916static hda_nid_t alc662_dac_to_mix(struct hda_codec *codec, hda_nid_t pin, 18917 hda_nid_t dac) 18918{ 18919 hda_nid_t mix[4]; 18920 int i, num; 18921 18922 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix)); 18923 for (i = 0; i < num; i++) { 18924 if (alc662_mix_to_dac(mix[i]) == dac) 18925 return mix[i]; 18926 } 18927 return 0; 18928} 18929 18930/* look for an empty DAC slot */ 18931static hda_nid_t alc662_look_for_dac(struct hda_codec *codec, hda_nid_t pin) 18932{ 18933 struct alc_spec *spec = codec->spec; 18934 hda_nid_t srcs[5]; 18935 int i, j, num; 18936 18937 num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs)); 18938 if (num < 0) 18939 return 0; 18940 for (i = 0; i < num; i++) { 18941 hda_nid_t nid = alc662_mix_to_dac(srcs[i]); 18942 if (!nid) 18943 continue; 18944 for (j = 0; j < spec->multiout.num_dacs; j++) 18945 if (spec->multiout.dac_nids[j] == nid) 18946 break; 18947 if (j >= spec->multiout.num_dacs) 18948 return nid; 18949 } 18950 return 0; 18951} 18952 18953/* fill in the dac_nids table from the parsed pin configuration */ 18954static int alc662_auto_fill_dac_nids(struct hda_codec *codec, 18955 const struct auto_pin_cfg *cfg) 18956{ 18957 struct alc_spec *spec = codec->spec; 18958 int i; 18959 hda_nid_t dac; 18960 18961 spec->multiout.dac_nids = spec->private_dac_nids; 18962 for (i = 0; i < cfg->line_outs; i++) { 18963 dac = alc662_look_for_dac(codec, cfg->line_out_pins[i]); 18964 if (!dac) 18965 continue; 18966 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac; 18967 } 18968 return 0; 18969} 18970 18971static inline int alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx, 18972 hda_nid_t nid, unsigned int chs) 18973{ 18974 return add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, 18975 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT)); 18976} 18977 18978static inline int alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx, 18979 hda_nid_t nid, unsigned int chs) 18980{ 18981 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, 18982 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT)); 18983} 18984 18985#define alc662_add_stereo_vol(spec, pfx, nid) \ 18986 alc662_add_vol_ctl(spec, pfx, nid, 3) 18987#define alc662_add_stereo_sw(spec, pfx, nid) \ 18988 alc662_add_sw_ctl(spec, pfx, nid, 3) 18989 18990/* add playback controls from the parsed DAC table */ 18991static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec, 18992 const struct auto_pin_cfg *cfg) 18993{ 18994 struct alc_spec *spec = codec->spec; 18995 static const char *chname[4] = { 18996 "Front", "Surround", NULL /*CLFE*/, "Side" 18997 }; 18998 hda_nid_t nid, mix; 18999 int i, err; 19000 19001 for (i = 0; i < cfg->line_outs; i++) { 19002 nid = spec->multiout.dac_nids[i]; 19003 if (!nid) 19004 continue; 19005 mix = alc662_dac_to_mix(codec, cfg->line_out_pins[i], nid); 19006 if (!mix) 19007 continue; 19008 if (i == 2) { 19009 /* Center/LFE */ 19010 err = alc662_add_vol_ctl(spec, "Center", nid, 1); 19011 if (err < 0) 19012 return err; 19013 err = alc662_add_vol_ctl(spec, "LFE", nid, 2); 19014 if (err < 0) 19015 return err; 19016 err = alc662_add_sw_ctl(spec, "Center", mix, 1); 19017 if (err < 0) 19018 return err; 19019 err = alc662_add_sw_ctl(spec, "LFE", mix, 2); 19020 if (err < 0) 19021 return err; 19022 } else { 19023 const char *pfx; 19024 if (cfg->line_outs == 1 && 19025 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) { 19026 if (cfg->hp_outs) 19027 pfx = "Speaker"; 19028 else 19029 pfx = "PCM"; 19030 } else 19031 pfx = chname[i]; 19032 err = alc662_add_vol_ctl(spec, pfx, nid, 3); 19033 if (err < 0) 19034 return err; 19035 if (cfg->line_outs == 1 && 19036 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) 19037 pfx = "Speaker"; 19038 err = alc662_add_sw_ctl(spec, pfx, mix, 3); 19039 if (err < 0) 19040 return err; 19041 } 19042 } 19043 return 0; 19044} 19045 19046/* add playback controls for speaker and HP outputs */ 19047/* return DAC nid if any new DAC is assigned */ 19048static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin, 19049 const char *pfx) 19050{ 19051 struct alc_spec *spec = codec->spec; 19052 hda_nid_t nid, mix; 19053 int err; 19054 19055 if (!pin) 19056 return 0; 19057 nid = alc662_look_for_dac(codec, pin); 19058 if (!nid) { 19059 /* the corresponding DAC is already occupied */ 19060 if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP)) 19061 return 0; /* no way */ 19062 /* create a switch only */ 19063 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, 19064 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); 19065 } 19066 19067 mix = alc662_dac_to_mix(codec, pin, nid); 19068 if (!mix) 19069 return 0; 19070 err = alc662_add_vol_ctl(spec, pfx, nid, 3); 19071 if (err < 0) 19072 return err; 19073 err = alc662_add_sw_ctl(spec, pfx, mix, 3); 19074 if (err < 0) 19075 return err; 19076 return nid; 19077} 19078 19079/* create playback/capture controls for input pins */ 19080#define alc662_auto_create_input_ctls \ 19081 alc882_auto_create_input_ctls 19082 19083static void alc662_auto_set_output_and_unmute(struct hda_codec *codec, 19084 hda_nid_t nid, int pin_type, 19085 hda_nid_t dac) 19086{ 19087 int i, num; 19088 hda_nid_t srcs[HDA_MAX_CONNECTIONS]; 19089 19090 alc_set_pin_output(codec, nid, pin_type); 19091 /* need the manual connection? */ 19092 num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs)); 19093 if (num <= 1) 19094 return; 19095 for (i = 0; i < num; i++) { 19096 if (alc662_mix_to_dac(srcs[i]) != dac) 19097 continue; 19098 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, i); 19099 return; 19100 } 19101} 19102 19103static void alc662_auto_init_multi_out(struct hda_codec *codec) 19104{ 19105 struct alc_spec *spec = codec->spec; 19106 int pin_type = get_pin_type(spec->autocfg.line_out_type); 19107 int i; 19108 19109 for (i = 0; i <= HDA_SIDE; i++) { 19110 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 19111 if (nid) 19112 alc662_auto_set_output_and_unmute(codec, nid, pin_type, 19113 spec->multiout.dac_nids[i]); 19114 } 19115} 19116 19117static void alc662_auto_init_hp_out(struct hda_codec *codec) 19118{ 19119 struct alc_spec *spec = codec->spec; 19120 hda_nid_t pin; 19121 19122 pin = spec->autocfg.hp_pins[0]; 19123 if (pin) 19124 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 19125 spec->multiout.hp_nid); 19126 pin = spec->autocfg.speaker_pins[0]; 19127 if (pin) 19128 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT, 19129 spec->multiout.extra_out_nid[0]); 19130} 19131 19132#define ALC662_PIN_CD_NID ALC880_PIN_CD_NID 19133 19134static void alc662_auto_init_analog_input(struct hda_codec *codec) 19135{ 19136 struct alc_spec *spec = codec->spec; 19137 struct auto_pin_cfg *cfg = &spec->autocfg; 19138 int i; 19139 19140 for (i = 0; i < cfg->num_inputs; i++) { 19141 hda_nid_t nid = cfg->inputs[i].pin; 19142 if (alc_is_input_pin(codec, nid)) { 19143 alc_set_input_pin(codec, nid, cfg->inputs[i].type); 19144 if (nid != ALC662_PIN_CD_NID && 19145 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)) 19146 snd_hda_codec_write(codec, nid, 0, 19147 AC_VERB_SET_AMP_GAIN_MUTE, 19148 AMP_OUT_MUTE); 19149 } 19150 } 19151} 19152 19153#define alc662_auto_init_input_src alc882_auto_init_input_src 19154 19155static int alc662_parse_auto_config(struct hda_codec *codec) 19156{ 19157 struct alc_spec *spec = codec->spec; 19158 int err; 19159 static hda_nid_t alc662_ignore[] = { 0x1d, 0 }; 19160 19161 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 19162 alc662_ignore); 19163 if (err < 0) 19164 return err; 19165 if (!spec->autocfg.line_outs) 19166 return 0; /* can't find valid BIOS pin config */ 19167 19168 err = alc662_auto_fill_dac_nids(codec, &spec->autocfg); 19169 if (err < 0) 19170 return err; 19171 err = alc662_auto_create_multi_out_ctls(codec, &spec->autocfg); 19172 if (err < 0) 19173 return err; 19174 err = alc662_auto_create_extra_out(codec, 19175 spec->autocfg.speaker_pins[0], 19176 "Speaker"); 19177 if (err < 0) 19178 return err; 19179 if (err) 19180 spec->multiout.extra_out_nid[0] = err; 19181 err = alc662_auto_create_extra_out(codec, spec->autocfg.hp_pins[0], 19182 "Headphone"); 19183 if (err < 0) 19184 return err; 19185 if (err) 19186 spec->multiout.hp_nid = err; 19187 err = alc662_auto_create_input_ctls(codec, &spec->autocfg); 19188 if (err < 0) 19189 return err; 19190 19191 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 19192 19193 alc_auto_parse_digital(codec); 19194 19195 if (spec->kctls.list) 19196 add_mixer(spec, spec->kctls.list); 19197 19198 spec->num_mux_defs = 1; 19199 spec->input_mux = &spec->private_imux[0]; 19200 19201 add_verb(spec, alc662_init_verbs); 19202 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 || 19203 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670) 19204 add_verb(spec, alc663_init_verbs); 19205 19206 if (codec->vendor_id == 0x10ec0272) 19207 add_verb(spec, alc272_init_verbs); 19208 19209 err = alc_auto_add_mic_boost(codec); 19210 if (err < 0) 19211 return err; 19212 19213 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 || 19214 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670) 19215 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0x21); 19216 else 19217 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); 19218 19219 return 1; 19220} 19221 19222/* additional initialization for auto-configuration model */ 19223static void alc662_auto_init(struct hda_codec *codec) 19224{ 19225 struct alc_spec *spec = codec->spec; 19226 alc662_auto_init_multi_out(codec); 19227 alc662_auto_init_hp_out(codec); 19228 alc662_auto_init_analog_input(codec); 19229 alc662_auto_init_input_src(codec); 19230 alc_auto_init_digital(codec); 19231 if (spec->unsol_event) 19232 alc_inithook(codec); 19233} 19234 19235enum { 19236 ALC662_FIXUP_ASPIRE, 19237 ALC662_FIXUP_IDEAPAD, 19238}; 19239 19240static const struct alc_fixup alc662_fixups[] = { 19241 [ALC662_FIXUP_ASPIRE] = { 19242 .pins = (const struct alc_pincfg[]) { 19243 { 0x15, 0x99130112 }, /* subwoofer */ 19244 { } 19245 } 19246 }, 19247 [ALC662_FIXUP_IDEAPAD] = { 19248 .pins = (const struct alc_pincfg[]) { 19249 { 0x17, 0x99130112 }, /* subwoofer */ 19250 { } 19251 } 19252 }, 19253}; 19254 19255static struct snd_pci_quirk alc662_fixup_tbl[] = { 19256 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE), 19257 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD), 19258 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD), 19259 {} 19260}; 19261 19262 19263 19264static int patch_alc662(struct hda_codec *codec) 19265{ 19266 struct alc_spec *spec; 19267 int err, board_config; 19268 19269 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 19270 if (!spec) 19271 return -ENOMEM; 19272 19273 codec->spec = spec; 19274 19275 alc_auto_parse_customize_define(codec); 19276 19277 alc_fix_pll_init(codec, 0x20, 0x04, 15); 19278 19279 if (alc_read_coef_idx(codec, 0) == 0x8020) 19280 alc_codec_rename(codec, "ALC661"); 19281 else if ((alc_read_coef_idx(codec, 0) & (1 << 14)) && 19282 codec->bus->pci->subsystem_vendor == 0x1025 && 19283 spec->cdefine.platform_type == 1) 19284 alc_codec_rename(codec, "ALC272X"); 19285 19286 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST, 19287 alc662_models, 19288 alc662_cfg_tbl); 19289 if (board_config < 0) { 19290 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 19291 codec->chip_name); 19292 board_config = ALC662_AUTO; 19293 } 19294 19295 if (board_config == ALC662_AUTO) { 19296 alc_pick_fixup(codec, alc662_fixup_tbl, alc662_fixups, 1); 19297 /* automatic parse from the BIOS config */ 19298 err = alc662_parse_auto_config(codec); 19299 if (err < 0) { 19300 alc_free(codec); 19301 return err; 19302 } else if (!err) { 19303 printk(KERN_INFO 19304 "hda_codec: Cannot set up configuration " 19305 "from BIOS. Using base mode...\n"); 19306 board_config = ALC662_3ST_2ch_DIG; 19307 } 19308 } 19309 19310 if (has_cdefine_beep(codec)) { 19311 err = snd_hda_attach_beep_device(codec, 0x1); 19312 if (err < 0) { 19313 alc_free(codec); 19314 return err; 19315 } 19316 } 19317 19318 if (board_config != ALC662_AUTO) 19319 setup_preset(codec, &alc662_presets[board_config]); 19320 19321 spec->stream_analog_playback = &alc662_pcm_analog_playback; 19322 spec->stream_analog_capture = &alc662_pcm_analog_capture; 19323 19324 spec->stream_digital_playback = &alc662_pcm_digital_playback; 19325 spec->stream_digital_capture = &alc662_pcm_digital_capture; 19326 19327 if (!spec->adc_nids) { 19328 spec->adc_nids = alc662_adc_nids; 19329 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids); 19330 } 19331 if (!spec->capsrc_nids) 19332 spec->capsrc_nids = alc662_capsrc_nids; 19333 19334 if (!spec->cap_mixer) 19335 set_capture_mixer(codec); 19336 19337 if (has_cdefine_beep(codec)) { 19338 switch (codec->vendor_id) { 19339 case 0x10ec0662: 19340 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 19341 break; 19342 case 0x10ec0272: 19343 case 0x10ec0663: 19344 case 0x10ec0665: 19345 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); 19346 break; 19347 case 0x10ec0273: 19348 set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT); 19349 break; 19350 } 19351 } 19352 spec->vmaster_nid = 0x02; 19353 19354 codec->patch_ops = alc_patch_ops; 19355 if (board_config == ALC662_AUTO) { 19356 spec->init_hook = alc662_auto_init; 19357 alc_pick_fixup(codec, alc662_fixup_tbl, alc662_fixups, 0); 19358 } 19359 19360#ifdef CONFIG_SND_HDA_POWER_SAVE 19361 if (!spec->loopback.amplist) 19362 spec->loopback.amplist = alc662_loopbacks; 19363#endif 19364 19365 return 0; 19366} 19367 19368static int patch_alc888(struct hda_codec *codec) 19369{ 19370 if ((alc_read_coef_idx(codec, 0) & 0x00f0)==0x0030){ 19371 kfree(codec->chip_name); 19372 codec->chip_name = kstrdup("ALC888-VD", GFP_KERNEL); 19373 if (!codec->chip_name) { 19374 alc_free(codec); 19375 return -ENOMEM; 19376 } 19377 return patch_alc662(codec); 19378 } 19379 return patch_alc882(codec); 19380} 19381 19382/* 19383 * ALC680 support 19384 */ 19385#define ALC680_DIGIN_NID ALC880_DIGIN_NID 19386#define ALC680_DIGOUT_NID ALC880_DIGOUT_NID 19387#define alc680_modes alc260_modes 19388 19389static hda_nid_t alc680_dac_nids[3] = { 19390 /* Lout1, Lout2, hp */ 19391 0x02, 0x03, 0x04 19392}; 19393 19394static hda_nid_t alc680_adc_nids[3] = { 19395 /* ADC0-2 */ 19396 /* DMIC, MIC, Line-in*/ 19397 0x07, 0x08, 0x09 19398}; 19399 19400/* 19401 * Analog capture ADC cgange 19402 */ 19403static void alc680_rec_autoswitch(struct hda_codec *codec) 19404{ 19405 struct alc_spec *spec = codec->spec; 19406 struct auto_pin_cfg *cfg = &spec->autocfg; 19407 int pin_found = 0; 19408 int type_found = AUTO_PIN_LAST; 19409 hda_nid_t nid; 19410 int i; 19411 19412 for (i = 0; i < cfg->num_inputs; i++) { 19413 nid = cfg->inputs[i].pin; 19414 if (!(snd_hda_query_pin_caps(codec, nid) & 19415 AC_PINCAP_PRES_DETECT)) 19416 continue; 19417 if (snd_hda_jack_detect(codec, nid)) { 19418 if (cfg->inputs[i].type < type_found) { 19419 type_found = cfg->inputs[i].type; 19420 pin_found = nid; 19421 } 19422 } 19423 } 19424 19425 nid = 0x07; 19426 if (pin_found) 19427 snd_hda_get_connections(codec, pin_found, &nid, 1); 19428 19429 if (nid != spec->cur_adc) 19430 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1); 19431 spec->cur_adc = nid; 19432 snd_hda_codec_setup_stream(codec, nid, spec->cur_adc_stream_tag, 0, 19433 spec->cur_adc_format); 19434} 19435 19436static int alc680_capture_pcm_prepare(struct hda_pcm_stream *hinfo, 19437 struct hda_codec *codec, 19438 unsigned int stream_tag, 19439 unsigned int format, 19440 struct snd_pcm_substream *substream) 19441{ 19442 struct alc_spec *spec = codec->spec; 19443 19444 spec->cur_adc = 0x07; 19445 spec->cur_adc_stream_tag = stream_tag; 19446 spec->cur_adc_format = format; 19447 19448 alc680_rec_autoswitch(codec); 19449 return 0; 19450} 19451 19452static int alc680_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, 19453 struct hda_codec *codec, 19454 struct snd_pcm_substream *substream) 19455{ 19456 snd_hda_codec_cleanup_stream(codec, 0x07); 19457 snd_hda_codec_cleanup_stream(codec, 0x08); 19458 snd_hda_codec_cleanup_stream(codec, 0x09); 19459 return 0; 19460} 19461 19462static struct hda_pcm_stream alc680_pcm_analog_auto_capture = { 19463 .substreams = 1, /* can be overridden */ 19464 .channels_min = 2, 19465 .channels_max = 2, 19466 /* NID is set in alc_build_pcms */ 19467 .ops = { 19468 .prepare = alc680_capture_pcm_prepare, 19469 .cleanup = alc680_capture_pcm_cleanup 19470 }, 19471}; 19472 19473static struct snd_kcontrol_new alc680_base_mixer[] = { 19474 /* output mixer control */ 19475 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), 19476 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 19477 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT), 19478 HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT), 19479 HDA_CODEC_VOLUME("Int Mic Boost", 0x12, 0, HDA_INPUT), 19480 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 19481 HDA_CODEC_VOLUME("Line In Boost", 0x19, 0, HDA_INPUT), 19482 { } 19483}; 19484 19485static struct hda_bind_ctls alc680_bind_cap_vol = { 19486 .ops = &snd_hda_bind_vol, 19487 .values = { 19488 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT), 19489 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT), 19490 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT), 19491 0 19492 }, 19493}; 19494 19495static struct hda_bind_ctls alc680_bind_cap_switch = { 19496 .ops = &snd_hda_bind_sw, 19497 .values = { 19498 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT), 19499 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT), 19500 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT), 19501 0 19502 }, 19503}; 19504 19505static struct snd_kcontrol_new alc680_master_capture_mixer[] = { 19506 HDA_BIND_VOL("Capture Volume", &alc680_bind_cap_vol), 19507 HDA_BIND_SW("Capture Switch", &alc680_bind_cap_switch), 19508 { } /* end */ 19509}; 19510 19511/* 19512 * generic initialization of ADC, input mixers and output mixers 19513 */ 19514static struct hda_verb alc680_init_verbs[] = { 19515 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 19516 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 19517 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 19518 19519 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 19520 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 19521 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 19522 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 19523 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 19524 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 19525 19526 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 19527 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 19528 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 19529 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 19530 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 19531 19532 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 19533 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, 19534 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, 19535 19536 { } 19537}; 19538 19539/* toggle speaker-output according to the hp-jack state */ 19540static void alc680_base_setup(struct hda_codec *codec) 19541{ 19542 struct alc_spec *spec = codec->spec; 19543 19544 spec->autocfg.hp_pins[0] = 0x16; 19545 spec->autocfg.speaker_pins[0] = 0x14; 19546 spec->autocfg.speaker_pins[1] = 0x15; 19547 spec->autocfg.num_inputs = 2; 19548 spec->autocfg.inputs[0].pin = 0x18; 19549 spec->autocfg.inputs[0].type = AUTO_PIN_MIC; 19550 spec->autocfg.inputs[1].pin = 0x19; 19551 spec->autocfg.inputs[1].type = AUTO_PIN_LINE_IN; 19552} 19553 19554static void alc680_unsol_event(struct hda_codec *codec, 19555 unsigned int res) 19556{ 19557 if ((res >> 26) == ALC880_HP_EVENT) 19558 alc_automute_amp(codec); 19559 if ((res >> 26) == ALC880_MIC_EVENT) 19560 alc680_rec_autoswitch(codec); 19561} 19562 19563static void alc680_inithook(struct hda_codec *codec) 19564{ 19565 alc_automute_amp(codec); 19566 alc680_rec_autoswitch(codec); 19567} 19568 19569/* create input playback/capture controls for the given pin */ 19570static int alc680_new_analog_output(struct alc_spec *spec, hda_nid_t nid, 19571 const char *ctlname, int idx) 19572{ 19573 hda_nid_t dac; 19574 int err; 19575 19576 switch (nid) { 19577 case 0x14: 19578 dac = 0x02; 19579 break; 19580 case 0x15: 19581 dac = 0x03; 19582 break; 19583 case 0x16: 19584 dac = 0x04; 19585 break; 19586 default: 19587 return 0; 19588 } 19589 if (spec->multiout.dac_nids[0] != dac && 19590 spec->multiout.dac_nids[1] != dac) { 19591 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname, 19592 HDA_COMPOSE_AMP_VAL(dac, 3, idx, 19593 HDA_OUTPUT)); 19594 if (err < 0) 19595 return err; 19596 19597 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname, 19598 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT)); 19599 19600 if (err < 0) 19601 return err; 19602 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac; 19603 } 19604 19605 return 0; 19606} 19607 19608/* add playback controls from the parsed DAC table */ 19609static int alc680_auto_create_multi_out_ctls(struct alc_spec *spec, 19610 const struct auto_pin_cfg *cfg) 19611{ 19612 hda_nid_t nid; 19613 int err; 19614 19615 spec->multiout.dac_nids = spec->private_dac_nids; 19616 19617 nid = cfg->line_out_pins[0]; 19618 if (nid) { 19619 const char *name; 19620 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) 19621 name = "Speaker"; 19622 else 19623 name = "Front"; 19624 err = alc680_new_analog_output(spec, nid, name, 0); 19625 if (err < 0) 19626 return err; 19627 } 19628 19629 nid = cfg->speaker_pins[0]; 19630 if (nid) { 19631 err = alc680_new_analog_output(spec, nid, "Speaker", 0); 19632 if (err < 0) 19633 return err; 19634 } 19635 nid = cfg->hp_pins[0]; 19636 if (nid) { 19637 err = alc680_new_analog_output(spec, nid, "Headphone", 0); 19638 if (err < 0) 19639 return err; 19640 } 19641 19642 return 0; 19643} 19644 19645static void alc680_auto_set_output_and_unmute(struct hda_codec *codec, 19646 hda_nid_t nid, int pin_type) 19647{ 19648 alc_set_pin_output(codec, nid, pin_type); 19649} 19650 19651static void alc680_auto_init_multi_out(struct hda_codec *codec) 19652{ 19653 struct alc_spec *spec = codec->spec; 19654 hda_nid_t nid = spec->autocfg.line_out_pins[0]; 19655 if (nid) { 19656 int pin_type = get_pin_type(spec->autocfg.line_out_type); 19657 alc680_auto_set_output_and_unmute(codec, nid, pin_type); 19658 } 19659} 19660 19661static void alc680_auto_init_hp_out(struct hda_codec *codec) 19662{ 19663 struct alc_spec *spec = codec->spec; 19664 hda_nid_t pin; 19665 19666 pin = spec->autocfg.hp_pins[0]; 19667 if (pin) 19668 alc680_auto_set_output_and_unmute(codec, pin, PIN_HP); 19669 pin = spec->autocfg.speaker_pins[0]; 19670 if (pin) 19671 alc680_auto_set_output_and_unmute(codec, pin, PIN_OUT); 19672} 19673 19674/* pcm configuration: identical with ALC880 */ 19675#define alc680_pcm_analog_playback alc880_pcm_analog_playback 19676#define alc680_pcm_analog_capture alc880_pcm_analog_capture 19677#define alc680_pcm_analog_alt_capture alc880_pcm_analog_alt_capture 19678#define alc680_pcm_digital_playback alc880_pcm_digital_playback 19679#define alc680_pcm_digital_capture alc880_pcm_digital_capture 19680 19681/* 19682 * BIOS auto configuration 19683 */ 19684static int alc680_parse_auto_config(struct hda_codec *codec) 19685{ 19686 struct alc_spec *spec = codec->spec; 19687 int err; 19688 static hda_nid_t alc680_ignore[] = { 0 }; 19689 19690 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 19691 alc680_ignore); 19692 if (err < 0) 19693 return err; 19694 19695 if (!spec->autocfg.line_outs) { 19696 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) { 19697 spec->multiout.max_channels = 2; 19698 spec->no_analog = 1; 19699 goto dig_only; 19700 } 19701 return 0; /* can't find valid BIOS pin config */ 19702 } 19703 err = alc680_auto_create_multi_out_ctls(spec, &spec->autocfg); 19704 if (err < 0) 19705 return err; 19706 19707 spec->multiout.max_channels = 2; 19708 19709 dig_only: 19710 /* digital only support output */ 19711 alc_auto_parse_digital(codec); 19712 if (spec->kctls.list) 19713 add_mixer(spec, spec->kctls.list); 19714 19715 add_verb(spec, alc680_init_verbs); 19716 19717 err = alc_auto_add_mic_boost(codec); 19718 if (err < 0) 19719 return err; 19720 19721 return 1; 19722} 19723 19724#define alc680_auto_init_analog_input alc882_auto_init_analog_input 19725 19726/* init callback for auto-configuration model -- overriding the default init */ 19727static void alc680_auto_init(struct hda_codec *codec) 19728{ 19729 struct alc_spec *spec = codec->spec; 19730 alc680_auto_init_multi_out(codec); 19731 alc680_auto_init_hp_out(codec); 19732 alc680_auto_init_analog_input(codec); 19733 alc_auto_init_digital(codec); 19734 if (spec->unsol_event) 19735 alc_inithook(codec); 19736} 19737 19738/* 19739 * configuration and preset 19740 */ 19741static const char *alc680_models[ALC680_MODEL_LAST] = { 19742 [ALC680_BASE] = "base", 19743 [ALC680_AUTO] = "auto", 19744}; 19745 19746static struct snd_pci_quirk alc680_cfg_tbl[] = { 19747 SND_PCI_QUIRK(0x1043, 0x12f3, "ASUS NX90", ALC680_BASE), 19748 {} 19749}; 19750 19751static struct alc_config_preset alc680_presets[] = { 19752 [ALC680_BASE] = { 19753 .mixers = { alc680_base_mixer }, 19754 .cap_mixer = alc680_master_capture_mixer, 19755 .init_verbs = { alc680_init_verbs }, 19756 .num_dacs = ARRAY_SIZE(alc680_dac_nids), 19757 .dac_nids = alc680_dac_nids, 19758 .dig_out_nid = ALC680_DIGOUT_NID, 19759 .num_channel_mode = ARRAY_SIZE(alc680_modes), 19760 .channel_mode = alc680_modes, 19761 .unsol_event = alc680_unsol_event, 19762 .setup = alc680_base_setup, 19763 .init_hook = alc680_inithook, 19764 19765 }, 19766}; 19767 19768static int patch_alc680(struct hda_codec *codec) 19769{ 19770 struct alc_spec *spec; 19771 int board_config; 19772 int err; 19773 19774 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 19775 if (spec == NULL) 19776 return -ENOMEM; 19777 19778 codec->spec = spec; 19779 19780 board_config = snd_hda_check_board_config(codec, ALC680_MODEL_LAST, 19781 alc680_models, 19782 alc680_cfg_tbl); 19783 19784 if (board_config < 0 || board_config >= ALC680_MODEL_LAST) { 19785 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 19786 codec->chip_name); 19787 board_config = ALC680_AUTO; 19788 } 19789 19790 if (board_config == ALC680_AUTO) { 19791 /* automatic parse from the BIOS config */ 19792 err = alc680_parse_auto_config(codec); 19793 if (err < 0) { 19794 alc_free(codec); 19795 return err; 19796 } else if (!err) { 19797 printk(KERN_INFO 19798 "hda_codec: Cannot set up configuration " 19799 "from BIOS. Using base mode...\n"); 19800 board_config = ALC680_BASE; 19801 } 19802 } 19803 19804 if (board_config != ALC680_AUTO) 19805 setup_preset(codec, &alc680_presets[board_config]); 19806 19807 spec->stream_analog_playback = &alc680_pcm_analog_playback; 19808 spec->stream_analog_capture = &alc680_pcm_analog_auto_capture; 19809 spec->stream_digital_playback = &alc680_pcm_digital_playback; 19810 spec->stream_digital_capture = &alc680_pcm_digital_capture; 19811 19812 if (!spec->adc_nids) { 19813 spec->adc_nids = alc680_adc_nids; 19814 spec->num_adc_nids = ARRAY_SIZE(alc680_adc_nids); 19815 } 19816 19817 if (!spec->cap_mixer) 19818 set_capture_mixer(codec); 19819 19820 spec->vmaster_nid = 0x02; 19821 19822 codec->patch_ops = alc_patch_ops; 19823 if (board_config == ALC680_AUTO) 19824 spec->init_hook = alc680_auto_init; 19825 19826 return 0; 19827} 19828 19829/* 19830 * patch entries 19831 */ 19832static struct hda_codec_preset snd_hda_preset_realtek[] = { 19833 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 }, 19834 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 }, 19835 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 }, 19836 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 }, 19837 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 }, 19838 { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 }, 19839 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 }, 19840 { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 }, 19841 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660", 19842 .patch = patch_alc861 }, 19843 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd }, 19844 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 }, 19845 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd }, 19846 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2", 19847 .patch = patch_alc882 }, 19848 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1", 19849 .patch = patch_alc662 }, 19850 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 }, 19851 { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 }, 19852 { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 }, 19853 { .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 }, 19854 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 }, 19855 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 }, 19856 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 }, 19857 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A", 19858 .patch = patch_alc882 }, 19859 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A", 19860 .patch = patch_alc882 }, 19861 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 }, 19862 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc882 }, 19863 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200", 19864 .patch = patch_alc882 }, 19865 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc888 }, 19866 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 }, 19867 { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 }, 19868 {} /* terminator */ 19869}; 19870 19871MODULE_ALIAS("snd-hda-codec-id:10ec*"); 19872 19873MODULE_LICENSE("GPL"); 19874MODULE_DESCRIPTION("Realtek HD-audio codec"); 19875 19876static struct hda_codec_preset_list realtek_list = { 19877 .preset = snd_hda_preset_realtek, 19878 .owner = THIS_MODULE, 19879}; 19880 19881static int __init patch_realtek_init(void) 19882{ 19883 return snd_hda_add_codec_preset(&realtek_list); 19884} 19885 19886static void __exit patch_realtek_exit(void) 19887{ 19888 snd_hda_delete_codec_preset(&realtek_list); 19889} 19890 19891module_init(patch_realtek_init) 19892module_exit(patch_realtek_exit) 19893