patch_realtek.c revision 7bfb9c031ec2d220d48bf679553d6177c2e66625
1/* 2 * Universal Interface for Intel High Definition Audio Codec 3 * 4 * HD audio interface patch for ALC 260/880/882 codecs 5 * 6 * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw> 7 * PeiSen Hou <pshou@realtek.com.tw> 8 * Takashi Iwai <tiwai@suse.de> 9 * Jonathan Woithe <jwoithe@physics.adelaide.edu.au> 10 * 11 * This driver is free software; you can redistribute it and/or modify 12 * it under the terms of the GNU General Public License as published by 13 * the Free Software Foundation; either version 2 of the License, or 14 * (at your option) any later version. 15 * 16 * This driver is distributed in the hope that it will be useful, 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 * GNU General Public License for more details. 20 * 21 * You should have received a copy of the GNU General Public License 22 * along with this program; if not, write to the Free Software 23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 24 */ 25 26#include <linux/init.h> 27#include <linux/delay.h> 28#include <linux/slab.h> 29#include <linux/pci.h> 30#include <sound/core.h> 31#include "hda_codec.h" 32#include "hda_local.h" 33#include "hda_beep.h" 34 35#define ALC880_FRONT_EVENT 0x01 36#define ALC880_DCVOL_EVENT 0x02 37#define ALC880_HP_EVENT 0x04 38#define ALC880_MIC_EVENT 0x08 39 40/* ALC880 board config type */ 41enum { 42 ALC880_3ST, 43 ALC880_3ST_DIG, 44 ALC880_5ST, 45 ALC880_5ST_DIG, 46 ALC880_W810, 47 ALC880_Z71V, 48 ALC880_6ST, 49 ALC880_6ST_DIG, 50 ALC880_F1734, 51 ALC880_ASUS, 52 ALC880_ASUS_DIG, 53 ALC880_ASUS_W1V, 54 ALC880_ASUS_DIG2, 55 ALC880_FUJITSU, 56 ALC880_UNIWILL_DIG, 57 ALC880_UNIWILL, 58 ALC880_UNIWILL_P53, 59 ALC880_CLEVO, 60 ALC880_TCL_S700, 61 ALC880_LG, 62 ALC880_LG_LW, 63 ALC880_MEDION_RIM, 64#ifdef CONFIG_SND_DEBUG 65 ALC880_TEST, 66#endif 67 ALC880_AUTO, 68 ALC880_MODEL_LAST /* last tag */ 69}; 70 71/* ALC260 models */ 72enum { 73 ALC260_BASIC, 74 ALC260_HP, 75 ALC260_HP_DC7600, 76 ALC260_HP_3013, 77 ALC260_FUJITSU_S702X, 78 ALC260_ACER, 79 ALC260_WILL, 80 ALC260_REPLACER_672V, 81 ALC260_FAVORIT100, 82#ifdef CONFIG_SND_DEBUG 83 ALC260_TEST, 84#endif 85 ALC260_AUTO, 86 ALC260_MODEL_LAST /* last tag */ 87}; 88 89/* ALC262 models */ 90enum { 91 ALC262_BASIC, 92 ALC262_HIPPO, 93 ALC262_HIPPO_1, 94 ALC262_FUJITSU, 95 ALC262_HP_BPC, 96 ALC262_HP_BPC_D7000_WL, 97 ALC262_HP_BPC_D7000_WF, 98 ALC262_HP_TC_T5735, 99 ALC262_HP_RP5700, 100 ALC262_BENQ_ED8, 101 ALC262_SONY_ASSAMD, 102 ALC262_BENQ_T31, 103 ALC262_ULTRA, 104 ALC262_LENOVO_3000, 105 ALC262_NEC, 106 ALC262_TOSHIBA_S06, 107 ALC262_TOSHIBA_RX1, 108 ALC262_TYAN, 109 ALC262_AUTO, 110 ALC262_MODEL_LAST /* last tag */ 111}; 112 113/* ALC268 models */ 114enum { 115 ALC267_QUANTA_IL1, 116 ALC268_3ST, 117 ALC268_TOSHIBA, 118 ALC268_ACER, 119 ALC268_ACER_DMIC, 120 ALC268_ACER_ASPIRE_ONE, 121 ALC268_DELL, 122 ALC268_ZEPTO, 123#ifdef CONFIG_SND_DEBUG 124 ALC268_TEST, 125#endif 126 ALC268_AUTO, 127 ALC268_MODEL_LAST /* last tag */ 128}; 129 130/* ALC269 models */ 131enum { 132 ALC269_BASIC, 133 ALC269_QUANTA_FL1, 134 ALC269_AMIC, 135 ALC269_DMIC, 136 ALC269VB_AMIC, 137 ALC269VB_DMIC, 138 ALC269_FUJITSU, 139 ALC269_LIFEBOOK, 140 ALC269_AUTO, 141 ALC269_MODEL_LAST /* last tag */ 142}; 143 144/* ALC861 models */ 145enum { 146 ALC861_3ST, 147 ALC660_3ST, 148 ALC861_3ST_DIG, 149 ALC861_6ST_DIG, 150 ALC861_UNIWILL_M31, 151 ALC861_TOSHIBA, 152 ALC861_ASUS, 153 ALC861_ASUS_LAPTOP, 154 ALC861_AUTO, 155 ALC861_MODEL_LAST, 156}; 157 158/* ALC861-VD models */ 159enum { 160 ALC660VD_3ST, 161 ALC660VD_3ST_DIG, 162 ALC660VD_ASUS_V1S, 163 ALC861VD_3ST, 164 ALC861VD_3ST_DIG, 165 ALC861VD_6ST_DIG, 166 ALC861VD_LENOVO, 167 ALC861VD_DALLAS, 168 ALC861VD_HP, 169 ALC861VD_AUTO, 170 ALC861VD_MODEL_LAST, 171}; 172 173/* ALC662 models */ 174enum { 175 ALC662_3ST_2ch_DIG, 176 ALC662_3ST_6ch_DIG, 177 ALC662_3ST_6ch, 178 ALC662_5ST_DIG, 179 ALC662_LENOVO_101E, 180 ALC662_ASUS_EEEPC_P701, 181 ALC662_ASUS_EEEPC_EP20, 182 ALC663_ASUS_M51VA, 183 ALC663_ASUS_G71V, 184 ALC663_ASUS_H13, 185 ALC663_ASUS_G50V, 186 ALC662_ECS, 187 ALC663_ASUS_MODE1, 188 ALC662_ASUS_MODE2, 189 ALC663_ASUS_MODE3, 190 ALC663_ASUS_MODE4, 191 ALC663_ASUS_MODE5, 192 ALC663_ASUS_MODE6, 193 ALC663_ASUS_MODE7, 194 ALC663_ASUS_MODE8, 195 ALC272_DELL, 196 ALC272_DELL_ZM1, 197 ALC272_SAMSUNG_NC10, 198 ALC662_AUTO, 199 ALC662_MODEL_LAST, 200}; 201 202/* ALC882 models */ 203enum { 204 ALC882_3ST_DIG, 205 ALC882_6ST_DIG, 206 ALC882_ARIMA, 207 ALC882_W2JC, 208 ALC882_TARGA, 209 ALC882_ASUS_A7J, 210 ALC882_ASUS_A7M, 211 ALC885_MACPRO, 212 ALC885_MBA21, 213 ALC885_MBP3, 214 ALC885_MB5, 215 ALC885_MACMINI3, 216 ALC885_IMAC24, 217 ALC885_IMAC91, 218 ALC883_3ST_2ch_DIG, 219 ALC883_3ST_6ch_DIG, 220 ALC883_3ST_6ch, 221 ALC883_6ST_DIG, 222 ALC883_TARGA_DIG, 223 ALC883_TARGA_2ch_DIG, 224 ALC883_TARGA_8ch_DIG, 225 ALC883_ACER, 226 ALC883_ACER_ASPIRE, 227 ALC888_ACER_ASPIRE_4930G, 228 ALC888_ACER_ASPIRE_6530G, 229 ALC888_ACER_ASPIRE_8930G, 230 ALC888_ACER_ASPIRE_7730G, 231 ALC883_MEDION, 232 ALC883_MEDION_MD2, 233 ALC883_MEDION_WIM2160, 234 ALC883_LAPTOP_EAPD, 235 ALC883_LENOVO_101E_2ch, 236 ALC883_LENOVO_NB0763, 237 ALC888_LENOVO_MS7195_DIG, 238 ALC888_LENOVO_SKY, 239 ALC883_HAIER_W66, 240 ALC888_3ST_HP, 241 ALC888_6ST_DELL, 242 ALC883_MITAC, 243 ALC883_CLEVO_M540R, 244 ALC883_CLEVO_M720, 245 ALC883_FUJITSU_PI2515, 246 ALC888_FUJITSU_XA3530, 247 ALC883_3ST_6ch_INTEL, 248 ALC889A_INTEL, 249 ALC889_INTEL, 250 ALC888_ASUS_M90V, 251 ALC888_ASUS_EEE1601, 252 ALC889A_MB31, 253 ALC1200_ASUS_P5Q, 254 ALC883_SONY_VAIO_TT, 255 ALC882_AUTO, 256 ALC882_MODEL_LAST, 257}; 258 259/* ALC680 models */ 260enum { 261 ALC680_BASE, 262 ALC680_AUTO, 263 ALC680_MODEL_LAST, 264}; 265 266/* for GPIO Poll */ 267#define GPIO_MASK 0x03 268 269/* extra amp-initialization sequence types */ 270enum { 271 ALC_INIT_NONE, 272 ALC_INIT_DEFAULT, 273 ALC_INIT_GPIO1, 274 ALC_INIT_GPIO2, 275 ALC_INIT_GPIO3, 276}; 277 278struct alc_mic_route { 279 hda_nid_t pin; 280 unsigned char mux_idx; 281 unsigned char amix_idx; 282}; 283 284#define MUX_IDX_UNDEF ((unsigned char)-1) 285 286struct alc_customize_define { 287 unsigned int sku_cfg; 288 unsigned char port_connectivity; 289 unsigned char check_sum; 290 unsigned char customization; 291 unsigned char external_amp; 292 unsigned int enable_pcbeep:1; 293 unsigned int platform_type:1; 294 unsigned int swap:1; 295 unsigned int override:1; 296}; 297 298struct alc_spec { 299 /* codec parameterization */ 300 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */ 301 unsigned int num_mixers; 302 struct snd_kcontrol_new *cap_mixer; /* capture mixer */ 303 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */ 304 305 const struct hda_verb *init_verbs[10]; /* initialization verbs 306 * don't forget NULL 307 * termination! 308 */ 309 unsigned int num_init_verbs; 310 311 char stream_name_analog[32]; /* analog PCM stream */ 312 struct hda_pcm_stream *stream_analog_playback; 313 struct hda_pcm_stream *stream_analog_capture; 314 struct hda_pcm_stream *stream_analog_alt_playback; 315 struct hda_pcm_stream *stream_analog_alt_capture; 316 317 char stream_name_digital[32]; /* digital PCM stream */ 318 struct hda_pcm_stream *stream_digital_playback; 319 struct hda_pcm_stream *stream_digital_capture; 320 321 /* playback */ 322 struct hda_multi_out multiout; /* playback set-up 323 * max_channels, dacs must be set 324 * dig_out_nid and hp_nid are optional 325 */ 326 hda_nid_t alt_dac_nid; 327 hda_nid_t slave_dig_outs[3]; /* optional - for auto-parsing */ 328 int dig_out_type; 329 330 /* capture */ 331 unsigned int num_adc_nids; 332 hda_nid_t *adc_nids; 333 hda_nid_t *capsrc_nids; 334 hda_nid_t dig_in_nid; /* digital-in NID; optional */ 335 336 /* capture setup for dynamic dual-adc switch */ 337 unsigned int cur_adc_idx; 338 hda_nid_t cur_adc; 339 unsigned int cur_adc_stream_tag; 340 unsigned int cur_adc_format; 341 342 /* capture source */ 343 unsigned int num_mux_defs; 344 const struct hda_input_mux *input_mux; 345 unsigned int cur_mux[3]; 346 struct alc_mic_route ext_mic; 347 struct alc_mic_route int_mic; 348 349 /* channel model */ 350 const struct hda_channel_mode *channel_mode; 351 int num_channel_mode; 352 int need_dac_fix; 353 int const_channel_count; 354 int ext_channel_count; 355 356 /* PCM information */ 357 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */ 358 359 /* dynamic controls, init_verbs and input_mux */ 360 struct auto_pin_cfg autocfg; 361 struct alc_customize_define cdefine; 362 struct snd_array kctls; 363 struct hda_input_mux private_imux[3]; 364 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; 365 hda_nid_t private_adc_nids[AUTO_CFG_MAX_OUTS]; 366 hda_nid_t private_capsrc_nids[AUTO_CFG_MAX_OUTS]; 367 368 /* hooks */ 369 void (*init_hook)(struct hda_codec *codec); 370 void (*unsol_event)(struct hda_codec *codec, unsigned int res); 371#ifdef CONFIG_SND_HDA_POWER_SAVE 372 void (*power_hook)(struct hda_codec *codec); 373#endif 374 375 /* for pin sensing */ 376 unsigned int sense_updated: 1; 377 unsigned int jack_present: 1; 378 unsigned int master_sw: 1; 379 unsigned int auto_mic:1; 380 381 /* other flags */ 382 unsigned int no_analog :1; /* digital I/O only */ 383 unsigned int dual_adc_switch:1; /* switch ADCs (for ALC275) */ 384 int init_amp; 385 386 /* for virtual master */ 387 hda_nid_t vmaster_nid; 388#ifdef CONFIG_SND_HDA_POWER_SAVE 389 struct hda_loopback_check loopback; 390#endif 391 392 /* for PLL fix */ 393 hda_nid_t pll_nid; 394 unsigned int pll_coef_idx, pll_coef_bit; 395}; 396 397/* 398 * configuration template - to be copied to the spec instance 399 */ 400struct alc_config_preset { 401 struct snd_kcontrol_new *mixers[5]; /* should be identical size 402 * with spec 403 */ 404 struct snd_kcontrol_new *cap_mixer; /* capture mixer */ 405 const struct hda_verb *init_verbs[5]; 406 unsigned int num_dacs; 407 hda_nid_t *dac_nids; 408 hda_nid_t dig_out_nid; /* optional */ 409 hda_nid_t hp_nid; /* optional */ 410 hda_nid_t *slave_dig_outs; 411 unsigned int num_adc_nids; 412 hda_nid_t *adc_nids; 413 hda_nid_t *capsrc_nids; 414 hda_nid_t dig_in_nid; 415 unsigned int num_channel_mode; 416 const struct hda_channel_mode *channel_mode; 417 int need_dac_fix; 418 int const_channel_count; 419 unsigned int num_mux_defs; 420 const struct hda_input_mux *input_mux; 421 void (*unsol_event)(struct hda_codec *, unsigned int); 422 void (*setup)(struct hda_codec *); 423 void (*init_hook)(struct hda_codec *); 424#ifdef CONFIG_SND_HDA_POWER_SAVE 425 struct hda_amp_list *loopbacks; 426 void (*power_hook)(struct hda_codec *codec); 427#endif 428}; 429 430 431/* 432 * input MUX handling 433 */ 434static int alc_mux_enum_info(struct snd_kcontrol *kcontrol, 435 struct snd_ctl_elem_info *uinfo) 436{ 437 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 438 struct alc_spec *spec = codec->spec; 439 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id); 440 if (mux_idx >= spec->num_mux_defs) 441 mux_idx = 0; 442 if (!spec->input_mux[mux_idx].num_items && mux_idx > 0) 443 mux_idx = 0; 444 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo); 445} 446 447static int alc_mux_enum_get(struct snd_kcontrol *kcontrol, 448 struct snd_ctl_elem_value *ucontrol) 449{ 450 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 451 struct alc_spec *spec = codec->spec; 452 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 453 454 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx]; 455 return 0; 456} 457 458static int alc_mux_enum_put(struct snd_kcontrol *kcontrol, 459 struct snd_ctl_elem_value *ucontrol) 460{ 461 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 462 struct alc_spec *spec = codec->spec; 463 const struct hda_input_mux *imux; 464 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 465 unsigned int mux_idx; 466 hda_nid_t nid = spec->capsrc_nids ? 467 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx]; 468 unsigned int type; 469 470 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx; 471 imux = &spec->input_mux[mux_idx]; 472 if (!imux->num_items && mux_idx > 0) 473 imux = &spec->input_mux[0]; 474 475 type = get_wcaps_type(get_wcaps(codec, nid)); 476 if (type == AC_WID_AUD_MIX) { 477 /* Matrix-mixer style (e.g. ALC882) */ 478 unsigned int *cur_val = &spec->cur_mux[adc_idx]; 479 unsigned int i, idx; 480 481 idx = ucontrol->value.enumerated.item[0]; 482 if (idx >= imux->num_items) 483 idx = imux->num_items - 1; 484 if (*cur_val == idx) 485 return 0; 486 for (i = 0; i < imux->num_items; i++) { 487 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE; 488 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 489 imux->items[i].index, 490 HDA_AMP_MUTE, v); 491 } 492 *cur_val = idx; 493 return 1; 494 } else { 495 /* MUX style (e.g. ALC880) */ 496 return snd_hda_input_mux_put(codec, imux, ucontrol, nid, 497 &spec->cur_mux[adc_idx]); 498 } 499} 500 501/* 502 * channel mode setting 503 */ 504static int alc_ch_mode_info(struct snd_kcontrol *kcontrol, 505 struct snd_ctl_elem_info *uinfo) 506{ 507 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 508 struct alc_spec *spec = codec->spec; 509 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode, 510 spec->num_channel_mode); 511} 512 513static int alc_ch_mode_get(struct snd_kcontrol *kcontrol, 514 struct snd_ctl_elem_value *ucontrol) 515{ 516 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 517 struct alc_spec *spec = codec->spec; 518 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode, 519 spec->num_channel_mode, 520 spec->ext_channel_count); 521} 522 523static int alc_ch_mode_put(struct snd_kcontrol *kcontrol, 524 struct snd_ctl_elem_value *ucontrol) 525{ 526 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 527 struct alc_spec *spec = codec->spec; 528 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode, 529 spec->num_channel_mode, 530 &spec->ext_channel_count); 531 if (err >= 0 && !spec->const_channel_count) { 532 spec->multiout.max_channels = spec->ext_channel_count; 533 if (spec->need_dac_fix) 534 spec->multiout.num_dacs = spec->multiout.max_channels / 2; 535 } 536 return err; 537} 538 539/* 540 * Control the mode of pin widget settings via the mixer. "pc" is used 541 * instead of "%" to avoid consequences of accidently treating the % as 542 * being part of a format specifier. Maximum allowed length of a value is 543 * 63 characters plus NULL terminator. 544 * 545 * Note: some retasking pin complexes seem to ignore requests for input 546 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these 547 * are requested. Therefore order this list so that this behaviour will not 548 * cause problems when mixer clients move through the enum sequentially. 549 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of 550 * March 2006. 551 */ 552static char *alc_pin_mode_names[] = { 553 "Mic 50pc bias", "Mic 80pc bias", 554 "Line in", "Line out", "Headphone out", 555}; 556static unsigned char alc_pin_mode_values[] = { 557 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP, 558}; 559/* The control can present all 5 options, or it can limit the options based 560 * in the pin being assumed to be exclusively an input or an output pin. In 561 * addition, "input" pins may or may not process the mic bias option 562 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to 563 * accept requests for bias as of chip versions up to March 2006) and/or 564 * wiring in the computer. 565 */ 566#define ALC_PIN_DIR_IN 0x00 567#define ALC_PIN_DIR_OUT 0x01 568#define ALC_PIN_DIR_INOUT 0x02 569#define ALC_PIN_DIR_IN_NOMICBIAS 0x03 570#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04 571 572/* Info about the pin modes supported by the different pin direction modes. 573 * For each direction the minimum and maximum values are given. 574 */ 575static signed char alc_pin_mode_dir_info[5][2] = { 576 { 0, 2 }, /* ALC_PIN_DIR_IN */ 577 { 3, 4 }, /* ALC_PIN_DIR_OUT */ 578 { 0, 4 }, /* ALC_PIN_DIR_INOUT */ 579 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */ 580 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */ 581}; 582#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0]) 583#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1]) 584#define alc_pin_mode_n_items(_dir) \ 585 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1) 586 587static int alc_pin_mode_info(struct snd_kcontrol *kcontrol, 588 struct snd_ctl_elem_info *uinfo) 589{ 590 unsigned int item_num = uinfo->value.enumerated.item; 591 unsigned char dir = (kcontrol->private_value >> 16) & 0xff; 592 593 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 594 uinfo->count = 1; 595 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir); 596 597 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir)) 598 item_num = alc_pin_mode_min(dir); 599 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]); 600 return 0; 601} 602 603static int alc_pin_mode_get(struct snd_kcontrol *kcontrol, 604 struct snd_ctl_elem_value *ucontrol) 605{ 606 unsigned int i; 607 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 608 hda_nid_t nid = kcontrol->private_value & 0xffff; 609 unsigned char dir = (kcontrol->private_value >> 16) & 0xff; 610 long *valp = ucontrol->value.integer.value; 611 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0, 612 AC_VERB_GET_PIN_WIDGET_CONTROL, 613 0x00); 614 615 /* Find enumerated value for current pinctl setting */ 616 i = alc_pin_mode_min(dir); 617 while (i <= alc_pin_mode_max(dir) && alc_pin_mode_values[i] != pinctl) 618 i++; 619 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir); 620 return 0; 621} 622 623static int alc_pin_mode_put(struct snd_kcontrol *kcontrol, 624 struct snd_ctl_elem_value *ucontrol) 625{ 626 signed int change; 627 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 628 hda_nid_t nid = kcontrol->private_value & 0xffff; 629 unsigned char dir = (kcontrol->private_value >> 16) & 0xff; 630 long val = *ucontrol->value.integer.value; 631 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0, 632 AC_VERB_GET_PIN_WIDGET_CONTROL, 633 0x00); 634 635 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir)) 636 val = alc_pin_mode_min(dir); 637 638 change = pinctl != alc_pin_mode_values[val]; 639 if (change) { 640 /* Set pin mode to that requested */ 641 snd_hda_codec_write_cache(codec, nid, 0, 642 AC_VERB_SET_PIN_WIDGET_CONTROL, 643 alc_pin_mode_values[val]); 644 645 /* Also enable the retasking pin's input/output as required 646 * for the requested pin mode. Enum values of 2 or less are 647 * input modes. 648 * 649 * Dynamically switching the input/output buffers probably 650 * reduces noise slightly (particularly on input) so we'll 651 * do it. However, having both input and output buffers 652 * enabled simultaneously doesn't seem to be problematic if 653 * this turns out to be necessary in the future. 654 */ 655 if (val <= 2) { 656 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, 657 HDA_AMP_MUTE, HDA_AMP_MUTE); 658 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0, 659 HDA_AMP_MUTE, 0); 660 } else { 661 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0, 662 HDA_AMP_MUTE, HDA_AMP_MUTE); 663 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, 664 HDA_AMP_MUTE, 0); 665 } 666 } 667 return change; 668} 669 670#define ALC_PIN_MODE(xname, nid, dir) \ 671 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 672 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \ 673 .info = alc_pin_mode_info, \ 674 .get = alc_pin_mode_get, \ 675 .put = alc_pin_mode_put, \ 676 .private_value = nid | (dir<<16) } 677 678/* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged 679 * together using a mask with more than one bit set. This control is 680 * currently used only by the ALC260 test model. At this stage they are not 681 * needed for any "production" models. 682 */ 683#ifdef CONFIG_SND_DEBUG 684#define alc_gpio_data_info snd_ctl_boolean_mono_info 685 686static int alc_gpio_data_get(struct snd_kcontrol *kcontrol, 687 struct snd_ctl_elem_value *ucontrol) 688{ 689 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 690 hda_nid_t nid = kcontrol->private_value & 0xffff; 691 unsigned char mask = (kcontrol->private_value >> 16) & 0xff; 692 long *valp = ucontrol->value.integer.value; 693 unsigned int val = snd_hda_codec_read(codec, nid, 0, 694 AC_VERB_GET_GPIO_DATA, 0x00); 695 696 *valp = (val & mask) != 0; 697 return 0; 698} 699static int alc_gpio_data_put(struct snd_kcontrol *kcontrol, 700 struct snd_ctl_elem_value *ucontrol) 701{ 702 signed int change; 703 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 704 hda_nid_t nid = kcontrol->private_value & 0xffff; 705 unsigned char mask = (kcontrol->private_value >> 16) & 0xff; 706 long val = *ucontrol->value.integer.value; 707 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0, 708 AC_VERB_GET_GPIO_DATA, 709 0x00); 710 711 /* Set/unset the masked GPIO bit(s) as needed */ 712 change = (val == 0 ? 0 : mask) != (gpio_data & mask); 713 if (val == 0) 714 gpio_data &= ~mask; 715 else 716 gpio_data |= mask; 717 snd_hda_codec_write_cache(codec, nid, 0, 718 AC_VERB_SET_GPIO_DATA, gpio_data); 719 720 return change; 721} 722#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \ 723 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 724 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \ 725 .info = alc_gpio_data_info, \ 726 .get = alc_gpio_data_get, \ 727 .put = alc_gpio_data_put, \ 728 .private_value = nid | (mask<<16) } 729#endif /* CONFIG_SND_DEBUG */ 730 731/* A switch control to allow the enabling of the digital IO pins on the 732 * ALC260. This is incredibly simplistic; the intention of this control is 733 * to provide something in the test model allowing digital outputs to be 734 * identified if present. If models are found which can utilise these 735 * outputs a more complete mixer control can be devised for those models if 736 * necessary. 737 */ 738#ifdef CONFIG_SND_DEBUG 739#define alc_spdif_ctrl_info snd_ctl_boolean_mono_info 740 741static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol, 742 struct snd_ctl_elem_value *ucontrol) 743{ 744 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 745 hda_nid_t nid = kcontrol->private_value & 0xffff; 746 unsigned char mask = (kcontrol->private_value >> 16) & 0xff; 747 long *valp = ucontrol->value.integer.value; 748 unsigned int val = snd_hda_codec_read(codec, nid, 0, 749 AC_VERB_GET_DIGI_CONVERT_1, 0x00); 750 751 *valp = (val & mask) != 0; 752 return 0; 753} 754static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol, 755 struct snd_ctl_elem_value *ucontrol) 756{ 757 signed int change; 758 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 759 hda_nid_t nid = kcontrol->private_value & 0xffff; 760 unsigned char mask = (kcontrol->private_value >> 16) & 0xff; 761 long val = *ucontrol->value.integer.value; 762 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0, 763 AC_VERB_GET_DIGI_CONVERT_1, 764 0x00); 765 766 /* Set/unset the masked control bit(s) as needed */ 767 change = (val == 0 ? 0 : mask) != (ctrl_data & mask); 768 if (val==0) 769 ctrl_data &= ~mask; 770 else 771 ctrl_data |= mask; 772 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, 773 ctrl_data); 774 775 return change; 776} 777#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \ 778 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 779 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \ 780 .info = alc_spdif_ctrl_info, \ 781 .get = alc_spdif_ctrl_get, \ 782 .put = alc_spdif_ctrl_put, \ 783 .private_value = nid | (mask<<16) } 784#endif /* CONFIG_SND_DEBUG */ 785 786/* A switch control to allow the enabling EAPD digital outputs on the ALC26x. 787 * Again, this is only used in the ALC26x test models to help identify when 788 * the EAPD line must be asserted for features to work. 789 */ 790#ifdef CONFIG_SND_DEBUG 791#define alc_eapd_ctrl_info snd_ctl_boolean_mono_info 792 793static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol, 794 struct snd_ctl_elem_value *ucontrol) 795{ 796 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 797 hda_nid_t nid = kcontrol->private_value & 0xffff; 798 unsigned char mask = (kcontrol->private_value >> 16) & 0xff; 799 long *valp = ucontrol->value.integer.value; 800 unsigned int val = snd_hda_codec_read(codec, nid, 0, 801 AC_VERB_GET_EAPD_BTLENABLE, 0x00); 802 803 *valp = (val & mask) != 0; 804 return 0; 805} 806 807static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol, 808 struct snd_ctl_elem_value *ucontrol) 809{ 810 int change; 811 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 812 hda_nid_t nid = kcontrol->private_value & 0xffff; 813 unsigned char mask = (kcontrol->private_value >> 16) & 0xff; 814 long val = *ucontrol->value.integer.value; 815 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0, 816 AC_VERB_GET_EAPD_BTLENABLE, 817 0x00); 818 819 /* Set/unset the masked control bit(s) as needed */ 820 change = (!val ? 0 : mask) != (ctrl_data & mask); 821 if (!val) 822 ctrl_data &= ~mask; 823 else 824 ctrl_data |= mask; 825 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE, 826 ctrl_data); 827 828 return change; 829} 830 831#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \ 832 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 833 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \ 834 .info = alc_eapd_ctrl_info, \ 835 .get = alc_eapd_ctrl_get, \ 836 .put = alc_eapd_ctrl_put, \ 837 .private_value = nid | (mask<<16) } 838#endif /* CONFIG_SND_DEBUG */ 839 840/* 841 * set up the input pin config (depending on the given auto-pin type) 842 */ 843static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid, 844 int auto_pin_type) 845{ 846 unsigned int val = PIN_IN; 847 848 if (auto_pin_type <= AUTO_PIN_FRONT_MIC) { 849 unsigned int pincap; 850 unsigned int oldval; 851 oldval = snd_hda_codec_read(codec, nid, 0, 852 AC_VERB_GET_PIN_WIDGET_CONTROL, 0); 853 pincap = snd_hda_query_pin_caps(codec, nid); 854 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT; 855 /* if the default pin setup is vref50, we give it priority */ 856 if ((pincap & AC_PINCAP_VREF_80) && oldval != PIN_VREF50) 857 val = PIN_VREF80; 858 else if (pincap & AC_PINCAP_VREF_50) 859 val = PIN_VREF50; 860 else if (pincap & AC_PINCAP_VREF_100) 861 val = PIN_VREF100; 862 else if (pincap & AC_PINCAP_VREF_GRD) 863 val = PIN_VREFGRD; 864 } 865 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val); 866} 867 868/* 869 */ 870static void add_mixer(struct alc_spec *spec, struct snd_kcontrol_new *mix) 871{ 872 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers))) 873 return; 874 spec->mixers[spec->num_mixers++] = mix; 875} 876 877static void add_verb(struct alc_spec *spec, const struct hda_verb *verb) 878{ 879 if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs))) 880 return; 881 spec->init_verbs[spec->num_init_verbs++] = verb; 882} 883 884/* 885 * set up from the preset table 886 */ 887static void setup_preset(struct hda_codec *codec, 888 const struct alc_config_preset *preset) 889{ 890 struct alc_spec *spec = codec->spec; 891 int i; 892 893 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++) 894 add_mixer(spec, preset->mixers[i]); 895 spec->cap_mixer = preset->cap_mixer; 896 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i]; 897 i++) 898 add_verb(spec, preset->init_verbs[i]); 899 900 spec->channel_mode = preset->channel_mode; 901 spec->num_channel_mode = preset->num_channel_mode; 902 spec->need_dac_fix = preset->need_dac_fix; 903 spec->const_channel_count = preset->const_channel_count; 904 905 if (preset->const_channel_count) 906 spec->multiout.max_channels = preset->const_channel_count; 907 else 908 spec->multiout.max_channels = spec->channel_mode[0].channels; 909 spec->ext_channel_count = spec->channel_mode[0].channels; 910 911 spec->multiout.num_dacs = preset->num_dacs; 912 spec->multiout.dac_nids = preset->dac_nids; 913 spec->multiout.dig_out_nid = preset->dig_out_nid; 914 spec->multiout.slave_dig_outs = preset->slave_dig_outs; 915 spec->multiout.hp_nid = preset->hp_nid; 916 917 spec->num_mux_defs = preset->num_mux_defs; 918 if (!spec->num_mux_defs) 919 spec->num_mux_defs = 1; 920 spec->input_mux = preset->input_mux; 921 922 spec->num_adc_nids = preset->num_adc_nids; 923 spec->adc_nids = preset->adc_nids; 924 spec->capsrc_nids = preset->capsrc_nids; 925 spec->dig_in_nid = preset->dig_in_nid; 926 927 spec->unsol_event = preset->unsol_event; 928 spec->init_hook = preset->init_hook; 929#ifdef CONFIG_SND_HDA_POWER_SAVE 930 spec->power_hook = preset->power_hook; 931 spec->loopback.amplist = preset->loopbacks; 932#endif 933 934 if (preset->setup) 935 preset->setup(codec); 936} 937 938/* Enable GPIO mask and set output */ 939static struct hda_verb alc_gpio1_init_verbs[] = { 940 {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, 941 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, 942 {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, 943 { } 944}; 945 946static struct hda_verb alc_gpio2_init_verbs[] = { 947 {0x01, AC_VERB_SET_GPIO_MASK, 0x02}, 948 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02}, 949 {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, 950 { } 951}; 952 953static struct hda_verb alc_gpio3_init_verbs[] = { 954 {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, 955 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03}, 956 {0x01, AC_VERB_SET_GPIO_DATA, 0x03}, 957 { } 958}; 959 960/* 961 * Fix hardware PLL issue 962 * On some codecs, the analog PLL gating control must be off while 963 * the default value is 1. 964 */ 965static void alc_fix_pll(struct hda_codec *codec) 966{ 967 struct alc_spec *spec = codec->spec; 968 unsigned int val; 969 970 if (!spec->pll_nid) 971 return; 972 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX, 973 spec->pll_coef_idx); 974 val = snd_hda_codec_read(codec, spec->pll_nid, 0, 975 AC_VERB_GET_PROC_COEF, 0); 976 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX, 977 spec->pll_coef_idx); 978 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF, 979 val & ~(1 << spec->pll_coef_bit)); 980} 981 982static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid, 983 unsigned int coef_idx, unsigned int coef_bit) 984{ 985 struct alc_spec *spec = codec->spec; 986 spec->pll_nid = nid; 987 spec->pll_coef_idx = coef_idx; 988 spec->pll_coef_bit = coef_bit; 989 alc_fix_pll(codec); 990} 991 992static void alc_automute_pin(struct hda_codec *codec) 993{ 994 struct alc_spec *spec = codec->spec; 995 unsigned int nid = spec->autocfg.hp_pins[0]; 996 int i; 997 998 if (!nid) 999 return; 1000 spec->jack_present = snd_hda_jack_detect(codec, nid); 1001 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) { 1002 nid = spec->autocfg.speaker_pins[i]; 1003 if (!nid) 1004 break; 1005 snd_hda_codec_write(codec, nid, 0, 1006 AC_VERB_SET_PIN_WIDGET_CONTROL, 1007 spec->jack_present ? 0 : PIN_OUT); 1008 } 1009} 1010 1011static int get_connection_index(struct hda_codec *codec, hda_nid_t mux, 1012 hda_nid_t nid) 1013{ 1014 hda_nid_t conn[HDA_MAX_NUM_INPUTS]; 1015 int i, nums; 1016 1017 nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn)); 1018 for (i = 0; i < nums; i++) 1019 if (conn[i] == nid) 1020 return i; 1021 return -1; 1022} 1023 1024/* switch the current ADC according to the jack state */ 1025static void alc_dual_mic_adc_auto_switch(struct hda_codec *codec) 1026{ 1027 struct alc_spec *spec = codec->spec; 1028 unsigned int present; 1029 hda_nid_t new_adc; 1030 1031 present = snd_hda_jack_detect(codec, spec->ext_mic.pin); 1032 if (present) 1033 spec->cur_adc_idx = 1; 1034 else 1035 spec->cur_adc_idx = 0; 1036 new_adc = spec->adc_nids[spec->cur_adc_idx]; 1037 if (spec->cur_adc && spec->cur_adc != new_adc) { 1038 /* stream is running, let's swap the current ADC */ 1039 snd_hda_codec_cleanup_stream(codec, spec->cur_adc); 1040 spec->cur_adc = new_adc; 1041 snd_hda_codec_setup_stream(codec, new_adc, 1042 spec->cur_adc_stream_tag, 0, 1043 spec->cur_adc_format); 1044 } 1045} 1046 1047static void alc_mic_automute(struct hda_codec *codec) 1048{ 1049 struct alc_spec *spec = codec->spec; 1050 struct alc_mic_route *dead, *alive; 1051 unsigned int present, type; 1052 hda_nid_t cap_nid; 1053 1054 if (!spec->auto_mic) 1055 return; 1056 if (!spec->int_mic.pin || !spec->ext_mic.pin) 1057 return; 1058 if (snd_BUG_ON(!spec->adc_nids)) 1059 return; 1060 1061 if (spec->dual_adc_switch) { 1062 alc_dual_mic_adc_auto_switch(codec); 1063 return; 1064 } 1065 1066 cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0]; 1067 1068 present = snd_hda_jack_detect(codec, spec->ext_mic.pin); 1069 if (present) { 1070 alive = &spec->ext_mic; 1071 dead = &spec->int_mic; 1072 } else { 1073 alive = &spec->int_mic; 1074 dead = &spec->ext_mic; 1075 } 1076 1077 type = get_wcaps_type(get_wcaps(codec, cap_nid)); 1078 if (type == AC_WID_AUD_MIX) { 1079 /* Matrix-mixer style (e.g. ALC882) */ 1080 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT, 1081 alive->mux_idx, 1082 HDA_AMP_MUTE, 0); 1083 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT, 1084 dead->mux_idx, 1085 HDA_AMP_MUTE, HDA_AMP_MUTE); 1086 } else { 1087 /* MUX style (e.g. ALC880) */ 1088 snd_hda_codec_write_cache(codec, cap_nid, 0, 1089 AC_VERB_SET_CONNECT_SEL, 1090 alive->mux_idx); 1091 } 1092 1093 /* FIXME: analog mixer */ 1094} 1095 1096/* unsolicited event for HP jack sensing */ 1097static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res) 1098{ 1099 if (codec->vendor_id == 0x10ec0880) 1100 res >>= 28; 1101 else 1102 res >>= 26; 1103 switch (res) { 1104 case ALC880_HP_EVENT: 1105 alc_automute_pin(codec); 1106 break; 1107 case ALC880_MIC_EVENT: 1108 alc_mic_automute(codec); 1109 break; 1110 } 1111} 1112 1113static void alc_inithook(struct hda_codec *codec) 1114{ 1115 alc_automute_pin(codec); 1116 alc_mic_automute(codec); 1117} 1118 1119/* additional initialization for ALC888 variants */ 1120static void alc888_coef_init(struct hda_codec *codec) 1121{ 1122 unsigned int tmp; 1123 1124 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0); 1125 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0); 1126 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7); 1127 if ((tmp & 0xf0) == 0x20) 1128 /* alc888S-VC */ 1129 snd_hda_codec_read(codec, 0x20, 0, 1130 AC_VERB_SET_PROC_COEF, 0x830); 1131 else 1132 /* alc888-VB */ 1133 snd_hda_codec_read(codec, 0x20, 0, 1134 AC_VERB_SET_PROC_COEF, 0x3030); 1135} 1136 1137static void alc889_coef_init(struct hda_codec *codec) 1138{ 1139 unsigned int tmp; 1140 1141 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7); 1142 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0); 1143 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7); 1144 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, tmp|0x2010); 1145} 1146 1147/* turn on/off EAPD control (only if available) */ 1148static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on) 1149{ 1150 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN) 1151 return; 1152 if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD) 1153 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE, 1154 on ? 2 : 0); 1155} 1156 1157static void alc_auto_init_amp(struct hda_codec *codec, int type) 1158{ 1159 unsigned int tmp; 1160 1161 switch (type) { 1162 case ALC_INIT_GPIO1: 1163 snd_hda_sequence_write(codec, alc_gpio1_init_verbs); 1164 break; 1165 case ALC_INIT_GPIO2: 1166 snd_hda_sequence_write(codec, alc_gpio2_init_verbs); 1167 break; 1168 case ALC_INIT_GPIO3: 1169 snd_hda_sequence_write(codec, alc_gpio3_init_verbs); 1170 break; 1171 case ALC_INIT_DEFAULT: 1172 switch (codec->vendor_id) { 1173 case 0x10ec0260: 1174 set_eapd(codec, 0x0f, 1); 1175 set_eapd(codec, 0x10, 1); 1176 break; 1177 case 0x10ec0262: 1178 case 0x10ec0267: 1179 case 0x10ec0268: 1180 case 0x10ec0269: 1181 case 0x10ec0270: 1182 case 0x10ec0272: 1183 case 0x10ec0660: 1184 case 0x10ec0662: 1185 case 0x10ec0663: 1186 case 0x10ec0862: 1187 case 0x10ec0889: 1188 set_eapd(codec, 0x14, 1); 1189 set_eapd(codec, 0x15, 1); 1190 break; 1191 } 1192 switch (codec->vendor_id) { 1193 case 0x10ec0260: 1194 snd_hda_codec_write(codec, 0x1a, 0, 1195 AC_VERB_SET_COEF_INDEX, 7); 1196 tmp = snd_hda_codec_read(codec, 0x1a, 0, 1197 AC_VERB_GET_PROC_COEF, 0); 1198 snd_hda_codec_write(codec, 0x1a, 0, 1199 AC_VERB_SET_COEF_INDEX, 7); 1200 snd_hda_codec_write(codec, 0x1a, 0, 1201 AC_VERB_SET_PROC_COEF, 1202 tmp | 0x2010); 1203 break; 1204 case 0x10ec0262: 1205 case 0x10ec0880: 1206 case 0x10ec0882: 1207 case 0x10ec0883: 1208 case 0x10ec0885: 1209 case 0x10ec0887: 1210 case 0x10ec0889: 1211 alc889_coef_init(codec); 1212 break; 1213 case 0x10ec0888: 1214 alc888_coef_init(codec); 1215 break; 1216#if 0 /* XXX: This may cause the silent output on speaker on some machines */ 1217 case 0x10ec0267: 1218 case 0x10ec0268: 1219 snd_hda_codec_write(codec, 0x20, 0, 1220 AC_VERB_SET_COEF_INDEX, 7); 1221 tmp = snd_hda_codec_read(codec, 0x20, 0, 1222 AC_VERB_GET_PROC_COEF, 0); 1223 snd_hda_codec_write(codec, 0x20, 0, 1224 AC_VERB_SET_COEF_INDEX, 7); 1225 snd_hda_codec_write(codec, 0x20, 0, 1226 AC_VERB_SET_PROC_COEF, 1227 tmp | 0x3000); 1228 break; 1229#endif /* XXX */ 1230 } 1231 break; 1232 } 1233} 1234 1235static void alc_init_auto_hp(struct hda_codec *codec) 1236{ 1237 struct alc_spec *spec = codec->spec; 1238 1239 if (!spec->autocfg.hp_pins[0]) 1240 return; 1241 1242 if (!spec->autocfg.speaker_pins[0]) { 1243 if (spec->autocfg.line_out_pins[0] && 1244 spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT) 1245 spec->autocfg.speaker_pins[0] = 1246 spec->autocfg.line_out_pins[0]; 1247 else 1248 return; 1249 } 1250 1251 snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n", 1252 spec->autocfg.hp_pins[0]); 1253 snd_hda_codec_write_cache(codec, spec->autocfg.hp_pins[0], 0, 1254 AC_VERB_SET_UNSOLICITED_ENABLE, 1255 AC_USRSP_EN | ALC880_HP_EVENT); 1256 spec->unsol_event = alc_sku_unsol_event; 1257} 1258 1259static void alc_init_auto_mic(struct hda_codec *codec) 1260{ 1261 struct alc_spec *spec = codec->spec; 1262 struct auto_pin_cfg *cfg = &spec->autocfg; 1263 hda_nid_t fixed, ext; 1264 int i; 1265 1266 /* there must be only two mic inputs exclusively */ 1267 for (i = AUTO_PIN_LINE; i < AUTO_PIN_LAST; i++) 1268 if (cfg->input_pins[i]) 1269 return; 1270 1271 fixed = ext = 0; 1272 for (i = AUTO_PIN_MIC; i <= AUTO_PIN_FRONT_MIC; i++) { 1273 hda_nid_t nid = cfg->input_pins[i]; 1274 unsigned int defcfg; 1275 if (!nid) 1276 return; 1277 defcfg = snd_hda_codec_get_pincfg(codec, nid); 1278 switch (get_defcfg_connect(defcfg)) { 1279 case AC_JACK_PORT_FIXED: 1280 if (fixed) 1281 return; /* already occupied */ 1282 fixed = nid; 1283 break; 1284 case AC_JACK_PORT_COMPLEX: 1285 if (ext) 1286 return; /* already occupied */ 1287 ext = nid; 1288 break; 1289 default: 1290 return; /* invalid entry */ 1291 } 1292 } 1293 if (!ext || !fixed) 1294 return; 1295 if (!(get_wcaps(codec, ext) & AC_WCAP_UNSOL_CAP)) 1296 return; /* no unsol support */ 1297 snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x\n", 1298 ext, fixed); 1299 spec->ext_mic.pin = ext; 1300 spec->int_mic.pin = fixed; 1301 spec->ext_mic.mux_idx = MUX_IDX_UNDEF; /* set later */ 1302 spec->int_mic.mux_idx = MUX_IDX_UNDEF; /* set later */ 1303 spec->auto_mic = 1; 1304 snd_hda_codec_write_cache(codec, spec->ext_mic.pin, 0, 1305 AC_VERB_SET_UNSOLICITED_ENABLE, 1306 AC_USRSP_EN | ALC880_MIC_EVENT); 1307 spec->unsol_event = alc_sku_unsol_event; 1308} 1309 1310static int alc_auto_parse_customize_define(struct hda_codec *codec) 1311{ 1312 unsigned int ass, tmp, i; 1313 unsigned nid = 0; 1314 struct alc_spec *spec = codec->spec; 1315 1316 spec->cdefine.enable_pcbeep = 1; /* assume always enabled */ 1317 1318 ass = codec->subsystem_id & 0xffff; 1319 if (ass != codec->bus->pci->subsystem_device && (ass & 1)) 1320 goto do_sku; 1321 1322 nid = 0x1d; 1323 if (codec->vendor_id == 0x10ec0260) 1324 nid = 0x17; 1325 ass = snd_hda_codec_get_pincfg(codec, nid); 1326 1327 if (!(ass & 1)) { 1328 printk(KERN_INFO "hda_codec: %s: SKU not ready 0x%08x\n", 1329 codec->chip_name, ass); 1330 return -1; 1331 } 1332 1333 /* check sum */ 1334 tmp = 0; 1335 for (i = 1; i < 16; i++) { 1336 if ((ass >> i) & 1) 1337 tmp++; 1338 } 1339 if (((ass >> 16) & 0xf) != tmp) 1340 return -1; 1341 1342 spec->cdefine.port_connectivity = ass >> 30; 1343 spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20; 1344 spec->cdefine.check_sum = (ass >> 16) & 0xf; 1345 spec->cdefine.customization = ass >> 8; 1346do_sku: 1347 spec->cdefine.sku_cfg = ass; 1348 spec->cdefine.external_amp = (ass & 0x38) >> 3; 1349 spec->cdefine.platform_type = (ass & 0x4) >> 2; 1350 spec->cdefine.swap = (ass & 0x2) >> 1; 1351 spec->cdefine.override = ass & 0x1; 1352 1353 snd_printd("SKU: Nid=0x%x sku_cfg=0x%08x\n", 1354 nid, spec->cdefine.sku_cfg); 1355 snd_printd("SKU: port_connectivity=0x%x\n", 1356 spec->cdefine.port_connectivity); 1357 snd_printd("SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep); 1358 snd_printd("SKU: check_sum=0x%08x\n", spec->cdefine.check_sum); 1359 snd_printd("SKU: customization=0x%08x\n", spec->cdefine.customization); 1360 snd_printd("SKU: external_amp=0x%x\n", spec->cdefine.external_amp); 1361 snd_printd("SKU: platform_type=0x%x\n", spec->cdefine.platform_type); 1362 snd_printd("SKU: swap=0x%x\n", spec->cdefine.swap); 1363 snd_printd("SKU: override=0x%x\n", spec->cdefine.override); 1364 1365 return 0; 1366} 1367 1368/* check subsystem ID and set up device-specific initialization; 1369 * return 1 if initialized, 0 if invalid SSID 1370 */ 1371/* 32-bit subsystem ID for BIOS loading in HD Audio codec. 1372 * 31 ~ 16 : Manufacture ID 1373 * 15 ~ 8 : SKU ID 1374 * 7 ~ 0 : Assembly ID 1375 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36 1376 */ 1377static int alc_subsystem_id(struct hda_codec *codec, 1378 hda_nid_t porta, hda_nid_t porte, 1379 hda_nid_t portd, hda_nid_t porti) 1380{ 1381 unsigned int ass, tmp, i; 1382 unsigned nid; 1383 struct alc_spec *spec = codec->spec; 1384 1385 ass = codec->subsystem_id & 0xffff; 1386 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1)) 1387 goto do_sku; 1388 1389 /* invalid SSID, check the special NID pin defcfg instead */ 1390 /* 1391 * 31~30 : port connectivity 1392 * 29~21 : reserve 1393 * 20 : PCBEEP input 1394 * 19~16 : Check sum (15:1) 1395 * 15~1 : Custom 1396 * 0 : override 1397 */ 1398 nid = 0x1d; 1399 if (codec->vendor_id == 0x10ec0260) 1400 nid = 0x17; 1401 ass = snd_hda_codec_get_pincfg(codec, nid); 1402 snd_printd("realtek: No valid SSID, " 1403 "checking pincfg 0x%08x for NID 0x%x\n", 1404 ass, nid); 1405 if (!(ass & 1)) 1406 return 0; 1407 if ((ass >> 30) != 1) /* no physical connection */ 1408 return 0; 1409 1410 /* check sum */ 1411 tmp = 0; 1412 for (i = 1; i < 16; i++) { 1413 if ((ass >> i) & 1) 1414 tmp++; 1415 } 1416 if (((ass >> 16) & 0xf) != tmp) 1417 return 0; 1418do_sku: 1419 snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n", 1420 ass & 0xffff, codec->vendor_id); 1421 /* 1422 * 0 : override 1423 * 1 : Swap Jack 1424 * 2 : 0 --> Desktop, 1 --> Laptop 1425 * 3~5 : External Amplifier control 1426 * 7~6 : Reserved 1427 */ 1428 tmp = (ass & 0x38) >> 3; /* external Amp control */ 1429 switch (tmp) { 1430 case 1: 1431 spec->init_amp = ALC_INIT_GPIO1; 1432 break; 1433 case 3: 1434 spec->init_amp = ALC_INIT_GPIO2; 1435 break; 1436 case 7: 1437 spec->init_amp = ALC_INIT_GPIO3; 1438 break; 1439 case 5: 1440 spec->init_amp = ALC_INIT_DEFAULT; 1441 break; 1442 } 1443 1444 /* is laptop or Desktop and enable the function "Mute internal speaker 1445 * when the external headphone out jack is plugged" 1446 */ 1447 if (!(ass & 0x8000)) 1448 return 1; 1449 /* 1450 * 10~8 : Jack location 1451 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered 1452 * 14~13: Resvered 1453 * 15 : 1 --> enable the function "Mute internal speaker 1454 * when the external headphone out jack is plugged" 1455 */ 1456 if (!spec->autocfg.hp_pins[0]) { 1457 hda_nid_t nid; 1458 tmp = (ass >> 11) & 0x3; /* HP to chassis */ 1459 if (tmp == 0) 1460 nid = porta; 1461 else if (tmp == 1) 1462 nid = porte; 1463 else if (tmp == 2) 1464 nid = portd; 1465 else if (tmp == 3) 1466 nid = porti; 1467 else 1468 return 1; 1469 for (i = 0; i < spec->autocfg.line_outs; i++) 1470 if (spec->autocfg.line_out_pins[i] == nid) 1471 return 1; 1472 spec->autocfg.hp_pins[0] = nid; 1473 } 1474 1475 alc_init_auto_hp(codec); 1476 alc_init_auto_mic(codec); 1477 return 1; 1478} 1479 1480static void alc_ssid_check(struct hda_codec *codec, 1481 hda_nid_t porta, hda_nid_t porte, 1482 hda_nid_t portd, hda_nid_t porti) 1483{ 1484 if (!alc_subsystem_id(codec, porta, porte, portd, porti)) { 1485 struct alc_spec *spec = codec->spec; 1486 snd_printd("realtek: " 1487 "Enable default setup for auto mode as fallback\n"); 1488 spec->init_amp = ALC_INIT_DEFAULT; 1489 alc_init_auto_hp(codec); 1490 alc_init_auto_mic(codec); 1491 } 1492} 1493 1494/* 1495 * Fix-up pin default configurations and add default verbs 1496 */ 1497 1498struct alc_pincfg { 1499 hda_nid_t nid; 1500 u32 val; 1501}; 1502 1503struct alc_fixup { 1504 const struct alc_pincfg *pins; 1505 const struct hda_verb *verbs; 1506}; 1507 1508static void alc_pick_fixup(struct hda_codec *codec, 1509 const struct snd_pci_quirk *quirk, 1510 const struct alc_fixup *fix, 1511 int pre_init) 1512{ 1513 const struct alc_pincfg *cfg; 1514 1515 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk); 1516 if (!quirk) 1517 return; 1518 fix += quirk->value; 1519 cfg = fix->pins; 1520 if (pre_init && cfg) { 1521#ifdef CONFIG_SND_DEBUG_VERBOSE 1522 snd_printdd(KERN_INFO "hda_codec: %s: Apply pincfg for %s\n", 1523 codec->chip_name, quirk->name); 1524#endif 1525 for (; cfg->nid; cfg++) 1526 snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val); 1527 } 1528 if (!pre_init && fix->verbs) { 1529#ifdef CONFIG_SND_DEBUG_VERBOSE 1530 snd_printdd(KERN_INFO "hda_codec: %s: Apply fix-verbs for %s\n", 1531 codec->chip_name, quirk->name); 1532#endif 1533 add_verb(codec->spec, fix->verbs); 1534 } 1535} 1536 1537static int alc_read_coef_idx(struct hda_codec *codec, 1538 unsigned int coef_idx) 1539{ 1540 unsigned int val; 1541 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 1542 coef_idx); 1543 val = snd_hda_codec_read(codec, 0x20, 0, 1544 AC_VERB_GET_PROC_COEF, 0); 1545 return val; 1546} 1547 1548/* set right pin controls for digital I/O */ 1549static void alc_auto_init_digital(struct hda_codec *codec) 1550{ 1551 struct alc_spec *spec = codec->spec; 1552 int i; 1553 hda_nid_t pin; 1554 1555 for (i = 0; i < spec->autocfg.dig_outs; i++) { 1556 pin = spec->autocfg.dig_out_pins[i]; 1557 if (pin) { 1558 snd_hda_codec_write(codec, pin, 0, 1559 AC_VERB_SET_PIN_WIDGET_CONTROL, 1560 PIN_OUT); 1561 } 1562 } 1563 pin = spec->autocfg.dig_in_pin; 1564 if (pin) 1565 snd_hda_codec_write(codec, pin, 0, 1566 AC_VERB_SET_PIN_WIDGET_CONTROL, 1567 PIN_IN); 1568} 1569 1570/* parse digital I/Os and set up NIDs in BIOS auto-parse mode */ 1571static void alc_auto_parse_digital(struct hda_codec *codec) 1572{ 1573 struct alc_spec *spec = codec->spec; 1574 int i, err; 1575 hda_nid_t dig_nid; 1576 1577 /* support multiple SPDIFs; the secondary is set up as a slave */ 1578 for (i = 0; i < spec->autocfg.dig_outs; i++) { 1579 err = snd_hda_get_connections(codec, 1580 spec->autocfg.dig_out_pins[i], 1581 &dig_nid, 1); 1582 if (err < 0) 1583 continue; 1584 if (!i) { 1585 spec->multiout.dig_out_nid = dig_nid; 1586 spec->dig_out_type = spec->autocfg.dig_out_type[0]; 1587 } else { 1588 spec->multiout.slave_dig_outs = spec->slave_dig_outs; 1589 if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1) 1590 break; 1591 spec->slave_dig_outs[i - 1] = dig_nid; 1592 } 1593 } 1594 1595 if (spec->autocfg.dig_in_pin) { 1596 hda_nid_t dig_nid; 1597 err = snd_hda_get_connections(codec, 1598 spec->autocfg.dig_in_pin, 1599 &dig_nid, 1); 1600 if (err > 0) 1601 spec->dig_in_nid = dig_nid; 1602 } 1603} 1604 1605/* 1606 * ALC888 1607 */ 1608 1609/* 1610 * 2ch mode 1611 */ 1612static struct hda_verb alc888_4ST_ch2_intel_init[] = { 1613/* Mic-in jack as mic in */ 1614 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 1615 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 1616/* Line-in jack as Line in */ 1617 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 1618 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 1619/* Line-Out as Front */ 1620 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00}, 1621 { } /* end */ 1622}; 1623 1624/* 1625 * 4ch mode 1626 */ 1627static struct hda_verb alc888_4ST_ch4_intel_init[] = { 1628/* Mic-in jack as mic in */ 1629 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 1630 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 1631/* Line-in jack as Surround */ 1632 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 1633 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 1634/* Line-Out as Front */ 1635 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00}, 1636 { } /* end */ 1637}; 1638 1639/* 1640 * 6ch mode 1641 */ 1642static struct hda_verb alc888_4ST_ch6_intel_init[] = { 1643/* Mic-in jack as CLFE */ 1644 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 1645 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 1646/* Line-in jack as Surround */ 1647 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 1648 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 1649/* Line-Out as CLFE (workaround because Mic-in is not loud enough) */ 1650 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, 1651 { } /* end */ 1652}; 1653 1654/* 1655 * 8ch mode 1656 */ 1657static struct hda_verb alc888_4ST_ch8_intel_init[] = { 1658/* Mic-in jack as CLFE */ 1659 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 1660 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 1661/* Line-in jack as Surround */ 1662 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 1663 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 1664/* Line-Out as Side */ 1665 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, 1666 { } /* end */ 1667}; 1668 1669static struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = { 1670 { 2, alc888_4ST_ch2_intel_init }, 1671 { 4, alc888_4ST_ch4_intel_init }, 1672 { 6, alc888_4ST_ch6_intel_init }, 1673 { 8, alc888_4ST_ch8_intel_init }, 1674}; 1675 1676/* 1677 * ALC888 Fujitsu Siemens Amillo xa3530 1678 */ 1679 1680static struct hda_verb alc888_fujitsu_xa3530_verbs[] = { 1681/* Front Mic: set to PIN_IN (empty by default) */ 1682 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1683/* Connect Internal HP to Front */ 1684 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1685 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1686 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 1687/* Connect Bass HP to Front */ 1688 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1689 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1690 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 1691/* Connect Line-Out side jack (SPDIF) to Side */ 1692 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1693 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1694 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, 1695/* Connect Mic jack to CLFE */ 1696 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1697 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1698 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, 1699/* Connect Line-in jack to Surround */ 1700 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1701 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1702 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, 1703/* Connect HP out jack to Front */ 1704 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1705 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1706 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 1707/* Enable unsolicited event for HP jack and Line-out jack */ 1708 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 1709 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 1710 {} 1711}; 1712 1713static void alc_automute_amp(struct hda_codec *codec) 1714{ 1715 struct alc_spec *spec = codec->spec; 1716 unsigned int mute; 1717 hda_nid_t nid; 1718 int i; 1719 1720 spec->jack_present = 0; 1721 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) { 1722 nid = spec->autocfg.hp_pins[i]; 1723 if (!nid) 1724 break; 1725 if (snd_hda_jack_detect(codec, nid)) { 1726 spec->jack_present = 1; 1727 break; 1728 } 1729 } 1730 1731 mute = spec->jack_present ? HDA_AMP_MUTE : 0; 1732 /* Toggle internal speakers muting */ 1733 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) { 1734 nid = spec->autocfg.speaker_pins[i]; 1735 if (!nid) 1736 break; 1737 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, 1738 HDA_AMP_MUTE, mute); 1739 } 1740} 1741 1742static void alc_automute_amp_unsol_event(struct hda_codec *codec, 1743 unsigned int res) 1744{ 1745 if (codec->vendor_id == 0x10ec0880) 1746 res >>= 28; 1747 else 1748 res >>= 26; 1749 if (res == ALC880_HP_EVENT) 1750 alc_automute_amp(codec); 1751} 1752 1753static void alc889_automute_setup(struct hda_codec *codec) 1754{ 1755 struct alc_spec *spec = codec->spec; 1756 1757 spec->autocfg.hp_pins[0] = 0x15; 1758 spec->autocfg.speaker_pins[0] = 0x14; 1759 spec->autocfg.speaker_pins[1] = 0x16; 1760 spec->autocfg.speaker_pins[2] = 0x17; 1761 spec->autocfg.speaker_pins[3] = 0x19; 1762 spec->autocfg.speaker_pins[4] = 0x1a; 1763} 1764 1765static void alc889_intel_init_hook(struct hda_codec *codec) 1766{ 1767 alc889_coef_init(codec); 1768 alc_automute_amp(codec); 1769} 1770 1771static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec) 1772{ 1773 struct alc_spec *spec = codec->spec; 1774 1775 spec->autocfg.hp_pins[0] = 0x17; /* line-out */ 1776 spec->autocfg.hp_pins[1] = 0x1b; /* hp */ 1777 spec->autocfg.speaker_pins[0] = 0x14; /* speaker */ 1778 spec->autocfg.speaker_pins[1] = 0x15; /* bass */ 1779} 1780 1781/* 1782 * ALC888 Acer Aspire 4930G model 1783 */ 1784 1785static struct hda_verb alc888_acer_aspire_4930g_verbs[] = { 1786/* Front Mic: set to PIN_IN (empty by default) */ 1787 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1788/* Unselect Front Mic by default in input mixer 3 */ 1789 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)}, 1790/* Enable unsolicited event for HP jack */ 1791 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 1792/* Connect Internal HP to front */ 1793 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1794 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1795 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 1796/* Connect HP out to front */ 1797 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1798 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1799 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 1800 { } 1801}; 1802 1803/* 1804 * ALC888 Acer Aspire 6530G model 1805 */ 1806 1807static struct hda_verb alc888_acer_aspire_6530g_verbs[] = { 1808/* Route to built-in subwoofer as well as speakers */ 1809 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1810 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 1811 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1812 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 1813/* Bias voltage on for external mic port */ 1814 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80}, 1815/* Front Mic: set to PIN_IN (empty by default) */ 1816 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1817/* Unselect Front Mic by default in input mixer 3 */ 1818 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)}, 1819/* Enable unsolicited event for HP jack */ 1820 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 1821/* Enable speaker output */ 1822 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1823 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1824 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 1825/* Enable headphone output */ 1826 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP}, 1827 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1828 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 1829 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, 1830 { } 1831}; 1832 1833/* 1834 * ALC889 Acer Aspire 8930G model 1835 */ 1836 1837static struct hda_verb alc889_acer_aspire_8930g_verbs[] = { 1838/* Front Mic: set to PIN_IN (empty by default) */ 1839 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1840/* Unselect Front Mic by default in input mixer 3 */ 1841 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)}, 1842/* Enable unsolicited event for HP jack */ 1843 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 1844/* Connect Internal Front to Front */ 1845 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1846 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1847 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 1848/* Connect Internal Rear to Rear */ 1849 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1850 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1851 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, 1852/* Connect Internal CLFE to CLFE */ 1853 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1854 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1855 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, 1856/* Connect HP out to Front */ 1857 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP}, 1858 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1859 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 1860/* Enable all DACs */ 1861/* DAC DISABLE/MUTE 1? */ 1862/* setting bits 1-5 disables DAC nids 0x02-0x06 apparently. Init=0x38 */ 1863 {0x20, AC_VERB_SET_COEF_INDEX, 0x03}, 1864 {0x20, AC_VERB_SET_PROC_COEF, 0x0000}, 1865/* DAC DISABLE/MUTE 2? */ 1866/* some bit here disables the other DACs. Init=0x4900 */ 1867 {0x20, AC_VERB_SET_COEF_INDEX, 0x08}, 1868 {0x20, AC_VERB_SET_PROC_COEF, 0x0000}, 1869/* DMIC fix 1870 * This laptop has a stereo digital microphone. The mics are only 1cm apart 1871 * which makes the stereo useless. However, either the mic or the ALC889 1872 * makes the signal become a difference/sum signal instead of standard 1873 * stereo, which is annoying. So instead we flip this bit which makes the 1874 * codec replicate the sum signal to both channels, turning it into a 1875 * normal mono mic. 1876 */ 1877/* DMIC_CONTROL? Init value = 0x0001 */ 1878 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b}, 1879 {0x20, AC_VERB_SET_PROC_COEF, 0x0003}, 1880 { } 1881}; 1882 1883static struct hda_input_mux alc888_2_capture_sources[2] = { 1884 /* Front mic only available on one ADC */ 1885 { 1886 .num_items = 4, 1887 .items = { 1888 { "Mic", 0x0 }, 1889 { "Line", 0x2 }, 1890 { "CD", 0x4 }, 1891 { "Front Mic", 0xb }, 1892 }, 1893 }, 1894 { 1895 .num_items = 3, 1896 .items = { 1897 { "Mic", 0x0 }, 1898 { "Line", 0x2 }, 1899 { "CD", 0x4 }, 1900 }, 1901 } 1902}; 1903 1904static struct hda_input_mux alc888_acer_aspire_6530_sources[2] = { 1905 /* Interal mic only available on one ADC */ 1906 { 1907 .num_items = 5, 1908 .items = { 1909 { "Ext Mic", 0x0 }, 1910 { "Line In", 0x2 }, 1911 { "CD", 0x4 }, 1912 { "Input Mix", 0xa }, 1913 { "Int Mic", 0xb }, 1914 }, 1915 }, 1916 { 1917 .num_items = 4, 1918 .items = { 1919 { "Ext Mic", 0x0 }, 1920 { "Line In", 0x2 }, 1921 { "CD", 0x4 }, 1922 { "Input Mix", 0xa }, 1923 }, 1924 } 1925}; 1926 1927static struct hda_input_mux alc889_capture_sources[3] = { 1928 /* Digital mic only available on first "ADC" */ 1929 { 1930 .num_items = 5, 1931 .items = { 1932 { "Mic", 0x0 }, 1933 { "Line", 0x2 }, 1934 { "CD", 0x4 }, 1935 { "Front Mic", 0xb }, 1936 { "Input Mix", 0xa }, 1937 }, 1938 }, 1939 { 1940 .num_items = 4, 1941 .items = { 1942 { "Mic", 0x0 }, 1943 { "Line", 0x2 }, 1944 { "CD", 0x4 }, 1945 { "Input Mix", 0xa }, 1946 }, 1947 }, 1948 { 1949 .num_items = 4, 1950 .items = { 1951 { "Mic", 0x0 }, 1952 { "Line", 0x2 }, 1953 { "CD", 0x4 }, 1954 { "Input Mix", 0xa }, 1955 }, 1956 } 1957}; 1958 1959static struct snd_kcontrol_new alc888_base_mixer[] = { 1960 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 1961 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 1962 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 1963 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 1964 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, 1965 HDA_OUTPUT), 1966 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 1967 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 1968 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 1969 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 1970 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 1971 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 1972 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 1973 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 1974 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 1975 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 1976 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 1977 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 1978 { } /* end */ 1979}; 1980 1981static struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = { 1982 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 1983 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 1984 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 1985 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 1986 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, 1987 HDA_OUTPUT), 1988 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 1989 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 1990 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 1991 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 1992 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 1993 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 1994 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 1995 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 1996 { } /* end */ 1997}; 1998 1999 2000static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec) 2001{ 2002 struct alc_spec *spec = codec->spec; 2003 2004 spec->autocfg.hp_pins[0] = 0x15; 2005 spec->autocfg.speaker_pins[0] = 0x14; 2006 spec->autocfg.speaker_pins[1] = 0x16; 2007 spec->autocfg.speaker_pins[2] = 0x17; 2008} 2009 2010static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec) 2011{ 2012 struct alc_spec *spec = codec->spec; 2013 2014 spec->autocfg.hp_pins[0] = 0x15; 2015 spec->autocfg.speaker_pins[0] = 0x14; 2016 spec->autocfg.speaker_pins[1] = 0x16; 2017 spec->autocfg.speaker_pins[2] = 0x17; 2018} 2019 2020static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec) 2021{ 2022 struct alc_spec *spec = codec->spec; 2023 2024 spec->autocfg.hp_pins[0] = 0x15; 2025 spec->autocfg.speaker_pins[0] = 0x14; 2026 spec->autocfg.speaker_pins[1] = 0x16; 2027 spec->autocfg.speaker_pins[2] = 0x1b; 2028} 2029 2030/* 2031 * ALC880 3-stack model 2032 * 2033 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e) 2034 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18, 2035 * F-Mic = 0x1b, HP = 0x19 2036 */ 2037 2038static hda_nid_t alc880_dac_nids[4] = { 2039 /* front, rear, clfe, rear_surr */ 2040 0x02, 0x05, 0x04, 0x03 2041}; 2042 2043static hda_nid_t alc880_adc_nids[3] = { 2044 /* ADC0-2 */ 2045 0x07, 0x08, 0x09, 2046}; 2047 2048/* The datasheet says the node 0x07 is connected from inputs, 2049 * but it shows zero connection in the real implementation on some devices. 2050 * Note: this is a 915GAV bug, fixed on 915GLV 2051 */ 2052static hda_nid_t alc880_adc_nids_alt[2] = { 2053 /* ADC1-2 */ 2054 0x08, 0x09, 2055}; 2056 2057#define ALC880_DIGOUT_NID 0x06 2058#define ALC880_DIGIN_NID 0x0a 2059 2060static struct hda_input_mux alc880_capture_source = { 2061 .num_items = 4, 2062 .items = { 2063 { "Mic", 0x0 }, 2064 { "Front Mic", 0x3 }, 2065 { "Line", 0x2 }, 2066 { "CD", 0x4 }, 2067 }, 2068}; 2069 2070/* channel source setting (2/6 channel selection for 3-stack) */ 2071/* 2ch mode */ 2072static struct hda_verb alc880_threestack_ch2_init[] = { 2073 /* set line-in to input, mute it */ 2074 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 2075 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 2076 /* set mic-in to input vref 80%, mute it */ 2077 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 2078 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 2079 { } /* end */ 2080}; 2081 2082/* 6ch mode */ 2083static struct hda_verb alc880_threestack_ch6_init[] = { 2084 /* set line-in to output, unmute it */ 2085 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 2086 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 2087 /* set mic-in to output, unmute it */ 2088 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 2089 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 2090 { } /* end */ 2091}; 2092 2093static struct hda_channel_mode alc880_threestack_modes[2] = { 2094 { 2, alc880_threestack_ch2_init }, 2095 { 6, alc880_threestack_ch6_init }, 2096}; 2097 2098static struct snd_kcontrol_new alc880_three_stack_mixer[] = { 2099 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2100 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 2101 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 2102 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT), 2103 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 2104 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 2105 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 2106 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 2107 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 2108 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 2109 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 2110 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 2111 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 2112 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 2113 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT), 2114 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT), 2115 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT), 2116 { 2117 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2118 .name = "Channel Mode", 2119 .info = alc_ch_mode_info, 2120 .get = alc_ch_mode_get, 2121 .put = alc_ch_mode_put, 2122 }, 2123 { } /* end */ 2124}; 2125 2126/* capture mixer elements */ 2127static int alc_cap_vol_info(struct snd_kcontrol *kcontrol, 2128 struct snd_ctl_elem_info *uinfo) 2129{ 2130 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2131 struct alc_spec *spec = codec->spec; 2132 int err; 2133 2134 mutex_lock(&codec->control_mutex); 2135 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0, 2136 HDA_INPUT); 2137 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo); 2138 mutex_unlock(&codec->control_mutex); 2139 return err; 2140} 2141 2142static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag, 2143 unsigned int size, unsigned int __user *tlv) 2144{ 2145 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2146 struct alc_spec *spec = codec->spec; 2147 int err; 2148 2149 mutex_lock(&codec->control_mutex); 2150 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0, 2151 HDA_INPUT); 2152 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv); 2153 mutex_unlock(&codec->control_mutex); 2154 return err; 2155} 2156 2157typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol, 2158 struct snd_ctl_elem_value *ucontrol); 2159 2160static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol, 2161 struct snd_ctl_elem_value *ucontrol, 2162 getput_call_t func) 2163{ 2164 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2165 struct alc_spec *spec = codec->spec; 2166 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 2167 int err; 2168 2169 mutex_lock(&codec->control_mutex); 2170 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx], 2171 3, 0, HDA_INPUT); 2172 err = func(kcontrol, ucontrol); 2173 mutex_unlock(&codec->control_mutex); 2174 return err; 2175} 2176 2177static int alc_cap_vol_get(struct snd_kcontrol *kcontrol, 2178 struct snd_ctl_elem_value *ucontrol) 2179{ 2180 return alc_cap_getput_caller(kcontrol, ucontrol, 2181 snd_hda_mixer_amp_volume_get); 2182} 2183 2184static int alc_cap_vol_put(struct snd_kcontrol *kcontrol, 2185 struct snd_ctl_elem_value *ucontrol) 2186{ 2187 return alc_cap_getput_caller(kcontrol, ucontrol, 2188 snd_hda_mixer_amp_volume_put); 2189} 2190 2191/* capture mixer elements */ 2192#define alc_cap_sw_info snd_ctl_boolean_stereo_info 2193 2194static int alc_cap_sw_get(struct snd_kcontrol *kcontrol, 2195 struct snd_ctl_elem_value *ucontrol) 2196{ 2197 return alc_cap_getput_caller(kcontrol, ucontrol, 2198 snd_hda_mixer_amp_switch_get); 2199} 2200 2201static int alc_cap_sw_put(struct snd_kcontrol *kcontrol, 2202 struct snd_ctl_elem_value *ucontrol) 2203{ 2204 return alc_cap_getput_caller(kcontrol, ucontrol, 2205 snd_hda_mixer_amp_switch_put); 2206} 2207 2208#define _DEFINE_CAPMIX(num) \ 2209 { \ 2210 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 2211 .name = "Capture Switch", \ 2212 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \ 2213 .count = num, \ 2214 .info = alc_cap_sw_info, \ 2215 .get = alc_cap_sw_get, \ 2216 .put = alc_cap_sw_put, \ 2217 }, \ 2218 { \ 2219 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 2220 .name = "Capture Volume", \ 2221 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \ 2222 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \ 2223 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \ 2224 .count = num, \ 2225 .info = alc_cap_vol_info, \ 2226 .get = alc_cap_vol_get, \ 2227 .put = alc_cap_vol_put, \ 2228 .tlv = { .c = alc_cap_vol_tlv }, \ 2229 } 2230 2231#define _DEFINE_CAPSRC(num) \ 2232 { \ 2233 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 2234 /* .name = "Capture Source", */ \ 2235 .name = "Input Source", \ 2236 .count = num, \ 2237 .info = alc_mux_enum_info, \ 2238 .get = alc_mux_enum_get, \ 2239 .put = alc_mux_enum_put, \ 2240 } 2241 2242#define DEFINE_CAPMIX(num) \ 2243static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \ 2244 _DEFINE_CAPMIX(num), \ 2245 _DEFINE_CAPSRC(num), \ 2246 { } /* end */ \ 2247} 2248 2249#define DEFINE_CAPMIX_NOSRC(num) \ 2250static struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \ 2251 _DEFINE_CAPMIX(num), \ 2252 { } /* end */ \ 2253} 2254 2255/* up to three ADCs */ 2256DEFINE_CAPMIX(1); 2257DEFINE_CAPMIX(2); 2258DEFINE_CAPMIX(3); 2259DEFINE_CAPMIX_NOSRC(1); 2260DEFINE_CAPMIX_NOSRC(2); 2261DEFINE_CAPMIX_NOSRC(3); 2262 2263/* 2264 * ALC880 5-stack model 2265 * 2266 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d), 2267 * Side = 0x02 (0xd) 2268 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16 2269 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19 2270 */ 2271 2272/* additional mixers to alc880_three_stack_mixer */ 2273static struct snd_kcontrol_new alc880_five_stack_mixer[] = { 2274 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2275 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT), 2276 { } /* end */ 2277}; 2278 2279/* channel source setting (6/8 channel selection for 5-stack) */ 2280/* 6ch mode */ 2281static struct hda_verb alc880_fivestack_ch6_init[] = { 2282 /* set line-in to input, mute it */ 2283 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 2284 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 2285 { } /* end */ 2286}; 2287 2288/* 8ch mode */ 2289static struct hda_verb alc880_fivestack_ch8_init[] = { 2290 /* set line-in to output, unmute it */ 2291 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 2292 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 2293 { } /* end */ 2294}; 2295 2296static struct hda_channel_mode alc880_fivestack_modes[2] = { 2297 { 6, alc880_fivestack_ch6_init }, 2298 { 8, alc880_fivestack_ch8_init }, 2299}; 2300 2301 2302/* 2303 * ALC880 6-stack model 2304 * 2305 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e), 2306 * Side = 0x05 (0x0f) 2307 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17, 2308 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b 2309 */ 2310 2311static hda_nid_t alc880_6st_dac_nids[4] = { 2312 /* front, rear, clfe, rear_surr */ 2313 0x02, 0x03, 0x04, 0x05 2314}; 2315 2316static struct hda_input_mux alc880_6stack_capture_source = { 2317 .num_items = 4, 2318 .items = { 2319 { "Mic", 0x0 }, 2320 { "Front Mic", 0x1 }, 2321 { "Line", 0x2 }, 2322 { "CD", 0x4 }, 2323 }, 2324}; 2325 2326/* fixed 8-channels */ 2327static struct hda_channel_mode alc880_sixstack_modes[1] = { 2328 { 8, NULL }, 2329}; 2330 2331static struct snd_kcontrol_new alc880_six_stack_mixer[] = { 2332 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2333 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 2334 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2335 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 2336 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 2337 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 2338 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 2339 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 2340 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 2341 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 2342 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 2343 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 2344 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 2345 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 2346 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 2347 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 2348 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 2349 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 2350 { 2351 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2352 .name = "Channel Mode", 2353 .info = alc_ch_mode_info, 2354 .get = alc_ch_mode_get, 2355 .put = alc_ch_mode_put, 2356 }, 2357 { } /* end */ 2358}; 2359 2360 2361/* 2362 * ALC880 W810 model 2363 * 2364 * W810 has rear IO for: 2365 * Front (DAC 02) 2366 * Surround (DAC 03) 2367 * Center/LFE (DAC 04) 2368 * Digital out (06) 2369 * 2370 * The system also has a pair of internal speakers, and a headphone jack. 2371 * These are both connected to Line2 on the codec, hence to DAC 02. 2372 * 2373 * There is a variable resistor to control the speaker or headphone 2374 * volume. This is a hardware-only device without a software API. 2375 * 2376 * Plugging headphones in will disable the internal speakers. This is 2377 * implemented in hardware, not via the driver using jack sense. In 2378 * a similar fashion, plugging into the rear socket marked "front" will 2379 * disable both the speakers and headphones. 2380 * 2381 * For input, there's a microphone jack, and an "audio in" jack. 2382 * These may not do anything useful with this driver yet, because I 2383 * haven't setup any initialization verbs for these yet... 2384 */ 2385 2386static hda_nid_t alc880_w810_dac_nids[3] = { 2387 /* front, rear/surround, clfe */ 2388 0x02, 0x03, 0x04 2389}; 2390 2391/* fixed 6 channels */ 2392static struct hda_channel_mode alc880_w810_modes[1] = { 2393 { 6, NULL } 2394}; 2395 2396/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */ 2397static struct snd_kcontrol_new alc880_w810_base_mixer[] = { 2398 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2399 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 2400 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2401 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 2402 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 2403 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 2404 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 2405 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 2406 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 2407 { } /* end */ 2408}; 2409 2410 2411/* 2412 * Z710V model 2413 * 2414 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d) 2415 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?), 2416 * Line = 0x1a 2417 */ 2418 2419static hda_nid_t alc880_z71v_dac_nids[1] = { 2420 0x02 2421}; 2422#define ALC880_Z71V_HP_DAC 0x03 2423 2424/* fixed 2 channels */ 2425static struct hda_channel_mode alc880_2_jack_modes[1] = { 2426 { 2, NULL } 2427}; 2428 2429static struct snd_kcontrol_new alc880_z71v_mixer[] = { 2430 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2431 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 2432 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2433 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT), 2434 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 2435 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 2436 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 2437 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 2438 { } /* end */ 2439}; 2440 2441 2442/* 2443 * ALC880 F1734 model 2444 * 2445 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d) 2446 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18 2447 */ 2448 2449static hda_nid_t alc880_f1734_dac_nids[1] = { 2450 0x03 2451}; 2452#define ALC880_F1734_HP_DAC 0x02 2453 2454static struct snd_kcontrol_new alc880_f1734_mixer[] = { 2455 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2456 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), 2457 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2458 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 2459 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 2460 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 2461 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 2462 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 2463 { } /* end */ 2464}; 2465 2466static struct hda_input_mux alc880_f1734_capture_source = { 2467 .num_items = 2, 2468 .items = { 2469 { "Mic", 0x1 }, 2470 { "CD", 0x4 }, 2471 }, 2472}; 2473 2474 2475/* 2476 * ALC880 ASUS model 2477 * 2478 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e) 2479 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16, 2480 * Mic = 0x18, Line = 0x1a 2481 */ 2482 2483#define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */ 2484#define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */ 2485 2486static struct snd_kcontrol_new alc880_asus_mixer[] = { 2487 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2488 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 2489 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2490 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 2491 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 2492 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 2493 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 2494 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 2495 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 2496 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 2497 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 2498 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 2499 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 2500 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 2501 { 2502 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2503 .name = "Channel Mode", 2504 .info = alc_ch_mode_info, 2505 .get = alc_ch_mode_get, 2506 .put = alc_ch_mode_put, 2507 }, 2508 { } /* end */ 2509}; 2510 2511/* 2512 * ALC880 ASUS W1V model 2513 * 2514 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e) 2515 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16, 2516 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b 2517 */ 2518 2519/* additional mixers to alc880_asus_mixer */ 2520static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = { 2521 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT), 2522 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT), 2523 { } /* end */ 2524}; 2525 2526/* TCL S700 */ 2527static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = { 2528 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2529 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 2530 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 2531 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT), 2532 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT), 2533 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT), 2534 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT), 2535 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 2536 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 2537 { } /* end */ 2538}; 2539 2540/* Uniwill */ 2541static struct snd_kcontrol_new alc880_uniwill_mixer[] = { 2542 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2543 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), 2544 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2545 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 2546 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 2547 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 2548 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 2549 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 2550 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 2551 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 2552 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 2553 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 2554 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 2555 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 2556 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 2557 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 2558 { 2559 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2560 .name = "Channel Mode", 2561 .info = alc_ch_mode_info, 2562 .get = alc_ch_mode_get, 2563 .put = alc_ch_mode_put, 2564 }, 2565 { } /* end */ 2566}; 2567 2568static struct snd_kcontrol_new alc880_fujitsu_mixer[] = { 2569 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2570 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), 2571 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2572 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 2573 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 2574 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 2575 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 2576 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 2577 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 2578 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 2579 { } /* end */ 2580}; 2581 2582static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = { 2583 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2584 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), 2585 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2586 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 2587 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 2588 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 2589 { } /* end */ 2590}; 2591 2592/* 2593 * virtual master controls 2594 */ 2595 2596/* 2597 * slave controls for virtual master 2598 */ 2599static const char *alc_slave_vols[] = { 2600 "Front Playback Volume", 2601 "Surround Playback Volume", 2602 "Center Playback Volume", 2603 "LFE Playback Volume", 2604 "Side Playback Volume", 2605 "Headphone Playback Volume", 2606 "Speaker Playback Volume", 2607 "Mono Playback Volume", 2608 "Line-Out Playback Volume", 2609 "PCM Playback Volume", 2610 NULL, 2611}; 2612 2613static const char *alc_slave_sws[] = { 2614 "Front Playback Switch", 2615 "Surround Playback Switch", 2616 "Center Playback Switch", 2617 "LFE Playback Switch", 2618 "Side Playback Switch", 2619 "Headphone Playback Switch", 2620 "Speaker Playback Switch", 2621 "Mono Playback Switch", 2622 "IEC958 Playback Switch", 2623 "Line-Out Playback Switch", 2624 "PCM Playback Switch", 2625 NULL, 2626}; 2627 2628/* 2629 * build control elements 2630 */ 2631 2632#define NID_MAPPING (-1) 2633 2634#define SUBDEV_SPEAKER_ (0 << 6) 2635#define SUBDEV_HP_ (1 << 6) 2636#define SUBDEV_LINE_ (2 << 6) 2637#define SUBDEV_SPEAKER(x) (SUBDEV_SPEAKER_ | ((x) & 0x3f)) 2638#define SUBDEV_HP(x) (SUBDEV_HP_ | ((x) & 0x3f)) 2639#define SUBDEV_LINE(x) (SUBDEV_LINE_ | ((x) & 0x3f)) 2640 2641static void alc_free_kctls(struct hda_codec *codec); 2642 2643#ifdef CONFIG_SND_HDA_INPUT_BEEP 2644/* additional beep mixers; the actual parameters are overwritten at build */ 2645static struct snd_kcontrol_new alc_beep_mixer[] = { 2646 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT), 2647 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT), 2648 { } /* end */ 2649}; 2650#endif 2651 2652static int alc_build_controls(struct hda_codec *codec) 2653{ 2654 struct alc_spec *spec = codec->spec; 2655 struct snd_kcontrol *kctl = NULL; 2656 struct snd_kcontrol_new *knew; 2657 int i, j, err; 2658 unsigned int u; 2659 hda_nid_t nid; 2660 2661 for (i = 0; i < spec->num_mixers; i++) { 2662 err = snd_hda_add_new_ctls(codec, spec->mixers[i]); 2663 if (err < 0) 2664 return err; 2665 } 2666 if (spec->cap_mixer) { 2667 err = snd_hda_add_new_ctls(codec, spec->cap_mixer); 2668 if (err < 0) 2669 return err; 2670 } 2671 if (spec->multiout.dig_out_nid) { 2672 err = snd_hda_create_spdif_out_ctls(codec, 2673 spec->multiout.dig_out_nid); 2674 if (err < 0) 2675 return err; 2676 if (!spec->no_analog) { 2677 err = snd_hda_create_spdif_share_sw(codec, 2678 &spec->multiout); 2679 if (err < 0) 2680 return err; 2681 spec->multiout.share_spdif = 1; 2682 } 2683 } 2684 if (spec->dig_in_nid) { 2685 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid); 2686 if (err < 0) 2687 return err; 2688 } 2689 2690#ifdef CONFIG_SND_HDA_INPUT_BEEP 2691 /* create beep controls if needed */ 2692 if (spec->beep_amp) { 2693 struct snd_kcontrol_new *knew; 2694 for (knew = alc_beep_mixer; knew->name; knew++) { 2695 struct snd_kcontrol *kctl; 2696 kctl = snd_ctl_new1(knew, codec); 2697 if (!kctl) 2698 return -ENOMEM; 2699 kctl->private_value = spec->beep_amp; 2700 err = snd_hda_ctl_add(codec, 0, kctl); 2701 if (err < 0) 2702 return err; 2703 } 2704 } 2705#endif 2706 2707 /* if we have no master control, let's create it */ 2708 if (!spec->no_analog && 2709 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) { 2710 unsigned int vmaster_tlv[4]; 2711 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid, 2712 HDA_OUTPUT, vmaster_tlv); 2713 err = snd_hda_add_vmaster(codec, "Master Playback Volume", 2714 vmaster_tlv, alc_slave_vols); 2715 if (err < 0) 2716 return err; 2717 } 2718 if (!spec->no_analog && 2719 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) { 2720 err = snd_hda_add_vmaster(codec, "Master Playback Switch", 2721 NULL, alc_slave_sws); 2722 if (err < 0) 2723 return err; 2724 } 2725 2726 /* assign Capture Source enums to NID */ 2727 if (spec->capsrc_nids || spec->adc_nids) { 2728 kctl = snd_hda_find_mixer_ctl(codec, "Capture Source"); 2729 if (!kctl) 2730 kctl = snd_hda_find_mixer_ctl(codec, "Input Source"); 2731 for (i = 0; kctl && i < kctl->count; i++) { 2732 hda_nid_t *nids = spec->capsrc_nids; 2733 if (!nids) 2734 nids = spec->adc_nids; 2735 err = snd_hda_add_nid(codec, kctl, i, nids[i]); 2736 if (err < 0) 2737 return err; 2738 } 2739 } 2740 if (spec->cap_mixer) { 2741 const char *kname = kctl ? kctl->id.name : NULL; 2742 for (knew = spec->cap_mixer; knew->name; knew++) { 2743 if (kname && strcmp(knew->name, kname) == 0) 2744 continue; 2745 kctl = snd_hda_find_mixer_ctl(codec, knew->name); 2746 for (i = 0; kctl && i < kctl->count; i++) { 2747 err = snd_hda_add_nid(codec, kctl, i, 2748 spec->adc_nids[i]); 2749 if (err < 0) 2750 return err; 2751 } 2752 } 2753 } 2754 2755 /* other nid->control mapping */ 2756 for (i = 0; i < spec->num_mixers; i++) { 2757 for (knew = spec->mixers[i]; knew->name; knew++) { 2758 if (knew->iface != NID_MAPPING) 2759 continue; 2760 kctl = snd_hda_find_mixer_ctl(codec, knew->name); 2761 if (kctl == NULL) 2762 continue; 2763 u = knew->subdevice; 2764 for (j = 0; j < 4; j++, u >>= 8) { 2765 nid = u & 0x3f; 2766 if (nid == 0) 2767 continue; 2768 switch (u & 0xc0) { 2769 case SUBDEV_SPEAKER_: 2770 nid = spec->autocfg.speaker_pins[nid]; 2771 break; 2772 case SUBDEV_LINE_: 2773 nid = spec->autocfg.line_out_pins[nid]; 2774 break; 2775 case SUBDEV_HP_: 2776 nid = spec->autocfg.hp_pins[nid]; 2777 break; 2778 default: 2779 continue; 2780 } 2781 err = snd_hda_add_nid(codec, kctl, 0, nid); 2782 if (err < 0) 2783 return err; 2784 } 2785 u = knew->private_value; 2786 for (j = 0; j < 4; j++, u >>= 8) { 2787 nid = u & 0xff; 2788 if (nid == 0) 2789 continue; 2790 err = snd_hda_add_nid(codec, kctl, 0, nid); 2791 if (err < 0) 2792 return err; 2793 } 2794 } 2795 } 2796 2797 alc_free_kctls(codec); /* no longer needed */ 2798 2799 return 0; 2800} 2801 2802 2803/* 2804 * initialize the codec volumes, etc 2805 */ 2806 2807/* 2808 * generic initialization of ADC, input mixers and output mixers 2809 */ 2810static struct hda_verb alc880_volume_init_verbs[] = { 2811 /* 2812 * Unmute ADC0-2 and set the default input to mic-in 2813 */ 2814 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 2815 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 2816 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 2817 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 2818 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 2819 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 2820 2821 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 2822 * mixer widget 2823 * Note: PASD motherboards uses the Line In 2 as the input for front 2824 * panel mic (mic 2) 2825 */ 2826 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 2827 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 2828 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 2829 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 2830 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 2831 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 2832 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, 2833 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, 2834 2835 /* 2836 * Set up output mixers (0x0c - 0x0f) 2837 */ 2838 /* set vol=0 to output mixers */ 2839 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 2840 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 2841 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 2842 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 2843 /* set up input amps for analog loopback */ 2844 /* Amp Indices: DAC = 0, mixer = 1 */ 2845 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 2846 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 2847 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 2848 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 2849 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 2850 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 2851 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 2852 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 2853 2854 { } 2855}; 2856 2857/* 2858 * 3-stack pin configuration: 2859 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b 2860 */ 2861static struct hda_verb alc880_pin_3stack_init_verbs[] = { 2862 /* 2863 * preset connection lists of input pins 2864 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround 2865 */ 2866 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ 2867 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 2868 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */ 2869 2870 /* 2871 * Set pin mode and muting 2872 */ 2873 /* set front pin widgets 0x14 for output */ 2874 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2875 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2876 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 2877 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2878 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2879 /* Mic2 (as headphone out) for HP output */ 2880 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 2881 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2882 /* Line In pin widget for input */ 2883 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2884 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2885 /* Line2 (as front mic) pin widget for input and vref at 80% */ 2886 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2887 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2888 /* CD pin widget for input */ 2889 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2890 2891 { } 2892}; 2893 2894/* 2895 * 5-stack pin configuration: 2896 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19, 2897 * line-in/side = 0x1a, f-mic = 0x1b 2898 */ 2899static struct hda_verb alc880_pin_5stack_init_verbs[] = { 2900 /* 2901 * preset connection lists of input pins 2902 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround 2903 */ 2904 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 2905 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */ 2906 2907 /* 2908 * Set pin mode and muting 2909 */ 2910 /* set pin widgets 0x14-0x17 for output */ 2911 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2912 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2913 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2914 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2915 /* unmute pins for output (no gain on this amp) */ 2916 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2917 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2918 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2919 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2920 2921 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 2922 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2923 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2924 /* Mic2 (as headphone out) for HP output */ 2925 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 2926 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2927 /* Line In pin widget for input */ 2928 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2929 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2930 /* Line2 (as front mic) pin widget for input and vref at 80% */ 2931 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2932 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2933 /* CD pin widget for input */ 2934 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2935 2936 { } 2937}; 2938 2939/* 2940 * W810 pin configuration: 2941 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b 2942 */ 2943static struct hda_verb alc880_pin_w810_init_verbs[] = { 2944 /* hphone/speaker input selector: front DAC */ 2945 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0}, 2946 2947 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2948 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2949 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2950 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2951 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2952 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2953 2954 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 2955 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2956 2957 { } 2958}; 2959 2960/* 2961 * Z71V pin configuration: 2962 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?) 2963 */ 2964static struct hda_verb alc880_pin_z71v_init_verbs[] = { 2965 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2966 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2967 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 2968 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2969 2970 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2971 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2972 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2973 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2974 2975 { } 2976}; 2977 2978/* 2979 * 6-stack pin configuration: 2980 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18, 2981 * f-mic = 0x19, line = 0x1a, HP = 0x1b 2982 */ 2983static struct hda_verb alc880_pin_6stack_init_verbs[] = { 2984 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 2985 2986 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2987 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2988 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2989 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2990 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2991 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2992 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2993 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2994 2995 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2996 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2997 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2998 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2999 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3000 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3001 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3002 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3003 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3004 3005 { } 3006}; 3007 3008/* 3009 * Uniwill pin configuration: 3010 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19, 3011 * line = 0x1a 3012 */ 3013static struct hda_verb alc880_uniwill_init_verbs[] = { 3014 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 3015 3016 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3017 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3018 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3019 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3020 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3021 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3022 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3023 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3024 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 3025 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 3026 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 3027 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 3028 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 3029 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 3030 3031 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3032 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3033 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3034 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3035 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3036 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3037 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */ 3038 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */ 3039 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3040 3041 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 3042 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 3043 3044 { } 3045}; 3046 3047/* 3048* Uniwill P53 3049* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19, 3050 */ 3051static struct hda_verb alc880_uniwill_p53_init_verbs[] = { 3052 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 3053 3054 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3055 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3056 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3057 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3058 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3059 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3060 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 3061 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 3062 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 3063 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 3064 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 3065 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 3066 3067 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3068 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3069 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3070 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3071 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3072 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3073 3074 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 3075 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT}, 3076 3077 { } 3078}; 3079 3080static struct hda_verb alc880_beep_init_verbs[] = { 3081 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) }, 3082 { } 3083}; 3084 3085/* auto-toggle front mic */ 3086static void alc880_uniwill_mic_automute(struct hda_codec *codec) 3087{ 3088 unsigned int present; 3089 unsigned char bits; 3090 3091 present = snd_hda_jack_detect(codec, 0x18); 3092 bits = present ? HDA_AMP_MUTE : 0; 3093 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits); 3094} 3095 3096static void alc880_uniwill_setup(struct hda_codec *codec) 3097{ 3098 struct alc_spec *spec = codec->spec; 3099 3100 spec->autocfg.hp_pins[0] = 0x14; 3101 spec->autocfg.speaker_pins[0] = 0x15; 3102 spec->autocfg.speaker_pins[0] = 0x16; 3103} 3104 3105static void alc880_uniwill_init_hook(struct hda_codec *codec) 3106{ 3107 alc_automute_amp(codec); 3108 alc880_uniwill_mic_automute(codec); 3109} 3110 3111static void alc880_uniwill_unsol_event(struct hda_codec *codec, 3112 unsigned int res) 3113{ 3114 /* Looks like the unsol event is incompatible with the standard 3115 * definition. 4bit tag is placed at 28 bit! 3116 */ 3117 switch (res >> 28) { 3118 case ALC880_MIC_EVENT: 3119 alc880_uniwill_mic_automute(codec); 3120 break; 3121 default: 3122 alc_automute_amp_unsol_event(codec, res); 3123 break; 3124 } 3125} 3126 3127static void alc880_uniwill_p53_setup(struct hda_codec *codec) 3128{ 3129 struct alc_spec *spec = codec->spec; 3130 3131 spec->autocfg.hp_pins[0] = 0x14; 3132 spec->autocfg.speaker_pins[0] = 0x15; 3133} 3134 3135static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec) 3136{ 3137 unsigned int present; 3138 3139 present = snd_hda_codec_read(codec, 0x21, 0, 3140 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0); 3141 present &= HDA_AMP_VOLMASK; 3142 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0, 3143 HDA_AMP_VOLMASK, present); 3144 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0, 3145 HDA_AMP_VOLMASK, present); 3146} 3147 3148static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec, 3149 unsigned int res) 3150{ 3151 /* Looks like the unsol event is incompatible with the standard 3152 * definition. 4bit tag is placed at 28 bit! 3153 */ 3154 if ((res >> 28) == ALC880_DCVOL_EVENT) 3155 alc880_uniwill_p53_dcvol_automute(codec); 3156 else 3157 alc_automute_amp_unsol_event(codec, res); 3158} 3159 3160/* 3161 * F1734 pin configuration: 3162 * HP = 0x14, speaker-out = 0x15, mic = 0x18 3163 */ 3164static struct hda_verb alc880_pin_f1734_init_verbs[] = { 3165 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01}, 3166 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, 3167 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, 3168 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, 3169 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, 3170 3171 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3172 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3173 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3174 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3175 3176 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3177 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3178 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, 3179 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3180 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3181 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3182 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3183 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3184 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3185 3186 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT}, 3187 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT}, 3188 3189 { } 3190}; 3191 3192/* 3193 * ASUS pin configuration: 3194 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a 3195 */ 3196static struct hda_verb alc880_pin_asus_init_verbs[] = { 3197 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, 3198 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, 3199 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, 3200 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, 3201 3202 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3203 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3204 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3205 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3206 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3207 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3208 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3209 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3210 3211 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3212 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3213 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3214 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3215 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3216 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3217 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3218 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3219 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3220 3221 { } 3222}; 3223 3224/* Enable GPIO mask and set output */ 3225#define alc880_gpio1_init_verbs alc_gpio1_init_verbs 3226#define alc880_gpio2_init_verbs alc_gpio2_init_verbs 3227#define alc880_gpio3_init_verbs alc_gpio3_init_verbs 3228 3229/* Clevo m520g init */ 3230static struct hda_verb alc880_pin_clevo_init_verbs[] = { 3231 /* headphone output */ 3232 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01}, 3233 /* line-out */ 3234 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3235 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3236 /* Line-in */ 3237 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3238 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3239 /* CD */ 3240 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3241 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3242 /* Mic1 (rear panel) */ 3243 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3244 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3245 /* Mic2 (front panel) */ 3246 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3247 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3248 /* headphone */ 3249 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3250 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3251 /* change to EAPD mode */ 3252 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 3253 {0x20, AC_VERB_SET_PROC_COEF, 0x3060}, 3254 3255 { } 3256}; 3257 3258static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = { 3259 /* change to EAPD mode */ 3260 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 3261 {0x20, AC_VERB_SET_PROC_COEF, 0x3060}, 3262 3263 /* Headphone output */ 3264 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3265 /* Front output*/ 3266 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3267 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 3268 3269 /* Line In pin widget for input */ 3270 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3271 /* CD pin widget for input */ 3272 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3273 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 3274 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3275 3276 /* change to EAPD mode */ 3277 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 3278 {0x20, AC_VERB_SET_PROC_COEF, 0x3070}, 3279 3280 { } 3281}; 3282 3283/* 3284 * LG m1 express dual 3285 * 3286 * Pin assignment: 3287 * Rear Line-In/Out (blue): 0x14 3288 * Build-in Mic-In: 0x15 3289 * Speaker-out: 0x17 3290 * HP-Out (green): 0x1b 3291 * Mic-In/Out (red): 0x19 3292 * SPDIF-Out: 0x1e 3293 */ 3294 3295/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */ 3296static hda_nid_t alc880_lg_dac_nids[3] = { 3297 0x05, 0x02, 0x03 3298}; 3299 3300/* seems analog CD is not working */ 3301static struct hda_input_mux alc880_lg_capture_source = { 3302 .num_items = 3, 3303 .items = { 3304 { "Mic", 0x1 }, 3305 { "Line", 0x5 }, 3306 { "Internal Mic", 0x6 }, 3307 }, 3308}; 3309 3310/* 2,4,6 channel modes */ 3311static struct hda_verb alc880_lg_ch2_init[] = { 3312 /* set line-in and mic-in to input */ 3313 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 3314 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 3315 { } 3316}; 3317 3318static struct hda_verb alc880_lg_ch4_init[] = { 3319 /* set line-in to out and mic-in to input */ 3320 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, 3321 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 3322 { } 3323}; 3324 3325static struct hda_verb alc880_lg_ch6_init[] = { 3326 /* set line-in and mic-in to output */ 3327 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, 3328 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, 3329 { } 3330}; 3331 3332static struct hda_channel_mode alc880_lg_ch_modes[3] = { 3333 { 2, alc880_lg_ch2_init }, 3334 { 4, alc880_lg_ch4_init }, 3335 { 6, alc880_lg_ch6_init }, 3336}; 3337 3338static struct snd_kcontrol_new alc880_lg_mixer[] = { 3339 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 3340 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT), 3341 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 3342 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT), 3343 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT), 3344 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT), 3345 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT), 3346 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT), 3347 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 3348 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 3349 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT), 3350 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT), 3351 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT), 3352 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT), 3353 { 3354 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 3355 .name = "Channel Mode", 3356 .info = alc_ch_mode_info, 3357 .get = alc_ch_mode_get, 3358 .put = alc_ch_mode_put, 3359 }, 3360 { } /* end */ 3361}; 3362 3363static struct hda_verb alc880_lg_init_verbs[] = { 3364 /* set capture source to mic-in */ 3365 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 3366 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 3367 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 3368 /* mute all amp mixer inputs */ 3369 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)}, 3370 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, 3371 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, 3372 /* line-in to input */ 3373 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3374 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3375 /* built-in mic */ 3376 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3377 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3378 /* speaker-out */ 3379 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3380 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3381 /* mic-in to input */ 3382 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01}, 3383 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3384 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3385 /* HP-out */ 3386 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03}, 3387 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3388 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3389 /* jack sense */ 3390 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 3391 { } 3392}; 3393 3394/* toggle speaker-output according to the hp-jack state */ 3395static void alc880_lg_setup(struct hda_codec *codec) 3396{ 3397 struct alc_spec *spec = codec->spec; 3398 3399 spec->autocfg.hp_pins[0] = 0x1b; 3400 spec->autocfg.speaker_pins[0] = 0x17; 3401} 3402 3403/* 3404 * LG LW20 3405 * 3406 * Pin assignment: 3407 * Speaker-out: 0x14 3408 * Mic-In: 0x18 3409 * Built-in Mic-In: 0x19 3410 * Line-In: 0x1b 3411 * HP-Out: 0x1a 3412 * SPDIF-Out: 0x1e 3413 */ 3414 3415static struct hda_input_mux alc880_lg_lw_capture_source = { 3416 .num_items = 3, 3417 .items = { 3418 { "Mic", 0x0 }, 3419 { "Internal Mic", 0x1 }, 3420 { "Line In", 0x2 }, 3421 }, 3422}; 3423 3424#define alc880_lg_lw_modes alc880_threestack_modes 3425 3426static struct snd_kcontrol_new alc880_lg_lw_mixer[] = { 3427 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 3428 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 3429 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 3430 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT), 3431 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 3432 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 3433 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 3434 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 3435 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 3436 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 3437 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 3438 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 3439 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 3440 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 3441 { 3442 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 3443 .name = "Channel Mode", 3444 .info = alc_ch_mode_info, 3445 .get = alc_ch_mode_get, 3446 .put = alc_ch_mode_put, 3447 }, 3448 { } /* end */ 3449}; 3450 3451static struct hda_verb alc880_lg_lw_init_verbs[] = { 3452 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 3453 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ 3454 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */ 3455 3456 /* set capture source to mic-in */ 3457 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3458 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3459 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3460 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, 3461 /* speaker-out */ 3462 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3463 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3464 /* HP-out */ 3465 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3466 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3467 /* mic-in to input */ 3468 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3469 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3470 /* built-in mic */ 3471 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3472 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3473 /* jack sense */ 3474 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 3475 { } 3476}; 3477 3478/* toggle speaker-output according to the hp-jack state */ 3479static void alc880_lg_lw_setup(struct hda_codec *codec) 3480{ 3481 struct alc_spec *spec = codec->spec; 3482 3483 spec->autocfg.hp_pins[0] = 0x1b; 3484 spec->autocfg.speaker_pins[0] = 0x14; 3485} 3486 3487static struct snd_kcontrol_new alc880_medion_rim_mixer[] = { 3488 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 3489 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT), 3490 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 3491 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 3492 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 3493 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT), 3494 { } /* end */ 3495}; 3496 3497static struct hda_input_mux alc880_medion_rim_capture_source = { 3498 .num_items = 2, 3499 .items = { 3500 { "Mic", 0x0 }, 3501 { "Internal Mic", 0x1 }, 3502 }, 3503}; 3504 3505static struct hda_verb alc880_medion_rim_init_verbs[] = { 3506 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 3507 3508 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3509 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3510 3511 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 3512 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3513 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3514 /* Mic2 (as headphone out) for HP output */ 3515 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3516 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3517 /* Internal Speaker */ 3518 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3519 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3520 3521 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 3522 {0x20, AC_VERB_SET_PROC_COEF, 0x3060}, 3523 3524 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 3525 { } 3526}; 3527 3528/* toggle speaker-output according to the hp-jack state */ 3529static void alc880_medion_rim_automute(struct hda_codec *codec) 3530{ 3531 struct alc_spec *spec = codec->spec; 3532 alc_automute_amp(codec); 3533 /* toggle EAPD */ 3534 if (spec->jack_present) 3535 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0); 3536 else 3537 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2); 3538} 3539 3540static void alc880_medion_rim_unsol_event(struct hda_codec *codec, 3541 unsigned int res) 3542{ 3543 /* Looks like the unsol event is incompatible with the standard 3544 * definition. 4bit tag is placed at 28 bit! 3545 */ 3546 if ((res >> 28) == ALC880_HP_EVENT) 3547 alc880_medion_rim_automute(codec); 3548} 3549 3550static void alc880_medion_rim_setup(struct hda_codec *codec) 3551{ 3552 struct alc_spec *spec = codec->spec; 3553 3554 spec->autocfg.hp_pins[0] = 0x14; 3555 spec->autocfg.speaker_pins[0] = 0x1b; 3556} 3557 3558#ifdef CONFIG_SND_HDA_POWER_SAVE 3559static struct hda_amp_list alc880_loopbacks[] = { 3560 { 0x0b, HDA_INPUT, 0 }, 3561 { 0x0b, HDA_INPUT, 1 }, 3562 { 0x0b, HDA_INPUT, 2 }, 3563 { 0x0b, HDA_INPUT, 3 }, 3564 { 0x0b, HDA_INPUT, 4 }, 3565 { } /* end */ 3566}; 3567 3568static struct hda_amp_list alc880_lg_loopbacks[] = { 3569 { 0x0b, HDA_INPUT, 1 }, 3570 { 0x0b, HDA_INPUT, 6 }, 3571 { 0x0b, HDA_INPUT, 7 }, 3572 { } /* end */ 3573}; 3574#endif 3575 3576/* 3577 * Common callbacks 3578 */ 3579 3580static int alc_init(struct hda_codec *codec) 3581{ 3582 struct alc_spec *spec = codec->spec; 3583 unsigned int i; 3584 3585 alc_fix_pll(codec); 3586 alc_auto_init_amp(codec, spec->init_amp); 3587 3588 for (i = 0; i < spec->num_init_verbs; i++) 3589 snd_hda_sequence_write(codec, spec->init_verbs[i]); 3590 3591 if (spec->init_hook) 3592 spec->init_hook(codec); 3593 3594#ifdef CONFIG_SND_HDA_POWER_SAVE 3595 if (codec->patch_ops.check_power_status) 3596 codec->patch_ops.check_power_status(codec, 0x01); 3597#endif 3598 return 0; 3599} 3600 3601static void alc_unsol_event(struct hda_codec *codec, unsigned int res) 3602{ 3603 struct alc_spec *spec = codec->spec; 3604 3605 if (spec->unsol_event) 3606 spec->unsol_event(codec, res); 3607} 3608 3609#ifdef CONFIG_SND_HDA_POWER_SAVE 3610static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid) 3611{ 3612 struct alc_spec *spec = codec->spec; 3613 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid); 3614} 3615#endif 3616 3617/* 3618 * Analog playback callbacks 3619 */ 3620static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo, 3621 struct hda_codec *codec, 3622 struct snd_pcm_substream *substream) 3623{ 3624 struct alc_spec *spec = codec->spec; 3625 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream, 3626 hinfo); 3627} 3628 3629static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo, 3630 struct hda_codec *codec, 3631 unsigned int stream_tag, 3632 unsigned int format, 3633 struct snd_pcm_substream *substream) 3634{ 3635 struct alc_spec *spec = codec->spec; 3636 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, 3637 stream_tag, format, substream); 3638} 3639 3640static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, 3641 struct hda_codec *codec, 3642 struct snd_pcm_substream *substream) 3643{ 3644 struct alc_spec *spec = codec->spec; 3645 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); 3646} 3647 3648/* 3649 * Digital out 3650 */ 3651static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo, 3652 struct hda_codec *codec, 3653 struct snd_pcm_substream *substream) 3654{ 3655 struct alc_spec *spec = codec->spec; 3656 return snd_hda_multi_out_dig_open(codec, &spec->multiout); 3657} 3658 3659static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, 3660 struct hda_codec *codec, 3661 unsigned int stream_tag, 3662 unsigned int format, 3663 struct snd_pcm_substream *substream) 3664{ 3665 struct alc_spec *spec = codec->spec; 3666 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, 3667 stream_tag, format, substream); 3668} 3669 3670static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, 3671 struct hda_codec *codec, 3672 struct snd_pcm_substream *substream) 3673{ 3674 struct alc_spec *spec = codec->spec; 3675 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout); 3676} 3677 3678static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, 3679 struct hda_codec *codec, 3680 struct snd_pcm_substream *substream) 3681{ 3682 struct alc_spec *spec = codec->spec; 3683 return snd_hda_multi_out_dig_close(codec, &spec->multiout); 3684} 3685 3686/* 3687 * Analog capture 3688 */ 3689static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo, 3690 struct hda_codec *codec, 3691 unsigned int stream_tag, 3692 unsigned int format, 3693 struct snd_pcm_substream *substream) 3694{ 3695 struct alc_spec *spec = codec->spec; 3696 3697 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1], 3698 stream_tag, 0, format); 3699 return 0; 3700} 3701 3702static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, 3703 struct hda_codec *codec, 3704 struct snd_pcm_substream *substream) 3705{ 3706 struct alc_spec *spec = codec->spec; 3707 3708 snd_hda_codec_cleanup_stream(codec, 3709 spec->adc_nids[substream->number + 1]); 3710 return 0; 3711} 3712 3713/* analog capture with dynamic dual-adc changes */ 3714static int dualmic_capture_pcm_prepare(struct hda_pcm_stream *hinfo, 3715 struct hda_codec *codec, 3716 unsigned int stream_tag, 3717 unsigned int format, 3718 struct snd_pcm_substream *substream) 3719{ 3720 struct alc_spec *spec = codec->spec; 3721 spec->cur_adc = spec->adc_nids[spec->cur_adc_idx]; 3722 spec->cur_adc_stream_tag = stream_tag; 3723 spec->cur_adc_format = format; 3724 snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format); 3725 return 0; 3726} 3727 3728static int dualmic_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, 3729 struct hda_codec *codec, 3730 struct snd_pcm_substream *substream) 3731{ 3732 struct alc_spec *spec = codec->spec; 3733 snd_hda_codec_cleanup_stream(codec, spec->cur_adc); 3734 spec->cur_adc = 0; 3735 return 0; 3736} 3737 3738static struct hda_pcm_stream dualmic_pcm_analog_capture = { 3739 .substreams = 1, 3740 .channels_min = 2, 3741 .channels_max = 2, 3742 .nid = 0, /* fill later */ 3743 .ops = { 3744 .prepare = dualmic_capture_pcm_prepare, 3745 .cleanup = dualmic_capture_pcm_cleanup 3746 }, 3747}; 3748 3749/* 3750 */ 3751static struct hda_pcm_stream alc880_pcm_analog_playback = { 3752 .substreams = 1, 3753 .channels_min = 2, 3754 .channels_max = 8, 3755 /* NID is set in alc_build_pcms */ 3756 .ops = { 3757 .open = alc880_playback_pcm_open, 3758 .prepare = alc880_playback_pcm_prepare, 3759 .cleanup = alc880_playback_pcm_cleanup 3760 }, 3761}; 3762 3763static struct hda_pcm_stream alc880_pcm_analog_capture = { 3764 .substreams = 1, 3765 .channels_min = 2, 3766 .channels_max = 2, 3767 /* NID is set in alc_build_pcms */ 3768}; 3769 3770static struct hda_pcm_stream alc880_pcm_analog_alt_playback = { 3771 .substreams = 1, 3772 .channels_min = 2, 3773 .channels_max = 2, 3774 /* NID is set in alc_build_pcms */ 3775}; 3776 3777static struct hda_pcm_stream alc880_pcm_analog_alt_capture = { 3778 .substreams = 2, /* can be overridden */ 3779 .channels_min = 2, 3780 .channels_max = 2, 3781 /* NID is set in alc_build_pcms */ 3782 .ops = { 3783 .prepare = alc880_alt_capture_pcm_prepare, 3784 .cleanup = alc880_alt_capture_pcm_cleanup 3785 }, 3786}; 3787 3788static struct hda_pcm_stream alc880_pcm_digital_playback = { 3789 .substreams = 1, 3790 .channels_min = 2, 3791 .channels_max = 2, 3792 /* NID is set in alc_build_pcms */ 3793 .ops = { 3794 .open = alc880_dig_playback_pcm_open, 3795 .close = alc880_dig_playback_pcm_close, 3796 .prepare = alc880_dig_playback_pcm_prepare, 3797 .cleanup = alc880_dig_playback_pcm_cleanup 3798 }, 3799}; 3800 3801static struct hda_pcm_stream alc880_pcm_digital_capture = { 3802 .substreams = 1, 3803 .channels_min = 2, 3804 .channels_max = 2, 3805 /* NID is set in alc_build_pcms */ 3806}; 3807 3808/* Used by alc_build_pcms to flag that a PCM has no playback stream */ 3809static struct hda_pcm_stream alc_pcm_null_stream = { 3810 .substreams = 0, 3811 .channels_min = 0, 3812 .channels_max = 0, 3813}; 3814 3815static int alc_build_pcms(struct hda_codec *codec) 3816{ 3817 struct alc_spec *spec = codec->spec; 3818 struct hda_pcm *info = spec->pcm_rec; 3819 int i; 3820 3821 codec->num_pcms = 1; 3822 codec->pcm_info = info; 3823 3824 if (spec->no_analog) 3825 goto skip_analog; 3826 3827 snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog), 3828 "%s Analog", codec->chip_name); 3829 info->name = spec->stream_name_analog; 3830 3831 if (spec->stream_analog_playback) { 3832 if (snd_BUG_ON(!spec->multiout.dac_nids)) 3833 return -EINVAL; 3834 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback); 3835 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0]; 3836 } 3837 if (spec->stream_analog_capture) { 3838 if (snd_BUG_ON(!spec->adc_nids)) 3839 return -EINVAL; 3840 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture); 3841 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0]; 3842 } 3843 3844 if (spec->channel_mode) { 3845 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0; 3846 for (i = 0; i < spec->num_channel_mode; i++) { 3847 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) { 3848 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels; 3849 } 3850 } 3851 } 3852 3853 skip_analog: 3854 /* SPDIF for stream index #1 */ 3855 if (spec->multiout.dig_out_nid || spec->dig_in_nid) { 3856 snprintf(spec->stream_name_digital, 3857 sizeof(spec->stream_name_digital), 3858 "%s Digital", codec->chip_name); 3859 codec->num_pcms = 2; 3860 codec->slave_dig_outs = spec->multiout.slave_dig_outs; 3861 info = spec->pcm_rec + 1; 3862 info->name = spec->stream_name_digital; 3863 if (spec->dig_out_type) 3864 info->pcm_type = spec->dig_out_type; 3865 else 3866 info->pcm_type = HDA_PCM_TYPE_SPDIF; 3867 if (spec->multiout.dig_out_nid && 3868 spec->stream_digital_playback) { 3869 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback); 3870 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid; 3871 } 3872 if (spec->dig_in_nid && 3873 spec->stream_digital_capture) { 3874 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture); 3875 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid; 3876 } 3877 /* FIXME: do we need this for all Realtek codec models? */ 3878 codec->spdif_status_reset = 1; 3879 } 3880 3881 if (spec->no_analog) 3882 return 0; 3883 3884 /* If the use of more than one ADC is requested for the current 3885 * model, configure a second analog capture-only PCM. 3886 */ 3887 /* Additional Analaog capture for index #2 */ 3888 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) || 3889 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) { 3890 codec->num_pcms = 3; 3891 info = spec->pcm_rec + 2; 3892 info->name = spec->stream_name_analog; 3893 if (spec->alt_dac_nid) { 3894 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = 3895 *spec->stream_analog_alt_playback; 3896 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 3897 spec->alt_dac_nid; 3898 } else { 3899 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = 3900 alc_pcm_null_stream; 3901 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0; 3902 } 3903 if (spec->num_adc_nids > 1) { 3904 info->stream[SNDRV_PCM_STREAM_CAPTURE] = 3905 *spec->stream_analog_alt_capture; 3906 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 3907 spec->adc_nids[1]; 3908 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = 3909 spec->num_adc_nids - 1; 3910 } else { 3911 info->stream[SNDRV_PCM_STREAM_CAPTURE] = 3912 alc_pcm_null_stream; 3913 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0; 3914 } 3915 } 3916 3917 return 0; 3918} 3919 3920static inline void alc_shutup(struct hda_codec *codec) 3921{ 3922 snd_hda_shutup_pins(codec); 3923} 3924 3925static void alc_free_kctls(struct hda_codec *codec) 3926{ 3927 struct alc_spec *spec = codec->spec; 3928 3929 if (spec->kctls.list) { 3930 struct snd_kcontrol_new *kctl = spec->kctls.list; 3931 int i; 3932 for (i = 0; i < spec->kctls.used; i++) 3933 kfree(kctl[i].name); 3934 } 3935 snd_array_free(&spec->kctls); 3936} 3937 3938static void alc_free(struct hda_codec *codec) 3939{ 3940 struct alc_spec *spec = codec->spec; 3941 3942 if (!spec) 3943 return; 3944 3945 alc_shutup(codec); 3946 alc_free_kctls(codec); 3947 kfree(spec); 3948 snd_hda_detach_beep_device(codec); 3949} 3950 3951#ifdef CONFIG_SND_HDA_POWER_SAVE 3952static void alc_power_eapd(struct hda_codec *codec) 3953{ 3954 /* We currently only handle front, HP */ 3955 switch (codec->vendor_id) { 3956 case 0x10ec0260: 3957 set_eapd(codec, 0x0f, 0); 3958 set_eapd(codec, 0x10, 0); 3959 break; 3960 case 0x10ec0262: 3961 case 0x10ec0267: 3962 case 0x10ec0268: 3963 case 0x10ec0269: 3964 case 0x10ec0270: 3965 case 0x10ec0272: 3966 case 0x10ec0660: 3967 case 0x10ec0662: 3968 case 0x10ec0663: 3969 case 0x10ec0862: 3970 case 0x10ec0889: 3971 set_eapd(codec, 0x14, 0); 3972 set_eapd(codec, 0x15, 0); 3973 break; 3974 } 3975} 3976 3977static int alc_suspend(struct hda_codec *codec, pm_message_t state) 3978{ 3979 struct alc_spec *spec = codec->spec; 3980 alc_shutup(codec); 3981 if (spec && spec->power_hook) 3982 spec->power_hook(codec); 3983 return 0; 3984} 3985#endif 3986 3987#ifdef SND_HDA_NEEDS_RESUME 3988static int alc_resume(struct hda_codec *codec) 3989{ 3990 codec->patch_ops.init(codec); 3991 snd_hda_codec_resume_amp(codec); 3992 snd_hda_codec_resume_cache(codec); 3993#ifdef CONFIG_SND_HDA_POWER_SAVE 3994 if (codec->patch_ops.check_power_status) 3995 codec->patch_ops.check_power_status(codec, 0x01); 3996#endif 3997 return 0; 3998} 3999#endif 4000 4001/* 4002 */ 4003static struct hda_codec_ops alc_patch_ops = { 4004 .build_controls = alc_build_controls, 4005 .build_pcms = alc_build_pcms, 4006 .init = alc_init, 4007 .free = alc_free, 4008 .unsol_event = alc_unsol_event, 4009#ifdef SND_HDA_NEEDS_RESUME 4010 .resume = alc_resume, 4011#endif 4012#ifdef CONFIG_SND_HDA_POWER_SAVE 4013 .suspend = alc_suspend, 4014 .check_power_status = alc_check_power_status, 4015#endif 4016 .reboot_notify = alc_shutup, 4017}; 4018 4019/* replace the codec chip_name with the given string */ 4020static int alc_codec_rename(struct hda_codec *codec, const char *name) 4021{ 4022 kfree(codec->chip_name); 4023 codec->chip_name = kstrdup(name, GFP_KERNEL); 4024 if (!codec->chip_name) { 4025 alc_free(codec); 4026 return -ENOMEM; 4027 } 4028 return 0; 4029} 4030 4031/* 4032 * Test configuration for debugging 4033 * 4034 * Almost all inputs/outputs are enabled. I/O pins can be configured via 4035 * enum controls. 4036 */ 4037#ifdef CONFIG_SND_DEBUG 4038static hda_nid_t alc880_test_dac_nids[4] = { 4039 0x02, 0x03, 0x04, 0x05 4040}; 4041 4042static struct hda_input_mux alc880_test_capture_source = { 4043 .num_items = 7, 4044 .items = { 4045 { "In-1", 0x0 }, 4046 { "In-2", 0x1 }, 4047 { "In-3", 0x2 }, 4048 { "In-4", 0x3 }, 4049 { "CD", 0x4 }, 4050 { "Front", 0x5 }, 4051 { "Surround", 0x6 }, 4052 }, 4053}; 4054 4055static struct hda_channel_mode alc880_test_modes[4] = { 4056 { 2, NULL }, 4057 { 4, NULL }, 4058 { 6, NULL }, 4059 { 8, NULL }, 4060}; 4061 4062static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol, 4063 struct snd_ctl_elem_info *uinfo) 4064{ 4065 static char *texts[] = { 4066 "N/A", "Line Out", "HP Out", 4067 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%" 4068 }; 4069 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 4070 uinfo->count = 1; 4071 uinfo->value.enumerated.items = 8; 4072 if (uinfo->value.enumerated.item >= 8) 4073 uinfo->value.enumerated.item = 7; 4074 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); 4075 return 0; 4076} 4077 4078static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol, 4079 struct snd_ctl_elem_value *ucontrol) 4080{ 4081 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 4082 hda_nid_t nid = (hda_nid_t)kcontrol->private_value; 4083 unsigned int pin_ctl, item = 0; 4084 4085 pin_ctl = snd_hda_codec_read(codec, nid, 0, 4086 AC_VERB_GET_PIN_WIDGET_CONTROL, 0); 4087 if (pin_ctl & AC_PINCTL_OUT_EN) { 4088 if (pin_ctl & AC_PINCTL_HP_EN) 4089 item = 2; 4090 else 4091 item = 1; 4092 } else if (pin_ctl & AC_PINCTL_IN_EN) { 4093 switch (pin_ctl & AC_PINCTL_VREFEN) { 4094 case AC_PINCTL_VREF_HIZ: item = 3; break; 4095 case AC_PINCTL_VREF_50: item = 4; break; 4096 case AC_PINCTL_VREF_GRD: item = 5; break; 4097 case AC_PINCTL_VREF_80: item = 6; break; 4098 case AC_PINCTL_VREF_100: item = 7; break; 4099 } 4100 } 4101 ucontrol->value.enumerated.item[0] = item; 4102 return 0; 4103} 4104 4105static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol, 4106 struct snd_ctl_elem_value *ucontrol) 4107{ 4108 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 4109 hda_nid_t nid = (hda_nid_t)kcontrol->private_value; 4110 static unsigned int ctls[] = { 4111 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN, 4112 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ, 4113 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50, 4114 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD, 4115 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80, 4116 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100, 4117 }; 4118 unsigned int old_ctl, new_ctl; 4119 4120 old_ctl = snd_hda_codec_read(codec, nid, 0, 4121 AC_VERB_GET_PIN_WIDGET_CONTROL, 0); 4122 new_ctl = ctls[ucontrol->value.enumerated.item[0]]; 4123 if (old_ctl != new_ctl) { 4124 int val; 4125 snd_hda_codec_write_cache(codec, nid, 0, 4126 AC_VERB_SET_PIN_WIDGET_CONTROL, 4127 new_ctl); 4128 val = ucontrol->value.enumerated.item[0] >= 3 ? 4129 HDA_AMP_MUTE : 0; 4130 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, 4131 HDA_AMP_MUTE, val); 4132 return 1; 4133 } 4134 return 0; 4135} 4136 4137static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol, 4138 struct snd_ctl_elem_info *uinfo) 4139{ 4140 static char *texts[] = { 4141 "Front", "Surround", "CLFE", "Side" 4142 }; 4143 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 4144 uinfo->count = 1; 4145 uinfo->value.enumerated.items = 4; 4146 if (uinfo->value.enumerated.item >= 4) 4147 uinfo->value.enumerated.item = 3; 4148 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); 4149 return 0; 4150} 4151 4152static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol, 4153 struct snd_ctl_elem_value *ucontrol) 4154{ 4155 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 4156 hda_nid_t nid = (hda_nid_t)kcontrol->private_value; 4157 unsigned int sel; 4158 4159 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0); 4160 ucontrol->value.enumerated.item[0] = sel & 3; 4161 return 0; 4162} 4163 4164static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol, 4165 struct snd_ctl_elem_value *ucontrol) 4166{ 4167 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 4168 hda_nid_t nid = (hda_nid_t)kcontrol->private_value; 4169 unsigned int sel; 4170 4171 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3; 4172 if (ucontrol->value.enumerated.item[0] != sel) { 4173 sel = ucontrol->value.enumerated.item[0] & 3; 4174 snd_hda_codec_write_cache(codec, nid, 0, 4175 AC_VERB_SET_CONNECT_SEL, sel); 4176 return 1; 4177 } 4178 return 0; 4179} 4180 4181#define PIN_CTL_TEST(xname,nid) { \ 4182 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 4183 .name = xname, \ 4184 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \ 4185 .info = alc_test_pin_ctl_info, \ 4186 .get = alc_test_pin_ctl_get, \ 4187 .put = alc_test_pin_ctl_put, \ 4188 .private_value = nid \ 4189 } 4190 4191#define PIN_SRC_TEST(xname,nid) { \ 4192 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 4193 .name = xname, \ 4194 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \ 4195 .info = alc_test_pin_src_info, \ 4196 .get = alc_test_pin_src_get, \ 4197 .put = alc_test_pin_src_put, \ 4198 .private_value = nid \ 4199 } 4200 4201static struct snd_kcontrol_new alc880_test_mixer[] = { 4202 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 4203 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 4204 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT), 4205 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 4206 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 4207 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 4208 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT), 4209 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 4210 PIN_CTL_TEST("Front Pin Mode", 0x14), 4211 PIN_CTL_TEST("Surround Pin Mode", 0x15), 4212 PIN_CTL_TEST("CLFE Pin Mode", 0x16), 4213 PIN_CTL_TEST("Side Pin Mode", 0x17), 4214 PIN_CTL_TEST("In-1 Pin Mode", 0x18), 4215 PIN_CTL_TEST("In-2 Pin Mode", 0x19), 4216 PIN_CTL_TEST("In-3 Pin Mode", 0x1a), 4217 PIN_CTL_TEST("In-4 Pin Mode", 0x1b), 4218 PIN_SRC_TEST("In-1 Pin Source", 0x18), 4219 PIN_SRC_TEST("In-2 Pin Source", 0x19), 4220 PIN_SRC_TEST("In-3 Pin Source", 0x1a), 4221 PIN_SRC_TEST("In-4 Pin Source", 0x1b), 4222 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT), 4223 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT), 4224 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT), 4225 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT), 4226 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT), 4227 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT), 4228 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT), 4229 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT), 4230 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT), 4231 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT), 4232 { 4233 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 4234 .name = "Channel Mode", 4235 .info = alc_ch_mode_info, 4236 .get = alc_ch_mode_get, 4237 .put = alc_ch_mode_put, 4238 }, 4239 { } /* end */ 4240}; 4241 4242static struct hda_verb alc880_test_init_verbs[] = { 4243 /* Unmute inputs of 0x0c - 0x0f */ 4244 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4245 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4246 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4247 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4248 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4249 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4250 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4251 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4252 /* Vol output for 0x0c-0x0f */ 4253 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4254 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4255 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4256 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4257 /* Set output pins 0x14-0x17 */ 4258 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4259 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4260 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4261 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4262 /* Unmute output pins 0x14-0x17 */ 4263 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4264 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4265 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4266 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4267 /* Set input pins 0x18-0x1c */ 4268 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 4269 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 4270 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 4271 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 4272 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 4273 /* Mute input pins 0x18-0x1b */ 4274 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 4275 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 4276 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 4277 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 4278 /* ADC set up */ 4279 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4280 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 4281 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4282 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 4283 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4284 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 4285 /* Analog input/passthru */ 4286 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4287 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4288 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 4289 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 4290 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 4291 { } 4292}; 4293#endif 4294 4295/* 4296 */ 4297 4298static const char *alc880_models[ALC880_MODEL_LAST] = { 4299 [ALC880_3ST] = "3stack", 4300 [ALC880_TCL_S700] = "tcl", 4301 [ALC880_3ST_DIG] = "3stack-digout", 4302 [ALC880_CLEVO] = "clevo", 4303 [ALC880_5ST] = "5stack", 4304 [ALC880_5ST_DIG] = "5stack-digout", 4305 [ALC880_W810] = "w810", 4306 [ALC880_Z71V] = "z71v", 4307 [ALC880_6ST] = "6stack", 4308 [ALC880_6ST_DIG] = "6stack-digout", 4309 [ALC880_ASUS] = "asus", 4310 [ALC880_ASUS_W1V] = "asus-w1v", 4311 [ALC880_ASUS_DIG] = "asus-dig", 4312 [ALC880_ASUS_DIG2] = "asus-dig2", 4313 [ALC880_UNIWILL_DIG] = "uniwill", 4314 [ALC880_UNIWILL_P53] = "uniwill-p53", 4315 [ALC880_FUJITSU] = "fujitsu", 4316 [ALC880_F1734] = "F1734", 4317 [ALC880_LG] = "lg", 4318 [ALC880_LG_LW] = "lg-lw", 4319 [ALC880_MEDION_RIM] = "medion", 4320#ifdef CONFIG_SND_DEBUG 4321 [ALC880_TEST] = "test", 4322#endif 4323 [ALC880_AUTO] = "auto", 4324}; 4325 4326static struct snd_pci_quirk alc880_cfg_tbl[] = { 4327 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810), 4328 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG), 4329 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST), 4330 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG), 4331 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG), 4332 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG), 4333 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG), 4334 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG), 4335 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST), 4336 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG), 4337 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST), 4338 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V), 4339 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG), 4340 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG), 4341 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG), 4342 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG), 4343 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG), 4344 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V), 4345 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */ 4346 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG), 4347 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG), 4348 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG), 4349 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG), 4350 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST), 4351 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST), 4352 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */ 4353 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST), 4354 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST), 4355 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST), 4356 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST), 4357 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST), 4358 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG), 4359 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG), 4360 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG), 4361 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG), 4362 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO), 4363 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO), 4364 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2), 4365 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG), 4366 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG), 4367 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734), 4368 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL), 4369 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53), 4370 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810), 4371 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM), 4372 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG), 4373 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG), 4374 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734), 4375 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU), 4376 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_F1734), 4377 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU), 4378 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW), 4379 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG), 4380 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG), 4381 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW), 4382 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700), 4383 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */ 4384 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG), 4385 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG), 4386 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG), 4387 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG), 4388 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG), 4389 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG), 4390 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG), 4391 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG), 4392 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG), 4393 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG), 4394 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG), 4395 /* default Intel */ 4396 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST), 4397 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG), 4398 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG), 4399 {} 4400}; 4401 4402/* 4403 * ALC880 codec presets 4404 */ 4405static struct alc_config_preset alc880_presets[] = { 4406 [ALC880_3ST] = { 4407 .mixers = { alc880_three_stack_mixer }, 4408 .init_verbs = { alc880_volume_init_verbs, 4409 alc880_pin_3stack_init_verbs }, 4410 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 4411 .dac_nids = alc880_dac_nids, 4412 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), 4413 .channel_mode = alc880_threestack_modes, 4414 .need_dac_fix = 1, 4415 .input_mux = &alc880_capture_source, 4416 }, 4417 [ALC880_3ST_DIG] = { 4418 .mixers = { alc880_three_stack_mixer }, 4419 .init_verbs = { alc880_volume_init_verbs, 4420 alc880_pin_3stack_init_verbs }, 4421 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 4422 .dac_nids = alc880_dac_nids, 4423 .dig_out_nid = ALC880_DIGOUT_NID, 4424 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), 4425 .channel_mode = alc880_threestack_modes, 4426 .need_dac_fix = 1, 4427 .input_mux = &alc880_capture_source, 4428 }, 4429 [ALC880_TCL_S700] = { 4430 .mixers = { alc880_tcl_s700_mixer }, 4431 .init_verbs = { alc880_volume_init_verbs, 4432 alc880_pin_tcl_S700_init_verbs, 4433 alc880_gpio2_init_verbs }, 4434 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 4435 .dac_nids = alc880_dac_nids, 4436 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */ 4437 .num_adc_nids = 1, /* single ADC */ 4438 .hp_nid = 0x03, 4439 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), 4440 .channel_mode = alc880_2_jack_modes, 4441 .input_mux = &alc880_capture_source, 4442 }, 4443 [ALC880_5ST] = { 4444 .mixers = { alc880_three_stack_mixer, 4445 alc880_five_stack_mixer}, 4446 .init_verbs = { alc880_volume_init_verbs, 4447 alc880_pin_5stack_init_verbs }, 4448 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 4449 .dac_nids = alc880_dac_nids, 4450 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes), 4451 .channel_mode = alc880_fivestack_modes, 4452 .input_mux = &alc880_capture_source, 4453 }, 4454 [ALC880_5ST_DIG] = { 4455 .mixers = { alc880_three_stack_mixer, 4456 alc880_five_stack_mixer }, 4457 .init_verbs = { alc880_volume_init_verbs, 4458 alc880_pin_5stack_init_verbs }, 4459 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 4460 .dac_nids = alc880_dac_nids, 4461 .dig_out_nid = ALC880_DIGOUT_NID, 4462 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes), 4463 .channel_mode = alc880_fivestack_modes, 4464 .input_mux = &alc880_capture_source, 4465 }, 4466 [ALC880_6ST] = { 4467 .mixers = { alc880_six_stack_mixer }, 4468 .init_verbs = { alc880_volume_init_verbs, 4469 alc880_pin_6stack_init_verbs }, 4470 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids), 4471 .dac_nids = alc880_6st_dac_nids, 4472 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes), 4473 .channel_mode = alc880_sixstack_modes, 4474 .input_mux = &alc880_6stack_capture_source, 4475 }, 4476 [ALC880_6ST_DIG] = { 4477 .mixers = { alc880_six_stack_mixer }, 4478 .init_verbs = { alc880_volume_init_verbs, 4479 alc880_pin_6stack_init_verbs }, 4480 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids), 4481 .dac_nids = alc880_6st_dac_nids, 4482 .dig_out_nid = ALC880_DIGOUT_NID, 4483 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes), 4484 .channel_mode = alc880_sixstack_modes, 4485 .input_mux = &alc880_6stack_capture_source, 4486 }, 4487 [ALC880_W810] = { 4488 .mixers = { alc880_w810_base_mixer }, 4489 .init_verbs = { alc880_volume_init_verbs, 4490 alc880_pin_w810_init_verbs, 4491 alc880_gpio2_init_verbs }, 4492 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids), 4493 .dac_nids = alc880_w810_dac_nids, 4494 .dig_out_nid = ALC880_DIGOUT_NID, 4495 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes), 4496 .channel_mode = alc880_w810_modes, 4497 .input_mux = &alc880_capture_source, 4498 }, 4499 [ALC880_Z71V] = { 4500 .mixers = { alc880_z71v_mixer }, 4501 .init_verbs = { alc880_volume_init_verbs, 4502 alc880_pin_z71v_init_verbs }, 4503 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids), 4504 .dac_nids = alc880_z71v_dac_nids, 4505 .dig_out_nid = ALC880_DIGOUT_NID, 4506 .hp_nid = 0x03, 4507 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), 4508 .channel_mode = alc880_2_jack_modes, 4509 .input_mux = &alc880_capture_source, 4510 }, 4511 [ALC880_F1734] = { 4512 .mixers = { alc880_f1734_mixer }, 4513 .init_verbs = { alc880_volume_init_verbs, 4514 alc880_pin_f1734_init_verbs }, 4515 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids), 4516 .dac_nids = alc880_f1734_dac_nids, 4517 .hp_nid = 0x02, 4518 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), 4519 .channel_mode = alc880_2_jack_modes, 4520 .input_mux = &alc880_f1734_capture_source, 4521 .unsol_event = alc880_uniwill_p53_unsol_event, 4522 .setup = alc880_uniwill_p53_setup, 4523 .init_hook = alc_automute_amp, 4524 }, 4525 [ALC880_ASUS] = { 4526 .mixers = { alc880_asus_mixer }, 4527 .init_verbs = { alc880_volume_init_verbs, 4528 alc880_pin_asus_init_verbs, 4529 alc880_gpio1_init_verbs }, 4530 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 4531 .dac_nids = alc880_asus_dac_nids, 4532 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), 4533 .channel_mode = alc880_asus_modes, 4534 .need_dac_fix = 1, 4535 .input_mux = &alc880_capture_source, 4536 }, 4537 [ALC880_ASUS_DIG] = { 4538 .mixers = { alc880_asus_mixer }, 4539 .init_verbs = { alc880_volume_init_verbs, 4540 alc880_pin_asus_init_verbs, 4541 alc880_gpio1_init_verbs }, 4542 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 4543 .dac_nids = alc880_asus_dac_nids, 4544 .dig_out_nid = ALC880_DIGOUT_NID, 4545 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), 4546 .channel_mode = alc880_asus_modes, 4547 .need_dac_fix = 1, 4548 .input_mux = &alc880_capture_source, 4549 }, 4550 [ALC880_ASUS_DIG2] = { 4551 .mixers = { alc880_asus_mixer }, 4552 .init_verbs = { alc880_volume_init_verbs, 4553 alc880_pin_asus_init_verbs, 4554 alc880_gpio2_init_verbs }, /* use GPIO2 */ 4555 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 4556 .dac_nids = alc880_asus_dac_nids, 4557 .dig_out_nid = ALC880_DIGOUT_NID, 4558 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), 4559 .channel_mode = alc880_asus_modes, 4560 .need_dac_fix = 1, 4561 .input_mux = &alc880_capture_source, 4562 }, 4563 [ALC880_ASUS_W1V] = { 4564 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer }, 4565 .init_verbs = { alc880_volume_init_verbs, 4566 alc880_pin_asus_init_verbs, 4567 alc880_gpio1_init_verbs }, 4568 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 4569 .dac_nids = alc880_asus_dac_nids, 4570 .dig_out_nid = ALC880_DIGOUT_NID, 4571 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), 4572 .channel_mode = alc880_asus_modes, 4573 .need_dac_fix = 1, 4574 .input_mux = &alc880_capture_source, 4575 }, 4576 [ALC880_UNIWILL_DIG] = { 4577 .mixers = { alc880_asus_mixer }, 4578 .init_verbs = { alc880_volume_init_verbs, 4579 alc880_pin_asus_init_verbs }, 4580 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 4581 .dac_nids = alc880_asus_dac_nids, 4582 .dig_out_nid = ALC880_DIGOUT_NID, 4583 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), 4584 .channel_mode = alc880_asus_modes, 4585 .need_dac_fix = 1, 4586 .input_mux = &alc880_capture_source, 4587 }, 4588 [ALC880_UNIWILL] = { 4589 .mixers = { alc880_uniwill_mixer }, 4590 .init_verbs = { alc880_volume_init_verbs, 4591 alc880_uniwill_init_verbs }, 4592 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 4593 .dac_nids = alc880_asus_dac_nids, 4594 .dig_out_nid = ALC880_DIGOUT_NID, 4595 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), 4596 .channel_mode = alc880_threestack_modes, 4597 .need_dac_fix = 1, 4598 .input_mux = &alc880_capture_source, 4599 .unsol_event = alc880_uniwill_unsol_event, 4600 .setup = alc880_uniwill_setup, 4601 .init_hook = alc880_uniwill_init_hook, 4602 }, 4603 [ALC880_UNIWILL_P53] = { 4604 .mixers = { alc880_uniwill_p53_mixer }, 4605 .init_verbs = { alc880_volume_init_verbs, 4606 alc880_uniwill_p53_init_verbs }, 4607 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 4608 .dac_nids = alc880_asus_dac_nids, 4609 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes), 4610 .channel_mode = alc880_threestack_modes, 4611 .input_mux = &alc880_capture_source, 4612 .unsol_event = alc880_uniwill_p53_unsol_event, 4613 .setup = alc880_uniwill_p53_setup, 4614 .init_hook = alc_automute_amp, 4615 }, 4616 [ALC880_FUJITSU] = { 4617 .mixers = { alc880_fujitsu_mixer }, 4618 .init_verbs = { alc880_volume_init_verbs, 4619 alc880_uniwill_p53_init_verbs, 4620 alc880_beep_init_verbs }, 4621 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 4622 .dac_nids = alc880_dac_nids, 4623 .dig_out_nid = ALC880_DIGOUT_NID, 4624 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), 4625 .channel_mode = alc880_2_jack_modes, 4626 .input_mux = &alc880_capture_source, 4627 .unsol_event = alc880_uniwill_p53_unsol_event, 4628 .setup = alc880_uniwill_p53_setup, 4629 .init_hook = alc_automute_amp, 4630 }, 4631 [ALC880_CLEVO] = { 4632 .mixers = { alc880_three_stack_mixer }, 4633 .init_verbs = { alc880_volume_init_verbs, 4634 alc880_pin_clevo_init_verbs }, 4635 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 4636 .dac_nids = alc880_dac_nids, 4637 .hp_nid = 0x03, 4638 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), 4639 .channel_mode = alc880_threestack_modes, 4640 .need_dac_fix = 1, 4641 .input_mux = &alc880_capture_source, 4642 }, 4643 [ALC880_LG] = { 4644 .mixers = { alc880_lg_mixer }, 4645 .init_verbs = { alc880_volume_init_verbs, 4646 alc880_lg_init_verbs }, 4647 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids), 4648 .dac_nids = alc880_lg_dac_nids, 4649 .dig_out_nid = ALC880_DIGOUT_NID, 4650 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes), 4651 .channel_mode = alc880_lg_ch_modes, 4652 .need_dac_fix = 1, 4653 .input_mux = &alc880_lg_capture_source, 4654 .unsol_event = alc_automute_amp_unsol_event, 4655 .setup = alc880_lg_setup, 4656 .init_hook = alc_automute_amp, 4657#ifdef CONFIG_SND_HDA_POWER_SAVE 4658 .loopbacks = alc880_lg_loopbacks, 4659#endif 4660 }, 4661 [ALC880_LG_LW] = { 4662 .mixers = { alc880_lg_lw_mixer }, 4663 .init_verbs = { alc880_volume_init_verbs, 4664 alc880_lg_lw_init_verbs }, 4665 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 4666 .dac_nids = alc880_dac_nids, 4667 .dig_out_nid = ALC880_DIGOUT_NID, 4668 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes), 4669 .channel_mode = alc880_lg_lw_modes, 4670 .input_mux = &alc880_lg_lw_capture_source, 4671 .unsol_event = alc_automute_amp_unsol_event, 4672 .setup = alc880_lg_lw_setup, 4673 .init_hook = alc_automute_amp, 4674 }, 4675 [ALC880_MEDION_RIM] = { 4676 .mixers = { alc880_medion_rim_mixer }, 4677 .init_verbs = { alc880_volume_init_verbs, 4678 alc880_medion_rim_init_verbs, 4679 alc_gpio2_init_verbs }, 4680 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 4681 .dac_nids = alc880_dac_nids, 4682 .dig_out_nid = ALC880_DIGOUT_NID, 4683 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), 4684 .channel_mode = alc880_2_jack_modes, 4685 .input_mux = &alc880_medion_rim_capture_source, 4686 .unsol_event = alc880_medion_rim_unsol_event, 4687 .setup = alc880_medion_rim_setup, 4688 .init_hook = alc880_medion_rim_automute, 4689 }, 4690#ifdef CONFIG_SND_DEBUG 4691 [ALC880_TEST] = { 4692 .mixers = { alc880_test_mixer }, 4693 .init_verbs = { alc880_test_init_verbs }, 4694 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids), 4695 .dac_nids = alc880_test_dac_nids, 4696 .dig_out_nid = ALC880_DIGOUT_NID, 4697 .num_channel_mode = ARRAY_SIZE(alc880_test_modes), 4698 .channel_mode = alc880_test_modes, 4699 .input_mux = &alc880_test_capture_source, 4700 }, 4701#endif 4702}; 4703 4704/* 4705 * Automatic parse of I/O pins from the BIOS configuration 4706 */ 4707 4708enum { 4709 ALC_CTL_WIDGET_VOL, 4710 ALC_CTL_WIDGET_MUTE, 4711 ALC_CTL_BIND_MUTE, 4712}; 4713static struct snd_kcontrol_new alc880_control_templates[] = { 4714 HDA_CODEC_VOLUME(NULL, 0, 0, 0), 4715 HDA_CODEC_MUTE(NULL, 0, 0, 0), 4716 HDA_BIND_MUTE(NULL, 0, 0, 0), 4717}; 4718 4719/* add dynamic controls */ 4720static int add_control(struct alc_spec *spec, int type, const char *name, 4721 unsigned long val) 4722{ 4723 struct snd_kcontrol_new *knew; 4724 4725 snd_array_init(&spec->kctls, sizeof(*knew), 32); 4726 knew = snd_array_new(&spec->kctls); 4727 if (!knew) 4728 return -ENOMEM; 4729 *knew = alc880_control_templates[type]; 4730 knew->name = kstrdup(name, GFP_KERNEL); 4731 if (!knew->name) 4732 return -ENOMEM; 4733 if (get_amp_nid_(val)) 4734 knew->subdevice = HDA_SUBDEV_AMP_FLAG; 4735 knew->private_value = val; 4736 return 0; 4737} 4738 4739static int add_control_with_pfx(struct alc_spec *spec, int type, 4740 const char *pfx, const char *dir, 4741 const char *sfx, unsigned long val) 4742{ 4743 char name[32]; 4744 snprintf(name, sizeof(name), "%s %s %s", pfx, dir, sfx); 4745 return add_control(spec, type, name, val); 4746} 4747 4748#define add_pb_vol_ctrl(spec, type, pfx, val) \ 4749 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", val) 4750#define add_pb_sw_ctrl(spec, type, pfx, val) \ 4751 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", val) 4752 4753#define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17) 4754#define alc880_fixed_pin_idx(nid) ((nid) - 0x14) 4755#define alc880_is_multi_pin(nid) ((nid) >= 0x18) 4756#define alc880_multi_pin_idx(nid) ((nid) - 0x18) 4757#define alc880_idx_to_dac(nid) ((nid) + 0x02) 4758#define alc880_dac_to_idx(nid) ((nid) - 0x02) 4759#define alc880_idx_to_mixer(nid) ((nid) + 0x0c) 4760#define alc880_idx_to_selector(nid) ((nid) + 0x10) 4761#define ALC880_PIN_CD_NID 0x1c 4762 4763/* fill in the dac_nids table from the parsed pin configuration */ 4764static int alc880_auto_fill_dac_nids(struct alc_spec *spec, 4765 const struct auto_pin_cfg *cfg) 4766{ 4767 hda_nid_t nid; 4768 int assigned[4]; 4769 int i, j; 4770 4771 memset(assigned, 0, sizeof(assigned)); 4772 spec->multiout.dac_nids = spec->private_dac_nids; 4773 4774 /* check the pins hardwired to audio widget */ 4775 for (i = 0; i < cfg->line_outs; i++) { 4776 nid = cfg->line_out_pins[i]; 4777 if (alc880_is_fixed_pin(nid)) { 4778 int idx = alc880_fixed_pin_idx(nid); 4779 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx); 4780 assigned[idx] = 1; 4781 } 4782 } 4783 /* left pins can be connect to any audio widget */ 4784 for (i = 0; i < cfg->line_outs; i++) { 4785 nid = cfg->line_out_pins[i]; 4786 if (alc880_is_fixed_pin(nid)) 4787 continue; 4788 /* search for an empty channel */ 4789 for (j = 0; j < cfg->line_outs; j++) { 4790 if (!assigned[j]) { 4791 spec->multiout.dac_nids[i] = 4792 alc880_idx_to_dac(j); 4793 assigned[j] = 1; 4794 break; 4795 } 4796 } 4797 } 4798 spec->multiout.num_dacs = cfg->line_outs; 4799 return 0; 4800} 4801 4802/* add playback controls from the parsed DAC table */ 4803static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec, 4804 const struct auto_pin_cfg *cfg) 4805{ 4806 static const char *chname[4] = { 4807 "Front", "Surround", NULL /*CLFE*/, "Side" 4808 }; 4809 hda_nid_t nid; 4810 int i, err; 4811 4812 for (i = 0; i < cfg->line_outs; i++) { 4813 if (!spec->multiout.dac_nids[i]) 4814 continue; 4815 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i])); 4816 if (i == 2) { 4817 /* Center/LFE */ 4818 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, 4819 "Center", 4820 HDA_COMPOSE_AMP_VAL(nid, 1, 0, 4821 HDA_OUTPUT)); 4822 if (err < 0) 4823 return err; 4824 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, 4825 "LFE", 4826 HDA_COMPOSE_AMP_VAL(nid, 2, 0, 4827 HDA_OUTPUT)); 4828 if (err < 0) 4829 return err; 4830 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, 4831 "Center", 4832 HDA_COMPOSE_AMP_VAL(nid, 1, 2, 4833 HDA_INPUT)); 4834 if (err < 0) 4835 return err; 4836 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, 4837 "LFE", 4838 HDA_COMPOSE_AMP_VAL(nid, 2, 2, 4839 HDA_INPUT)); 4840 if (err < 0) 4841 return err; 4842 } else { 4843 const char *pfx; 4844 if (cfg->line_outs == 1 && 4845 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) 4846 pfx = "Speaker"; 4847 else 4848 pfx = chname[i]; 4849 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, 4850 HDA_COMPOSE_AMP_VAL(nid, 3, 0, 4851 HDA_OUTPUT)); 4852 if (err < 0) 4853 return err; 4854 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx, 4855 HDA_COMPOSE_AMP_VAL(nid, 3, 2, 4856 HDA_INPUT)); 4857 if (err < 0) 4858 return err; 4859 } 4860 } 4861 return 0; 4862} 4863 4864/* add playback controls for speaker and HP outputs */ 4865static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin, 4866 const char *pfx) 4867{ 4868 hda_nid_t nid; 4869 int err; 4870 4871 if (!pin) 4872 return 0; 4873 4874 if (alc880_is_fixed_pin(pin)) { 4875 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); 4876 /* specify the DAC as the extra output */ 4877 if (!spec->multiout.hp_nid) 4878 spec->multiout.hp_nid = nid; 4879 else 4880 spec->multiout.extra_out_nid[0] = nid; 4881 /* control HP volume/switch on the output mixer amp */ 4882 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin)); 4883 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, 4884 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); 4885 if (err < 0) 4886 return err; 4887 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx, 4888 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT)); 4889 if (err < 0) 4890 return err; 4891 } else if (alc880_is_multi_pin(pin)) { 4892 /* set manual connection */ 4893 /* we have only a switch on HP-out PIN */ 4894 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, 4895 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); 4896 if (err < 0) 4897 return err; 4898 } 4899 return 0; 4900} 4901 4902/* create input playback/capture controls for the given pin */ 4903static int new_analog_input(struct alc_spec *spec, hda_nid_t pin, 4904 const char *ctlname, 4905 int idx, hda_nid_t mix_nid) 4906{ 4907 int err; 4908 4909 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname, 4910 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT)); 4911 if (err < 0) 4912 return err; 4913 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname, 4914 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT)); 4915 if (err < 0) 4916 return err; 4917 return 0; 4918} 4919 4920static int alc_is_input_pin(struct hda_codec *codec, hda_nid_t nid) 4921{ 4922 unsigned int pincap = snd_hda_query_pin_caps(codec, nid); 4923 return (pincap & AC_PINCAP_IN) != 0; 4924} 4925 4926/* create playback/capture controls for input pins */ 4927static int alc_auto_create_input_ctls(struct hda_codec *codec, 4928 const struct auto_pin_cfg *cfg, 4929 hda_nid_t mixer, 4930 hda_nid_t cap1, hda_nid_t cap2) 4931{ 4932 struct alc_spec *spec = codec->spec; 4933 struct hda_input_mux *imux = &spec->private_imux[0]; 4934 int i, err, idx; 4935 4936 for (i = 0; i < AUTO_PIN_LAST; i++) { 4937 hda_nid_t pin; 4938 4939 pin = cfg->input_pins[i]; 4940 if (!alc_is_input_pin(codec, pin)) 4941 continue; 4942 4943 if (mixer) { 4944 idx = get_connection_index(codec, mixer, pin); 4945 if (idx >= 0) { 4946 err = new_analog_input(spec, pin, 4947 auto_pin_cfg_labels[i], 4948 idx, mixer); 4949 if (err < 0) 4950 return err; 4951 } 4952 } 4953 4954 if (!cap1) 4955 continue; 4956 idx = get_connection_index(codec, cap1, pin); 4957 if (idx < 0 && cap2) 4958 idx = get_connection_index(codec, cap2, pin); 4959 if (idx >= 0) { 4960 imux->items[imux->num_items].label = 4961 auto_pin_cfg_labels[i]; 4962 imux->items[imux->num_items].index = idx; 4963 imux->num_items++; 4964 } 4965 } 4966 return 0; 4967} 4968 4969static int alc880_auto_create_input_ctls(struct hda_codec *codec, 4970 const struct auto_pin_cfg *cfg) 4971{ 4972 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x08, 0x09); 4973} 4974 4975static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid, 4976 unsigned int pin_type) 4977{ 4978 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 4979 pin_type); 4980 /* unmute pin */ 4981 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, 4982 AMP_OUT_UNMUTE); 4983} 4984 4985static void alc880_auto_set_output_and_unmute(struct hda_codec *codec, 4986 hda_nid_t nid, int pin_type, 4987 int dac_idx) 4988{ 4989 alc_set_pin_output(codec, nid, pin_type); 4990 /* need the manual connection? */ 4991 if (alc880_is_multi_pin(nid)) { 4992 struct alc_spec *spec = codec->spec; 4993 int idx = alc880_multi_pin_idx(nid); 4994 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0, 4995 AC_VERB_SET_CONNECT_SEL, 4996 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx])); 4997 } 4998} 4999 5000static int get_pin_type(int line_out_type) 5001{ 5002 if (line_out_type == AUTO_PIN_HP_OUT) 5003 return PIN_HP; 5004 else 5005 return PIN_OUT; 5006} 5007 5008static void alc880_auto_init_multi_out(struct hda_codec *codec) 5009{ 5010 struct alc_spec *spec = codec->spec; 5011 int i; 5012 5013 for (i = 0; i < spec->autocfg.line_outs; i++) { 5014 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 5015 int pin_type = get_pin_type(spec->autocfg.line_out_type); 5016 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i); 5017 } 5018} 5019 5020static void alc880_auto_init_extra_out(struct hda_codec *codec) 5021{ 5022 struct alc_spec *spec = codec->spec; 5023 hda_nid_t pin; 5024 5025 pin = spec->autocfg.speaker_pins[0]; 5026 if (pin) /* connect to front */ 5027 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0); 5028 pin = spec->autocfg.hp_pins[0]; 5029 if (pin) /* connect to front */ 5030 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); 5031} 5032 5033static void alc880_auto_init_analog_input(struct hda_codec *codec) 5034{ 5035 struct alc_spec *spec = codec->spec; 5036 int i; 5037 5038 for (i = 0; i < AUTO_PIN_LAST; i++) { 5039 hda_nid_t nid = spec->autocfg.input_pins[i]; 5040 if (alc_is_input_pin(codec, nid)) { 5041 alc_set_input_pin(codec, nid, i); 5042 if (nid != ALC880_PIN_CD_NID && 5043 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)) 5044 snd_hda_codec_write(codec, nid, 0, 5045 AC_VERB_SET_AMP_GAIN_MUTE, 5046 AMP_OUT_MUTE); 5047 } 5048 } 5049} 5050 5051static void alc880_auto_init_input_src(struct hda_codec *codec) 5052{ 5053 struct alc_spec *spec = codec->spec; 5054 int c; 5055 5056 for (c = 0; c < spec->num_adc_nids; c++) { 5057 unsigned int mux_idx; 5058 const struct hda_input_mux *imux; 5059 mux_idx = c >= spec->num_mux_defs ? 0 : c; 5060 imux = &spec->input_mux[mux_idx]; 5061 if (!imux->num_items && mux_idx > 0) 5062 imux = &spec->input_mux[0]; 5063 if (imux) 5064 snd_hda_codec_write(codec, spec->adc_nids[c], 0, 5065 AC_VERB_SET_CONNECT_SEL, 5066 imux->items[0].index); 5067 } 5068} 5069 5070/* parse the BIOS configuration and set up the alc_spec */ 5071/* return 1 if successful, 0 if the proper config is not found, 5072 * or a negative error code 5073 */ 5074static int alc880_parse_auto_config(struct hda_codec *codec) 5075{ 5076 struct alc_spec *spec = codec->spec; 5077 int err; 5078 static hda_nid_t alc880_ignore[] = { 0x1d, 0 }; 5079 5080 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 5081 alc880_ignore); 5082 if (err < 0) 5083 return err; 5084 if (!spec->autocfg.line_outs) 5085 return 0; /* can't find valid BIOS pin config */ 5086 5087 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); 5088 if (err < 0) 5089 return err; 5090 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg); 5091 if (err < 0) 5092 return err; 5093 err = alc880_auto_create_extra_out(spec, 5094 spec->autocfg.speaker_pins[0], 5095 "Speaker"); 5096 if (err < 0) 5097 return err; 5098 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0], 5099 "Headphone"); 5100 if (err < 0) 5101 return err; 5102 err = alc880_auto_create_input_ctls(codec, &spec->autocfg); 5103 if (err < 0) 5104 return err; 5105 5106 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 5107 5108 alc_auto_parse_digital(codec); 5109 5110 if (spec->kctls.list) 5111 add_mixer(spec, spec->kctls.list); 5112 5113 add_verb(spec, alc880_volume_init_verbs); 5114 5115 spec->num_mux_defs = 1; 5116 spec->input_mux = &spec->private_imux[0]; 5117 5118 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); 5119 5120 return 1; 5121} 5122 5123/* additional initialization for auto-configuration model */ 5124static void alc880_auto_init(struct hda_codec *codec) 5125{ 5126 struct alc_spec *spec = codec->spec; 5127 alc880_auto_init_multi_out(codec); 5128 alc880_auto_init_extra_out(codec); 5129 alc880_auto_init_analog_input(codec); 5130 alc880_auto_init_input_src(codec); 5131 alc_auto_init_digital(codec); 5132 if (spec->unsol_event) 5133 alc_inithook(codec); 5134} 5135 5136/* check the ADC/MUX contains all input pins; some ADC/MUX contains only 5137 * one of two digital mic pins, e.g. on ALC272 5138 */ 5139static void fixup_automic_adc(struct hda_codec *codec) 5140{ 5141 struct alc_spec *spec = codec->spec; 5142 int i; 5143 5144 for (i = 0; i < spec->num_adc_nids; i++) { 5145 hda_nid_t cap = spec->capsrc_nids ? 5146 spec->capsrc_nids[i] : spec->adc_nids[i]; 5147 int iidx, eidx; 5148 5149 iidx = get_connection_index(codec, cap, spec->int_mic.pin); 5150 if (iidx < 0) 5151 continue; 5152 eidx = get_connection_index(codec, cap, spec->ext_mic.pin); 5153 if (eidx < 0) 5154 continue; 5155 spec->int_mic.mux_idx = iidx; 5156 spec->ext_mic.mux_idx = eidx; 5157 if (spec->capsrc_nids) 5158 spec->capsrc_nids += i; 5159 spec->adc_nids += i; 5160 spec->num_adc_nids = 1; 5161 return; 5162 } 5163 snd_printd(KERN_INFO "hda_codec: %s: " 5164 "No ADC/MUX containing both 0x%x and 0x%x pins\n", 5165 codec->chip_name, spec->int_mic.pin, spec->ext_mic.pin); 5166 spec->auto_mic = 0; /* disable auto-mic to be sure */ 5167} 5168 5169/* set the default connection to that pin */ 5170static int init_capsrc_for_pin(struct hda_codec *codec, hda_nid_t pin) 5171{ 5172 struct alc_spec *spec = codec->spec; 5173 int i; 5174 5175 for (i = 0; i < spec->num_adc_nids; i++) { 5176 hda_nid_t cap = spec->capsrc_nids ? 5177 spec->capsrc_nids[i] : spec->adc_nids[i]; 5178 int idx; 5179 5180 idx = get_connection_index(codec, cap, pin); 5181 if (idx < 0) 5182 continue; 5183 /* select or unmute this route */ 5184 if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) { 5185 snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx, 5186 HDA_AMP_MUTE, 0); 5187 } else { 5188 snd_hda_codec_write_cache(codec, cap, 0, 5189 AC_VERB_SET_CONNECT_SEL, idx); 5190 } 5191 return i; /* return the found index */ 5192 } 5193 return -1; /* not found */ 5194} 5195 5196/* choose the ADC/MUX containing the input pin and initialize the setup */ 5197static void fixup_single_adc(struct hda_codec *codec) 5198{ 5199 struct alc_spec *spec = codec->spec; 5200 hda_nid_t pin = 0; 5201 int i; 5202 5203 /* search for the input pin; there must be only one */ 5204 for (i = 0; i < AUTO_PIN_LAST; i++) { 5205 if (spec->autocfg.input_pins[i]) { 5206 pin = spec->autocfg.input_pins[i]; 5207 break; 5208 } 5209 } 5210 if (!pin) 5211 return; 5212 i = init_capsrc_for_pin(codec, pin); 5213 if (i >= 0) { 5214 /* use only this ADC */ 5215 if (spec->capsrc_nids) 5216 spec->capsrc_nids += i; 5217 spec->adc_nids += i; 5218 spec->num_adc_nids = 1; 5219 } 5220} 5221 5222/* initialize dual adcs */ 5223static void fixup_dual_adc_switch(struct hda_codec *codec) 5224{ 5225 struct alc_spec *spec = codec->spec; 5226 init_capsrc_for_pin(codec, spec->ext_mic.pin); 5227 init_capsrc_for_pin(codec, spec->int_mic.pin); 5228} 5229 5230static void set_capture_mixer(struct hda_codec *codec) 5231{ 5232 struct alc_spec *spec = codec->spec; 5233 static struct snd_kcontrol_new *caps[2][3] = { 5234 { alc_capture_mixer_nosrc1, 5235 alc_capture_mixer_nosrc2, 5236 alc_capture_mixer_nosrc3 }, 5237 { alc_capture_mixer1, 5238 alc_capture_mixer2, 5239 alc_capture_mixer3 }, 5240 }; 5241 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) { 5242 int mux = 0; 5243 int num_adcs = spec->num_adc_nids; 5244 if (spec->dual_adc_switch) 5245 fixup_dual_adc_switch(codec); 5246 else if (spec->auto_mic) 5247 fixup_automic_adc(codec); 5248 else if (spec->input_mux) { 5249 if (spec->input_mux->num_items > 1) 5250 mux = 1; 5251 else if (spec->input_mux->num_items == 1) 5252 fixup_single_adc(codec); 5253 } 5254 if (spec->dual_adc_switch) 5255 num_adcs = 1; 5256 spec->cap_mixer = caps[mux][num_adcs - 1]; 5257 } 5258} 5259 5260/* fill adc_nids (and capsrc_nids) containing all active input pins */ 5261static void fillup_priv_adc_nids(struct hda_codec *codec, hda_nid_t *nids, 5262 int num_nids) 5263{ 5264 struct alc_spec *spec = codec->spec; 5265 int n; 5266 hda_nid_t fallback_adc = 0, fallback_cap = 0; 5267 5268 for (n = 0; n < num_nids; n++) { 5269 hda_nid_t adc, cap; 5270 hda_nid_t conn[HDA_MAX_NUM_INPUTS]; 5271 int nconns, i, j; 5272 5273 adc = nids[n]; 5274 if (get_wcaps_type(get_wcaps(codec, adc)) != AC_WID_AUD_IN) 5275 continue; 5276 cap = adc; 5277 nconns = snd_hda_get_connections(codec, cap, conn, 5278 ARRAY_SIZE(conn)); 5279 if (nconns == 1) { 5280 cap = conn[0]; 5281 nconns = snd_hda_get_connections(codec, cap, conn, 5282 ARRAY_SIZE(conn)); 5283 } 5284 if (nconns <= 0) 5285 continue; 5286 if (!fallback_adc) { 5287 fallback_adc = adc; 5288 fallback_cap = cap; 5289 } 5290 for (i = 0; i < AUTO_PIN_LAST; i++) { 5291 hda_nid_t nid = spec->autocfg.input_pins[i]; 5292 if (!nid) 5293 continue; 5294 for (j = 0; j < nconns; j++) { 5295 if (conn[j] == nid) 5296 break; 5297 } 5298 if (j >= nconns) 5299 break; 5300 } 5301 if (i >= AUTO_PIN_LAST) { 5302 int num_adcs = spec->num_adc_nids; 5303 spec->private_adc_nids[num_adcs] = adc; 5304 spec->private_capsrc_nids[num_adcs] = cap; 5305 spec->num_adc_nids++; 5306 spec->adc_nids = spec->private_adc_nids; 5307 if (adc != cap) 5308 spec->capsrc_nids = spec->private_capsrc_nids; 5309 } 5310 } 5311 if (!spec->num_adc_nids) { 5312 printk(KERN_WARNING "hda_codec: %s: no valid ADC found;" 5313 " using fallback 0x%x\n", 5314 codec->chip_name, fallback_adc); 5315 spec->private_adc_nids[0] = fallback_adc; 5316 spec->adc_nids = spec->private_adc_nids; 5317 if (fallback_adc != fallback_cap) { 5318 spec->private_capsrc_nids[0] = fallback_cap; 5319 spec->capsrc_nids = spec->private_adc_nids; 5320 } 5321 } 5322} 5323 5324#ifdef CONFIG_SND_HDA_INPUT_BEEP 5325#define set_beep_amp(spec, nid, idx, dir) \ 5326 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir)) 5327 5328static struct snd_pci_quirk beep_white_list[] = { 5329 SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1), 5330 {} 5331}; 5332 5333static inline int has_cdefine_beep(struct hda_codec *codec) 5334{ 5335 struct alc_spec *spec = codec->spec; 5336 const struct snd_pci_quirk *q; 5337 q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list); 5338 if (q) 5339 return q->value; 5340 return spec->cdefine.enable_pcbeep; 5341} 5342#else 5343#define set_beep_amp(spec, nid, idx, dir) /* NOP */ 5344#define has_cdefine_beep(codec) 0 5345#endif 5346 5347/* 5348 * OK, here we have finally the patch for ALC880 5349 */ 5350 5351static int patch_alc880(struct hda_codec *codec) 5352{ 5353 struct alc_spec *spec; 5354 int board_config; 5355 int err; 5356 5357 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 5358 if (spec == NULL) 5359 return -ENOMEM; 5360 5361 codec->spec = spec; 5362 5363 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST, 5364 alc880_models, 5365 alc880_cfg_tbl); 5366 if (board_config < 0) { 5367 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 5368 codec->chip_name); 5369 board_config = ALC880_AUTO; 5370 } 5371 5372 if (board_config == ALC880_AUTO) { 5373 /* automatic parse from the BIOS config */ 5374 err = alc880_parse_auto_config(codec); 5375 if (err < 0) { 5376 alc_free(codec); 5377 return err; 5378 } else if (!err) { 5379 printk(KERN_INFO 5380 "hda_codec: Cannot set up configuration " 5381 "from BIOS. Using 3-stack mode...\n"); 5382 board_config = ALC880_3ST; 5383 } 5384 } 5385 5386 err = snd_hda_attach_beep_device(codec, 0x1); 5387 if (err < 0) { 5388 alc_free(codec); 5389 return err; 5390 } 5391 5392 if (board_config != ALC880_AUTO) 5393 setup_preset(codec, &alc880_presets[board_config]); 5394 5395 spec->stream_analog_playback = &alc880_pcm_analog_playback; 5396 spec->stream_analog_capture = &alc880_pcm_analog_capture; 5397 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture; 5398 5399 spec->stream_digital_playback = &alc880_pcm_digital_playback; 5400 spec->stream_digital_capture = &alc880_pcm_digital_capture; 5401 5402 if (!spec->adc_nids && spec->input_mux) { 5403 /* check whether NID 0x07 is valid */ 5404 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]); 5405 /* get type */ 5406 wcap = get_wcaps_type(wcap); 5407 if (wcap != AC_WID_AUD_IN) { 5408 spec->adc_nids = alc880_adc_nids_alt; 5409 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt); 5410 } else { 5411 spec->adc_nids = alc880_adc_nids; 5412 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids); 5413 } 5414 } 5415 set_capture_mixer(codec); 5416 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 5417 5418 spec->vmaster_nid = 0x0c; 5419 5420 codec->patch_ops = alc_patch_ops; 5421 if (board_config == ALC880_AUTO) 5422 spec->init_hook = alc880_auto_init; 5423#ifdef CONFIG_SND_HDA_POWER_SAVE 5424 if (!spec->loopback.amplist) 5425 spec->loopback.amplist = alc880_loopbacks; 5426#endif 5427 5428 return 0; 5429} 5430 5431 5432/* 5433 * ALC260 support 5434 */ 5435 5436static hda_nid_t alc260_dac_nids[1] = { 5437 /* front */ 5438 0x02, 5439}; 5440 5441static hda_nid_t alc260_adc_nids[1] = { 5442 /* ADC0 */ 5443 0x04, 5444}; 5445 5446static hda_nid_t alc260_adc_nids_alt[1] = { 5447 /* ADC1 */ 5448 0x05, 5449}; 5450 5451/* NIDs used when simultaneous access to both ADCs makes sense. Note that 5452 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC. 5453 */ 5454static hda_nid_t alc260_dual_adc_nids[2] = { 5455 /* ADC0, ADC1 */ 5456 0x04, 0x05 5457}; 5458 5459#define ALC260_DIGOUT_NID 0x03 5460#define ALC260_DIGIN_NID 0x06 5461 5462static struct hda_input_mux alc260_capture_source = { 5463 .num_items = 4, 5464 .items = { 5465 { "Mic", 0x0 }, 5466 { "Front Mic", 0x1 }, 5467 { "Line", 0x2 }, 5468 { "CD", 0x4 }, 5469 }, 5470}; 5471 5472/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack, 5473 * headphone jack and the internal CD lines since these are the only pins at 5474 * which audio can appear. For flexibility, also allow the option of 5475 * recording the mixer output on the second ADC (ADC0 doesn't have a 5476 * connection to the mixer output). 5477 */ 5478static struct hda_input_mux alc260_fujitsu_capture_sources[2] = { 5479 { 5480 .num_items = 3, 5481 .items = { 5482 { "Mic/Line", 0x0 }, 5483 { "CD", 0x4 }, 5484 { "Headphone", 0x2 }, 5485 }, 5486 }, 5487 { 5488 .num_items = 4, 5489 .items = { 5490 { "Mic/Line", 0x0 }, 5491 { "CD", 0x4 }, 5492 { "Headphone", 0x2 }, 5493 { "Mixer", 0x5 }, 5494 }, 5495 }, 5496 5497}; 5498 5499/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to 5500 * the Fujitsu S702x, but jacks are marked differently. 5501 */ 5502static struct hda_input_mux alc260_acer_capture_sources[2] = { 5503 { 5504 .num_items = 4, 5505 .items = { 5506 { "Mic", 0x0 }, 5507 { "Line", 0x2 }, 5508 { "CD", 0x4 }, 5509 { "Headphone", 0x5 }, 5510 }, 5511 }, 5512 { 5513 .num_items = 5, 5514 .items = { 5515 { "Mic", 0x0 }, 5516 { "Line", 0x2 }, 5517 { "CD", 0x4 }, 5518 { "Headphone", 0x6 }, 5519 { "Mixer", 0x5 }, 5520 }, 5521 }, 5522}; 5523 5524/* Maxdata Favorit 100XS */ 5525static struct hda_input_mux alc260_favorit100_capture_sources[2] = { 5526 { 5527 .num_items = 2, 5528 .items = { 5529 { "Line/Mic", 0x0 }, 5530 { "CD", 0x4 }, 5531 }, 5532 }, 5533 { 5534 .num_items = 3, 5535 .items = { 5536 { "Line/Mic", 0x0 }, 5537 { "CD", 0x4 }, 5538 { "Mixer", 0x5 }, 5539 }, 5540 }, 5541}; 5542 5543/* 5544 * This is just place-holder, so there's something for alc_build_pcms to look 5545 * at when it calculates the maximum number of channels. ALC260 has no mixer 5546 * element which allows changing the channel mode, so the verb list is 5547 * never used. 5548 */ 5549static struct hda_channel_mode alc260_modes[1] = { 5550 { 2, NULL }, 5551}; 5552 5553 5554/* Mixer combinations 5555 * 5556 * basic: base_output + input + pc_beep + capture 5557 * HP: base_output + input + capture_alt 5558 * HP_3013: hp_3013 + input + capture 5559 * fujitsu: fujitsu + capture 5560 * acer: acer + capture 5561 */ 5562 5563static struct snd_kcontrol_new alc260_base_output_mixer[] = { 5564 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT), 5565 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT), 5566 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT), 5567 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT), 5568 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), 5569 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT), 5570 { } /* end */ 5571}; 5572 5573static struct snd_kcontrol_new alc260_input_mixer[] = { 5574 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), 5575 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), 5576 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), 5577 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT), 5578 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), 5579 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT), 5580 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT), 5581 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT), 5582 { } /* end */ 5583}; 5584 5585/* update HP, line and mono out pins according to the master switch */ 5586static void alc260_hp_master_update(struct hda_codec *codec, 5587 hda_nid_t hp, hda_nid_t line, 5588 hda_nid_t mono) 5589{ 5590 struct alc_spec *spec = codec->spec; 5591 unsigned int val = spec->master_sw ? PIN_HP : 0; 5592 /* change HP and line-out pins */ 5593 snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 5594 val); 5595 snd_hda_codec_write(codec, line, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 5596 val); 5597 /* mono (speaker) depending on the HP jack sense */ 5598 val = (val && !spec->jack_present) ? PIN_OUT : 0; 5599 snd_hda_codec_write(codec, mono, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 5600 val); 5601} 5602 5603static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol, 5604 struct snd_ctl_elem_value *ucontrol) 5605{ 5606 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 5607 struct alc_spec *spec = codec->spec; 5608 *ucontrol->value.integer.value = spec->master_sw; 5609 return 0; 5610} 5611 5612static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol, 5613 struct snd_ctl_elem_value *ucontrol) 5614{ 5615 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 5616 struct alc_spec *spec = codec->spec; 5617 int val = !!*ucontrol->value.integer.value; 5618 hda_nid_t hp, line, mono; 5619 5620 if (val == spec->master_sw) 5621 return 0; 5622 spec->master_sw = val; 5623 hp = (kcontrol->private_value >> 16) & 0xff; 5624 line = (kcontrol->private_value >> 8) & 0xff; 5625 mono = kcontrol->private_value & 0xff; 5626 alc260_hp_master_update(codec, hp, line, mono); 5627 return 1; 5628} 5629 5630static struct snd_kcontrol_new alc260_hp_output_mixer[] = { 5631 { 5632 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 5633 .name = "Master Playback Switch", 5634 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11, 5635 .info = snd_ctl_boolean_mono_info, 5636 .get = alc260_hp_master_sw_get, 5637 .put = alc260_hp_master_sw_put, 5638 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11 5639 }, 5640 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT), 5641 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT), 5642 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT), 5643 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT), 5644 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, 5645 HDA_OUTPUT), 5646 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT), 5647 { } /* end */ 5648}; 5649 5650static struct hda_verb alc260_hp_unsol_verbs[] = { 5651 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 5652 {}, 5653}; 5654 5655static void alc260_hp_automute(struct hda_codec *codec) 5656{ 5657 struct alc_spec *spec = codec->spec; 5658 5659 spec->jack_present = snd_hda_jack_detect(codec, 0x10); 5660 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11); 5661} 5662 5663static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res) 5664{ 5665 if ((res >> 26) == ALC880_HP_EVENT) 5666 alc260_hp_automute(codec); 5667} 5668 5669static struct snd_kcontrol_new alc260_hp_3013_mixer[] = { 5670 { 5671 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 5672 .name = "Master Playback Switch", 5673 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11, 5674 .info = snd_ctl_boolean_mono_info, 5675 .get = alc260_hp_master_sw_get, 5676 .put = alc260_hp_master_sw_put, 5677 .private_value = (0x15 << 16) | (0x10 << 8) | 0x11 5678 }, 5679 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT), 5680 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT), 5681 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT), 5682 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT), 5683 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT), 5684 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 5685 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), 5686 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT), 5687 { } /* end */ 5688}; 5689 5690static struct hda_bind_ctls alc260_dc7600_bind_master_vol = { 5691 .ops = &snd_hda_bind_vol, 5692 .values = { 5693 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT), 5694 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT), 5695 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT), 5696 0 5697 }, 5698}; 5699 5700static struct hda_bind_ctls alc260_dc7600_bind_switch = { 5701 .ops = &snd_hda_bind_sw, 5702 .values = { 5703 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT), 5704 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT), 5705 0 5706 }, 5707}; 5708 5709static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = { 5710 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol), 5711 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch), 5712 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT), 5713 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT), 5714 { } /* end */ 5715}; 5716 5717static struct hda_verb alc260_hp_3013_unsol_verbs[] = { 5718 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 5719 {}, 5720}; 5721 5722static void alc260_hp_3013_automute(struct hda_codec *codec) 5723{ 5724 struct alc_spec *spec = codec->spec; 5725 5726 spec->jack_present = snd_hda_jack_detect(codec, 0x15); 5727 alc260_hp_master_update(codec, 0x15, 0x10, 0x11); 5728} 5729 5730static void alc260_hp_3013_unsol_event(struct hda_codec *codec, 5731 unsigned int res) 5732{ 5733 if ((res >> 26) == ALC880_HP_EVENT) 5734 alc260_hp_3013_automute(codec); 5735} 5736 5737static void alc260_hp_3012_automute(struct hda_codec *codec) 5738{ 5739 unsigned int bits = snd_hda_jack_detect(codec, 0x10) ? 0 : PIN_OUT; 5740 5741 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 5742 bits); 5743 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 5744 bits); 5745 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 5746 bits); 5747} 5748 5749static void alc260_hp_3012_unsol_event(struct hda_codec *codec, 5750 unsigned int res) 5751{ 5752 if ((res >> 26) == ALC880_HP_EVENT) 5753 alc260_hp_3012_automute(codec); 5754} 5755 5756/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12, 5757 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10. 5758 */ 5759static struct snd_kcontrol_new alc260_fujitsu_mixer[] = { 5760 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT), 5761 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT), 5762 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT), 5763 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), 5764 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), 5765 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT), 5766 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT), 5767 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN), 5768 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT), 5769 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT), 5770 { } /* end */ 5771}; 5772 5773/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current 5774 * versions of the ALC260 don't act on requests to enable mic bias from NID 5775 * 0x0f (used to drive the headphone jack in these laptops). The ALC260 5776 * datasheet doesn't mention this restriction. At this stage it's not clear 5777 * whether this behaviour is intentional or is a hardware bug in chip 5778 * revisions available in early 2006. Therefore for now allow the 5779 * "Headphone Jack Mode" control to span all choices, but if it turns out 5780 * that the lack of mic bias for this NID is intentional we could change the 5781 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS. 5782 * 5783 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006 5784 * don't appear to make the mic bias available from the "line" jack, even 5785 * though the NID used for this jack (0x14) can supply it. The theory is 5786 * that perhaps Acer have included blocking capacitors between the ALC260 5787 * and the output jack. If this turns out to be the case for all such 5788 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT 5789 * to ALC_PIN_DIR_INOUT_NOMICBIAS. 5790 * 5791 * The C20x Tablet series have a mono internal speaker which is controlled 5792 * via the chip's Mono sum widget and pin complex, so include the necessary 5793 * controls for such models. On models without a "mono speaker" the control 5794 * won't do anything. 5795 */ 5796static struct snd_kcontrol_new alc260_acer_mixer[] = { 5797 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), 5798 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT), 5799 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT), 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, 5803 HDA_INPUT), 5804 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), 5805 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), 5806 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), 5807 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT), 5808 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN), 5809 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), 5810 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT), 5811 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT), 5812 { } /* end */ 5813}; 5814 5815/* Maxdata Favorit 100XS: one output and one input (0x12) jack 5816 */ 5817static struct snd_kcontrol_new alc260_favorit100_mixer[] = { 5818 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), 5819 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT), 5820 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT), 5821 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT), 5822 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT), 5823 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN), 5824 { } /* end */ 5825}; 5826 5827/* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12, 5828 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17. 5829 */ 5830static struct snd_kcontrol_new alc260_will_mixer[] = { 5831 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), 5832 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT), 5833 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), 5834 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT), 5835 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN), 5836 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), 5837 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT), 5838 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT), 5839 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), 5840 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), 5841 { } /* end */ 5842}; 5843 5844/* Replacer 672V ALC260 pin usage: Mic jack = 0x12, 5845 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f. 5846 */ 5847static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = { 5848 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), 5849 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT), 5850 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), 5851 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT), 5852 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN), 5853 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT), 5854 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT), 5855 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), 5856 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT), 5857 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT), 5858 { } /* end */ 5859}; 5860 5861/* 5862 * initialization verbs 5863 */ 5864static struct hda_verb alc260_init_verbs[] = { 5865 /* Line In pin widget for input */ 5866 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 5867 /* CD pin widget for input */ 5868 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 5869 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 5870 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 5871 /* Mic2 (front panel) pin widget for input and vref at 80% */ 5872 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 5873 /* LINE-2 is used for line-out in rear */ 5874 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5875 /* select line-out */ 5876 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00}, 5877 /* LINE-OUT pin */ 5878 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5879 /* enable HP */ 5880 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 5881 /* enable Mono */ 5882 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5883 /* mute capture amp left and right */ 5884 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5885 /* set connection select to line in (default select for this ADC) */ 5886 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02}, 5887 /* mute capture amp left and right */ 5888 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5889 /* set connection select to line in (default select for this ADC) */ 5890 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02}, 5891 /* set vol=0 Line-Out mixer amp left and right */ 5892 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5893 /* unmute pin widget amp left and right (no gain on this amp) */ 5894 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5895 /* set vol=0 HP mixer amp left and right */ 5896 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5897 /* unmute pin widget amp left and right (no gain on this amp) */ 5898 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5899 /* set vol=0 Mono mixer amp left and right */ 5900 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5901 /* unmute pin widget amp left and right (no gain on this amp) */ 5902 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5903 /* unmute LINE-2 out pin */ 5904 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5905 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & 5906 * Line In 2 = 0x03 5907 */ 5908 /* mute analog inputs */ 5909 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5910 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 5911 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 5912 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 5913 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 5914 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */ 5915 /* mute Front out path */ 5916 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5917 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 5918 /* mute Headphone out path */ 5919 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5920 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 5921 /* mute Mono out path */ 5922 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5923 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 5924 { } 5925}; 5926 5927#if 0 /* should be identical with alc260_init_verbs? */ 5928static struct hda_verb alc260_hp_init_verbs[] = { 5929 /* Headphone and output */ 5930 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 5931 /* mono output */ 5932 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 5933 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 5934 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 5935 /* Mic2 (front panel) pin widget for input and vref at 80% */ 5936 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 5937 /* Line In pin widget for input */ 5938 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 5939 /* Line-2 pin widget for output */ 5940 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 5941 /* CD pin widget for input */ 5942 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 5943 /* unmute amp left and right */ 5944 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000}, 5945 /* set connection select to line in (default select for this ADC) */ 5946 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02}, 5947 /* unmute Line-Out mixer amp left and right (volume = 0) */ 5948 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 5949 /* mute pin widget amp left and right (no gain on this amp) */ 5950 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 5951 /* unmute HP mixer amp left and right (volume = 0) */ 5952 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 5953 /* mute pin widget amp left and right (no gain on this amp) */ 5954 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 5955 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & 5956 * Line In 2 = 0x03 5957 */ 5958 /* mute analog inputs */ 5959 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5960 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 5961 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 5962 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 5963 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 5964 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */ 5965 /* Unmute Front out path */ 5966 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 5967 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 5968 /* Unmute Headphone out path */ 5969 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 5970 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 5971 /* Unmute Mono out path */ 5972 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 5973 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 5974 { } 5975}; 5976#endif 5977 5978static struct hda_verb alc260_hp_3013_init_verbs[] = { 5979 /* Line out and output */ 5980 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 5981 /* mono output */ 5982 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 5983 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 5984 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 5985 /* Mic2 (front panel) pin widget for input and vref at 80% */ 5986 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 5987 /* Line In pin widget for input */ 5988 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 5989 /* Headphone pin widget for output */ 5990 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 5991 /* CD pin widget for input */ 5992 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 5993 /* unmute amp left and right */ 5994 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000}, 5995 /* set connection select to line in (default select for this ADC) */ 5996 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02}, 5997 /* unmute Line-Out mixer amp left and right (volume = 0) */ 5998 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 5999 /* mute pin widget amp left and right (no gain on this amp) */ 6000 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 6001 /* unmute HP mixer amp left and right (volume = 0) */ 6002 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 6003 /* mute pin widget amp left and right (no gain on this amp) */ 6004 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 6005 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & 6006 * Line In 2 = 0x03 6007 */ 6008 /* mute analog inputs */ 6009 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6010 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6011 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 6012 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 6013 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 6014 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */ 6015 /* Unmute Front out path */ 6016 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 6017 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 6018 /* Unmute Headphone out path */ 6019 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 6020 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 6021 /* Unmute Mono out path */ 6022 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 6023 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 6024 { } 6025}; 6026 6027/* Initialisation sequence for ALC260 as configured in Fujitsu S702x 6028 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD 6029 * audio = 0x16, internal speaker = 0x10. 6030 */ 6031static struct hda_verb alc260_fujitsu_init_verbs[] = { 6032 /* Disable all GPIOs */ 6033 {0x01, AC_VERB_SET_GPIO_MASK, 0}, 6034 /* Internal speaker is connected to headphone pin */ 6035 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6036 /* Headphone/Line-out jack connects to Line1 pin; make it an output */ 6037 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6038 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */ 6039 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 6040 /* Ensure all other unused pins are disabled and muted. */ 6041 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6042 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6043 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6044 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6045 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6046 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6047 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6048 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6049 6050 /* Disable digital (SPDIF) pins */ 6051 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0}, 6052 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0}, 6053 6054 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus 6055 * when acting as an output. 6056 */ 6057 {0x0d, AC_VERB_SET_CONNECT_SEL, 0}, 6058 6059 /* Start with output sum widgets muted and their output gains at min */ 6060 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6061 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6062 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6063 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6064 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6065 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6066 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6067 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6068 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6069 6070 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */ 6071 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6072 /* Unmute Line1 pin widget output buffer since it starts as an output. 6073 * If the pin mode is changed by the user the pin mode control will 6074 * take care of enabling the pin's input/output buffers as needed. 6075 * Therefore there's no need to enable the input buffer at this 6076 * stage. 6077 */ 6078 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6079 /* Unmute input buffer of pin widget used for Line-in (no equiv 6080 * mixer ctrl) 6081 */ 6082 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6083 6084 /* Mute capture amp left and right */ 6085 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6086 /* Set ADC connection select to match default mixer setting - line 6087 * in (on mic1 pin) 6088 */ 6089 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, 6090 6091 /* Do the same for the second ADC: mute capture input amp and 6092 * set ADC connection to line in (on mic1 pin) 6093 */ 6094 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6095 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, 6096 6097 /* Mute all inputs to mixer widget (even unconnected ones) */ 6098 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */ 6099 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */ 6100 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */ 6101 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */ 6102 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */ 6103 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */ 6104 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */ 6105 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */ 6106 6107 { } 6108}; 6109 6110/* Initialisation sequence for ALC260 as configured in Acer TravelMate and 6111 * similar laptops (adapted from Fujitsu init verbs). 6112 */ 6113static struct hda_verb alc260_acer_init_verbs[] = { 6114 /* On TravelMate laptops, GPIO 0 enables the internal speaker and 6115 * the headphone jack. Turn this on and rely on the standard mute 6116 * methods whenever the user wants to turn these outputs off. 6117 */ 6118 {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, 6119 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, 6120 {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, 6121 /* Internal speaker/Headphone jack is connected to Line-out pin */ 6122 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6123 /* Internal microphone/Mic jack is connected to Mic1 pin */ 6124 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, 6125 /* Line In jack is connected to Line1 pin */ 6126 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 6127 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */ 6128 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6129 /* Ensure all other unused pins are disabled and muted. */ 6130 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6131 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6132 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6133 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6134 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6135 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6136 /* Disable digital (SPDIF) pins */ 6137 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0}, 6138 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0}, 6139 6140 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum 6141 * bus when acting as outputs. 6142 */ 6143 {0x0b, AC_VERB_SET_CONNECT_SEL, 0}, 6144 {0x0d, AC_VERB_SET_CONNECT_SEL, 0}, 6145 6146 /* Start with output sum widgets muted and their output gains at min */ 6147 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6148 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6149 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6150 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6151 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6152 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6153 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6154 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6155 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6156 6157 /* Unmute Line-out pin widget amp left and right 6158 * (no equiv mixer ctrl) 6159 */ 6160 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6161 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */ 6162 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6163 /* Unmute Mic1 and Line1 pin widget input buffers since they start as 6164 * inputs. If the pin mode is changed by the user the pin mode control 6165 * will take care of enabling the pin's input/output buffers as needed. 6166 * Therefore there's no need to enable the input buffer at this 6167 * stage. 6168 */ 6169 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6170 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6171 6172 /* Mute capture amp left and right */ 6173 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6174 /* Set ADC connection select to match default mixer setting - mic 6175 * (on mic1 pin) 6176 */ 6177 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, 6178 6179 /* Do similar with the second ADC: mute capture input amp and 6180 * set ADC connection to mic to match ALSA's default state. 6181 */ 6182 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6183 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, 6184 6185 /* Mute all inputs to mixer widget (even unconnected ones) */ 6186 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */ 6187 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */ 6188 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */ 6189 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */ 6190 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */ 6191 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */ 6192 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */ 6193 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */ 6194 6195 { } 6196}; 6197 6198/* Initialisation sequence for Maxdata Favorit 100XS 6199 * (adapted from Acer init verbs). 6200 */ 6201static struct hda_verb alc260_favorit100_init_verbs[] = { 6202 /* GPIO 0 enables the output jack. 6203 * Turn this on and rely on the standard mute 6204 * methods whenever the user wants to turn these outputs off. 6205 */ 6206 {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, 6207 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, 6208 {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, 6209 /* Line/Mic input jack is connected to Mic1 pin */ 6210 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, 6211 /* Ensure all other unused pins are disabled and muted. */ 6212 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6213 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6214 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6215 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6216 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6217 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6218 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6219 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6220 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6221 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6222 /* Disable digital (SPDIF) pins */ 6223 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0}, 6224 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0}, 6225 6226 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum 6227 * bus when acting as outputs. 6228 */ 6229 {0x0b, AC_VERB_SET_CONNECT_SEL, 0}, 6230 {0x0d, AC_VERB_SET_CONNECT_SEL, 0}, 6231 6232 /* Start with output sum widgets muted and their output gains at min */ 6233 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6234 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6235 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6236 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6237 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6238 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6239 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6240 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6241 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6242 6243 /* Unmute Line-out pin widget amp left and right 6244 * (no equiv mixer ctrl) 6245 */ 6246 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6247 /* Unmute Mic1 and Line1 pin widget input buffers since they start as 6248 * inputs. If the pin mode is changed by the user the pin mode control 6249 * will take care of enabling the pin's input/output buffers as needed. 6250 * Therefore there's no need to enable the input buffer at this 6251 * stage. 6252 */ 6253 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6254 6255 /* Mute capture amp left and right */ 6256 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6257 /* Set ADC connection select to match default mixer setting - mic 6258 * (on mic1 pin) 6259 */ 6260 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, 6261 6262 /* Do similar with the second ADC: mute capture input amp and 6263 * set ADC connection to mic to match ALSA's default state. 6264 */ 6265 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6266 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, 6267 6268 /* Mute all inputs to mixer widget (even unconnected ones) */ 6269 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */ 6270 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */ 6271 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */ 6272 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */ 6273 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */ 6274 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */ 6275 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */ 6276 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */ 6277 6278 { } 6279}; 6280 6281static struct hda_verb alc260_will_verbs[] = { 6282 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6283 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00}, 6284 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00}, 6285 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02}, 6286 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07}, 6287 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040}, 6288 {} 6289}; 6290 6291static struct hda_verb alc260_replacer_672v_verbs[] = { 6292 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02}, 6293 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07}, 6294 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050}, 6295 6296 {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, 6297 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, 6298 {0x01, AC_VERB_SET_GPIO_DATA, 0x00}, 6299 6300 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 6301 {} 6302}; 6303 6304/* toggle speaker-output according to the hp-jack state */ 6305static void alc260_replacer_672v_automute(struct hda_codec *codec) 6306{ 6307 unsigned int present; 6308 6309 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */ 6310 present = snd_hda_jack_detect(codec, 0x0f); 6311 if (present) { 6312 snd_hda_codec_write_cache(codec, 0x01, 0, 6313 AC_VERB_SET_GPIO_DATA, 1); 6314 snd_hda_codec_write_cache(codec, 0x0f, 0, 6315 AC_VERB_SET_PIN_WIDGET_CONTROL, 6316 PIN_HP); 6317 } else { 6318 snd_hda_codec_write_cache(codec, 0x01, 0, 6319 AC_VERB_SET_GPIO_DATA, 0); 6320 snd_hda_codec_write_cache(codec, 0x0f, 0, 6321 AC_VERB_SET_PIN_WIDGET_CONTROL, 6322 PIN_OUT); 6323 } 6324} 6325 6326static void alc260_replacer_672v_unsol_event(struct hda_codec *codec, 6327 unsigned int res) 6328{ 6329 if ((res >> 26) == ALC880_HP_EVENT) 6330 alc260_replacer_672v_automute(codec); 6331} 6332 6333static struct hda_verb alc260_hp_dc7600_verbs[] = { 6334 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01}, 6335 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 6336 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6337 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6338 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6339 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6340 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 6341 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 6342 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 6343 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 6344 {} 6345}; 6346 6347/* Test configuration for debugging, modelled after the ALC880 test 6348 * configuration. 6349 */ 6350#ifdef CONFIG_SND_DEBUG 6351static hda_nid_t alc260_test_dac_nids[1] = { 6352 0x02, 6353}; 6354static hda_nid_t alc260_test_adc_nids[2] = { 6355 0x04, 0x05, 6356}; 6357/* For testing the ALC260, each input MUX needs its own definition since 6358 * the signal assignments are different. This assumes that the first ADC 6359 * is NID 0x04. 6360 */ 6361static struct hda_input_mux alc260_test_capture_sources[2] = { 6362 { 6363 .num_items = 7, 6364 .items = { 6365 { "MIC1 pin", 0x0 }, 6366 { "MIC2 pin", 0x1 }, 6367 { "LINE1 pin", 0x2 }, 6368 { "LINE2 pin", 0x3 }, 6369 { "CD pin", 0x4 }, 6370 { "LINE-OUT pin", 0x5 }, 6371 { "HP-OUT pin", 0x6 }, 6372 }, 6373 }, 6374 { 6375 .num_items = 8, 6376 .items = { 6377 { "MIC1 pin", 0x0 }, 6378 { "MIC2 pin", 0x1 }, 6379 { "LINE1 pin", 0x2 }, 6380 { "LINE2 pin", 0x3 }, 6381 { "CD pin", 0x4 }, 6382 { "Mixer", 0x5 }, 6383 { "LINE-OUT pin", 0x6 }, 6384 { "HP-OUT pin", 0x7 }, 6385 }, 6386 }, 6387}; 6388static struct snd_kcontrol_new alc260_test_mixer[] = { 6389 /* Output driver widgets */ 6390 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), 6391 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT), 6392 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT), 6393 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT), 6394 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT), 6395 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT), 6396 6397 /* Modes for retasking pin widgets 6398 * Note: the ALC260 doesn't seem to act on requests to enable mic 6399 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't 6400 * mention this restriction. At this stage it's not clear whether 6401 * this behaviour is intentional or is a hardware bug in chip 6402 * revisions available at least up until early 2006. Therefore for 6403 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all 6404 * choices, but if it turns out that the lack of mic bias for these 6405 * NIDs is intentional we could change their modes from 6406 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS. 6407 */ 6408 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT), 6409 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT), 6410 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT), 6411 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT), 6412 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT), 6413 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT), 6414 6415 /* Loopback mixer controls */ 6416 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT), 6417 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT), 6418 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT), 6419 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT), 6420 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT), 6421 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT), 6422 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT), 6423 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT), 6424 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), 6425 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), 6426 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT), 6427 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT), 6428 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT), 6429 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT), 6430 6431 /* Controls for GPIO pins, assuming they are configured as outputs */ 6432 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01), 6433 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02), 6434 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04), 6435 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08), 6436 6437 /* Switches to allow the digital IO pins to be enabled. The datasheet 6438 * is ambigious as to which NID is which; testing on laptops which 6439 * make this output available should provide clarification. 6440 */ 6441 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01), 6442 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01), 6443 6444 /* A switch allowing EAPD to be enabled. Some laptops seem to use 6445 * this output to turn on an external amplifier. 6446 */ 6447 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02), 6448 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02), 6449 6450 { } /* end */ 6451}; 6452static struct hda_verb alc260_test_init_verbs[] = { 6453 /* Enable all GPIOs as outputs with an initial value of 0 */ 6454 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f}, 6455 {0x01, AC_VERB_SET_GPIO_DATA, 0x00}, 6456 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f}, 6457 6458 /* Enable retasking pins as output, initially without power amp */ 6459 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6460 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6461 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6462 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6463 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6464 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6465 6466 /* Disable digital (SPDIF) pins initially, but users can enable 6467 * them via a mixer switch. In the case of SPDIF-out, this initverb 6468 * payload also sets the generation to 0, output to be in "consumer" 6469 * PCM format, copyright asserted, no pre-emphasis and no validity 6470 * control. 6471 */ 6472 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0}, 6473 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0}, 6474 6475 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the 6476 * OUT1 sum bus when acting as an output. 6477 */ 6478 {0x0b, AC_VERB_SET_CONNECT_SEL, 0}, 6479 {0x0c, AC_VERB_SET_CONNECT_SEL, 0}, 6480 {0x0d, AC_VERB_SET_CONNECT_SEL, 0}, 6481 {0x0e, AC_VERB_SET_CONNECT_SEL, 0}, 6482 6483 /* Start with output sum widgets muted and their output gains at min */ 6484 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6485 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6486 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6487 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6488 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6489 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6490 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6491 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6492 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6493 6494 /* Unmute retasking pin widget output buffers since the default 6495 * state appears to be output. As the pin mode is changed by the 6496 * user the pin mode control will take care of enabling the pin's 6497 * input/output buffers as needed. 6498 */ 6499 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6500 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6501 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6502 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6503 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6504 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6505 /* Also unmute the mono-out pin widget */ 6506 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6507 6508 /* Mute capture amp left and right */ 6509 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6510 /* Set ADC connection select to match default mixer setting (mic1 6511 * pin) 6512 */ 6513 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, 6514 6515 /* Do the same for the second ADC: mute capture input amp and 6516 * set ADC connection to mic1 pin 6517 */ 6518 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6519 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, 6520 6521 /* Mute all inputs to mixer widget (even unconnected ones) */ 6522 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */ 6523 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */ 6524 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */ 6525 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */ 6526 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */ 6527 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */ 6528 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */ 6529 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */ 6530 6531 { } 6532}; 6533#endif 6534 6535#define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback 6536#define alc260_pcm_analog_capture alc880_pcm_analog_capture 6537 6538#define alc260_pcm_digital_playback alc880_pcm_digital_playback 6539#define alc260_pcm_digital_capture alc880_pcm_digital_capture 6540 6541/* 6542 * for BIOS auto-configuration 6543 */ 6544 6545static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid, 6546 const char *pfx, int *vol_bits) 6547{ 6548 hda_nid_t nid_vol; 6549 unsigned long vol_val, sw_val; 6550 int err; 6551 6552 if (nid >= 0x0f && nid < 0x11) { 6553 nid_vol = nid - 0x7; 6554 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT); 6555 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT); 6556 } else if (nid == 0x11) { 6557 nid_vol = nid - 0x7; 6558 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT); 6559 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT); 6560 } else if (nid >= 0x12 && nid <= 0x15) { 6561 nid_vol = 0x08; 6562 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT); 6563 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT); 6564 } else 6565 return 0; /* N/A */ 6566 6567 if (!(*vol_bits & (1 << nid_vol))) { 6568 /* first control for the volume widget */ 6569 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, vol_val); 6570 if (err < 0) 6571 return err; 6572 *vol_bits |= (1 << nid_vol); 6573 } 6574 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, sw_val); 6575 if (err < 0) 6576 return err; 6577 return 1; 6578} 6579 6580/* add playback controls from the parsed DAC table */ 6581static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec, 6582 const struct auto_pin_cfg *cfg) 6583{ 6584 hda_nid_t nid; 6585 int err; 6586 int vols = 0; 6587 6588 spec->multiout.num_dacs = 1; 6589 spec->multiout.dac_nids = spec->private_dac_nids; 6590 spec->multiout.dac_nids[0] = 0x02; 6591 6592 nid = cfg->line_out_pins[0]; 6593 if (nid) { 6594 const char *pfx; 6595 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0]) 6596 pfx = "Master"; 6597 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) 6598 pfx = "Speaker"; 6599 else 6600 pfx = "Front"; 6601 err = alc260_add_playback_controls(spec, nid, pfx, &vols); 6602 if (err < 0) 6603 return err; 6604 } 6605 6606 nid = cfg->speaker_pins[0]; 6607 if (nid) { 6608 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols); 6609 if (err < 0) 6610 return err; 6611 } 6612 6613 nid = cfg->hp_pins[0]; 6614 if (nid) { 6615 err = alc260_add_playback_controls(spec, nid, "Headphone", 6616 &vols); 6617 if (err < 0) 6618 return err; 6619 } 6620 return 0; 6621} 6622 6623/* create playback/capture controls for input pins */ 6624static int alc260_auto_create_input_ctls(struct hda_codec *codec, 6625 const struct auto_pin_cfg *cfg) 6626{ 6627 return alc_auto_create_input_ctls(codec, cfg, 0x07, 0x04, 0x05); 6628} 6629 6630static void alc260_auto_set_output_and_unmute(struct hda_codec *codec, 6631 hda_nid_t nid, int pin_type, 6632 int sel_idx) 6633{ 6634 alc_set_pin_output(codec, nid, pin_type); 6635 /* need the manual connection? */ 6636 if (nid >= 0x12) { 6637 int idx = nid - 0x12; 6638 snd_hda_codec_write(codec, idx + 0x0b, 0, 6639 AC_VERB_SET_CONNECT_SEL, sel_idx); 6640 } 6641} 6642 6643static void alc260_auto_init_multi_out(struct hda_codec *codec) 6644{ 6645 struct alc_spec *spec = codec->spec; 6646 hda_nid_t nid; 6647 6648 nid = spec->autocfg.line_out_pins[0]; 6649 if (nid) { 6650 int pin_type = get_pin_type(spec->autocfg.line_out_type); 6651 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0); 6652 } 6653 6654 nid = spec->autocfg.speaker_pins[0]; 6655 if (nid) 6656 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0); 6657 6658 nid = spec->autocfg.hp_pins[0]; 6659 if (nid) 6660 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0); 6661} 6662 6663#define ALC260_PIN_CD_NID 0x16 6664static void alc260_auto_init_analog_input(struct hda_codec *codec) 6665{ 6666 struct alc_spec *spec = codec->spec; 6667 int i; 6668 6669 for (i = 0; i < AUTO_PIN_LAST; i++) { 6670 hda_nid_t nid = spec->autocfg.input_pins[i]; 6671 if (nid >= 0x12) { 6672 alc_set_input_pin(codec, nid, i); 6673 if (nid != ALC260_PIN_CD_NID && 6674 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)) 6675 snd_hda_codec_write(codec, nid, 0, 6676 AC_VERB_SET_AMP_GAIN_MUTE, 6677 AMP_OUT_MUTE); 6678 } 6679 } 6680} 6681 6682#define alc260_auto_init_input_src alc880_auto_init_input_src 6683 6684/* 6685 * generic initialization of ADC, input mixers and output mixers 6686 */ 6687static struct hda_verb alc260_volume_init_verbs[] = { 6688 /* 6689 * Unmute ADC0-1 and set the default input to mic-in 6690 */ 6691 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, 6692 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6693 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, 6694 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6695 6696 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 6697 * mixer widget 6698 * Note: PASD motherboards uses the Line In 2 as the input for 6699 * front panel mic (mic 2) 6700 */ 6701 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 6702 /* mute analog inputs */ 6703 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6704 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6705 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 6706 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 6707 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 6708 6709 /* 6710 * Set up output mixers (0x08 - 0x0a) 6711 */ 6712 /* set vol=0 to output mixers */ 6713 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6714 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6715 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6716 /* set up input amps for analog loopback */ 6717 /* Amp Indices: DAC = 0, mixer = 1 */ 6718 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6719 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 6720 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6721 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 6722 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6723 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 6724 6725 { } 6726}; 6727 6728static int alc260_parse_auto_config(struct hda_codec *codec) 6729{ 6730 struct alc_spec *spec = codec->spec; 6731 int err; 6732 static hda_nid_t alc260_ignore[] = { 0x17, 0 }; 6733 6734 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 6735 alc260_ignore); 6736 if (err < 0) 6737 return err; 6738 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg); 6739 if (err < 0) 6740 return err; 6741 if (!spec->kctls.list) 6742 return 0; /* can't find valid BIOS pin config */ 6743 err = alc260_auto_create_input_ctls(codec, &spec->autocfg); 6744 if (err < 0) 6745 return err; 6746 6747 spec->multiout.max_channels = 2; 6748 6749 if (spec->autocfg.dig_outs) 6750 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID; 6751 if (spec->kctls.list) 6752 add_mixer(spec, spec->kctls.list); 6753 6754 add_verb(spec, alc260_volume_init_verbs); 6755 6756 spec->num_mux_defs = 1; 6757 spec->input_mux = &spec->private_imux[0]; 6758 6759 alc_ssid_check(codec, 0x10, 0x15, 0x0f, 0); 6760 6761 return 1; 6762} 6763 6764/* additional initialization for auto-configuration model */ 6765static void alc260_auto_init(struct hda_codec *codec) 6766{ 6767 struct alc_spec *spec = codec->spec; 6768 alc260_auto_init_multi_out(codec); 6769 alc260_auto_init_analog_input(codec); 6770 alc260_auto_init_input_src(codec); 6771 alc_auto_init_digital(codec); 6772 if (spec->unsol_event) 6773 alc_inithook(codec); 6774} 6775 6776#ifdef CONFIG_SND_HDA_POWER_SAVE 6777static struct hda_amp_list alc260_loopbacks[] = { 6778 { 0x07, HDA_INPUT, 0 }, 6779 { 0x07, HDA_INPUT, 1 }, 6780 { 0x07, HDA_INPUT, 2 }, 6781 { 0x07, HDA_INPUT, 3 }, 6782 { 0x07, HDA_INPUT, 4 }, 6783 { } /* end */ 6784}; 6785#endif 6786 6787/* 6788 * ALC260 configurations 6789 */ 6790static const char *alc260_models[ALC260_MODEL_LAST] = { 6791 [ALC260_BASIC] = "basic", 6792 [ALC260_HP] = "hp", 6793 [ALC260_HP_3013] = "hp-3013", 6794 [ALC260_HP_DC7600] = "hp-dc7600", 6795 [ALC260_FUJITSU_S702X] = "fujitsu", 6796 [ALC260_ACER] = "acer", 6797 [ALC260_WILL] = "will", 6798 [ALC260_REPLACER_672V] = "replacer", 6799 [ALC260_FAVORIT100] = "favorit100", 6800#ifdef CONFIG_SND_DEBUG 6801 [ALC260_TEST] = "test", 6802#endif 6803 [ALC260_AUTO] = "auto", 6804}; 6805 6806static struct snd_pci_quirk alc260_cfg_tbl[] = { 6807 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER), 6808 SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL), 6809 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER), 6810 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100), 6811 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013), 6812 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_AUTO), /* no quirk */ 6813 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013), 6814 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013), 6815 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600), 6816 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013), 6817 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP), 6818 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP), 6819 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP), 6820 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC), 6821 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC), 6822 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC), 6823 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X), 6824 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC), 6825 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V), 6826 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL), 6827 {} 6828}; 6829 6830static struct alc_config_preset alc260_presets[] = { 6831 [ALC260_BASIC] = { 6832 .mixers = { alc260_base_output_mixer, 6833 alc260_input_mixer }, 6834 .init_verbs = { alc260_init_verbs }, 6835 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 6836 .dac_nids = alc260_dac_nids, 6837 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids), 6838 .adc_nids = alc260_dual_adc_nids, 6839 .num_channel_mode = ARRAY_SIZE(alc260_modes), 6840 .channel_mode = alc260_modes, 6841 .input_mux = &alc260_capture_source, 6842 }, 6843 [ALC260_HP] = { 6844 .mixers = { alc260_hp_output_mixer, 6845 alc260_input_mixer }, 6846 .init_verbs = { alc260_init_verbs, 6847 alc260_hp_unsol_verbs }, 6848 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 6849 .dac_nids = alc260_dac_nids, 6850 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt), 6851 .adc_nids = alc260_adc_nids_alt, 6852 .num_channel_mode = ARRAY_SIZE(alc260_modes), 6853 .channel_mode = alc260_modes, 6854 .input_mux = &alc260_capture_source, 6855 .unsol_event = alc260_hp_unsol_event, 6856 .init_hook = alc260_hp_automute, 6857 }, 6858 [ALC260_HP_DC7600] = { 6859 .mixers = { alc260_hp_dc7600_mixer, 6860 alc260_input_mixer }, 6861 .init_verbs = { alc260_init_verbs, 6862 alc260_hp_dc7600_verbs }, 6863 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 6864 .dac_nids = alc260_dac_nids, 6865 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt), 6866 .adc_nids = alc260_adc_nids_alt, 6867 .num_channel_mode = ARRAY_SIZE(alc260_modes), 6868 .channel_mode = alc260_modes, 6869 .input_mux = &alc260_capture_source, 6870 .unsol_event = alc260_hp_3012_unsol_event, 6871 .init_hook = alc260_hp_3012_automute, 6872 }, 6873 [ALC260_HP_3013] = { 6874 .mixers = { alc260_hp_3013_mixer, 6875 alc260_input_mixer }, 6876 .init_verbs = { alc260_hp_3013_init_verbs, 6877 alc260_hp_3013_unsol_verbs }, 6878 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 6879 .dac_nids = alc260_dac_nids, 6880 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt), 6881 .adc_nids = alc260_adc_nids_alt, 6882 .num_channel_mode = ARRAY_SIZE(alc260_modes), 6883 .channel_mode = alc260_modes, 6884 .input_mux = &alc260_capture_source, 6885 .unsol_event = alc260_hp_3013_unsol_event, 6886 .init_hook = alc260_hp_3013_automute, 6887 }, 6888 [ALC260_FUJITSU_S702X] = { 6889 .mixers = { alc260_fujitsu_mixer }, 6890 .init_verbs = { alc260_fujitsu_init_verbs }, 6891 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 6892 .dac_nids = alc260_dac_nids, 6893 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids), 6894 .adc_nids = alc260_dual_adc_nids, 6895 .num_channel_mode = ARRAY_SIZE(alc260_modes), 6896 .channel_mode = alc260_modes, 6897 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources), 6898 .input_mux = alc260_fujitsu_capture_sources, 6899 }, 6900 [ALC260_ACER] = { 6901 .mixers = { alc260_acer_mixer }, 6902 .init_verbs = { alc260_acer_init_verbs }, 6903 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 6904 .dac_nids = alc260_dac_nids, 6905 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids), 6906 .adc_nids = alc260_dual_adc_nids, 6907 .num_channel_mode = ARRAY_SIZE(alc260_modes), 6908 .channel_mode = alc260_modes, 6909 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources), 6910 .input_mux = alc260_acer_capture_sources, 6911 }, 6912 [ALC260_FAVORIT100] = { 6913 .mixers = { alc260_favorit100_mixer }, 6914 .init_verbs = { alc260_favorit100_init_verbs }, 6915 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 6916 .dac_nids = alc260_dac_nids, 6917 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids), 6918 .adc_nids = alc260_dual_adc_nids, 6919 .num_channel_mode = ARRAY_SIZE(alc260_modes), 6920 .channel_mode = alc260_modes, 6921 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources), 6922 .input_mux = alc260_favorit100_capture_sources, 6923 }, 6924 [ALC260_WILL] = { 6925 .mixers = { alc260_will_mixer }, 6926 .init_verbs = { alc260_init_verbs, alc260_will_verbs }, 6927 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 6928 .dac_nids = alc260_dac_nids, 6929 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids), 6930 .adc_nids = alc260_adc_nids, 6931 .dig_out_nid = ALC260_DIGOUT_NID, 6932 .num_channel_mode = ARRAY_SIZE(alc260_modes), 6933 .channel_mode = alc260_modes, 6934 .input_mux = &alc260_capture_source, 6935 }, 6936 [ALC260_REPLACER_672V] = { 6937 .mixers = { alc260_replacer_672v_mixer }, 6938 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs }, 6939 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 6940 .dac_nids = alc260_dac_nids, 6941 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids), 6942 .adc_nids = alc260_adc_nids, 6943 .dig_out_nid = ALC260_DIGOUT_NID, 6944 .num_channel_mode = ARRAY_SIZE(alc260_modes), 6945 .channel_mode = alc260_modes, 6946 .input_mux = &alc260_capture_source, 6947 .unsol_event = alc260_replacer_672v_unsol_event, 6948 .init_hook = alc260_replacer_672v_automute, 6949 }, 6950#ifdef CONFIG_SND_DEBUG 6951 [ALC260_TEST] = { 6952 .mixers = { alc260_test_mixer }, 6953 .init_verbs = { alc260_test_init_verbs }, 6954 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids), 6955 .dac_nids = alc260_test_dac_nids, 6956 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids), 6957 .adc_nids = alc260_test_adc_nids, 6958 .num_channel_mode = ARRAY_SIZE(alc260_modes), 6959 .channel_mode = alc260_modes, 6960 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources), 6961 .input_mux = alc260_test_capture_sources, 6962 }, 6963#endif 6964}; 6965 6966static int patch_alc260(struct hda_codec *codec) 6967{ 6968 struct alc_spec *spec; 6969 int err, board_config; 6970 6971 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 6972 if (spec == NULL) 6973 return -ENOMEM; 6974 6975 codec->spec = spec; 6976 6977 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST, 6978 alc260_models, 6979 alc260_cfg_tbl); 6980 if (board_config < 0) { 6981 snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 6982 codec->chip_name); 6983 board_config = ALC260_AUTO; 6984 } 6985 6986 if (board_config == ALC260_AUTO) { 6987 /* automatic parse from the BIOS config */ 6988 err = alc260_parse_auto_config(codec); 6989 if (err < 0) { 6990 alc_free(codec); 6991 return err; 6992 } else if (!err) { 6993 printk(KERN_INFO 6994 "hda_codec: Cannot set up configuration " 6995 "from BIOS. Using base mode...\n"); 6996 board_config = ALC260_BASIC; 6997 } 6998 } 6999 7000 err = snd_hda_attach_beep_device(codec, 0x1); 7001 if (err < 0) { 7002 alc_free(codec); 7003 return err; 7004 } 7005 7006 if (board_config != ALC260_AUTO) 7007 setup_preset(codec, &alc260_presets[board_config]); 7008 7009 spec->stream_analog_playback = &alc260_pcm_analog_playback; 7010 spec->stream_analog_capture = &alc260_pcm_analog_capture; 7011 7012 spec->stream_digital_playback = &alc260_pcm_digital_playback; 7013 spec->stream_digital_capture = &alc260_pcm_digital_capture; 7014 7015 if (!spec->adc_nids && spec->input_mux) { 7016 /* check whether NID 0x04 is valid */ 7017 unsigned int wcap = get_wcaps(codec, 0x04); 7018 wcap = get_wcaps_type(wcap); 7019 /* get type */ 7020 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) { 7021 spec->adc_nids = alc260_adc_nids_alt; 7022 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt); 7023 } else { 7024 spec->adc_nids = alc260_adc_nids; 7025 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids); 7026 } 7027 } 7028 set_capture_mixer(codec); 7029 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT); 7030 7031 spec->vmaster_nid = 0x08; 7032 7033 codec->patch_ops = alc_patch_ops; 7034 if (board_config == ALC260_AUTO) 7035 spec->init_hook = alc260_auto_init; 7036#ifdef CONFIG_SND_HDA_POWER_SAVE 7037 if (!spec->loopback.amplist) 7038 spec->loopback.amplist = alc260_loopbacks; 7039#endif 7040 7041 return 0; 7042} 7043 7044 7045/* 7046 * ALC882/883/885/888/889 support 7047 * 7048 * ALC882 is almost identical with ALC880 but has cleaner and more flexible 7049 * configuration. Each pin widget can choose any input DACs and a mixer. 7050 * Each ADC is connected from a mixer of all inputs. This makes possible 7051 * 6-channel independent captures. 7052 * 7053 * In addition, an independent DAC for the multi-playback (not used in this 7054 * driver yet). 7055 */ 7056#define ALC882_DIGOUT_NID 0x06 7057#define ALC882_DIGIN_NID 0x0a 7058#define ALC883_DIGOUT_NID ALC882_DIGOUT_NID 7059#define ALC883_DIGIN_NID ALC882_DIGIN_NID 7060#define ALC1200_DIGOUT_NID 0x10 7061 7062 7063static struct hda_channel_mode alc882_ch_modes[1] = { 7064 { 8, NULL } 7065}; 7066 7067/* DACs */ 7068static hda_nid_t alc882_dac_nids[4] = { 7069 /* front, rear, clfe, rear_surr */ 7070 0x02, 0x03, 0x04, 0x05 7071}; 7072#define alc883_dac_nids alc882_dac_nids 7073 7074/* ADCs */ 7075#define alc882_adc_nids alc880_adc_nids 7076#define alc882_adc_nids_alt alc880_adc_nids_alt 7077#define alc883_adc_nids alc882_adc_nids_alt 7078static hda_nid_t alc883_adc_nids_alt[1] = { 0x08 }; 7079static hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 }; 7080#define alc889_adc_nids alc880_adc_nids 7081 7082static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 }; 7083static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 }; 7084#define alc883_capsrc_nids alc882_capsrc_nids_alt 7085static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 }; 7086#define alc889_capsrc_nids alc882_capsrc_nids 7087 7088/* input MUX */ 7089/* FIXME: should be a matrix-type input source selection */ 7090 7091static struct hda_input_mux alc882_capture_source = { 7092 .num_items = 4, 7093 .items = { 7094 { "Mic", 0x0 }, 7095 { "Front Mic", 0x1 }, 7096 { "Line", 0x2 }, 7097 { "CD", 0x4 }, 7098 }, 7099}; 7100 7101#define alc883_capture_source alc882_capture_source 7102 7103static struct hda_input_mux alc889_capture_source = { 7104 .num_items = 3, 7105 .items = { 7106 { "Front Mic", 0x0 }, 7107 { "Mic", 0x3 }, 7108 { "Line", 0x2 }, 7109 }, 7110}; 7111 7112static struct hda_input_mux mb5_capture_source = { 7113 .num_items = 3, 7114 .items = { 7115 { "Mic", 0x1 }, 7116 { "Line", 0x7 }, 7117 { "CD", 0x4 }, 7118 }, 7119}; 7120 7121static struct hda_input_mux macmini3_capture_source = { 7122 .num_items = 2, 7123 .items = { 7124 { "Line", 0x2 }, 7125 { "CD", 0x4 }, 7126 }, 7127}; 7128 7129static struct hda_input_mux alc883_3stack_6ch_intel = { 7130 .num_items = 4, 7131 .items = { 7132 { "Mic", 0x1 }, 7133 { "Front Mic", 0x0 }, 7134 { "Line", 0x2 }, 7135 { "CD", 0x4 }, 7136 }, 7137}; 7138 7139static struct hda_input_mux alc883_lenovo_101e_capture_source = { 7140 .num_items = 2, 7141 .items = { 7142 { "Mic", 0x1 }, 7143 { "Line", 0x2 }, 7144 }, 7145}; 7146 7147static struct hda_input_mux alc883_lenovo_nb0763_capture_source = { 7148 .num_items = 4, 7149 .items = { 7150 { "Mic", 0x0 }, 7151 { "Int Mic", 0x1 }, 7152 { "Line", 0x2 }, 7153 { "CD", 0x4 }, 7154 }, 7155}; 7156 7157static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = { 7158 .num_items = 2, 7159 .items = { 7160 { "Mic", 0x0 }, 7161 { "Int Mic", 0x1 }, 7162 }, 7163}; 7164 7165static struct hda_input_mux alc883_lenovo_sky_capture_source = { 7166 .num_items = 3, 7167 .items = { 7168 { "Mic", 0x0 }, 7169 { "Front Mic", 0x1 }, 7170 { "Line", 0x4 }, 7171 }, 7172}; 7173 7174static struct hda_input_mux alc883_asus_eee1601_capture_source = { 7175 .num_items = 2, 7176 .items = { 7177 { "Mic", 0x0 }, 7178 { "Line", 0x2 }, 7179 }, 7180}; 7181 7182static struct hda_input_mux alc889A_mb31_capture_source = { 7183 .num_items = 2, 7184 .items = { 7185 { "Mic", 0x0 }, 7186 /* Front Mic (0x01) unused */ 7187 { "Line", 0x2 }, 7188 /* Line 2 (0x03) unused */ 7189 /* CD (0x04) unused? */ 7190 }, 7191}; 7192 7193static struct hda_input_mux alc889A_imac91_capture_source = { 7194 .num_items = 2, 7195 .items = { 7196 { "Mic", 0x01 }, 7197 { "Line", 0x2 }, /* Not sure! */ 7198 }, 7199}; 7200 7201/* 7202 * 2ch mode 7203 */ 7204static struct hda_channel_mode alc883_3ST_2ch_modes[1] = { 7205 { 2, NULL } 7206}; 7207 7208/* 7209 * 2ch mode 7210 */ 7211static struct hda_verb alc882_3ST_ch2_init[] = { 7212 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 7213 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7214 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 7215 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7216 { } /* end */ 7217}; 7218 7219/* 7220 * 4ch mode 7221 */ 7222static struct hda_verb alc882_3ST_ch4_init[] = { 7223 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 7224 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7225 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7226 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7227 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7228 { } /* end */ 7229}; 7230 7231/* 7232 * 6ch mode 7233 */ 7234static struct hda_verb alc882_3ST_ch6_init[] = { 7235 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7236 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7237 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, 7238 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7239 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7240 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7241 { } /* end */ 7242}; 7243 7244static struct hda_channel_mode alc882_3ST_6ch_modes[3] = { 7245 { 2, alc882_3ST_ch2_init }, 7246 { 4, alc882_3ST_ch4_init }, 7247 { 6, alc882_3ST_ch6_init }, 7248}; 7249 7250#define alc883_3ST_6ch_modes alc882_3ST_6ch_modes 7251 7252/* 7253 * 2ch mode 7254 */ 7255static struct hda_verb alc883_3ST_ch2_clevo_init[] = { 7256 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, 7257 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 7258 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7259 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 7260 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7261 { } /* end */ 7262}; 7263 7264/* 7265 * 4ch mode 7266 */ 7267static struct hda_verb alc883_3ST_ch4_clevo_init[] = { 7268 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7269 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 7270 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7271 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7272 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7273 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7274 { } /* end */ 7275}; 7276 7277/* 7278 * 6ch mode 7279 */ 7280static struct hda_verb alc883_3ST_ch6_clevo_init[] = { 7281 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7282 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7283 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7284 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, 7285 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7286 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7287 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7288 { } /* end */ 7289}; 7290 7291static struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = { 7292 { 2, alc883_3ST_ch2_clevo_init }, 7293 { 4, alc883_3ST_ch4_clevo_init }, 7294 { 6, alc883_3ST_ch6_clevo_init }, 7295}; 7296 7297 7298/* 7299 * 6ch mode 7300 */ 7301static struct hda_verb alc882_sixstack_ch6_init[] = { 7302 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 7303 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7304 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7305 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7306 { } /* end */ 7307}; 7308 7309/* 7310 * 8ch mode 7311 */ 7312static struct hda_verb alc882_sixstack_ch8_init[] = { 7313 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7314 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7315 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7316 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7317 { } /* end */ 7318}; 7319 7320static struct hda_channel_mode alc882_sixstack_modes[2] = { 7321 { 6, alc882_sixstack_ch6_init }, 7322 { 8, alc882_sixstack_ch8_init }, 7323}; 7324 7325 7326/* Macbook Air 2,1 */ 7327 7328static struct hda_channel_mode alc885_mba21_ch_modes[1] = { 7329 { 2, NULL }, 7330}; 7331 7332/* 7333 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic 7334 */ 7335 7336/* 7337 * 2ch mode 7338 */ 7339static struct hda_verb alc885_mbp_ch2_init[] = { 7340 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 7341 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7342 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7343 { } /* end */ 7344}; 7345 7346/* 7347 * 4ch mode 7348 */ 7349static struct hda_verb alc885_mbp_ch4_init[] = { 7350 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7351 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7352 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7353 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7354 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 7355 { } /* end */ 7356}; 7357 7358static struct hda_channel_mode alc885_mbp_4ch_modes[2] = { 7359 { 2, alc885_mbp_ch2_init }, 7360 { 4, alc885_mbp_ch4_init }, 7361}; 7362 7363/* 7364 * 2ch 7365 * Speakers/Woofer/HP = Front 7366 * LineIn = Input 7367 */ 7368static struct hda_verb alc885_mb5_ch2_init[] = { 7369 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 7370 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 7371 { } /* end */ 7372}; 7373 7374/* 7375 * 6ch mode 7376 * Speakers/HP = Front 7377 * Woofer = LFE 7378 * LineIn = Surround 7379 */ 7380static struct hda_verb alc885_mb5_ch6_init[] = { 7381 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 7382 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7383 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 7384 { } /* end */ 7385}; 7386 7387static struct hda_channel_mode alc885_mb5_6ch_modes[2] = { 7388 { 2, alc885_mb5_ch2_init }, 7389 { 6, alc885_mb5_ch6_init }, 7390}; 7391 7392#define alc885_macmini3_6ch_modes alc885_mb5_6ch_modes 7393 7394/* 7395 * 2ch mode 7396 */ 7397static struct hda_verb alc883_4ST_ch2_init[] = { 7398 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7399 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7400 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 7401 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7402 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 7403 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7404 { } /* end */ 7405}; 7406 7407/* 7408 * 4ch mode 7409 */ 7410static struct hda_verb alc883_4ST_ch4_init[] = { 7411 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7412 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7413 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 7414 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7415 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7416 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7417 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7418 { } /* end */ 7419}; 7420 7421/* 7422 * 6ch mode 7423 */ 7424static struct hda_verb alc883_4ST_ch6_init[] = { 7425 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7426 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7427 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7428 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7429 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, 7430 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7431 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7432 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7433 { } /* end */ 7434}; 7435 7436/* 7437 * 8ch mode 7438 */ 7439static struct hda_verb alc883_4ST_ch8_init[] = { 7440 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7441 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7442 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 }, 7443 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7444 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7445 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, 7446 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7447 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7448 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7449 { } /* end */ 7450}; 7451 7452static struct hda_channel_mode alc883_4ST_8ch_modes[4] = { 7453 { 2, alc883_4ST_ch2_init }, 7454 { 4, alc883_4ST_ch4_init }, 7455 { 6, alc883_4ST_ch6_init }, 7456 { 8, alc883_4ST_ch8_init }, 7457}; 7458 7459 7460/* 7461 * 2ch mode 7462 */ 7463static struct hda_verb alc883_3ST_ch2_intel_init[] = { 7464 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 7465 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7466 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 7467 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7468 { } /* end */ 7469}; 7470 7471/* 7472 * 4ch mode 7473 */ 7474static struct hda_verb alc883_3ST_ch4_intel_init[] = { 7475 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 7476 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7477 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7478 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7479 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7480 { } /* end */ 7481}; 7482 7483/* 7484 * 6ch mode 7485 */ 7486static struct hda_verb alc883_3ST_ch6_intel_init[] = { 7487 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7488 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7489 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 }, 7490 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7491 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7492 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7493 { } /* end */ 7494}; 7495 7496static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = { 7497 { 2, alc883_3ST_ch2_intel_init }, 7498 { 4, alc883_3ST_ch4_intel_init }, 7499 { 6, alc883_3ST_ch6_intel_init }, 7500}; 7501 7502/* 7503 * 2ch mode 7504 */ 7505static struct hda_verb alc889_ch2_intel_init[] = { 7506 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 }, 7507 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 }, 7508 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 }, 7509 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00 }, 7510 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 7511 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7512 { } /* end */ 7513}; 7514 7515/* 7516 * 6ch mode 7517 */ 7518static struct hda_verb alc889_ch6_intel_init[] = { 7519 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 }, 7520 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7521 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 }, 7522 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 }, 7523 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 7524 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7525 { } /* end */ 7526}; 7527 7528/* 7529 * 8ch mode 7530 */ 7531static struct hda_verb alc889_ch8_intel_init[] = { 7532 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 }, 7533 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7534 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 }, 7535 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 }, 7536 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x03 }, 7537 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7538 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7539 { } /* end */ 7540}; 7541 7542static struct hda_channel_mode alc889_8ch_intel_modes[3] = { 7543 { 2, alc889_ch2_intel_init }, 7544 { 6, alc889_ch6_intel_init }, 7545 { 8, alc889_ch8_intel_init }, 7546}; 7547 7548/* 7549 * 6ch mode 7550 */ 7551static struct hda_verb alc883_sixstack_ch6_init[] = { 7552 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 7553 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7554 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7555 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7556 { } /* end */ 7557}; 7558 7559/* 7560 * 8ch mode 7561 */ 7562static struct hda_verb alc883_sixstack_ch8_init[] = { 7563 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7564 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7565 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7566 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7567 { } /* end */ 7568}; 7569 7570static struct hda_channel_mode alc883_sixstack_modes[2] = { 7571 { 6, alc883_sixstack_ch6_init }, 7572 { 8, alc883_sixstack_ch8_init }, 7573}; 7574 7575 7576/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 7577 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b 7578 */ 7579static struct snd_kcontrol_new alc882_base_mixer[] = { 7580 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7581 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 7582 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 7583 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 7584 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 7585 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 7586 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 7587 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 7588 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 7589 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 7590 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 7591 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 7592 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 7593 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 7594 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 7595 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7596 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 7597 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7598 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 7599 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 7600 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 7601 { } /* end */ 7602}; 7603 7604/* Macbook Air 2,1 same control for HP and internal Speaker */ 7605 7606static struct snd_kcontrol_new alc885_mba21_mixer[] = { 7607 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 7608 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT), 7609 { } 7610}; 7611 7612 7613static struct snd_kcontrol_new alc885_mbp3_mixer[] = { 7614 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 7615 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT), 7616 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT), 7617 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0e, 0x02, HDA_INPUT), 7618 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT), 7619 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 7620 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 7621 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT), 7622 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT), 7623 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT), 7624 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT), 7625 { } /* end */ 7626}; 7627 7628static struct snd_kcontrol_new alc885_mb5_mixer[] = { 7629 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 7630 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT), 7631 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT), 7632 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT), 7633 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT), 7634 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT), 7635 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT), 7636 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT), 7637 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT), 7638 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT), 7639 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 7640 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 7641 HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT), 7642 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0x00, HDA_INPUT), 7643 { } /* end */ 7644}; 7645 7646static struct snd_kcontrol_new alc885_macmini3_mixer[] = { 7647 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 7648 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT), 7649 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT), 7650 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT), 7651 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT), 7652 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT), 7653 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT), 7654 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT), 7655 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT), 7656 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT), 7657 HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT), 7658 { } /* end */ 7659}; 7660 7661static struct snd_kcontrol_new alc885_imac91_mixer[] = { 7662 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 7663 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT), 7664 { } /* end */ 7665}; 7666 7667 7668static struct snd_kcontrol_new alc882_w2jc_mixer[] = { 7669 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7670 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 7671 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 7672 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 7673 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 7674 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 7675 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7676 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 7677 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7678 { } /* end */ 7679}; 7680 7681static struct snd_kcontrol_new alc882_targa_mixer[] = { 7682 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7683 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 7684 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 7685 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 7686 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 7687 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 7688 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 7689 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7690 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7691 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 7692 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 7693 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 7694 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 7695 { } /* end */ 7696}; 7697 7698/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ??? 7699 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c 7700 */ 7701static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = { 7702 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7703 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 7704 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 7705 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT), 7706 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 7707 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 7708 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 7709 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 7710 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT), 7711 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT), 7712 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7713 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7714 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 7715 { } /* end */ 7716}; 7717 7718static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = { 7719 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7720 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 7721 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 7722 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 7723 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 7724 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 7725 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 7726 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7727 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 7728 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7729 { } /* end */ 7730}; 7731 7732static struct snd_kcontrol_new alc882_chmode_mixer[] = { 7733 { 7734 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 7735 .name = "Channel Mode", 7736 .info = alc_ch_mode_info, 7737 .get = alc_ch_mode_get, 7738 .put = alc_ch_mode_put, 7739 }, 7740 { } /* end */ 7741}; 7742 7743static struct hda_verb alc882_base_init_verbs[] = { 7744 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 7745 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7746 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7747 /* Rear mixer */ 7748 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7749 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7750 /* CLFE mixer */ 7751 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7752 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7753 /* Side mixer */ 7754 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7755 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7756 7757 /* Front Pin: output 0 (0x0c) */ 7758 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 7759 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7760 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 7761 /* Rear Pin: output 1 (0x0d) */ 7762 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 7763 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7764 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 7765 /* CLFE Pin: output 2 (0x0e) */ 7766 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 7767 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7768 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, 7769 /* Side Pin: output 3 (0x0f) */ 7770 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 7771 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7772 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, 7773 /* Mic (rear) pin: input vref at 80% */ 7774 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 7775 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 7776 /* Front Mic pin: input vref at 80% */ 7777 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 7778 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 7779 /* Line In pin: input */ 7780 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 7781 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 7782 /* Line-2 In: Headphone output (output 0 - 0x0c) */ 7783 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 7784 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7785 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 7786 /* CD pin widget for input */ 7787 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 7788 7789 /* FIXME: use matrix-type input source selection */ 7790 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 7791 /* Input mixer2 */ 7792 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7793 /* Input mixer3 */ 7794 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7795 /* ADC2: mute amp left and right */ 7796 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7797 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 7798 /* ADC3: mute amp left and right */ 7799 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7800 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 7801 7802 { } 7803}; 7804 7805static struct hda_verb alc882_adc1_init_verbs[] = { 7806 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 7807 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7808 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 7809 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 7810 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 7811 /* ADC1: mute amp left and right */ 7812 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7813 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 7814 { } 7815}; 7816 7817static struct hda_verb alc882_eapd_verbs[] = { 7818 /* change to EAPD mode */ 7819 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 7820 {0x20, AC_VERB_SET_PROC_COEF, 0x3060}, 7821 { } 7822}; 7823 7824static struct hda_verb alc889_eapd_verbs[] = { 7825 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 7826 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, 7827 { } 7828}; 7829 7830static struct hda_verb alc_hp15_unsol_verbs[] = { 7831 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 7832 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 7833 {} 7834}; 7835 7836static struct hda_verb alc885_init_verbs[] = { 7837 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 7838 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7839 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 7840 /* Rear mixer */ 7841 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7842 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 7843 /* CLFE mixer */ 7844 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7845 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 7846 /* Side mixer */ 7847 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7848 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 7849 7850 /* Front HP Pin: output 0 (0x0c) */ 7851 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 7852 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7853 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 7854 /* Front Pin: output 0 (0x0c) */ 7855 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 7856 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7857 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 7858 /* Rear Pin: output 1 (0x0d) */ 7859 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 7860 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7861 {0x19, AC_VERB_SET_CONNECT_SEL, 0x01}, 7862 /* CLFE Pin: output 2 (0x0e) */ 7863 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 7864 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7865 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, 7866 /* Side Pin: output 3 (0x0f) */ 7867 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 7868 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7869 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, 7870 /* Mic (rear) pin: input vref at 80% */ 7871 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 7872 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 7873 /* Front Mic pin: input vref at 80% */ 7874 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 7875 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 7876 /* Line In pin: input */ 7877 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 7878 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 7879 7880 /* Mixer elements: 0x18, , 0x1a, 0x1b */ 7881 /* Input mixer1 */ 7882 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7883 /* Input mixer2 */ 7884 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7885 /* Input mixer3 */ 7886 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7887 /* ADC2: mute amp left and right */ 7888 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7889 /* ADC3: mute amp left and right */ 7890 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7891 7892 { } 7893}; 7894 7895static struct hda_verb alc885_init_input_verbs[] = { 7896 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7897 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 7898 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 7899 { } 7900}; 7901 7902 7903/* Unmute Selector 24h and set the default input to front mic */ 7904static struct hda_verb alc889_init_input_verbs[] = { 7905 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00}, 7906 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7907 { } 7908}; 7909 7910 7911#define alc883_init_verbs alc882_base_init_verbs 7912 7913/* Mac Pro test */ 7914static struct snd_kcontrol_new alc882_macpro_mixer[] = { 7915 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7916 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 7917 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT), 7918 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT), 7919 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT), 7920 /* FIXME: this looks suspicious... 7921 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x02, HDA_INPUT), 7922 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x02, HDA_INPUT), 7923 */ 7924 { } /* end */ 7925}; 7926 7927static struct hda_verb alc882_macpro_init_verbs[] = { 7928 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 7929 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 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 /* Front Pin: output 0 (0x0c) */ 7933 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 7934 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7935 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 7936 /* Front Mic pin: input vref at 80% */ 7937 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 7938 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 7939 /* Speaker: output */ 7940 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 7941 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7942 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04}, 7943 /* Headphone output (output 0 - 0x0c) */ 7944 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 7945 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7946 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00}, 7947 7948 /* FIXME: use matrix-type input source selection */ 7949 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 7950 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 7951 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7952 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 7953 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 7954 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 7955 /* Input mixer2 */ 7956 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7957 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 7958 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 7959 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 7960 /* Input mixer3 */ 7961 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7962 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 7963 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 7964 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 7965 /* ADC1: mute amp left and right */ 7966 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7967 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 7968 /* ADC2: mute amp left and right */ 7969 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7970 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 7971 /* ADC3: mute amp left and right */ 7972 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7973 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 7974 7975 { } 7976}; 7977 7978/* Macbook 5,1 */ 7979static struct hda_verb alc885_mb5_init_verbs[] = { 7980 /* DACs */ 7981 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7982 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7983 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7984 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7985 /* Front mixer */ 7986 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 7987 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7988 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7989 /* Surround mixer */ 7990 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 7991 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7992 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7993 /* LFE mixer */ 7994 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 7995 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7996 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7997 /* HP mixer */ 7998 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 7999 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8000 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8001 /* Front Pin (0x0c) */ 8002 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01}, 8003 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8004 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00}, 8005 /* LFE Pin (0x0e) */ 8006 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01}, 8007 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8008 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, 8009 /* HP Pin (0x0f) */ 8010 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8011 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8012 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03}, 8013 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 8014 /* Front Mic pin: input vref at 80% */ 8015 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 8016 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8017 /* Line In pin */ 8018 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 8019 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8020 8021 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0x1)}, 8022 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x7)}, 8023 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x4)}, 8024 { } 8025}; 8026 8027/* Macmini 3,1 */ 8028static struct hda_verb alc885_macmini3_init_verbs[] = { 8029 /* DACs */ 8030 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8031 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8032 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8033 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8034 /* Front mixer */ 8035 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8036 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8037 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8038 /* Surround mixer */ 8039 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8040 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8041 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8042 /* LFE mixer */ 8043 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8044 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8045 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8046 /* HP mixer */ 8047 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8048 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8049 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8050 /* Front Pin (0x0c) */ 8051 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01}, 8052 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8053 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00}, 8054 /* LFE Pin (0x0e) */ 8055 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01}, 8056 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8057 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, 8058 /* HP Pin (0x0f) */ 8059 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8060 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8061 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03}, 8062 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 8063 /* Line In pin */ 8064 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 8065 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8066 8067 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8068 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8069 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 8070 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8071 { } 8072}; 8073 8074 8075static struct hda_verb alc885_mba21_init_verbs[] = { 8076 /*Internal and HP Speaker Mixer*/ 8077 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8078 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8079 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8080 /*Internal Speaker Pin (0x0c)*/ 8081 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) }, 8082 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8083 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00}, 8084 /* HP Pin: output 0 (0x0e) */ 8085 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, 8086 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8087 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 8088 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)}, 8089 /* Line in (is hp when jack connected)*/ 8090 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50}, 8091 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8092 8093 { } 8094 }; 8095 8096 8097/* Macbook Pro rev3 */ 8098static struct hda_verb alc885_mbp3_init_verbs[] = { 8099 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 8100 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8101 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8102 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8103 /* Rear mixer */ 8104 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8105 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8106 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8107 /* HP mixer */ 8108 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8109 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8110 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8111 /* Front Pin: output 0 (0x0c) */ 8112 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8113 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8114 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 8115 /* HP Pin: output 0 (0x0e) */ 8116 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, 8117 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8118 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02}, 8119 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 8120 /* Mic (rear) pin: input vref at 80% */ 8121 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 8122 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8123 /* Front Mic pin: input vref at 80% */ 8124 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 8125 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8126 /* Line In pin: use output 1 when in LineOut mode */ 8127 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 8128 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8129 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, 8130 8131 /* FIXME: use matrix-type input source selection */ 8132 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 8133 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 8134 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8135 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8136 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 8137 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8138 /* Input mixer2 */ 8139 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8140 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8141 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 8142 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8143 /* Input mixer3 */ 8144 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8145 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8146 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 8147 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8148 /* ADC1: mute amp left and right */ 8149 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8150 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 8151 /* ADC2: mute amp left and right */ 8152 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8153 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 8154 /* ADC3: mute amp left and right */ 8155 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8156 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 8157 8158 { } 8159}; 8160 8161/* iMac 9,1 */ 8162static struct hda_verb alc885_imac91_init_verbs[] = { 8163 /* Internal Speaker Pin (0x0c) */ 8164 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) }, 8165 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8166 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00}, 8167 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) }, 8168 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8169 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00}, 8170 /* HP Pin: Rear */ 8171 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8172 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8173 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 8174 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)}, 8175 /* Line in Rear */ 8176 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50}, 8177 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8178 /* Front Mic pin: input vref at 80% */ 8179 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 8180 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8181 /* Rear mixer */ 8182 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8183 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8184 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8185 /* Line-Out mixer: unmute input/output amp left and right (volume = 0) */ 8186 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8187 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8188 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8189 /* 0x24 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */ 8190 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8191 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8192 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 8193 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8194 /* 0x23 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */ 8195 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8196 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8197 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 8198 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8199 /* 0x22 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */ 8200 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8201 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8202 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 8203 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8204 /* 0x07 [Audio Input] wcaps 0x10011b: Stereo Amp-In */ 8205 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8206 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 8207 /* 0x08 [Audio Input] wcaps 0x10011b: Stereo Amp-In */ 8208 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8209 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 8210 /* 0x09 [Audio Input] wcaps 0x10011b: Stereo Amp-In */ 8211 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8212 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 8213 { } 8214}; 8215 8216/* iMac 24 mixer. */ 8217static struct snd_kcontrol_new alc885_imac24_mixer[] = { 8218 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 8219 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT), 8220 { } /* end */ 8221}; 8222 8223/* iMac 24 init verbs. */ 8224static struct hda_verb alc885_imac24_init_verbs[] = { 8225 /* Internal speakers: output 0 (0x0c) */ 8226 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8227 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8228 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00}, 8229 /* Internal speakers: output 0 (0x0c) */ 8230 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8231 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8232 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00}, 8233 /* Headphone: output 0 (0x0c) */ 8234 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8235 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8236 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 8237 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 8238 /* Front Mic: input vref at 80% */ 8239 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 8240 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8241 { } 8242}; 8243 8244/* Toggle speaker-output according to the hp-jack state */ 8245static void alc885_imac24_setup(struct hda_codec *codec) 8246{ 8247 struct alc_spec *spec = codec->spec; 8248 8249 spec->autocfg.hp_pins[0] = 0x14; 8250 spec->autocfg.speaker_pins[0] = 0x18; 8251 spec->autocfg.speaker_pins[1] = 0x1a; 8252} 8253 8254#define alc885_mb5_setup alc885_imac24_setup 8255#define alc885_macmini3_setup alc885_imac24_setup 8256 8257/* Macbook Air 2,1 */ 8258static void alc885_mba21_setup(struct hda_codec *codec) 8259{ 8260 struct alc_spec *spec = codec->spec; 8261 8262 spec->autocfg.hp_pins[0] = 0x14; 8263 spec->autocfg.speaker_pins[0] = 0x18; 8264} 8265 8266 8267 8268static void alc885_mbp3_setup(struct hda_codec *codec) 8269{ 8270 struct alc_spec *spec = codec->spec; 8271 8272 spec->autocfg.hp_pins[0] = 0x15; 8273 spec->autocfg.speaker_pins[0] = 0x14; 8274} 8275 8276static void alc885_imac91_setup(struct hda_codec *codec) 8277{ 8278 struct alc_spec *spec = codec->spec; 8279 8280 spec->autocfg.hp_pins[0] = 0x14; 8281 spec->autocfg.speaker_pins[0] = 0x18; 8282 spec->autocfg.speaker_pins[1] = 0x1a; 8283} 8284 8285static struct hda_verb alc882_targa_verbs[] = { 8286 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8287 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8288 8289 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8290 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8291 8292 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ 8293 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */ 8294 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 8295 8296 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 8297 { } /* end */ 8298}; 8299 8300/* toggle speaker-output according to the hp-jack state */ 8301static void alc882_targa_automute(struct hda_codec *codec) 8302{ 8303 struct alc_spec *spec = codec->spec; 8304 alc_automute_amp(codec); 8305 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA, 8306 spec->jack_present ? 1 : 3); 8307} 8308 8309static void alc882_targa_setup(struct hda_codec *codec) 8310{ 8311 struct alc_spec *spec = codec->spec; 8312 8313 spec->autocfg.hp_pins[0] = 0x14; 8314 spec->autocfg.speaker_pins[0] = 0x1b; 8315} 8316 8317static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res) 8318{ 8319 if ((res >> 26) == ALC880_HP_EVENT) 8320 alc882_targa_automute(codec); 8321} 8322 8323static struct hda_verb alc882_asus_a7j_verbs[] = { 8324 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8325 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8326 8327 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8328 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8329 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8330 8331 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */ 8332 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 8333 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */ 8334 8335 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ 8336 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */ 8337 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 8338 { } /* end */ 8339}; 8340 8341static struct hda_verb alc882_asus_a7m_verbs[] = { 8342 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8343 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8344 8345 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8346 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8347 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8348 8349 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */ 8350 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 8351 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */ 8352 8353 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ 8354 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */ 8355 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 8356 { } /* end */ 8357}; 8358 8359static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted) 8360{ 8361 unsigned int gpiostate, gpiomask, gpiodir; 8362 8363 gpiostate = snd_hda_codec_read(codec, codec->afg, 0, 8364 AC_VERB_GET_GPIO_DATA, 0); 8365 8366 if (!muted) 8367 gpiostate |= (1 << pin); 8368 else 8369 gpiostate &= ~(1 << pin); 8370 8371 gpiomask = snd_hda_codec_read(codec, codec->afg, 0, 8372 AC_VERB_GET_GPIO_MASK, 0); 8373 gpiomask |= (1 << pin); 8374 8375 gpiodir = snd_hda_codec_read(codec, codec->afg, 0, 8376 AC_VERB_GET_GPIO_DIRECTION, 0); 8377 gpiodir |= (1 << pin); 8378 8379 8380 snd_hda_codec_write(codec, codec->afg, 0, 8381 AC_VERB_SET_GPIO_MASK, gpiomask); 8382 snd_hda_codec_write(codec, codec->afg, 0, 8383 AC_VERB_SET_GPIO_DIRECTION, gpiodir); 8384 8385 msleep(1); 8386 8387 snd_hda_codec_write(codec, codec->afg, 0, 8388 AC_VERB_SET_GPIO_DATA, gpiostate); 8389} 8390 8391/* set up GPIO at initialization */ 8392static void alc885_macpro_init_hook(struct hda_codec *codec) 8393{ 8394 alc882_gpio_mute(codec, 0, 0); 8395 alc882_gpio_mute(codec, 1, 0); 8396} 8397 8398/* set up GPIO and update auto-muting at initialization */ 8399static void alc885_imac24_init_hook(struct hda_codec *codec) 8400{ 8401 alc885_macpro_init_hook(codec); 8402 alc_automute_amp(codec); 8403} 8404 8405/* 8406 * generic initialization of ADC, input mixers and output mixers 8407 */ 8408static struct hda_verb alc883_auto_init_verbs[] = { 8409 /* 8410 * Unmute ADC0-2 and set the default input to mic-in 8411 */ 8412 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 8413 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8414 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 8415 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8416 8417 /* 8418 * Set up output mixers (0x0c - 0x0f) 8419 */ 8420 /* set vol=0 to output mixers */ 8421 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8422 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8423 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8424 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8425 /* set up input amps for analog loopback */ 8426 /* Amp Indices: DAC = 0, mixer = 1 */ 8427 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8428 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8429 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8430 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8431 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8432 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8433 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8434 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8435 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8436 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8437 8438 /* FIXME: use matrix-type input source selection */ 8439 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 8440 /* Input mixer2 */ 8441 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8442 /* Input mixer3 */ 8443 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8444 { } 8445}; 8446 8447/* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */ 8448static struct hda_verb alc889A_mb31_ch2_init[] = { 8449 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */ 8450 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */ 8451 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */ 8452 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */ 8453 { } /* end */ 8454}; 8455 8456/* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */ 8457static struct hda_verb alc889A_mb31_ch4_init[] = { 8458 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */ 8459 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */ 8460 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */ 8461 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */ 8462 { } /* end */ 8463}; 8464 8465/* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */ 8466static struct hda_verb alc889A_mb31_ch5_init[] = { 8467 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */ 8468 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */ 8469 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */ 8470 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */ 8471 { } /* end */ 8472}; 8473 8474/* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */ 8475static struct hda_verb alc889A_mb31_ch6_init[] = { 8476 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */ 8477 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */ 8478 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */ 8479 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */ 8480 { } /* end */ 8481}; 8482 8483static struct hda_channel_mode alc889A_mb31_6ch_modes[4] = { 8484 { 2, alc889A_mb31_ch2_init }, 8485 { 4, alc889A_mb31_ch4_init }, 8486 { 5, alc889A_mb31_ch5_init }, 8487 { 6, alc889A_mb31_ch6_init }, 8488}; 8489 8490static struct hda_verb alc883_medion_eapd_verbs[] = { 8491 /* eanable EAPD on medion laptop */ 8492 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 8493 {0x20, AC_VERB_SET_PROC_COEF, 0x3070}, 8494 { } 8495}; 8496 8497#define alc883_base_mixer alc882_base_mixer 8498 8499static struct snd_kcontrol_new alc883_mitac_mixer[] = { 8500 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8501 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8502 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 8503 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 8504 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 8505 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 8506 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 8507 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8508 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8509 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8510 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8511 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 8512 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8513 { } /* end */ 8514}; 8515 8516static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = { 8517 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8518 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), 8519 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 8520 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 8521 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8522 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8523 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8524 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8525 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 8526 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8527 { } /* end */ 8528}; 8529 8530static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = { 8531 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8532 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), 8533 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 8534 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 8535 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8536 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8537 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8538 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8539 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 8540 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8541 { } /* end */ 8542}; 8543 8544static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = { 8545 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8546 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8547 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 8548 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 8549 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 8550 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8551 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8552 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8553 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8554 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8555 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8556 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 8557 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8558 { } /* end */ 8559}; 8560 8561static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = { 8562 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8563 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8564 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 8565 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 8566 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 8567 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 8568 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 8569 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 8570 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 8571 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 8572 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 8573 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8574 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8575 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8576 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8577 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8578 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8579 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 8580 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8581 { } /* end */ 8582}; 8583 8584static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = { 8585 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8586 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8587 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 8588 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 8589 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, 8590 HDA_OUTPUT), 8591 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 8592 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 8593 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 8594 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 8595 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 8596 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 8597 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8598 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8599 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8600 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT), 8601 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8602 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8603 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT), 8604 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8605 { } /* end */ 8606}; 8607 8608static struct snd_kcontrol_new alc885_8ch_intel_mixer[] = { 8609 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8610 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8611 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 8612 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 8613 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, 8614 HDA_OUTPUT), 8615 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 8616 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 8617 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 8618 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 8619 HDA_BIND_MUTE("Speaker Playback Switch", 0x0f, 2, HDA_INPUT), 8620 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 8621 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8622 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8623 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT), 8624 HDA_CODEC_VOLUME("Mic Boost", 0x1b, 0, HDA_INPUT), 8625 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT), 8626 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8627 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT), 8628 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8629 { } /* end */ 8630}; 8631 8632static struct snd_kcontrol_new alc883_fivestack_mixer[] = { 8633 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8634 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8635 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 8636 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 8637 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 8638 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 8639 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 8640 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 8641 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 8642 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 8643 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 8644 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8645 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8646 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8647 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8648 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8649 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8650 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 8651 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8652 { } /* end */ 8653}; 8654 8655static struct snd_kcontrol_new alc883_targa_mixer[] = { 8656 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8657 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8658 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 8659 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 8660 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 8661 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 8662 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 8663 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 8664 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 8665 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 8666 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 8667 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 8668 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8669 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8670 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8671 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8672 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8673 { } /* end */ 8674}; 8675 8676static struct snd_kcontrol_new alc883_targa_2ch_mixer[] = { 8677 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8678 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8679 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 8680 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 8681 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 8682 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 8683 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8684 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8685 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8686 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8687 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 8688 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8689 { } /* end */ 8690}; 8691 8692static struct snd_kcontrol_new alc883_targa_8ch_mixer[] = { 8693 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 8694 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 8695 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8696 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 8697 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8698 { } /* end */ 8699}; 8700 8701static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = { 8702 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8703 HDA_BIND_MUTE("Front 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_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 8707 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8708 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8709 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8710 { } /* end */ 8711}; 8712 8713static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = { 8714 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8715 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT), 8716 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 8717 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 8718 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 8719 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8720 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8721 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8722 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8723 { } /* end */ 8724}; 8725 8726static struct snd_kcontrol_new alc883_medion_md2_mixer[] = { 8727 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8728 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 8729 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT), 8730 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 8731 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 8732 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8733 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8734 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8735 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8736 { } /* end */ 8737}; 8738 8739static struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = { 8740 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8741 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8742 HDA_CODEC_MUTE("Speaker Playback Switch", 0x15, 0x0, HDA_OUTPUT), 8743 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT), 8744 HDA_CODEC_VOLUME("Line Playback Volume", 0x08, 0x0, HDA_INPUT), 8745 HDA_CODEC_MUTE("Line Playback Switch", 0x08, 0x0, HDA_INPUT), 8746 { } /* end */ 8747}; 8748 8749static struct hda_verb alc883_medion_wim2160_verbs[] = { 8750 /* Unmute front mixer */ 8751 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8752 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8753 8754 /* Set speaker pin to front mixer */ 8755 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 8756 8757 /* Init headphone pin */ 8758 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8759 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8760 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00}, 8761 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 8762 8763 { } /* end */ 8764}; 8765 8766/* toggle speaker-output according to the hp-jack state */ 8767static void alc883_medion_wim2160_setup(struct hda_codec *codec) 8768{ 8769 struct alc_spec *spec = codec->spec; 8770 8771 spec->autocfg.hp_pins[0] = 0x1a; 8772 spec->autocfg.speaker_pins[0] = 0x15; 8773} 8774 8775static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = { 8776 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8777 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8778 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 8779 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8780 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8781 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8782 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8783 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8784 { } /* end */ 8785}; 8786 8787static struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = { 8788 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8789 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 8790 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8791 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8792 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 8793 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 8794 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8795 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8796 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8797 { } /* end */ 8798}; 8799 8800static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = { 8801 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8802 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8803 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT), 8804 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT), 8805 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 8806 0x0d, 1, 0x0, HDA_OUTPUT), 8807 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT), 8808 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT), 8809 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT), 8810 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 8811 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 8812 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 8813 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 8814 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8815 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8816 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8817 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8818 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8819 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8820 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 8821 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8822 { } /* end */ 8823}; 8824 8825static struct snd_kcontrol_new alc889A_mb31_mixer[] = { 8826 /* Output mixers */ 8827 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 8828 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT), 8829 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT), 8830 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT), 8831 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00, 8832 HDA_OUTPUT), 8833 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT), 8834 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT), 8835 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT), 8836 /* Output switches */ 8837 HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT), 8838 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT), 8839 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT), 8840 /* Boost mixers */ 8841 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT), 8842 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT), 8843 /* Input mixers */ 8844 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT), 8845 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT), 8846 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8847 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8848 { } /* end */ 8849}; 8850 8851static struct snd_kcontrol_new alc883_vaiott_mixer[] = { 8852 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8853 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8854 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 8855 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8856 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT), 8857 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8858 { } /* end */ 8859}; 8860 8861static struct hda_bind_ctls alc883_bind_cap_vol = { 8862 .ops = &snd_hda_bind_vol, 8863 .values = { 8864 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT), 8865 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT), 8866 0 8867 }, 8868}; 8869 8870static struct hda_bind_ctls alc883_bind_cap_switch = { 8871 .ops = &snd_hda_bind_sw, 8872 .values = { 8873 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT), 8874 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT), 8875 0 8876 }, 8877}; 8878 8879static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = { 8880 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8881 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8882 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 8883 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8884 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8885 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8886 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8887 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8888 { } /* end */ 8889}; 8890 8891static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = { 8892 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol), 8893 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch), 8894 { 8895 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 8896 /* .name = "Capture Source", */ 8897 .name = "Input Source", 8898 .count = 1, 8899 .info = alc_mux_enum_info, 8900 .get = alc_mux_enum_get, 8901 .put = alc_mux_enum_put, 8902 }, 8903 { } /* end */ 8904}; 8905 8906static struct snd_kcontrol_new alc883_chmode_mixer[] = { 8907 { 8908 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 8909 .name = "Channel Mode", 8910 .info = alc_ch_mode_info, 8911 .get = alc_ch_mode_get, 8912 .put = alc_ch_mode_put, 8913 }, 8914 { } /* end */ 8915}; 8916 8917/* toggle speaker-output according to the hp-jack state */ 8918static void alc883_mitac_setup(struct hda_codec *codec) 8919{ 8920 struct alc_spec *spec = codec->spec; 8921 8922 spec->autocfg.hp_pins[0] = 0x15; 8923 spec->autocfg.speaker_pins[0] = 0x14; 8924 spec->autocfg.speaker_pins[1] = 0x17; 8925} 8926 8927/* auto-toggle front mic */ 8928/* 8929static void alc883_mitac_mic_automute(struct hda_codec *codec) 8930{ 8931 unsigned char bits = snd_hda_jack_detect(codec, 0x18) ? HDA_AMP_MUTE : 0; 8932 8933 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits); 8934} 8935*/ 8936 8937static struct hda_verb alc883_mitac_verbs[] = { 8938 /* HP */ 8939 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 8940 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8941 /* Subwoofer */ 8942 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02}, 8943 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8944 8945 /* enable unsolicited event */ 8946 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 8947 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */ 8948 8949 { } /* end */ 8950}; 8951 8952static struct hda_verb alc883_clevo_m540r_verbs[] = { 8953 /* HP */ 8954 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 8955 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8956 /* Int speaker */ 8957 /*{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},*/ 8958 8959 /* enable unsolicited event */ 8960 /* 8961 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 8962 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, 8963 */ 8964 8965 { } /* end */ 8966}; 8967 8968static struct hda_verb alc883_clevo_m720_verbs[] = { 8969 /* HP */ 8970 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 8971 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8972 /* Int speaker */ 8973 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01}, 8974 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8975 8976 /* enable unsolicited event */ 8977 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 8978 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, 8979 8980 { } /* end */ 8981}; 8982 8983static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = { 8984 /* HP */ 8985 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 8986 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8987 /* Subwoofer */ 8988 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 8989 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8990 8991 /* enable unsolicited event */ 8992 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 8993 8994 { } /* end */ 8995}; 8996 8997static struct hda_verb alc883_targa_verbs[] = { 8998 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8999 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9000 9001 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9002 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9003 9004/* Connect Line-Out side jack (SPDIF) to Side */ 9005 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9006 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9007 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, 9008/* Connect Mic jack to CLFE */ 9009 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9010 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9011 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, 9012/* Connect Line-in jack to Surround */ 9013 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9014 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9015 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, 9016/* Connect HP out jack to Front */ 9017 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9018 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9019 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 9020 9021 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9022 9023 { } /* end */ 9024}; 9025 9026static struct hda_verb alc883_lenovo_101e_verbs[] = { 9027 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9028 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN}, 9029 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN}, 9030 { } /* end */ 9031}; 9032 9033static struct hda_verb alc883_lenovo_nb0763_verbs[] = { 9034 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9035 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9036 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9037 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9038 { } /* end */ 9039}; 9040 9041static struct hda_verb alc888_lenovo_ms7195_verbs[] = { 9042 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9043 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9044 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9045 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN}, 9046 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9047 { } /* end */ 9048}; 9049 9050static struct hda_verb alc883_haier_w66_verbs[] = { 9051 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9052 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9053 9054 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9055 9056 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 9057 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9058 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9059 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9060 { } /* end */ 9061}; 9062 9063static struct hda_verb alc888_lenovo_sky_verbs[] = { 9064 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9065 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9066 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9067 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9068 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9069 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9070 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00}, 9071 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9072 { } /* end */ 9073}; 9074 9075static struct hda_verb alc888_6st_dell_verbs[] = { 9076 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9077 { } 9078}; 9079 9080static struct hda_verb alc883_vaiott_verbs[] = { 9081 /* HP */ 9082 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9083 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9084 9085 /* enable unsolicited event */ 9086 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9087 9088 { } /* end */ 9089}; 9090 9091static void alc888_3st_hp_setup(struct hda_codec *codec) 9092{ 9093 struct alc_spec *spec = codec->spec; 9094 9095 spec->autocfg.hp_pins[0] = 0x1b; 9096 spec->autocfg.speaker_pins[0] = 0x14; 9097 spec->autocfg.speaker_pins[1] = 0x16; 9098 spec->autocfg.speaker_pins[2] = 0x18; 9099} 9100 9101static struct hda_verb alc888_3st_hp_verbs[] = { 9102 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */ 9103 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */ 9104 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */ 9105 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9106 { } /* end */ 9107}; 9108 9109/* 9110 * 2ch mode 9111 */ 9112static struct hda_verb alc888_3st_hp_2ch_init[] = { 9113 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 9114 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 9115 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 9116 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 9117 { } /* end */ 9118}; 9119 9120/* 9121 * 4ch mode 9122 */ 9123static struct hda_verb alc888_3st_hp_4ch_init[] = { 9124 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 9125 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 9126 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 9127 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 9128 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 }, 9129 { } /* end */ 9130}; 9131 9132/* 9133 * 6ch mode 9134 */ 9135static struct hda_verb alc888_3st_hp_6ch_init[] = { 9136 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 9137 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 9138 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, 9139 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 9140 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 9141 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 }, 9142 { } /* end */ 9143}; 9144 9145static struct hda_channel_mode alc888_3st_hp_modes[3] = { 9146 { 2, alc888_3st_hp_2ch_init }, 9147 { 4, alc888_3st_hp_4ch_init }, 9148 { 6, alc888_3st_hp_6ch_init }, 9149}; 9150 9151/* toggle front-jack and RCA according to the hp-jack state */ 9152static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec) 9153{ 9154 unsigned int present = snd_hda_jack_detect(codec, 0x1b); 9155 9156 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 9157 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 9158 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 9159 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 9160} 9161 9162/* toggle RCA according to the front-jack state */ 9163static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec) 9164{ 9165 unsigned int present = snd_hda_jack_detect(codec, 0x14); 9166 9167 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 9168 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 9169} 9170 9171static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec, 9172 unsigned int res) 9173{ 9174 if ((res >> 26) == ALC880_HP_EVENT) 9175 alc888_lenovo_ms7195_front_automute(codec); 9176 if ((res >> 26) == ALC880_FRONT_EVENT) 9177 alc888_lenovo_ms7195_rca_automute(codec); 9178} 9179 9180static struct hda_verb alc883_medion_md2_verbs[] = { 9181 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9182 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9183 9184 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9185 9186 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9187 { } /* end */ 9188}; 9189 9190/* toggle speaker-output according to the hp-jack state */ 9191static void alc883_medion_md2_setup(struct hda_codec *codec) 9192{ 9193 struct alc_spec *spec = codec->spec; 9194 9195 spec->autocfg.hp_pins[0] = 0x14; 9196 spec->autocfg.speaker_pins[0] = 0x15; 9197} 9198 9199/* toggle speaker-output according to the hp-jack state */ 9200#define alc883_targa_init_hook alc882_targa_init_hook 9201#define alc883_targa_unsol_event alc882_targa_unsol_event 9202 9203static void alc883_clevo_m720_mic_automute(struct hda_codec *codec) 9204{ 9205 unsigned int present; 9206 9207 present = snd_hda_jack_detect(codec, 0x18); 9208 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, 9209 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 9210} 9211 9212static void alc883_clevo_m720_setup(struct hda_codec *codec) 9213{ 9214 struct alc_spec *spec = codec->spec; 9215 9216 spec->autocfg.hp_pins[0] = 0x15; 9217 spec->autocfg.speaker_pins[0] = 0x14; 9218} 9219 9220static void alc883_clevo_m720_init_hook(struct hda_codec *codec) 9221{ 9222 alc_automute_amp(codec); 9223 alc883_clevo_m720_mic_automute(codec); 9224} 9225 9226static void alc883_clevo_m720_unsol_event(struct hda_codec *codec, 9227 unsigned int res) 9228{ 9229 switch (res >> 26) { 9230 case ALC880_MIC_EVENT: 9231 alc883_clevo_m720_mic_automute(codec); 9232 break; 9233 default: 9234 alc_automute_amp_unsol_event(codec, res); 9235 break; 9236 } 9237} 9238 9239/* toggle speaker-output according to the hp-jack state */ 9240static void alc883_2ch_fujitsu_pi2515_setup(struct hda_codec *codec) 9241{ 9242 struct alc_spec *spec = codec->spec; 9243 9244 spec->autocfg.hp_pins[0] = 0x14; 9245 spec->autocfg.speaker_pins[0] = 0x15; 9246} 9247 9248static void alc883_haier_w66_setup(struct hda_codec *codec) 9249{ 9250 struct alc_spec *spec = codec->spec; 9251 9252 spec->autocfg.hp_pins[0] = 0x1b; 9253 spec->autocfg.speaker_pins[0] = 0x14; 9254} 9255 9256static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec) 9257{ 9258 int bits = snd_hda_jack_detect(codec, 0x14) ? HDA_AMP_MUTE : 0; 9259 9260 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 9261 HDA_AMP_MUTE, bits); 9262} 9263 9264static void alc883_lenovo_101e_all_automute(struct hda_codec *codec) 9265{ 9266 int bits = snd_hda_jack_detect(codec, 0x1b) ? HDA_AMP_MUTE : 0; 9267 9268 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 9269 HDA_AMP_MUTE, bits); 9270 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 9271 HDA_AMP_MUTE, bits); 9272} 9273 9274static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec, 9275 unsigned int res) 9276{ 9277 if ((res >> 26) == ALC880_HP_EVENT) 9278 alc883_lenovo_101e_all_automute(codec); 9279 if ((res >> 26) == ALC880_FRONT_EVENT) 9280 alc883_lenovo_101e_ispeaker_automute(codec); 9281} 9282 9283/* toggle speaker-output according to the hp-jack state */ 9284static void alc883_acer_aspire_setup(struct hda_codec *codec) 9285{ 9286 struct alc_spec *spec = codec->spec; 9287 9288 spec->autocfg.hp_pins[0] = 0x14; 9289 spec->autocfg.speaker_pins[0] = 0x15; 9290 spec->autocfg.speaker_pins[1] = 0x16; 9291} 9292 9293static struct hda_verb alc883_acer_eapd_verbs[] = { 9294 /* HP Pin: output 0 (0x0c) */ 9295 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9296 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9297 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 9298 /* Front Pin: output 0 (0x0c) */ 9299 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9300 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9301 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9302 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, 9303 /* eanable EAPD on medion laptop */ 9304 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 9305 {0x20, AC_VERB_SET_PROC_COEF, 0x3050}, 9306 /* enable unsolicited event */ 9307 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9308 { } 9309}; 9310 9311static struct hda_verb alc888_acer_aspire_7730G_verbs[] = { 9312 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9313 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02}, 9314 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9315 { } /* end */ 9316}; 9317 9318static void alc888_6st_dell_setup(struct hda_codec *codec) 9319{ 9320 struct alc_spec *spec = codec->spec; 9321 9322 spec->autocfg.hp_pins[0] = 0x1b; 9323 spec->autocfg.speaker_pins[0] = 0x14; 9324 spec->autocfg.speaker_pins[1] = 0x15; 9325 spec->autocfg.speaker_pins[2] = 0x16; 9326 spec->autocfg.speaker_pins[3] = 0x17; 9327} 9328 9329static void alc888_lenovo_sky_setup(struct hda_codec *codec) 9330{ 9331 struct alc_spec *spec = codec->spec; 9332 9333 spec->autocfg.hp_pins[0] = 0x1b; 9334 spec->autocfg.speaker_pins[0] = 0x14; 9335 spec->autocfg.speaker_pins[1] = 0x15; 9336 spec->autocfg.speaker_pins[2] = 0x16; 9337 spec->autocfg.speaker_pins[3] = 0x17; 9338 spec->autocfg.speaker_pins[4] = 0x1a; 9339} 9340 9341static void alc883_vaiott_setup(struct hda_codec *codec) 9342{ 9343 struct alc_spec *spec = codec->spec; 9344 9345 spec->autocfg.hp_pins[0] = 0x15; 9346 spec->autocfg.speaker_pins[0] = 0x14; 9347 spec->autocfg.speaker_pins[1] = 0x17; 9348} 9349 9350static struct hda_verb alc888_asus_m90v_verbs[] = { 9351 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 9352 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 9353 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9354 /* enable unsolicited event */ 9355 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9356 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, 9357 { } /* end */ 9358}; 9359 9360static void alc883_mode2_setup(struct hda_codec *codec) 9361{ 9362 struct alc_spec *spec = codec->spec; 9363 9364 spec->autocfg.hp_pins[0] = 0x1b; 9365 spec->autocfg.speaker_pins[0] = 0x14; 9366 spec->autocfg.speaker_pins[1] = 0x15; 9367 spec->autocfg.speaker_pins[2] = 0x16; 9368 spec->ext_mic.pin = 0x18; 9369 spec->int_mic.pin = 0x19; 9370 spec->ext_mic.mux_idx = 0; 9371 spec->int_mic.mux_idx = 1; 9372 spec->auto_mic = 1; 9373} 9374 9375static struct hda_verb alc888_asus_eee1601_verbs[] = { 9376 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9377 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9378 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 9379 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9380 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 9381 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b}, 9382 {0x20, AC_VERB_SET_PROC_COEF, 0x0838}, 9383 /* enable unsolicited event */ 9384 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9385 { } /* end */ 9386}; 9387 9388static void alc883_eee1601_inithook(struct hda_codec *codec) 9389{ 9390 struct alc_spec *spec = codec->spec; 9391 9392 spec->autocfg.hp_pins[0] = 0x14; 9393 spec->autocfg.speaker_pins[0] = 0x1b; 9394 alc_automute_pin(codec); 9395} 9396 9397static struct hda_verb alc889A_mb31_verbs[] = { 9398 /* Init rear pin (used as headphone output) */ 9399 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */ 9400 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */ 9401 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9402 /* Init line pin (used as output in 4ch and 6ch mode) */ 9403 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */ 9404 /* Init line 2 pin (used as headphone out by default) */ 9405 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */ 9406 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */ 9407 { } /* end */ 9408}; 9409 9410/* Mute speakers according to the headphone jack state */ 9411static void alc889A_mb31_automute(struct hda_codec *codec) 9412{ 9413 unsigned int present; 9414 9415 /* Mute only in 2ch or 4ch mode */ 9416 if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0) 9417 == 0x00) { 9418 present = snd_hda_jack_detect(codec, 0x15); 9419 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 9420 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 9421 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0, 9422 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 9423 } 9424} 9425 9426static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res) 9427{ 9428 if ((res >> 26) == ALC880_HP_EVENT) 9429 alc889A_mb31_automute(codec); 9430} 9431 9432 9433#ifdef CONFIG_SND_HDA_POWER_SAVE 9434#define alc882_loopbacks alc880_loopbacks 9435#endif 9436 9437/* pcm configuration: identical with ALC880 */ 9438#define alc882_pcm_analog_playback alc880_pcm_analog_playback 9439#define alc882_pcm_analog_capture alc880_pcm_analog_capture 9440#define alc882_pcm_digital_playback alc880_pcm_digital_playback 9441#define alc882_pcm_digital_capture alc880_pcm_digital_capture 9442 9443static hda_nid_t alc883_slave_dig_outs[] = { 9444 ALC1200_DIGOUT_NID, 0, 9445}; 9446 9447static hda_nid_t alc1200_slave_dig_outs[] = { 9448 ALC883_DIGOUT_NID, 0, 9449}; 9450 9451/* 9452 * configuration and preset 9453 */ 9454static const char *alc882_models[ALC882_MODEL_LAST] = { 9455 [ALC882_3ST_DIG] = "3stack-dig", 9456 [ALC882_6ST_DIG] = "6stack-dig", 9457 [ALC882_ARIMA] = "arima", 9458 [ALC882_W2JC] = "w2jc", 9459 [ALC882_TARGA] = "targa", 9460 [ALC882_ASUS_A7J] = "asus-a7j", 9461 [ALC882_ASUS_A7M] = "asus-a7m", 9462 [ALC885_MACPRO] = "macpro", 9463 [ALC885_MB5] = "mb5", 9464 [ALC885_MACMINI3] = "macmini3", 9465 [ALC885_MBA21] = "mba21", 9466 [ALC885_MBP3] = "mbp3", 9467 [ALC885_IMAC24] = "imac24", 9468 [ALC885_IMAC91] = "imac91", 9469 [ALC883_3ST_2ch_DIG] = "3stack-2ch-dig", 9470 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig", 9471 [ALC883_3ST_6ch] = "3stack-6ch", 9472 [ALC883_6ST_DIG] = "alc883-6stack-dig", 9473 [ALC883_TARGA_DIG] = "targa-dig", 9474 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig", 9475 [ALC883_TARGA_8ch_DIG] = "targa-8ch-dig", 9476 [ALC883_ACER] = "acer", 9477 [ALC883_ACER_ASPIRE] = "acer-aspire", 9478 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g", 9479 [ALC888_ACER_ASPIRE_6530G] = "acer-aspire-6530g", 9480 [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g", 9481 [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g", 9482 [ALC883_MEDION] = "medion", 9483 [ALC883_MEDION_MD2] = "medion-md2", 9484 [ALC883_MEDION_WIM2160] = "medion-wim2160", 9485 [ALC883_LAPTOP_EAPD] = "laptop-eapd", 9486 [ALC883_LENOVO_101E_2ch] = "lenovo-101e", 9487 [ALC883_LENOVO_NB0763] = "lenovo-nb0763", 9488 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig", 9489 [ALC888_LENOVO_SKY] = "lenovo-sky", 9490 [ALC883_HAIER_W66] = "haier-w66", 9491 [ALC888_3ST_HP] = "3stack-hp", 9492 [ALC888_6ST_DELL] = "6stack-dell", 9493 [ALC883_MITAC] = "mitac", 9494 [ALC883_CLEVO_M540R] = "clevo-m540r", 9495 [ALC883_CLEVO_M720] = "clevo-m720", 9496 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515", 9497 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530", 9498 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel", 9499 [ALC889A_INTEL] = "intel-alc889a", 9500 [ALC889_INTEL] = "intel-x58", 9501 [ALC1200_ASUS_P5Q] = "asus-p5q", 9502 [ALC889A_MB31] = "mb31", 9503 [ALC883_SONY_VAIO_TT] = "sony-vaio-tt", 9504 [ALC882_AUTO] = "auto", 9505}; 9506 9507static struct snd_pci_quirk alc882_cfg_tbl[] = { 9508 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG), 9509 9510 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE), 9511 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE), 9512 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE), 9513 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE), 9514 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE), 9515 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE), 9516 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G", 9517 ALC888_ACER_ASPIRE_4930G), 9518 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G", 9519 ALC888_ACER_ASPIRE_4930G), 9520 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G", 9521 ALC888_ACER_ASPIRE_8930G), 9522 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G", 9523 ALC888_ACER_ASPIRE_8930G), 9524 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC882_AUTO), 9525 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC882_AUTO), 9526 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G", 9527 ALC888_ACER_ASPIRE_6530G), 9528 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G", 9529 ALC888_ACER_ASPIRE_6530G), 9530 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G", 9531 ALC888_ACER_ASPIRE_7730G), 9532 /* default Acer -- disabled as it causes more problems. 9533 * model=auto should work fine now 9534 */ 9535 /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */ 9536 9537 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL), 9538 9539 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG), 9540 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP), 9541 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP), 9542 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG), 9543 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP), 9544 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP), 9545 9546 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J), 9547 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J), 9548 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M), 9549 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V), 9550 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC), 9551 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG), 9552 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG), 9553 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG), 9554 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG), 9555 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q), 9556 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601), 9557 9558 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT), 9559 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG), 9560 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG), 9561 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC), 9562 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC), 9563 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD), 9564 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL), 9565 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch), 9566 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG), 9567 9568 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG), 9569 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG), 9570 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG), 9571 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */ 9572 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC882_AUTO), 9573 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG), 9574 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG), 9575 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG), 9576 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG), 9577 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG), 9578 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG), 9579 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG), 9580 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG), 9581 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG), 9582 SND_PCI_QUIRK(0x1462, 0x42cd, "MSI", ALC883_TARGA_DIG), 9583 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG), 9584 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG), 9585 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG), 9586 SND_PCI_QUIRK(0x1462, 0x4570, "MSI Wind Top AE2220", ALC883_TARGA_DIG), 9587 SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG), 9588 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG), 9589 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG), 9590 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG), 9591 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG), 9592 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG), 9593 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG), 9594 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG), 9595 SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG), 9596 SND_PCI_QUIRK(0x1462, 0x7437, "MSI NetOn AP1900", ALC883_TARGA_DIG), 9597 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG), 9598 SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG), 9599 9600 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG), 9601 SND_PCI_QUIRK(0x1558, 0x0571, "Clevo laptop M570U", ALC883_3ST_6ch_DIG), 9602 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720), 9603 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720), 9604 SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R), 9605 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD), 9606 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch), 9607 /* SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), */ 9608 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION), 9609 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx", 9610 ALC883_FUJITSU_PI2515), 9611 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx", 9612 ALC888_FUJITSU_XA3530), 9613 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch), 9614 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763), 9615 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763), 9616 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763), 9617 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY), 9618 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2), 9619 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG), 9620 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG), 9621 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66), 9622 9623 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL), 9624 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL), 9625 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC), 9626 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL), 9627 SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL), 9628 SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL), 9629 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC882_6ST_DIG), 9630 9631 {} 9632}; 9633 9634/* codec SSID table for Intel Mac */ 9635static struct snd_pci_quirk alc882_ssid_cfg_tbl[] = { 9636 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3), 9637 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3), 9638 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3), 9639 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_MACPRO), 9640 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24), 9641 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24), 9642 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3), 9643 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889A_MB31), 9644 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_ASUS_A7M), 9645 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC885_MBP3), 9646 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC885_MBA21), 9647 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31), 9648 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3), 9649 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24), 9650 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC885_IMAC91), 9651 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5), 9652 SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC885_MB5), 9653 /* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2, 9654 * so apparently no perfect solution yet 9655 */ 9656 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5), 9657 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5), 9658 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC885_MACMINI3), 9659 {} /* terminator */ 9660}; 9661 9662static struct alc_config_preset alc882_presets[] = { 9663 [ALC882_3ST_DIG] = { 9664 .mixers = { alc882_base_mixer }, 9665 .init_verbs = { alc882_base_init_verbs, 9666 alc882_adc1_init_verbs }, 9667 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 9668 .dac_nids = alc882_dac_nids, 9669 .dig_out_nid = ALC882_DIGOUT_NID, 9670 .dig_in_nid = ALC882_DIGIN_NID, 9671 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes), 9672 .channel_mode = alc882_ch_modes, 9673 .need_dac_fix = 1, 9674 .input_mux = &alc882_capture_source, 9675 }, 9676 [ALC882_6ST_DIG] = { 9677 .mixers = { alc882_base_mixer, alc882_chmode_mixer }, 9678 .init_verbs = { alc882_base_init_verbs, 9679 alc882_adc1_init_verbs }, 9680 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 9681 .dac_nids = alc882_dac_nids, 9682 .dig_out_nid = ALC882_DIGOUT_NID, 9683 .dig_in_nid = ALC882_DIGIN_NID, 9684 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes), 9685 .channel_mode = alc882_sixstack_modes, 9686 .input_mux = &alc882_capture_source, 9687 }, 9688 [ALC882_ARIMA] = { 9689 .mixers = { alc882_base_mixer, alc882_chmode_mixer }, 9690 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs, 9691 alc882_eapd_verbs }, 9692 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 9693 .dac_nids = alc882_dac_nids, 9694 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes), 9695 .channel_mode = alc882_sixstack_modes, 9696 .input_mux = &alc882_capture_source, 9697 }, 9698 [ALC882_W2JC] = { 9699 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer }, 9700 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs, 9701 alc882_eapd_verbs, alc880_gpio1_init_verbs }, 9702 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 9703 .dac_nids = alc882_dac_nids, 9704 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), 9705 .channel_mode = alc880_threestack_modes, 9706 .need_dac_fix = 1, 9707 .input_mux = &alc882_capture_source, 9708 .dig_out_nid = ALC882_DIGOUT_NID, 9709 }, 9710 [ALC885_MBA21] = { 9711 .mixers = { alc885_mba21_mixer }, 9712 .init_verbs = { alc885_mba21_init_verbs, alc880_gpio1_init_verbs }, 9713 .num_dacs = 2, 9714 .dac_nids = alc882_dac_nids, 9715 .channel_mode = alc885_mba21_ch_modes, 9716 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes), 9717 .input_mux = &alc882_capture_source, 9718 .unsol_event = alc_automute_amp_unsol_event, 9719 .setup = alc885_mba21_setup, 9720 .init_hook = alc_automute_amp, 9721 }, 9722 [ALC885_MBP3] = { 9723 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer }, 9724 .init_verbs = { alc885_mbp3_init_verbs, 9725 alc880_gpio1_init_verbs }, 9726 .num_dacs = 2, 9727 .dac_nids = alc882_dac_nids, 9728 .hp_nid = 0x04, 9729 .channel_mode = alc885_mbp_4ch_modes, 9730 .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes), 9731 .input_mux = &alc882_capture_source, 9732 .dig_out_nid = ALC882_DIGOUT_NID, 9733 .dig_in_nid = ALC882_DIGIN_NID, 9734 .unsol_event = alc_automute_amp_unsol_event, 9735 .setup = alc885_mbp3_setup, 9736 .init_hook = alc_automute_amp, 9737 }, 9738 [ALC885_MB5] = { 9739 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer }, 9740 .init_verbs = { alc885_mb5_init_verbs, 9741 alc880_gpio1_init_verbs }, 9742 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 9743 .dac_nids = alc882_dac_nids, 9744 .channel_mode = alc885_mb5_6ch_modes, 9745 .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes), 9746 .input_mux = &mb5_capture_source, 9747 .dig_out_nid = ALC882_DIGOUT_NID, 9748 .dig_in_nid = ALC882_DIGIN_NID, 9749 .unsol_event = alc_automute_amp_unsol_event, 9750 .setup = alc885_mb5_setup, 9751 .init_hook = alc_automute_amp, 9752 }, 9753 [ALC885_MACMINI3] = { 9754 .mixers = { alc885_macmini3_mixer, alc882_chmode_mixer }, 9755 .init_verbs = { alc885_macmini3_init_verbs, 9756 alc880_gpio1_init_verbs }, 9757 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 9758 .dac_nids = alc882_dac_nids, 9759 .channel_mode = alc885_macmini3_6ch_modes, 9760 .num_channel_mode = ARRAY_SIZE(alc885_macmini3_6ch_modes), 9761 .input_mux = &macmini3_capture_source, 9762 .dig_out_nid = ALC882_DIGOUT_NID, 9763 .dig_in_nid = ALC882_DIGIN_NID, 9764 .unsol_event = alc_automute_amp_unsol_event, 9765 .setup = alc885_macmini3_setup, 9766 .init_hook = alc_automute_amp, 9767 }, 9768 [ALC885_MACPRO] = { 9769 .mixers = { alc882_macpro_mixer }, 9770 .init_verbs = { alc882_macpro_init_verbs }, 9771 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 9772 .dac_nids = alc882_dac_nids, 9773 .dig_out_nid = ALC882_DIGOUT_NID, 9774 .dig_in_nid = ALC882_DIGIN_NID, 9775 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes), 9776 .channel_mode = alc882_ch_modes, 9777 .input_mux = &alc882_capture_source, 9778 .init_hook = alc885_macpro_init_hook, 9779 }, 9780 [ALC885_IMAC24] = { 9781 .mixers = { alc885_imac24_mixer }, 9782 .init_verbs = { alc885_imac24_init_verbs }, 9783 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 9784 .dac_nids = alc882_dac_nids, 9785 .dig_out_nid = ALC882_DIGOUT_NID, 9786 .dig_in_nid = ALC882_DIGIN_NID, 9787 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes), 9788 .channel_mode = alc882_ch_modes, 9789 .input_mux = &alc882_capture_source, 9790 .unsol_event = alc_automute_amp_unsol_event, 9791 .setup = alc885_imac24_setup, 9792 .init_hook = alc885_imac24_init_hook, 9793 }, 9794 [ALC885_IMAC91] = { 9795 .mixers = {alc885_imac91_mixer}, 9796 .init_verbs = { alc885_imac91_init_verbs, 9797 alc880_gpio1_init_verbs }, 9798 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 9799 .dac_nids = alc882_dac_nids, 9800 .channel_mode = alc885_mba21_ch_modes, 9801 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes), 9802 .input_mux = &alc889A_imac91_capture_source, 9803 .dig_out_nid = ALC882_DIGOUT_NID, 9804 .dig_in_nid = ALC882_DIGIN_NID, 9805 .unsol_event = alc_automute_amp_unsol_event, 9806 .setup = alc885_imac91_setup, 9807 .init_hook = alc_automute_amp, 9808 }, 9809 [ALC882_TARGA] = { 9810 .mixers = { alc882_targa_mixer, alc882_chmode_mixer }, 9811 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs, 9812 alc880_gpio3_init_verbs, alc882_targa_verbs}, 9813 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 9814 .dac_nids = alc882_dac_nids, 9815 .dig_out_nid = ALC882_DIGOUT_NID, 9816 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids), 9817 .adc_nids = alc882_adc_nids, 9818 .capsrc_nids = alc882_capsrc_nids, 9819 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes), 9820 .channel_mode = alc882_3ST_6ch_modes, 9821 .need_dac_fix = 1, 9822 .input_mux = &alc882_capture_source, 9823 .unsol_event = alc882_targa_unsol_event, 9824 .setup = alc882_targa_setup, 9825 .init_hook = alc882_targa_automute, 9826 }, 9827 [ALC882_ASUS_A7J] = { 9828 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer }, 9829 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs, 9830 alc882_asus_a7j_verbs}, 9831 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 9832 .dac_nids = alc882_dac_nids, 9833 .dig_out_nid = ALC882_DIGOUT_NID, 9834 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids), 9835 .adc_nids = alc882_adc_nids, 9836 .capsrc_nids = alc882_capsrc_nids, 9837 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes), 9838 .channel_mode = alc882_3ST_6ch_modes, 9839 .need_dac_fix = 1, 9840 .input_mux = &alc882_capture_source, 9841 }, 9842 [ALC882_ASUS_A7M] = { 9843 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer }, 9844 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs, 9845 alc882_eapd_verbs, alc880_gpio1_init_verbs, 9846 alc882_asus_a7m_verbs }, 9847 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 9848 .dac_nids = alc882_dac_nids, 9849 .dig_out_nid = ALC882_DIGOUT_NID, 9850 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), 9851 .channel_mode = alc880_threestack_modes, 9852 .need_dac_fix = 1, 9853 .input_mux = &alc882_capture_source, 9854 }, 9855 [ALC883_3ST_2ch_DIG] = { 9856 .mixers = { alc883_3ST_2ch_mixer }, 9857 .init_verbs = { alc883_init_verbs }, 9858 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 9859 .dac_nids = alc883_dac_nids, 9860 .dig_out_nid = ALC883_DIGOUT_NID, 9861 .dig_in_nid = ALC883_DIGIN_NID, 9862 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 9863 .channel_mode = alc883_3ST_2ch_modes, 9864 .input_mux = &alc883_capture_source, 9865 }, 9866 [ALC883_3ST_6ch_DIG] = { 9867 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, 9868 .init_verbs = { alc883_init_verbs }, 9869 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 9870 .dac_nids = alc883_dac_nids, 9871 .dig_out_nid = ALC883_DIGOUT_NID, 9872 .dig_in_nid = ALC883_DIGIN_NID, 9873 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 9874 .channel_mode = alc883_3ST_6ch_modes, 9875 .need_dac_fix = 1, 9876 .input_mux = &alc883_capture_source, 9877 }, 9878 [ALC883_3ST_6ch] = { 9879 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, 9880 .init_verbs = { alc883_init_verbs }, 9881 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 9882 .dac_nids = alc883_dac_nids, 9883 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 9884 .channel_mode = alc883_3ST_6ch_modes, 9885 .need_dac_fix = 1, 9886 .input_mux = &alc883_capture_source, 9887 }, 9888 [ALC883_3ST_6ch_INTEL] = { 9889 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer }, 9890 .init_verbs = { alc883_init_verbs }, 9891 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 9892 .dac_nids = alc883_dac_nids, 9893 .dig_out_nid = ALC883_DIGOUT_NID, 9894 .dig_in_nid = ALC883_DIGIN_NID, 9895 .slave_dig_outs = alc883_slave_dig_outs, 9896 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes), 9897 .channel_mode = alc883_3ST_6ch_intel_modes, 9898 .need_dac_fix = 1, 9899 .input_mux = &alc883_3stack_6ch_intel, 9900 }, 9901 [ALC889A_INTEL] = { 9902 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer }, 9903 .init_verbs = { alc885_init_verbs, alc885_init_input_verbs, 9904 alc_hp15_unsol_verbs }, 9905 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 9906 .dac_nids = alc883_dac_nids, 9907 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids), 9908 .adc_nids = alc889_adc_nids, 9909 .dig_out_nid = ALC883_DIGOUT_NID, 9910 .dig_in_nid = ALC883_DIGIN_NID, 9911 .slave_dig_outs = alc883_slave_dig_outs, 9912 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes), 9913 .channel_mode = alc889_8ch_intel_modes, 9914 .capsrc_nids = alc889_capsrc_nids, 9915 .input_mux = &alc889_capture_source, 9916 .setup = alc889_automute_setup, 9917 .init_hook = alc_automute_amp, 9918 .unsol_event = alc_automute_amp_unsol_event, 9919 .need_dac_fix = 1, 9920 }, 9921 [ALC889_INTEL] = { 9922 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer }, 9923 .init_verbs = { alc885_init_verbs, alc889_init_input_verbs, 9924 alc889_eapd_verbs, alc_hp15_unsol_verbs}, 9925 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 9926 .dac_nids = alc883_dac_nids, 9927 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids), 9928 .adc_nids = alc889_adc_nids, 9929 .dig_out_nid = ALC883_DIGOUT_NID, 9930 .dig_in_nid = ALC883_DIGIN_NID, 9931 .slave_dig_outs = alc883_slave_dig_outs, 9932 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes), 9933 .channel_mode = alc889_8ch_intel_modes, 9934 .capsrc_nids = alc889_capsrc_nids, 9935 .input_mux = &alc889_capture_source, 9936 .setup = alc889_automute_setup, 9937 .init_hook = alc889_intel_init_hook, 9938 .unsol_event = alc_automute_amp_unsol_event, 9939 .need_dac_fix = 1, 9940 }, 9941 [ALC883_6ST_DIG] = { 9942 .mixers = { alc883_base_mixer, alc883_chmode_mixer }, 9943 .init_verbs = { alc883_init_verbs }, 9944 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 9945 .dac_nids = alc883_dac_nids, 9946 .dig_out_nid = ALC883_DIGOUT_NID, 9947 .dig_in_nid = ALC883_DIGIN_NID, 9948 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), 9949 .channel_mode = alc883_sixstack_modes, 9950 .input_mux = &alc883_capture_source, 9951 }, 9952 [ALC883_TARGA_DIG] = { 9953 .mixers = { alc883_targa_mixer, alc883_chmode_mixer }, 9954 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs, 9955 alc883_targa_verbs}, 9956 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 9957 .dac_nids = alc883_dac_nids, 9958 .dig_out_nid = ALC883_DIGOUT_NID, 9959 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 9960 .channel_mode = alc883_3ST_6ch_modes, 9961 .need_dac_fix = 1, 9962 .input_mux = &alc883_capture_source, 9963 .unsol_event = alc883_targa_unsol_event, 9964 .setup = alc882_targa_setup, 9965 .init_hook = alc882_targa_automute, 9966 }, 9967 [ALC883_TARGA_2ch_DIG] = { 9968 .mixers = { alc883_targa_2ch_mixer}, 9969 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs, 9970 alc883_targa_verbs}, 9971 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 9972 .dac_nids = alc883_dac_nids, 9973 .adc_nids = alc883_adc_nids_alt, 9974 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt), 9975 .capsrc_nids = alc883_capsrc_nids, 9976 .dig_out_nid = ALC883_DIGOUT_NID, 9977 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 9978 .channel_mode = alc883_3ST_2ch_modes, 9979 .input_mux = &alc883_capture_source, 9980 .unsol_event = alc883_targa_unsol_event, 9981 .setup = alc882_targa_setup, 9982 .init_hook = alc882_targa_automute, 9983 }, 9984 [ALC883_TARGA_8ch_DIG] = { 9985 .mixers = { alc883_targa_mixer, alc883_targa_8ch_mixer, 9986 alc883_chmode_mixer }, 9987 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs, 9988 alc883_targa_verbs }, 9989 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 9990 .dac_nids = alc883_dac_nids, 9991 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev), 9992 .adc_nids = alc883_adc_nids_rev, 9993 .capsrc_nids = alc883_capsrc_nids_rev, 9994 .dig_out_nid = ALC883_DIGOUT_NID, 9995 .dig_in_nid = ALC883_DIGIN_NID, 9996 .num_channel_mode = ARRAY_SIZE(alc883_4ST_8ch_modes), 9997 .channel_mode = alc883_4ST_8ch_modes, 9998 .need_dac_fix = 1, 9999 .input_mux = &alc883_capture_source, 10000 .unsol_event = alc883_targa_unsol_event, 10001 .setup = alc882_targa_setup, 10002 .init_hook = alc882_targa_automute, 10003 }, 10004 [ALC883_ACER] = { 10005 .mixers = { alc883_base_mixer }, 10006 /* On TravelMate laptops, GPIO 0 enables the internal speaker 10007 * and the headphone jack. Turn this on and rely on the 10008 * standard mute methods whenever the user wants to turn 10009 * these outputs off. 10010 */ 10011 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs }, 10012 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10013 .dac_nids = alc883_dac_nids, 10014 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10015 .channel_mode = alc883_3ST_2ch_modes, 10016 .input_mux = &alc883_capture_source, 10017 }, 10018 [ALC883_ACER_ASPIRE] = { 10019 .mixers = { alc883_acer_aspire_mixer }, 10020 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs }, 10021 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10022 .dac_nids = alc883_dac_nids, 10023 .dig_out_nid = ALC883_DIGOUT_NID, 10024 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10025 .channel_mode = alc883_3ST_2ch_modes, 10026 .input_mux = &alc883_capture_source, 10027 .unsol_event = alc_automute_amp_unsol_event, 10028 .setup = alc883_acer_aspire_setup, 10029 .init_hook = alc_automute_amp, 10030 }, 10031 [ALC888_ACER_ASPIRE_4930G] = { 10032 .mixers = { alc888_base_mixer, 10033 alc883_chmode_mixer }, 10034 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs, 10035 alc888_acer_aspire_4930g_verbs }, 10036 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10037 .dac_nids = alc883_dac_nids, 10038 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev), 10039 .adc_nids = alc883_adc_nids_rev, 10040 .capsrc_nids = alc883_capsrc_nids_rev, 10041 .dig_out_nid = ALC883_DIGOUT_NID, 10042 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 10043 .channel_mode = alc883_3ST_6ch_modes, 10044 .need_dac_fix = 1, 10045 .const_channel_count = 6, 10046 .num_mux_defs = 10047 ARRAY_SIZE(alc888_2_capture_sources), 10048 .input_mux = alc888_2_capture_sources, 10049 .unsol_event = alc_automute_amp_unsol_event, 10050 .setup = alc888_acer_aspire_4930g_setup, 10051 .init_hook = alc_automute_amp, 10052 }, 10053 [ALC888_ACER_ASPIRE_6530G] = { 10054 .mixers = { alc888_acer_aspire_6530_mixer }, 10055 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs, 10056 alc888_acer_aspire_6530g_verbs }, 10057 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10058 .dac_nids = alc883_dac_nids, 10059 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev), 10060 .adc_nids = alc883_adc_nids_rev, 10061 .capsrc_nids = alc883_capsrc_nids_rev, 10062 .dig_out_nid = ALC883_DIGOUT_NID, 10063 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10064 .channel_mode = alc883_3ST_2ch_modes, 10065 .num_mux_defs = 10066 ARRAY_SIZE(alc888_2_capture_sources), 10067 .input_mux = alc888_acer_aspire_6530_sources, 10068 .unsol_event = alc_automute_amp_unsol_event, 10069 .setup = alc888_acer_aspire_6530g_setup, 10070 .init_hook = alc_automute_amp, 10071 }, 10072 [ALC888_ACER_ASPIRE_8930G] = { 10073 .mixers = { alc889_acer_aspire_8930g_mixer, 10074 alc883_chmode_mixer }, 10075 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs, 10076 alc889_acer_aspire_8930g_verbs, 10077 alc889_eapd_verbs}, 10078 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10079 .dac_nids = alc883_dac_nids, 10080 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids), 10081 .adc_nids = alc889_adc_nids, 10082 .capsrc_nids = alc889_capsrc_nids, 10083 .dig_out_nid = ALC883_DIGOUT_NID, 10084 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 10085 .channel_mode = alc883_3ST_6ch_modes, 10086 .need_dac_fix = 1, 10087 .const_channel_count = 6, 10088 .num_mux_defs = 10089 ARRAY_SIZE(alc889_capture_sources), 10090 .input_mux = alc889_capture_sources, 10091 .unsol_event = alc_automute_amp_unsol_event, 10092 .setup = alc889_acer_aspire_8930g_setup, 10093 .init_hook = alc_automute_amp, 10094#ifdef CONFIG_SND_HDA_POWER_SAVE 10095 .power_hook = alc_power_eapd, 10096#endif 10097 }, 10098 [ALC888_ACER_ASPIRE_7730G] = { 10099 .mixers = { alc883_3ST_6ch_mixer, 10100 alc883_chmode_mixer }, 10101 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs, 10102 alc888_acer_aspire_7730G_verbs }, 10103 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10104 .dac_nids = alc883_dac_nids, 10105 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev), 10106 .adc_nids = alc883_adc_nids_rev, 10107 .capsrc_nids = alc883_capsrc_nids_rev, 10108 .dig_out_nid = ALC883_DIGOUT_NID, 10109 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 10110 .channel_mode = alc883_3ST_6ch_modes, 10111 .need_dac_fix = 1, 10112 .const_channel_count = 6, 10113 .input_mux = &alc883_capture_source, 10114 .unsol_event = alc_automute_amp_unsol_event, 10115 .setup = alc888_acer_aspire_6530g_setup, 10116 .init_hook = alc_automute_amp, 10117 }, 10118 [ALC883_MEDION] = { 10119 .mixers = { alc883_fivestack_mixer, 10120 alc883_chmode_mixer }, 10121 .init_verbs = { alc883_init_verbs, 10122 alc883_medion_eapd_verbs }, 10123 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10124 .dac_nids = alc883_dac_nids, 10125 .adc_nids = alc883_adc_nids_alt, 10126 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt), 10127 .capsrc_nids = alc883_capsrc_nids, 10128 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), 10129 .channel_mode = alc883_sixstack_modes, 10130 .input_mux = &alc883_capture_source, 10131 }, 10132 [ALC883_MEDION_MD2] = { 10133 .mixers = { alc883_medion_md2_mixer}, 10134 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs}, 10135 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10136 .dac_nids = alc883_dac_nids, 10137 .dig_out_nid = ALC883_DIGOUT_NID, 10138 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10139 .channel_mode = alc883_3ST_2ch_modes, 10140 .input_mux = &alc883_capture_source, 10141 .unsol_event = alc_automute_amp_unsol_event, 10142 .setup = alc883_medion_md2_setup, 10143 .init_hook = alc_automute_amp, 10144 }, 10145 [ALC883_MEDION_WIM2160] = { 10146 .mixers = { alc883_medion_wim2160_mixer }, 10147 .init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs }, 10148 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10149 .dac_nids = alc883_dac_nids, 10150 .dig_out_nid = ALC883_DIGOUT_NID, 10151 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 10152 .adc_nids = alc883_adc_nids, 10153 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10154 .channel_mode = alc883_3ST_2ch_modes, 10155 .input_mux = &alc883_capture_source, 10156 .unsol_event = alc_automute_amp_unsol_event, 10157 .setup = alc883_medion_wim2160_setup, 10158 .init_hook = alc_automute_amp, 10159 }, 10160 [ALC883_LAPTOP_EAPD] = { 10161 .mixers = { alc883_base_mixer }, 10162 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs }, 10163 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10164 .dac_nids = alc883_dac_nids, 10165 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10166 .channel_mode = alc883_3ST_2ch_modes, 10167 .input_mux = &alc883_capture_source, 10168 }, 10169 [ALC883_CLEVO_M540R] = { 10170 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, 10171 .init_verbs = { alc883_init_verbs, alc883_clevo_m540r_verbs }, 10172 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10173 .dac_nids = alc883_dac_nids, 10174 .dig_out_nid = ALC883_DIGOUT_NID, 10175 .dig_in_nid = ALC883_DIGIN_NID, 10176 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_clevo_modes), 10177 .channel_mode = alc883_3ST_6ch_clevo_modes, 10178 .need_dac_fix = 1, 10179 .input_mux = &alc883_capture_source, 10180 /* This machine has the hardware HP auto-muting, thus 10181 * we need no software mute via unsol event 10182 */ 10183 }, 10184 [ALC883_CLEVO_M720] = { 10185 .mixers = { alc883_clevo_m720_mixer }, 10186 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs }, 10187 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10188 .dac_nids = alc883_dac_nids, 10189 .dig_out_nid = ALC883_DIGOUT_NID, 10190 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10191 .channel_mode = alc883_3ST_2ch_modes, 10192 .input_mux = &alc883_capture_source, 10193 .unsol_event = alc883_clevo_m720_unsol_event, 10194 .setup = alc883_clevo_m720_setup, 10195 .init_hook = alc883_clevo_m720_init_hook, 10196 }, 10197 [ALC883_LENOVO_101E_2ch] = { 10198 .mixers = { alc883_lenovo_101e_2ch_mixer}, 10199 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs}, 10200 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10201 .dac_nids = alc883_dac_nids, 10202 .adc_nids = alc883_adc_nids_alt, 10203 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt), 10204 .capsrc_nids = alc883_capsrc_nids, 10205 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10206 .channel_mode = alc883_3ST_2ch_modes, 10207 .input_mux = &alc883_lenovo_101e_capture_source, 10208 .unsol_event = alc883_lenovo_101e_unsol_event, 10209 .init_hook = alc883_lenovo_101e_all_automute, 10210 }, 10211 [ALC883_LENOVO_NB0763] = { 10212 .mixers = { alc883_lenovo_nb0763_mixer }, 10213 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs}, 10214 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10215 .dac_nids = alc883_dac_nids, 10216 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10217 .channel_mode = alc883_3ST_2ch_modes, 10218 .need_dac_fix = 1, 10219 .input_mux = &alc883_lenovo_nb0763_capture_source, 10220 .unsol_event = alc_automute_amp_unsol_event, 10221 .setup = alc883_medion_md2_setup, 10222 .init_hook = alc_automute_amp, 10223 }, 10224 [ALC888_LENOVO_MS7195_DIG] = { 10225 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, 10226 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs}, 10227 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10228 .dac_nids = alc883_dac_nids, 10229 .dig_out_nid = ALC883_DIGOUT_NID, 10230 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 10231 .channel_mode = alc883_3ST_6ch_modes, 10232 .need_dac_fix = 1, 10233 .input_mux = &alc883_capture_source, 10234 .unsol_event = alc883_lenovo_ms7195_unsol_event, 10235 .init_hook = alc888_lenovo_ms7195_front_automute, 10236 }, 10237 [ALC883_HAIER_W66] = { 10238 .mixers = { alc883_targa_2ch_mixer}, 10239 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs}, 10240 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10241 .dac_nids = alc883_dac_nids, 10242 .dig_out_nid = ALC883_DIGOUT_NID, 10243 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10244 .channel_mode = alc883_3ST_2ch_modes, 10245 .input_mux = &alc883_capture_source, 10246 .unsol_event = alc_automute_amp_unsol_event, 10247 .setup = alc883_haier_w66_setup, 10248 .init_hook = alc_automute_amp, 10249 }, 10250 [ALC888_3ST_HP] = { 10251 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, 10252 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs }, 10253 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10254 .dac_nids = alc883_dac_nids, 10255 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes), 10256 .channel_mode = alc888_3st_hp_modes, 10257 .need_dac_fix = 1, 10258 .input_mux = &alc883_capture_source, 10259 .unsol_event = alc_automute_amp_unsol_event, 10260 .setup = alc888_3st_hp_setup, 10261 .init_hook = alc_automute_amp, 10262 }, 10263 [ALC888_6ST_DELL] = { 10264 .mixers = { alc883_base_mixer, alc883_chmode_mixer }, 10265 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs }, 10266 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10267 .dac_nids = alc883_dac_nids, 10268 .dig_out_nid = ALC883_DIGOUT_NID, 10269 .dig_in_nid = ALC883_DIGIN_NID, 10270 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), 10271 .channel_mode = alc883_sixstack_modes, 10272 .input_mux = &alc883_capture_source, 10273 .unsol_event = alc_automute_amp_unsol_event, 10274 .setup = alc888_6st_dell_setup, 10275 .init_hook = alc_automute_amp, 10276 }, 10277 [ALC883_MITAC] = { 10278 .mixers = { alc883_mitac_mixer }, 10279 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs }, 10280 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10281 .dac_nids = alc883_dac_nids, 10282 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10283 .channel_mode = alc883_3ST_2ch_modes, 10284 .input_mux = &alc883_capture_source, 10285 .unsol_event = alc_automute_amp_unsol_event, 10286 .setup = alc883_mitac_setup, 10287 .init_hook = alc_automute_amp, 10288 }, 10289 [ALC883_FUJITSU_PI2515] = { 10290 .mixers = { alc883_2ch_fujitsu_pi2515_mixer }, 10291 .init_verbs = { alc883_init_verbs, 10292 alc883_2ch_fujitsu_pi2515_verbs}, 10293 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10294 .dac_nids = alc883_dac_nids, 10295 .dig_out_nid = ALC883_DIGOUT_NID, 10296 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10297 .channel_mode = alc883_3ST_2ch_modes, 10298 .input_mux = &alc883_fujitsu_pi2515_capture_source, 10299 .unsol_event = alc_automute_amp_unsol_event, 10300 .setup = alc883_2ch_fujitsu_pi2515_setup, 10301 .init_hook = alc_automute_amp, 10302 }, 10303 [ALC888_FUJITSU_XA3530] = { 10304 .mixers = { alc888_base_mixer, alc883_chmode_mixer }, 10305 .init_verbs = { alc883_init_verbs, 10306 alc888_fujitsu_xa3530_verbs }, 10307 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10308 .dac_nids = alc883_dac_nids, 10309 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev), 10310 .adc_nids = alc883_adc_nids_rev, 10311 .capsrc_nids = alc883_capsrc_nids_rev, 10312 .dig_out_nid = ALC883_DIGOUT_NID, 10313 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes), 10314 .channel_mode = alc888_4ST_8ch_intel_modes, 10315 .num_mux_defs = 10316 ARRAY_SIZE(alc888_2_capture_sources), 10317 .input_mux = alc888_2_capture_sources, 10318 .unsol_event = alc_automute_amp_unsol_event, 10319 .setup = alc888_fujitsu_xa3530_setup, 10320 .init_hook = alc_automute_amp, 10321 }, 10322 [ALC888_LENOVO_SKY] = { 10323 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer }, 10324 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs}, 10325 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10326 .dac_nids = alc883_dac_nids, 10327 .dig_out_nid = ALC883_DIGOUT_NID, 10328 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), 10329 .channel_mode = alc883_sixstack_modes, 10330 .need_dac_fix = 1, 10331 .input_mux = &alc883_lenovo_sky_capture_source, 10332 .unsol_event = alc_automute_amp_unsol_event, 10333 .setup = alc888_lenovo_sky_setup, 10334 .init_hook = alc_automute_amp, 10335 }, 10336 [ALC888_ASUS_M90V] = { 10337 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, 10338 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs }, 10339 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10340 .dac_nids = alc883_dac_nids, 10341 .dig_out_nid = ALC883_DIGOUT_NID, 10342 .dig_in_nid = ALC883_DIGIN_NID, 10343 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 10344 .channel_mode = alc883_3ST_6ch_modes, 10345 .need_dac_fix = 1, 10346 .input_mux = &alc883_fujitsu_pi2515_capture_source, 10347 .unsol_event = alc_sku_unsol_event, 10348 .setup = alc883_mode2_setup, 10349 .init_hook = alc_inithook, 10350 }, 10351 [ALC888_ASUS_EEE1601] = { 10352 .mixers = { alc883_asus_eee1601_mixer }, 10353 .cap_mixer = alc883_asus_eee1601_cap_mixer, 10354 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs }, 10355 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10356 .dac_nids = alc883_dac_nids, 10357 .dig_out_nid = ALC883_DIGOUT_NID, 10358 .dig_in_nid = ALC883_DIGIN_NID, 10359 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10360 .channel_mode = alc883_3ST_2ch_modes, 10361 .need_dac_fix = 1, 10362 .input_mux = &alc883_asus_eee1601_capture_source, 10363 .unsol_event = alc_sku_unsol_event, 10364 .init_hook = alc883_eee1601_inithook, 10365 }, 10366 [ALC1200_ASUS_P5Q] = { 10367 .mixers = { alc883_base_mixer, alc883_chmode_mixer }, 10368 .init_verbs = { alc883_init_verbs }, 10369 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10370 .dac_nids = alc883_dac_nids, 10371 .dig_out_nid = ALC1200_DIGOUT_NID, 10372 .dig_in_nid = ALC883_DIGIN_NID, 10373 .slave_dig_outs = alc1200_slave_dig_outs, 10374 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), 10375 .channel_mode = alc883_sixstack_modes, 10376 .input_mux = &alc883_capture_source, 10377 }, 10378 [ALC889A_MB31] = { 10379 .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer}, 10380 .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs, 10381 alc880_gpio1_init_verbs }, 10382 .adc_nids = alc883_adc_nids, 10383 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 10384 .capsrc_nids = alc883_capsrc_nids, 10385 .dac_nids = alc883_dac_nids, 10386 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10387 .channel_mode = alc889A_mb31_6ch_modes, 10388 .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes), 10389 .input_mux = &alc889A_mb31_capture_source, 10390 .dig_out_nid = ALC883_DIGOUT_NID, 10391 .unsol_event = alc889A_mb31_unsol_event, 10392 .init_hook = alc889A_mb31_automute, 10393 }, 10394 [ALC883_SONY_VAIO_TT] = { 10395 .mixers = { alc883_vaiott_mixer }, 10396 .init_verbs = { alc883_init_verbs, alc883_vaiott_verbs }, 10397 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10398 .dac_nids = alc883_dac_nids, 10399 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10400 .channel_mode = alc883_3ST_2ch_modes, 10401 .input_mux = &alc883_capture_source, 10402 .unsol_event = alc_automute_amp_unsol_event, 10403 .setup = alc883_vaiott_setup, 10404 .init_hook = alc_automute_amp, 10405 }, 10406}; 10407 10408 10409/* 10410 * Pin config fixes 10411 */ 10412enum { 10413 PINFIX_ABIT_AW9D_MAX, 10414 PINFIX_PB_M5210, 10415}; 10416 10417static struct alc_pincfg alc882_abit_aw9d_pinfix[] = { 10418 { 0x15, 0x01080104 }, /* side */ 10419 { 0x16, 0x01011012 }, /* rear */ 10420 { 0x17, 0x01016011 }, /* clfe */ 10421 { } 10422}; 10423 10424static const struct hda_verb pb_m5210_verbs[] = { 10425 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 }, 10426 {} 10427}; 10428 10429static const struct alc_fixup alc882_fixups[] = { 10430 [PINFIX_ABIT_AW9D_MAX] = { 10431 .pins = alc882_abit_aw9d_pinfix 10432 }, 10433 [PINFIX_PB_M5210] = { 10434 .verbs = pb_m5210_verbs 10435 }, 10436}; 10437 10438static struct snd_pci_quirk alc882_fixup_tbl[] = { 10439 SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", PINFIX_PB_M5210), 10440 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX), 10441 {} 10442}; 10443 10444/* 10445 * BIOS auto configuration 10446 */ 10447static int alc882_auto_create_input_ctls(struct hda_codec *codec, 10448 const struct auto_pin_cfg *cfg) 10449{ 10450 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x23, 0x22); 10451} 10452 10453static void alc882_auto_set_output_and_unmute(struct hda_codec *codec, 10454 hda_nid_t nid, int pin_type, 10455 hda_nid_t dac) 10456{ 10457 int idx; 10458 10459 /* set as output */ 10460 alc_set_pin_output(codec, nid, pin_type); 10461 10462 if (dac == 0x25) 10463 idx = 4; 10464 else if (dac >= 0x02 && dac <= 0x05) 10465 idx = dac - 2; 10466 else 10467 return; 10468 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx); 10469} 10470 10471static void alc882_auto_init_multi_out(struct hda_codec *codec) 10472{ 10473 struct alc_spec *spec = codec->spec; 10474 int i; 10475 10476 for (i = 0; i <= HDA_SIDE; i++) { 10477 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 10478 int pin_type = get_pin_type(spec->autocfg.line_out_type); 10479 if (nid) 10480 alc882_auto_set_output_and_unmute(codec, nid, pin_type, 10481 spec->multiout.dac_nids[i]); 10482 } 10483} 10484 10485static void alc882_auto_init_hp_out(struct hda_codec *codec) 10486{ 10487 struct alc_spec *spec = codec->spec; 10488 hda_nid_t pin, dac; 10489 10490 pin = spec->autocfg.hp_pins[0]; 10491 if (pin) { 10492 dac = spec->multiout.hp_nid; 10493 if (!dac) 10494 dac = spec->multiout.dac_nids[0]; /* to front */ 10495 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, dac); 10496 } 10497 pin = spec->autocfg.speaker_pins[0]; 10498 if (pin) { 10499 dac = spec->multiout.extra_out_nid[0]; 10500 if (!dac) 10501 dac = spec->multiout.dac_nids[0]; /* to front */ 10502 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac); 10503 } 10504} 10505 10506static void alc882_auto_init_analog_input(struct hda_codec *codec) 10507{ 10508 struct alc_spec *spec = codec->spec; 10509 int i; 10510 10511 for (i = 0; i < AUTO_PIN_LAST; i++) { 10512 hda_nid_t nid = spec->autocfg.input_pins[i]; 10513 if (!nid) 10514 continue; 10515 alc_set_input_pin(codec, nid, i); 10516 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP) 10517 snd_hda_codec_write(codec, nid, 0, 10518 AC_VERB_SET_AMP_GAIN_MUTE, 10519 AMP_OUT_MUTE); 10520 } 10521} 10522 10523static void alc882_auto_init_input_src(struct hda_codec *codec) 10524{ 10525 struct alc_spec *spec = codec->spec; 10526 int c; 10527 10528 for (c = 0; c < spec->num_adc_nids; c++) { 10529 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS]; 10530 hda_nid_t nid = spec->capsrc_nids[c]; 10531 unsigned int mux_idx; 10532 const struct hda_input_mux *imux; 10533 int conns, mute, idx, item; 10534 10535 conns = snd_hda_get_connections(codec, nid, conn_list, 10536 ARRAY_SIZE(conn_list)); 10537 if (conns < 0) 10538 continue; 10539 mux_idx = c >= spec->num_mux_defs ? 0 : c; 10540 imux = &spec->input_mux[mux_idx]; 10541 if (!imux->num_items && mux_idx > 0) 10542 imux = &spec->input_mux[0]; 10543 for (idx = 0; idx < conns; idx++) { 10544 /* if the current connection is the selected one, 10545 * unmute it as default - otherwise mute it 10546 */ 10547 mute = AMP_IN_MUTE(idx); 10548 for (item = 0; item < imux->num_items; item++) { 10549 if (imux->items[item].index == idx) { 10550 if (spec->cur_mux[c] == item) 10551 mute = AMP_IN_UNMUTE(idx); 10552 break; 10553 } 10554 } 10555 /* check if we have a selector or mixer 10556 * we could check for the widget type instead, but 10557 * just check for Amp-In presence (in case of mixer 10558 * without amp-in there is something wrong, this 10559 * function shouldn't be used or capsrc nid is wrong) 10560 */ 10561 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) 10562 snd_hda_codec_write(codec, nid, 0, 10563 AC_VERB_SET_AMP_GAIN_MUTE, 10564 mute); 10565 else if (mute != AMP_IN_MUTE(idx)) 10566 snd_hda_codec_write(codec, nid, 0, 10567 AC_VERB_SET_CONNECT_SEL, 10568 idx); 10569 } 10570 } 10571} 10572 10573/* add mic boosts if needed */ 10574static int alc_auto_add_mic_boost(struct hda_codec *codec) 10575{ 10576 struct alc_spec *spec = codec->spec; 10577 int err; 10578 hda_nid_t nid; 10579 10580 nid = spec->autocfg.input_pins[AUTO_PIN_MIC]; 10581 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) { 10582 err = add_control(spec, ALC_CTL_WIDGET_VOL, 10583 "Mic Boost", 10584 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT)); 10585 if (err < 0) 10586 return err; 10587 } 10588 nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC]; 10589 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) { 10590 err = add_control(spec, ALC_CTL_WIDGET_VOL, 10591 "Front Mic Boost", 10592 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT)); 10593 if (err < 0) 10594 return err; 10595 } 10596 return 0; 10597} 10598 10599/* almost identical with ALC880 parser... */ 10600static int alc882_parse_auto_config(struct hda_codec *codec) 10601{ 10602 struct alc_spec *spec = codec->spec; 10603 static hda_nid_t alc882_ignore[] = { 0x1d, 0 }; 10604 int err; 10605 10606 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 10607 alc882_ignore); 10608 if (err < 0) 10609 return err; 10610 if (!spec->autocfg.line_outs) 10611 return 0; /* can't find valid BIOS pin config */ 10612 10613 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); 10614 if (err < 0) 10615 return err; 10616 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg); 10617 if (err < 0) 10618 return err; 10619 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0], 10620 "Headphone"); 10621 if (err < 0) 10622 return err; 10623 err = alc880_auto_create_extra_out(spec, 10624 spec->autocfg.speaker_pins[0], 10625 "Speaker"); 10626 if (err < 0) 10627 return err; 10628 err = alc882_auto_create_input_ctls(codec, &spec->autocfg); 10629 if (err < 0) 10630 return err; 10631 10632 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 10633 10634 alc_auto_parse_digital(codec); 10635 10636 if (spec->kctls.list) 10637 add_mixer(spec, spec->kctls.list); 10638 10639 add_verb(spec, alc883_auto_init_verbs); 10640 /* if ADC 0x07 is available, initialize it, too */ 10641 if (get_wcaps_type(get_wcaps(codec, 0x07)) == AC_WID_AUD_IN) 10642 add_verb(spec, alc882_adc1_init_verbs); 10643 10644 spec->num_mux_defs = 1; 10645 spec->input_mux = &spec->private_imux[0]; 10646 10647 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); 10648 10649 err = alc_auto_add_mic_boost(codec); 10650 if (err < 0) 10651 return err; 10652 10653 return 1; /* config found */ 10654} 10655 10656/* additional initialization for auto-configuration model */ 10657static void alc882_auto_init(struct hda_codec *codec) 10658{ 10659 struct alc_spec *spec = codec->spec; 10660 alc882_auto_init_multi_out(codec); 10661 alc882_auto_init_hp_out(codec); 10662 alc882_auto_init_analog_input(codec); 10663 alc882_auto_init_input_src(codec); 10664 alc_auto_init_digital(codec); 10665 if (spec->unsol_event) 10666 alc_inithook(codec); 10667} 10668 10669static int patch_alc882(struct hda_codec *codec) 10670{ 10671 struct alc_spec *spec; 10672 int err, board_config; 10673 10674 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 10675 if (spec == NULL) 10676 return -ENOMEM; 10677 10678 codec->spec = spec; 10679 10680 alc_auto_parse_customize_define(codec); 10681 10682 switch (codec->vendor_id) { 10683 case 0x10ec0882: 10684 case 0x10ec0885: 10685 break; 10686 default: 10687 /* ALC883 and variants */ 10688 alc_fix_pll_init(codec, 0x20, 0x0a, 10); 10689 break; 10690 } 10691 10692 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST, 10693 alc882_models, 10694 alc882_cfg_tbl); 10695 10696 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) 10697 board_config = snd_hda_check_board_codec_sid_config(codec, 10698 ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl); 10699 10700 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) { 10701 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 10702 codec->chip_name); 10703 board_config = ALC882_AUTO; 10704 } 10705 10706 if (board_config == ALC882_AUTO) 10707 alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups, 1); 10708 10709 if (board_config == ALC882_AUTO) { 10710 /* automatic parse from the BIOS config */ 10711 err = alc882_parse_auto_config(codec); 10712 if (err < 0) { 10713 alc_free(codec); 10714 return err; 10715 } else if (!err) { 10716 printk(KERN_INFO 10717 "hda_codec: Cannot set up configuration " 10718 "from BIOS. Using base mode...\n"); 10719 board_config = ALC882_3ST_DIG; 10720 } 10721 } 10722 10723 if (has_cdefine_beep(codec)) { 10724 err = snd_hda_attach_beep_device(codec, 0x1); 10725 if (err < 0) { 10726 alc_free(codec); 10727 return err; 10728 } 10729 } 10730 10731 if (board_config != ALC882_AUTO) 10732 setup_preset(codec, &alc882_presets[board_config]); 10733 10734 spec->stream_analog_playback = &alc882_pcm_analog_playback; 10735 spec->stream_analog_capture = &alc882_pcm_analog_capture; 10736 /* FIXME: setup DAC5 */ 10737 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/ 10738 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture; 10739 10740 spec->stream_digital_playback = &alc882_pcm_digital_playback; 10741 spec->stream_digital_capture = &alc882_pcm_digital_capture; 10742 10743 if (!spec->adc_nids && spec->input_mux) { 10744 int i, j; 10745 spec->num_adc_nids = 0; 10746 for (i = 0; i < ARRAY_SIZE(alc882_adc_nids); i++) { 10747 const struct hda_input_mux *imux = spec->input_mux; 10748 hda_nid_t cap; 10749 hda_nid_t items[16]; 10750 hda_nid_t nid = alc882_adc_nids[i]; 10751 unsigned int wcap = get_wcaps(codec, nid); 10752 /* get type */ 10753 wcap = get_wcaps_type(wcap); 10754 if (wcap != AC_WID_AUD_IN) 10755 continue; 10756 spec->private_adc_nids[spec->num_adc_nids] = nid; 10757 err = snd_hda_get_connections(codec, nid, &cap, 1); 10758 if (err < 0) 10759 continue; 10760 err = snd_hda_get_connections(codec, cap, items, 10761 ARRAY_SIZE(items)); 10762 if (err < 0) 10763 continue; 10764 for (j = 0; j < imux->num_items; j++) 10765 if (imux->items[j].index >= err) 10766 break; 10767 if (j < imux->num_items) 10768 continue; 10769 spec->private_capsrc_nids[spec->num_adc_nids] = cap; 10770 spec->num_adc_nids++; 10771 } 10772 spec->adc_nids = spec->private_adc_nids; 10773 spec->capsrc_nids = spec->private_capsrc_nids; 10774 } 10775 10776 set_capture_mixer(codec); 10777 10778 if (has_cdefine_beep(codec)) 10779 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 10780 10781 if (board_config == ALC882_AUTO) 10782 alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups, 0); 10783 10784 spec->vmaster_nid = 0x0c; 10785 10786 codec->patch_ops = alc_patch_ops; 10787 if (board_config == ALC882_AUTO) 10788 spec->init_hook = alc882_auto_init; 10789#ifdef CONFIG_SND_HDA_POWER_SAVE 10790 if (!spec->loopback.amplist) 10791 spec->loopback.amplist = alc882_loopbacks; 10792#endif 10793 10794 return 0; 10795} 10796 10797 10798/* 10799 * ALC262 support 10800 */ 10801 10802#define ALC262_DIGOUT_NID ALC880_DIGOUT_NID 10803#define ALC262_DIGIN_NID ALC880_DIGIN_NID 10804 10805#define alc262_dac_nids alc260_dac_nids 10806#define alc262_adc_nids alc882_adc_nids 10807#define alc262_adc_nids_alt alc882_adc_nids_alt 10808#define alc262_capsrc_nids alc882_capsrc_nids 10809#define alc262_capsrc_nids_alt alc882_capsrc_nids_alt 10810 10811#define alc262_modes alc260_modes 10812#define alc262_capture_source alc882_capture_source 10813 10814static hda_nid_t alc262_dmic_adc_nids[1] = { 10815 /* ADC0 */ 10816 0x09 10817}; 10818 10819static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 }; 10820 10821static struct snd_kcontrol_new alc262_base_mixer[] = { 10822 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 10823 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 10824 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 10825 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 10826 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 10827 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 10828 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 10829 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 10830 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 10831 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 10832 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 10833 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 10834 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT), 10835 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 10836 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 10837 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT), 10838 { } /* end */ 10839}; 10840 10841/* update HP, line and mono-out pins according to the master switch */ 10842static void alc262_hp_master_update(struct hda_codec *codec) 10843{ 10844 struct alc_spec *spec = codec->spec; 10845 int val = spec->master_sw; 10846 10847 /* HP & line-out */ 10848 snd_hda_codec_write_cache(codec, 0x1b, 0, 10849 AC_VERB_SET_PIN_WIDGET_CONTROL, 10850 val ? PIN_HP : 0); 10851 snd_hda_codec_write_cache(codec, 0x15, 0, 10852 AC_VERB_SET_PIN_WIDGET_CONTROL, 10853 val ? PIN_HP : 0); 10854 /* mono (speaker) depending on the HP jack sense */ 10855 val = val && !spec->jack_present; 10856 snd_hda_codec_write_cache(codec, 0x16, 0, 10857 AC_VERB_SET_PIN_WIDGET_CONTROL, 10858 val ? PIN_OUT : 0); 10859} 10860 10861static void alc262_hp_bpc_automute(struct hda_codec *codec) 10862{ 10863 struct alc_spec *spec = codec->spec; 10864 10865 spec->jack_present = snd_hda_jack_detect(codec, 0x1b); 10866 alc262_hp_master_update(codec); 10867} 10868 10869static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res) 10870{ 10871 if ((res >> 26) != ALC880_HP_EVENT) 10872 return; 10873 alc262_hp_bpc_automute(codec); 10874} 10875 10876static void alc262_hp_wildwest_automute(struct hda_codec *codec) 10877{ 10878 struct alc_spec *spec = codec->spec; 10879 10880 spec->jack_present = snd_hda_jack_detect(codec, 0x15); 10881 alc262_hp_master_update(codec); 10882} 10883 10884static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec, 10885 unsigned int res) 10886{ 10887 if ((res >> 26) != ALC880_HP_EVENT) 10888 return; 10889 alc262_hp_wildwest_automute(codec); 10890} 10891 10892#define alc262_hp_master_sw_get alc260_hp_master_sw_get 10893 10894static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol, 10895 struct snd_ctl_elem_value *ucontrol) 10896{ 10897 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 10898 struct alc_spec *spec = codec->spec; 10899 int val = !!*ucontrol->value.integer.value; 10900 10901 if (val == spec->master_sw) 10902 return 0; 10903 spec->master_sw = val; 10904 alc262_hp_master_update(codec); 10905 return 1; 10906} 10907 10908#define ALC262_HP_MASTER_SWITCH \ 10909 { \ 10910 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 10911 .name = "Master Playback Switch", \ 10912 .info = snd_ctl_boolean_mono_info, \ 10913 .get = alc262_hp_master_sw_get, \ 10914 .put = alc262_hp_master_sw_put, \ 10915 }, \ 10916 { \ 10917 .iface = NID_MAPPING, \ 10918 .name = "Master Playback Switch", \ 10919 .private_value = 0x15 | (0x16 << 8) | (0x1b << 16), \ 10920 } 10921 10922 10923static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = { 10924 ALC262_HP_MASTER_SWITCH, 10925 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 10926 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT), 10927 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 10928 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0, 10929 HDA_OUTPUT), 10930 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0, 10931 HDA_OUTPUT), 10932 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 10933 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 10934 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 10935 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 10936 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 10937 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 10938 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 10939 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 10940 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 10941 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 10942 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT), 10943 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT), 10944 { } /* end */ 10945}; 10946 10947static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = { 10948 ALC262_HP_MASTER_SWITCH, 10949 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 10950 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 10951 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 10952 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 10953 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0, 10954 HDA_OUTPUT), 10955 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0, 10956 HDA_OUTPUT), 10957 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT), 10958 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT), 10959 HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT), 10960 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT), 10961 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT), 10962 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 10963 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 10964 { } /* end */ 10965}; 10966 10967static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = { 10968 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 10969 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 10970 HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT), 10971 { } /* end */ 10972}; 10973 10974/* mute/unmute internal speaker according to the hp jack and mute state */ 10975static void alc262_hp_t5735_setup(struct hda_codec *codec) 10976{ 10977 struct alc_spec *spec = codec->spec; 10978 10979 spec->autocfg.hp_pins[0] = 0x15; 10980 spec->autocfg.speaker_pins[0] = 0x14; 10981} 10982 10983static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = { 10984 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 10985 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 10986 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 10987 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 10988 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 10989 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 10990 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 10991 { } /* end */ 10992}; 10993 10994static struct hda_verb alc262_hp_t5735_verbs[] = { 10995 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 10996 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 10997 10998 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 10999 { } 11000}; 11001 11002static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = { 11003 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11004 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 11005 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT), 11006 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT), 11007 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT), 11008 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT), 11009 { } /* end */ 11010}; 11011 11012static struct hda_verb alc262_hp_rp5700_verbs[] = { 11013 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 11014 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 11015 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 11016 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 11017 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 11018 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 11019 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 11020 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 11021 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))}, 11022 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))}, 11023 {} 11024}; 11025 11026static struct hda_input_mux alc262_hp_rp5700_capture_source = { 11027 .num_items = 1, 11028 .items = { 11029 { "Line", 0x1 }, 11030 }, 11031}; 11032 11033/* bind hp and internal speaker mute (with plug check) as master switch */ 11034static void alc262_hippo_master_update(struct hda_codec *codec) 11035{ 11036 struct alc_spec *spec = codec->spec; 11037 hda_nid_t hp_nid = spec->autocfg.hp_pins[0]; 11038 hda_nid_t line_nid = spec->autocfg.line_out_pins[0]; 11039 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0]; 11040 unsigned int mute; 11041 11042 /* HP */ 11043 mute = spec->master_sw ? 0 : HDA_AMP_MUTE; 11044 snd_hda_codec_amp_stereo(codec, hp_nid, HDA_OUTPUT, 0, 11045 HDA_AMP_MUTE, mute); 11046 /* mute internal speaker per jack sense */ 11047 if (spec->jack_present) 11048 mute = HDA_AMP_MUTE; 11049 if (line_nid) 11050 snd_hda_codec_amp_stereo(codec, line_nid, HDA_OUTPUT, 0, 11051 HDA_AMP_MUTE, mute); 11052 if (speaker_nid && speaker_nid != line_nid) 11053 snd_hda_codec_amp_stereo(codec, speaker_nid, HDA_OUTPUT, 0, 11054 HDA_AMP_MUTE, mute); 11055} 11056 11057#define alc262_hippo_master_sw_get alc262_hp_master_sw_get 11058 11059static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol, 11060 struct snd_ctl_elem_value *ucontrol) 11061{ 11062 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 11063 struct alc_spec *spec = codec->spec; 11064 int val = !!*ucontrol->value.integer.value; 11065 11066 if (val == spec->master_sw) 11067 return 0; 11068 spec->master_sw = val; 11069 alc262_hippo_master_update(codec); 11070 return 1; 11071} 11072 11073#define ALC262_HIPPO_MASTER_SWITCH \ 11074 { \ 11075 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 11076 .name = "Master Playback Switch", \ 11077 .info = snd_ctl_boolean_mono_info, \ 11078 .get = alc262_hippo_master_sw_get, \ 11079 .put = alc262_hippo_master_sw_put, \ 11080 }, \ 11081 { \ 11082 .iface = NID_MAPPING, \ 11083 .name = "Master Playback Switch", \ 11084 .subdevice = SUBDEV_HP(0) | (SUBDEV_LINE(0) << 8) | \ 11085 (SUBDEV_SPEAKER(0) << 16), \ 11086 } 11087 11088static struct snd_kcontrol_new alc262_hippo_mixer[] = { 11089 ALC262_HIPPO_MASTER_SWITCH, 11090 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11091 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 11092 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 11093 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 11094 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 11095 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11096 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11097 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 11098 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 11099 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 11100 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 11101 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 11102 { } /* end */ 11103}; 11104 11105static struct snd_kcontrol_new alc262_hippo1_mixer[] = { 11106 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11107 ALC262_HIPPO_MASTER_SWITCH, 11108 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 11109 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 11110 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 11111 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 11112 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11113 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11114 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 11115 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 11116 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 11117 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 11118 { } /* end */ 11119}; 11120 11121/* mute/unmute internal speaker according to the hp jack and mute state */ 11122static void alc262_hippo_automute(struct hda_codec *codec) 11123{ 11124 struct alc_spec *spec = codec->spec; 11125 hda_nid_t hp_nid = spec->autocfg.hp_pins[0]; 11126 11127 spec->jack_present = snd_hda_jack_detect(codec, hp_nid); 11128 alc262_hippo_master_update(codec); 11129} 11130 11131static void alc262_hippo_unsol_event(struct hda_codec *codec, unsigned int res) 11132{ 11133 if ((res >> 26) != ALC880_HP_EVENT) 11134 return; 11135 alc262_hippo_automute(codec); 11136} 11137 11138static void alc262_hippo_setup(struct hda_codec *codec) 11139{ 11140 struct alc_spec *spec = codec->spec; 11141 11142 spec->autocfg.hp_pins[0] = 0x15; 11143 spec->autocfg.speaker_pins[0] = 0x14; 11144} 11145 11146static void alc262_hippo1_setup(struct hda_codec *codec) 11147{ 11148 struct alc_spec *spec = codec->spec; 11149 11150 spec->autocfg.hp_pins[0] = 0x1b; 11151 spec->autocfg.speaker_pins[0] = 0x14; 11152} 11153 11154 11155static struct snd_kcontrol_new alc262_sony_mixer[] = { 11156 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11157 ALC262_HIPPO_MASTER_SWITCH, 11158 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11159 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11160 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 11161 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 11162 { } /* end */ 11163}; 11164 11165static struct snd_kcontrol_new alc262_benq_t31_mixer[] = { 11166 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11167 ALC262_HIPPO_MASTER_SWITCH, 11168 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 11169 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11170 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11171 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 11172 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 11173 { } /* end */ 11174}; 11175 11176static struct snd_kcontrol_new alc262_tyan_mixer[] = { 11177 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11178 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT), 11179 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT), 11180 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT), 11181 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 11182 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 11183 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11184 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11185 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 11186 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 11187 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 11188 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 11189 { } /* end */ 11190}; 11191 11192static struct hda_verb alc262_tyan_verbs[] = { 11193 /* Headphone automute */ 11194 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 11195 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11196 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 11197 11198 /* P11 AUX_IN, white 4-pin connector */ 11199 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 11200 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1}, 11201 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93}, 11202 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19}, 11203 11204 {} 11205}; 11206 11207/* unsolicited event for HP jack sensing */ 11208static void alc262_tyan_setup(struct hda_codec *codec) 11209{ 11210 struct alc_spec *spec = codec->spec; 11211 11212 spec->autocfg.hp_pins[0] = 0x1b; 11213 spec->autocfg.speaker_pins[0] = 0x15; 11214} 11215 11216 11217#define alc262_capture_mixer alc882_capture_mixer 11218#define alc262_capture_alt_mixer alc882_capture_alt_mixer 11219 11220/* 11221 * generic initialization of ADC, input mixers and output mixers 11222 */ 11223static struct hda_verb alc262_init_verbs[] = { 11224 /* 11225 * Unmute ADC0-2 and set the default input to mic-in 11226 */ 11227 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 11228 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11229 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 11230 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11231 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 11232 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11233 11234 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 11235 * mixer widget 11236 * Note: PASD motherboards uses the Line In 2 as the input for 11237 * front panel mic (mic 2) 11238 */ 11239 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 11240 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 11241 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 11242 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 11243 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 11244 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 11245 11246 /* 11247 * Set up output mixers (0x0c - 0x0e) 11248 */ 11249 /* set vol=0 to output mixers */ 11250 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 11251 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 11252 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 11253 /* set up input amps for analog loopback */ 11254 /* Amp Indices: DAC = 0, mixer = 1 */ 11255 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11256 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11257 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11258 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11259 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11260 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11261 11262 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 11263 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 11264 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 11265 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 11266 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 11267 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 11268 11269 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 11270 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 11271 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 11272 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 11273 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 11274 11275 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 11276 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 11277 11278 /* FIXME: use matrix-type input source selection */ 11279 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 11280 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 11281 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 11282 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 11283 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 11284 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 11285 /* Input mixer2 */ 11286 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 11287 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 11288 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 11289 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 11290 /* Input mixer3 */ 11291 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 11292 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 11293 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 11294 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 11295 11296 { } 11297}; 11298 11299static struct hda_verb alc262_eapd_verbs[] = { 11300 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 11301 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, 11302 { } 11303}; 11304 11305static struct hda_verb alc262_hippo1_unsol_verbs[] = { 11306 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 11307 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 11308 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 11309 11310 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 11311 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11312 {} 11313}; 11314 11315static struct hda_verb alc262_sony_unsol_verbs[] = { 11316 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 11317 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 11318 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic 11319 11320 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 11321 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11322 {} 11323}; 11324 11325static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = { 11326 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11327 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 11328 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 11329 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11330 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11331 { } /* end */ 11332}; 11333 11334static struct hda_verb alc262_toshiba_s06_verbs[] = { 11335 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 11336 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 11337 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11338 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 11339 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09}, 11340 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 11341 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 11342 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 11343 {} 11344}; 11345 11346static void alc262_toshiba_s06_setup(struct hda_codec *codec) 11347{ 11348 struct alc_spec *spec = codec->spec; 11349 11350 spec->autocfg.hp_pins[0] = 0x15; 11351 spec->autocfg.speaker_pins[0] = 0x14; 11352 spec->ext_mic.pin = 0x18; 11353 spec->ext_mic.mux_idx = 0; 11354 spec->int_mic.pin = 0x12; 11355 spec->int_mic.mux_idx = 9; 11356 spec->auto_mic = 1; 11357} 11358 11359/* 11360 * nec model 11361 * 0x15 = headphone 11362 * 0x16 = internal speaker 11363 * 0x18 = external mic 11364 */ 11365 11366static struct snd_kcontrol_new alc262_nec_mixer[] = { 11367 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 11368 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT), 11369 11370 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11371 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11372 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 11373 11374 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 11375 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 11376 { } /* end */ 11377}; 11378 11379static struct hda_verb alc262_nec_verbs[] = { 11380 /* Unmute Speaker */ 11381 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 11382 11383 /* Headphone */ 11384 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 11385 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 11386 11387 /* External mic to headphone */ 11388 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11389 /* External mic to speaker */ 11390 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11391 {} 11392}; 11393 11394/* 11395 * fujitsu model 11396 * 0x14 = headphone/spdif-out, 0x15 = internal speaker, 11397 * 0x1b = port replicator headphone out 11398 */ 11399 11400#define ALC_HP_EVENT 0x37 11401 11402static struct hda_verb alc262_fujitsu_unsol_verbs[] = { 11403 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, 11404 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11405 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, 11406 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11407 {} 11408}; 11409 11410static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = { 11411 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, 11412 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11413 {} 11414}; 11415 11416static struct hda_verb alc262_lenovo_3000_init_verbs[] = { 11417 /* Front Mic pin: input vref at 50% */ 11418 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, 11419 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 11420 {} 11421}; 11422 11423static struct hda_input_mux alc262_fujitsu_capture_source = { 11424 .num_items = 3, 11425 .items = { 11426 { "Mic", 0x0 }, 11427 { "Int Mic", 0x1 }, 11428 { "CD", 0x4 }, 11429 }, 11430}; 11431 11432static struct hda_input_mux alc262_HP_capture_source = { 11433 .num_items = 5, 11434 .items = { 11435 { "Mic", 0x0 }, 11436 { "Front Mic", 0x1 }, 11437 { "Line", 0x2 }, 11438 { "CD", 0x4 }, 11439 { "AUX IN", 0x6 }, 11440 }, 11441}; 11442 11443static struct hda_input_mux alc262_HP_D7000_capture_source = { 11444 .num_items = 4, 11445 .items = { 11446 { "Mic", 0x0 }, 11447 { "Front Mic", 0x2 }, 11448 { "Line", 0x1 }, 11449 { "CD", 0x4 }, 11450 }, 11451}; 11452 11453/* mute/unmute internal speaker according to the hp jacks and mute state */ 11454static void alc262_fujitsu_automute(struct hda_codec *codec, int force) 11455{ 11456 struct alc_spec *spec = codec->spec; 11457 unsigned int mute; 11458 11459 if (force || !spec->sense_updated) { 11460 spec->jack_present = snd_hda_jack_detect(codec, 0x14) || 11461 snd_hda_jack_detect(codec, 0x1b); 11462 spec->sense_updated = 1; 11463 } 11464 /* unmute internal speaker only if both HPs are unplugged and 11465 * master switch is on 11466 */ 11467 if (spec->jack_present) 11468 mute = HDA_AMP_MUTE; 11469 else 11470 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0); 11471 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 11472 HDA_AMP_MUTE, mute); 11473} 11474 11475/* unsolicited event for HP jack sensing */ 11476static void alc262_fujitsu_unsol_event(struct hda_codec *codec, 11477 unsigned int res) 11478{ 11479 if ((res >> 26) != ALC_HP_EVENT) 11480 return; 11481 alc262_fujitsu_automute(codec, 1); 11482} 11483 11484static void alc262_fujitsu_init_hook(struct hda_codec *codec) 11485{ 11486 alc262_fujitsu_automute(codec, 1); 11487} 11488 11489/* bind volumes of both NID 0x0c and 0x0d */ 11490static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = { 11491 .ops = &snd_hda_bind_vol, 11492 .values = { 11493 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT), 11494 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT), 11495 0 11496 }, 11497}; 11498 11499/* mute/unmute internal speaker according to the hp jack and mute state */ 11500static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force) 11501{ 11502 struct alc_spec *spec = codec->spec; 11503 unsigned int mute; 11504 11505 if (force || !spec->sense_updated) { 11506 spec->jack_present = snd_hda_jack_detect(codec, 0x1b); 11507 spec->sense_updated = 1; 11508 } 11509 if (spec->jack_present) { 11510 /* mute internal speaker */ 11511 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 11512 HDA_AMP_MUTE, HDA_AMP_MUTE); 11513 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0, 11514 HDA_AMP_MUTE, HDA_AMP_MUTE); 11515 } else { 11516 /* unmute internal speaker if necessary */ 11517 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0); 11518 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 11519 HDA_AMP_MUTE, mute); 11520 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0, 11521 HDA_AMP_MUTE, mute); 11522 } 11523} 11524 11525/* unsolicited event for HP jack sensing */ 11526static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec, 11527 unsigned int res) 11528{ 11529 if ((res >> 26) != ALC_HP_EVENT) 11530 return; 11531 alc262_lenovo_3000_automute(codec, 1); 11532} 11533 11534static int amp_stereo_mute_update(struct hda_codec *codec, hda_nid_t nid, 11535 int dir, int idx, long *valp) 11536{ 11537 int i, change = 0; 11538 11539 for (i = 0; i < 2; i++, valp++) 11540 change |= snd_hda_codec_amp_update(codec, nid, i, dir, idx, 11541 HDA_AMP_MUTE, 11542 *valp ? 0 : HDA_AMP_MUTE); 11543 return change; 11544} 11545 11546/* bind hp and internal speaker mute (with plug check) */ 11547static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol, 11548 struct snd_ctl_elem_value *ucontrol) 11549{ 11550 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 11551 long *valp = ucontrol->value.integer.value; 11552 int change; 11553 11554 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp); 11555 change |= amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp); 11556 if (change) 11557 alc262_fujitsu_automute(codec, 0); 11558 return change; 11559} 11560 11561static struct snd_kcontrol_new alc262_fujitsu_mixer[] = { 11562 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol), 11563 { 11564 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 11565 .name = "Master Playback Switch", 11566 .subdevice = HDA_SUBDEV_AMP_FLAG, 11567 .info = snd_hda_mixer_amp_switch_info, 11568 .get = snd_hda_mixer_amp_switch_get, 11569 .put = alc262_fujitsu_master_sw_put, 11570 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 11571 }, 11572 { 11573 .iface = NID_MAPPING, 11574 .name = "Master Playback Switch", 11575 .private_value = 0x1b, 11576 }, 11577 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 11578 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 11579 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 11580 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11581 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11582 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 11583 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 11584 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 11585 { } /* end */ 11586}; 11587 11588/* bind hp and internal speaker mute (with plug check) */ 11589static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol, 11590 struct snd_ctl_elem_value *ucontrol) 11591{ 11592 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 11593 long *valp = ucontrol->value.integer.value; 11594 int change; 11595 11596 change = amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp); 11597 if (change) 11598 alc262_lenovo_3000_automute(codec, 0); 11599 return change; 11600} 11601 11602static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = { 11603 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol), 11604 { 11605 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 11606 .name = "Master Playback Switch", 11607 .subdevice = HDA_SUBDEV_AMP_FLAG, 11608 .info = snd_hda_mixer_amp_switch_info, 11609 .get = snd_hda_mixer_amp_switch_get, 11610 .put = alc262_lenovo_3000_master_sw_put, 11611 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT), 11612 }, 11613 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 11614 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 11615 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 11616 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11617 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11618 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 11619 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 11620 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 11621 { } /* end */ 11622}; 11623 11624static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = { 11625 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol), 11626 ALC262_HIPPO_MASTER_SWITCH, 11627 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11628 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11629 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 11630 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 11631 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 11632 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 11633 { } /* end */ 11634}; 11635 11636/* additional init verbs for Benq laptops */ 11637static struct hda_verb alc262_EAPD_verbs[] = { 11638 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 11639 {0x20, AC_VERB_SET_PROC_COEF, 0x3070}, 11640 {} 11641}; 11642 11643static struct hda_verb alc262_benq_t31_EAPD_verbs[] = { 11644 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 11645 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 11646 11647 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 11648 {0x20, AC_VERB_SET_PROC_COEF, 0x3050}, 11649 {} 11650}; 11651 11652/* Samsung Q1 Ultra Vista model setup */ 11653static struct snd_kcontrol_new alc262_ultra_mixer[] = { 11654 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11655 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT), 11656 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 11657 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 11658 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT), 11659 HDA_CODEC_VOLUME("Headphone Mic Boost", 0x15, 0, HDA_INPUT), 11660 { } /* end */ 11661}; 11662 11663static struct hda_verb alc262_ultra_verbs[] = { 11664 /* output mixer */ 11665 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 11666 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 11667 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 11668 /* speaker */ 11669 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 11670 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 11671 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11672 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 11673 /* HP */ 11674 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11675 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 11676 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11677 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 11678 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 11679 /* internal mic */ 11680 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 11681 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 11682 /* ADC, choose mic */ 11683 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 11684 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 11685 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11686 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 11687 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 11688 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 11689 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, 11690 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, 11691 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, 11692 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)}, 11693 {} 11694}; 11695 11696/* mute/unmute internal speaker according to the hp jack and mute state */ 11697static void alc262_ultra_automute(struct hda_codec *codec) 11698{ 11699 struct alc_spec *spec = codec->spec; 11700 unsigned int mute; 11701 11702 mute = 0; 11703 /* auto-mute only when HP is used as HP */ 11704 if (!spec->cur_mux[0]) { 11705 spec->jack_present = snd_hda_jack_detect(codec, 0x15); 11706 if (spec->jack_present) 11707 mute = HDA_AMP_MUTE; 11708 } 11709 /* mute/unmute internal speaker */ 11710 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 11711 HDA_AMP_MUTE, mute); 11712 /* mute/unmute HP */ 11713 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 11714 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE); 11715} 11716 11717/* unsolicited event for HP jack sensing */ 11718static void alc262_ultra_unsol_event(struct hda_codec *codec, 11719 unsigned int res) 11720{ 11721 if ((res >> 26) != ALC880_HP_EVENT) 11722 return; 11723 alc262_ultra_automute(codec); 11724} 11725 11726static struct hda_input_mux alc262_ultra_capture_source = { 11727 .num_items = 2, 11728 .items = { 11729 { "Mic", 0x1 }, 11730 { "Headphone", 0x7 }, 11731 }, 11732}; 11733 11734static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol, 11735 struct snd_ctl_elem_value *ucontrol) 11736{ 11737 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 11738 struct alc_spec *spec = codec->spec; 11739 int ret; 11740 11741 ret = alc_mux_enum_put(kcontrol, ucontrol); 11742 if (!ret) 11743 return 0; 11744 /* reprogram the HP pin as mic or HP according to the input source */ 11745 snd_hda_codec_write_cache(codec, 0x15, 0, 11746 AC_VERB_SET_PIN_WIDGET_CONTROL, 11747 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP); 11748 alc262_ultra_automute(codec); /* mute/unmute HP */ 11749 return ret; 11750} 11751 11752static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = { 11753 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT), 11754 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT), 11755 { 11756 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 11757 .name = "Capture Source", 11758 .info = alc_mux_enum_info, 11759 .get = alc_mux_enum_get, 11760 .put = alc262_ultra_mux_enum_put, 11761 }, 11762 { 11763 .iface = NID_MAPPING, 11764 .name = "Capture Source", 11765 .private_value = 0x15, 11766 }, 11767 { } /* end */ 11768}; 11769 11770/* We use two mixers depending on the output pin; 0x16 is a mono output 11771 * and thus it's bound with a different mixer. 11772 * This function returns which mixer amp should be used. 11773 */ 11774static int alc262_check_volbit(hda_nid_t nid) 11775{ 11776 if (!nid) 11777 return 0; 11778 else if (nid == 0x16) 11779 return 2; 11780 else 11781 return 1; 11782} 11783 11784static int alc262_add_out_vol_ctl(struct alc_spec *spec, hda_nid_t nid, 11785 const char *pfx, int *vbits) 11786{ 11787 unsigned long val; 11788 int vbit; 11789 11790 vbit = alc262_check_volbit(nid); 11791 if (!vbit) 11792 return 0; 11793 if (*vbits & vbit) /* a volume control for this mixer already there */ 11794 return 0; 11795 *vbits |= vbit; 11796 if (vbit == 2) 11797 val = HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT); 11798 else 11799 val = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT); 11800 return add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, val); 11801} 11802 11803static int alc262_add_out_sw_ctl(struct alc_spec *spec, hda_nid_t nid, 11804 const char *pfx) 11805{ 11806 unsigned long val; 11807 11808 if (!nid) 11809 return 0; 11810 if (nid == 0x16) 11811 val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT); 11812 else 11813 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT); 11814 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, val); 11815} 11816 11817/* add playback controls from the parsed DAC table */ 11818static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, 11819 const struct auto_pin_cfg *cfg) 11820{ 11821 const char *pfx; 11822 int vbits; 11823 int err; 11824 11825 spec->multiout.num_dacs = 1; /* only use one dac */ 11826 spec->multiout.dac_nids = spec->private_dac_nids; 11827 spec->multiout.dac_nids[0] = 2; 11828 11829 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0]) 11830 pfx = "Master"; 11831 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) 11832 pfx = "Speaker"; 11833 else 11834 pfx = "Front"; 11835 err = alc262_add_out_sw_ctl(spec, cfg->line_out_pins[0], pfx); 11836 if (err < 0) 11837 return err; 11838 err = alc262_add_out_sw_ctl(spec, cfg->speaker_pins[0], "Speaker"); 11839 if (err < 0) 11840 return err; 11841 err = alc262_add_out_sw_ctl(spec, cfg->hp_pins[0], "Headphone"); 11842 if (err < 0) 11843 return err; 11844 11845 vbits = alc262_check_volbit(cfg->line_out_pins[0]) | 11846 alc262_check_volbit(cfg->speaker_pins[0]) | 11847 alc262_check_volbit(cfg->hp_pins[0]); 11848 if (vbits == 1 || vbits == 2) 11849 pfx = "Master"; /* only one mixer is used */ 11850 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) 11851 pfx = "Speaker"; 11852 else 11853 pfx = "Front"; 11854 vbits = 0; 11855 err = alc262_add_out_vol_ctl(spec, cfg->line_out_pins[0], pfx, &vbits); 11856 if (err < 0) 11857 return err; 11858 err = alc262_add_out_vol_ctl(spec, cfg->speaker_pins[0], "Speaker", 11859 &vbits); 11860 if (err < 0) 11861 return err; 11862 err = alc262_add_out_vol_ctl(spec, cfg->hp_pins[0], "Headphone", 11863 &vbits); 11864 if (err < 0) 11865 return err; 11866 return 0; 11867} 11868 11869#define alc262_auto_create_input_ctls \ 11870 alc882_auto_create_input_ctls 11871 11872/* 11873 * generic initialization of ADC, input mixers and output mixers 11874 */ 11875static struct hda_verb alc262_volume_init_verbs[] = { 11876 /* 11877 * Unmute ADC0-2 and set the default input to mic-in 11878 */ 11879 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 11880 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11881 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 11882 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11883 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 11884 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11885 11886 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 11887 * mixer widget 11888 * Note: PASD motherboards uses the Line In 2 as the input for 11889 * front panel mic (mic 2) 11890 */ 11891 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 11892 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 11893 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 11894 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 11895 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 11896 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 11897 11898 /* 11899 * Set up output mixers (0x0c - 0x0f) 11900 */ 11901 /* set vol=0 to output mixers */ 11902 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 11903 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 11904 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 11905 11906 /* set up input amps for analog loopback */ 11907 /* Amp Indices: DAC = 0, mixer = 1 */ 11908 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11909 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11910 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11911 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11912 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11913 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11914 11915 /* FIXME: use matrix-type input source selection */ 11916 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 11917 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 11918 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 11919 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 11920 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 11921 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 11922 /* Input mixer2 */ 11923 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 11924 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 11925 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 11926 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 11927 /* Input mixer3 */ 11928 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 11929 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 11930 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 11931 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 11932 11933 { } 11934}; 11935 11936static struct hda_verb alc262_HP_BPC_init_verbs[] = { 11937 /* 11938 * Unmute ADC0-2 and set the default input to mic-in 11939 */ 11940 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 11941 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11942 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 11943 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11944 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 11945 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11946 11947 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 11948 * mixer widget 11949 * Note: PASD motherboards uses the Line In 2 as the input for 11950 * front panel mic (mic 2) 11951 */ 11952 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 11953 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 11954 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 11955 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 11956 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 11957 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 11958 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, 11959 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, 11960 11961 /* 11962 * Set up output mixers (0x0c - 0x0e) 11963 */ 11964 /* set vol=0 to output mixers */ 11965 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 11966 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 11967 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 11968 11969 /* set up input amps for analog loopback */ 11970 /* Amp Indices: DAC = 0, mixer = 1 */ 11971 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11972 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11973 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11974 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11975 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11976 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11977 11978 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11979 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 11980 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 11981 11982 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 11983 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 11984 11985 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 11986 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 11987 11988 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 11989 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 11990 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 11991 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 11992 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 11993 11994 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 11995 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 11996 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 11997 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 11998 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 11999 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 12000 12001 12002 /* FIXME: use matrix-type input source selection */ 12003 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */ 12004 /* Input mixer1: only unmute Mic */ 12005 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 12006 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))}, 12007 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 12008 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 12009 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 12010 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))}, 12011 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))}, 12012 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))}, 12013 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))}, 12014 /* Input mixer2 */ 12015 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 12016 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))}, 12017 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 12018 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 12019 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 12020 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))}, 12021 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))}, 12022 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))}, 12023 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))}, 12024 /* Input mixer3 */ 12025 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 12026 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))}, 12027 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 12028 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 12029 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 12030 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))}, 12031 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))}, 12032 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))}, 12033 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))}, 12034 12035 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 12036 12037 { } 12038}; 12039 12040static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = { 12041 /* 12042 * Unmute ADC0-2 and set the default input to mic-in 12043 */ 12044 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 12045 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12046 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 12047 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12048 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 12049 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12050 12051 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 12052 * mixer widget 12053 * Note: PASD motherboards uses the Line In 2 as the input for front 12054 * panel mic (mic 2) 12055 */ 12056 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 12057 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 12058 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 12059 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 12060 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 12061 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 12062 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, 12063 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, 12064 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, 12065 /* 12066 * Set up output mixers (0x0c - 0x0e) 12067 */ 12068 /* set vol=0 to output mixers */ 12069 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 12070 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 12071 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 12072 12073 /* set up input amps for analog loopback */ 12074 /* Amp Indices: DAC = 0, mixer = 1 */ 12075 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12076 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12077 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12078 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12079 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12080 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12081 12082 12083 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */ 12084 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */ 12085 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */ 12086 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */ 12087 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */ 12088 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */ 12089 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */ 12090 12091 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 12092 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 12093 12094 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 12095 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 12096 12097 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */ 12098 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 12099 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 12100 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, 12101 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 12102 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 12103 12104 /* FIXME: use matrix-type input source selection */ 12105 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 12106 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 12107 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/ 12108 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/ 12109 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/ 12110 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/ 12111 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/ 12112 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */ 12113 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/ 12114 /* Input mixer2 */ 12115 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 12116 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 12117 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, 12118 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, 12119 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, 12120 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */ 12121 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, 12122 /* Input mixer3 */ 12123 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 12124 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 12125 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, 12126 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, 12127 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, 12128 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */ 12129 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, 12130 12131 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 12132 12133 { } 12134}; 12135 12136static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = { 12137 12138 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */ 12139 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 12140 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01}, 12141 12142 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */ 12143 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */ 12144 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) }, 12145 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) }, 12146 12147 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */ 12148 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 12149 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 12150 {} 12151}; 12152 12153 12154#ifdef CONFIG_SND_HDA_POWER_SAVE 12155#define alc262_loopbacks alc880_loopbacks 12156#endif 12157 12158/* pcm configuration: identical with ALC880 */ 12159#define alc262_pcm_analog_playback alc880_pcm_analog_playback 12160#define alc262_pcm_analog_capture alc880_pcm_analog_capture 12161#define alc262_pcm_digital_playback alc880_pcm_digital_playback 12162#define alc262_pcm_digital_capture alc880_pcm_digital_capture 12163 12164/* 12165 * BIOS auto configuration 12166 */ 12167static int alc262_parse_auto_config(struct hda_codec *codec) 12168{ 12169 struct alc_spec *spec = codec->spec; 12170 int err; 12171 static hda_nid_t alc262_ignore[] = { 0x1d, 0 }; 12172 12173 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 12174 alc262_ignore); 12175 if (err < 0) 12176 return err; 12177 if (!spec->autocfg.line_outs) { 12178 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) { 12179 spec->multiout.max_channels = 2; 12180 spec->no_analog = 1; 12181 goto dig_only; 12182 } 12183 return 0; /* can't find valid BIOS pin config */ 12184 } 12185 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg); 12186 if (err < 0) 12187 return err; 12188 err = alc262_auto_create_input_ctls(codec, &spec->autocfg); 12189 if (err < 0) 12190 return err; 12191 12192 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 12193 12194 dig_only: 12195 alc_auto_parse_digital(codec); 12196 12197 if (spec->kctls.list) 12198 add_mixer(spec, spec->kctls.list); 12199 12200 add_verb(spec, alc262_volume_init_verbs); 12201 spec->num_mux_defs = 1; 12202 spec->input_mux = &spec->private_imux[0]; 12203 12204 err = alc_auto_add_mic_boost(codec); 12205 if (err < 0) 12206 return err; 12207 12208 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); 12209 12210 return 1; 12211} 12212 12213#define alc262_auto_init_multi_out alc882_auto_init_multi_out 12214#define alc262_auto_init_hp_out alc882_auto_init_hp_out 12215#define alc262_auto_init_analog_input alc882_auto_init_analog_input 12216#define alc262_auto_init_input_src alc882_auto_init_input_src 12217 12218 12219/* init callback for auto-configuration model -- overriding the default init */ 12220static void alc262_auto_init(struct hda_codec *codec) 12221{ 12222 struct alc_spec *spec = codec->spec; 12223 alc262_auto_init_multi_out(codec); 12224 alc262_auto_init_hp_out(codec); 12225 alc262_auto_init_analog_input(codec); 12226 alc262_auto_init_input_src(codec); 12227 alc_auto_init_digital(codec); 12228 if (spec->unsol_event) 12229 alc_inithook(codec); 12230} 12231 12232/* 12233 * configuration and preset 12234 */ 12235static const char *alc262_models[ALC262_MODEL_LAST] = { 12236 [ALC262_BASIC] = "basic", 12237 [ALC262_HIPPO] = "hippo", 12238 [ALC262_HIPPO_1] = "hippo_1", 12239 [ALC262_FUJITSU] = "fujitsu", 12240 [ALC262_HP_BPC] = "hp-bpc", 12241 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000", 12242 [ALC262_HP_TC_T5735] = "hp-tc-t5735", 12243 [ALC262_HP_RP5700] = "hp-rp5700", 12244 [ALC262_BENQ_ED8] = "benq", 12245 [ALC262_BENQ_T31] = "benq-t31", 12246 [ALC262_SONY_ASSAMD] = "sony-assamd", 12247 [ALC262_TOSHIBA_S06] = "toshiba-s06", 12248 [ALC262_TOSHIBA_RX1] = "toshiba-rx1", 12249 [ALC262_ULTRA] = "ultra", 12250 [ALC262_LENOVO_3000] = "lenovo-3000", 12251 [ALC262_NEC] = "nec", 12252 [ALC262_TYAN] = "tyan", 12253 [ALC262_AUTO] = "auto", 12254}; 12255 12256static struct snd_pci_quirk alc262_cfg_tbl[] = { 12257 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO), 12258 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC), 12259 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series", 12260 ALC262_HP_BPC), 12261 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series", 12262 ALC262_HP_BPC), 12263 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series", 12264 ALC262_HP_BPC), 12265 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL), 12266 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF), 12267 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL), 12268 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF), 12269 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL), 12270 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF), 12271 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL), 12272 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF), 12273 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC), 12274 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC), 12275 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC), 12276 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735", 12277 ALC262_HP_TC_T5735), 12278 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700), 12279 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD), 12280 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO), 12281 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD), 12282 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */ 12283 SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06), 12284 SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO), 12285 SND_PCI_QUIRK(0x104d, 0x9047, "Sony VAIO Type G", ALC262_AUTO), 12286#if 0 /* disable the quirk since model=auto works better in recent versions */ 12287 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO", 12288 ALC262_SONY_ASSAMD), 12289#endif 12290 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1", 12291 ALC262_TOSHIBA_RX1), 12292 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06), 12293 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU), 12294 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU), 12295 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN), 12296 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1", 12297 ALC262_ULTRA), 12298 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO), 12299 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000), 12300 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8), 12301 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31), 12302 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1), 12303 {} 12304}; 12305 12306static struct alc_config_preset alc262_presets[] = { 12307 [ALC262_BASIC] = { 12308 .mixers = { alc262_base_mixer }, 12309 .init_verbs = { alc262_init_verbs }, 12310 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12311 .dac_nids = alc262_dac_nids, 12312 .hp_nid = 0x03, 12313 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12314 .channel_mode = alc262_modes, 12315 .input_mux = &alc262_capture_source, 12316 }, 12317 [ALC262_HIPPO] = { 12318 .mixers = { alc262_hippo_mixer }, 12319 .init_verbs = { alc262_init_verbs, alc_hp15_unsol_verbs}, 12320 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12321 .dac_nids = alc262_dac_nids, 12322 .hp_nid = 0x03, 12323 .dig_out_nid = ALC262_DIGOUT_NID, 12324 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12325 .channel_mode = alc262_modes, 12326 .input_mux = &alc262_capture_source, 12327 .unsol_event = alc262_hippo_unsol_event, 12328 .setup = alc262_hippo_setup, 12329 .init_hook = alc262_hippo_automute, 12330 }, 12331 [ALC262_HIPPO_1] = { 12332 .mixers = { alc262_hippo1_mixer }, 12333 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs}, 12334 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12335 .dac_nids = alc262_dac_nids, 12336 .hp_nid = 0x02, 12337 .dig_out_nid = ALC262_DIGOUT_NID, 12338 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12339 .channel_mode = alc262_modes, 12340 .input_mux = &alc262_capture_source, 12341 .unsol_event = alc262_hippo_unsol_event, 12342 .setup = alc262_hippo1_setup, 12343 .init_hook = alc262_hippo_automute, 12344 }, 12345 [ALC262_FUJITSU] = { 12346 .mixers = { alc262_fujitsu_mixer }, 12347 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs, 12348 alc262_fujitsu_unsol_verbs }, 12349 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12350 .dac_nids = alc262_dac_nids, 12351 .hp_nid = 0x03, 12352 .dig_out_nid = ALC262_DIGOUT_NID, 12353 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12354 .channel_mode = alc262_modes, 12355 .input_mux = &alc262_fujitsu_capture_source, 12356 .unsol_event = alc262_fujitsu_unsol_event, 12357 .init_hook = alc262_fujitsu_init_hook, 12358 }, 12359 [ALC262_HP_BPC] = { 12360 .mixers = { alc262_HP_BPC_mixer }, 12361 .init_verbs = { alc262_HP_BPC_init_verbs }, 12362 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12363 .dac_nids = alc262_dac_nids, 12364 .hp_nid = 0x03, 12365 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12366 .channel_mode = alc262_modes, 12367 .input_mux = &alc262_HP_capture_source, 12368 .unsol_event = alc262_hp_bpc_unsol_event, 12369 .init_hook = alc262_hp_bpc_automute, 12370 }, 12371 [ALC262_HP_BPC_D7000_WF] = { 12372 .mixers = { alc262_HP_BPC_WildWest_mixer }, 12373 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs }, 12374 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12375 .dac_nids = alc262_dac_nids, 12376 .hp_nid = 0x03, 12377 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12378 .channel_mode = alc262_modes, 12379 .input_mux = &alc262_HP_D7000_capture_source, 12380 .unsol_event = alc262_hp_wildwest_unsol_event, 12381 .init_hook = alc262_hp_wildwest_automute, 12382 }, 12383 [ALC262_HP_BPC_D7000_WL] = { 12384 .mixers = { alc262_HP_BPC_WildWest_mixer, 12385 alc262_HP_BPC_WildWest_option_mixer }, 12386 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs }, 12387 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12388 .dac_nids = alc262_dac_nids, 12389 .hp_nid = 0x03, 12390 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12391 .channel_mode = alc262_modes, 12392 .input_mux = &alc262_HP_D7000_capture_source, 12393 .unsol_event = alc262_hp_wildwest_unsol_event, 12394 .init_hook = alc262_hp_wildwest_automute, 12395 }, 12396 [ALC262_HP_TC_T5735] = { 12397 .mixers = { alc262_hp_t5735_mixer }, 12398 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs }, 12399 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12400 .dac_nids = alc262_dac_nids, 12401 .hp_nid = 0x03, 12402 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12403 .channel_mode = alc262_modes, 12404 .input_mux = &alc262_capture_source, 12405 .unsol_event = alc_sku_unsol_event, 12406 .setup = alc262_hp_t5735_setup, 12407 .init_hook = alc_inithook, 12408 }, 12409 [ALC262_HP_RP5700] = { 12410 .mixers = { alc262_hp_rp5700_mixer }, 12411 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs }, 12412 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12413 .dac_nids = alc262_dac_nids, 12414 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12415 .channel_mode = alc262_modes, 12416 .input_mux = &alc262_hp_rp5700_capture_source, 12417 }, 12418 [ALC262_BENQ_ED8] = { 12419 .mixers = { alc262_base_mixer }, 12420 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs }, 12421 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12422 .dac_nids = alc262_dac_nids, 12423 .hp_nid = 0x03, 12424 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12425 .channel_mode = alc262_modes, 12426 .input_mux = &alc262_capture_source, 12427 }, 12428 [ALC262_SONY_ASSAMD] = { 12429 .mixers = { alc262_sony_mixer }, 12430 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs}, 12431 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12432 .dac_nids = alc262_dac_nids, 12433 .hp_nid = 0x02, 12434 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12435 .channel_mode = alc262_modes, 12436 .input_mux = &alc262_capture_source, 12437 .unsol_event = alc262_hippo_unsol_event, 12438 .setup = alc262_hippo_setup, 12439 .init_hook = alc262_hippo_automute, 12440 }, 12441 [ALC262_BENQ_T31] = { 12442 .mixers = { alc262_benq_t31_mixer }, 12443 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, 12444 alc_hp15_unsol_verbs }, 12445 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12446 .dac_nids = alc262_dac_nids, 12447 .hp_nid = 0x03, 12448 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12449 .channel_mode = alc262_modes, 12450 .input_mux = &alc262_capture_source, 12451 .unsol_event = alc262_hippo_unsol_event, 12452 .setup = alc262_hippo_setup, 12453 .init_hook = alc262_hippo_automute, 12454 }, 12455 [ALC262_ULTRA] = { 12456 .mixers = { alc262_ultra_mixer }, 12457 .cap_mixer = alc262_ultra_capture_mixer, 12458 .init_verbs = { alc262_ultra_verbs }, 12459 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12460 .dac_nids = alc262_dac_nids, 12461 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12462 .channel_mode = alc262_modes, 12463 .input_mux = &alc262_ultra_capture_source, 12464 .adc_nids = alc262_adc_nids, /* ADC0 */ 12465 .capsrc_nids = alc262_capsrc_nids, 12466 .num_adc_nids = 1, /* single ADC */ 12467 .unsol_event = alc262_ultra_unsol_event, 12468 .init_hook = alc262_ultra_automute, 12469 }, 12470 [ALC262_LENOVO_3000] = { 12471 .mixers = { alc262_lenovo_3000_mixer }, 12472 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs, 12473 alc262_lenovo_3000_unsol_verbs, 12474 alc262_lenovo_3000_init_verbs }, 12475 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12476 .dac_nids = alc262_dac_nids, 12477 .hp_nid = 0x03, 12478 .dig_out_nid = ALC262_DIGOUT_NID, 12479 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12480 .channel_mode = alc262_modes, 12481 .input_mux = &alc262_fujitsu_capture_source, 12482 .unsol_event = alc262_lenovo_3000_unsol_event, 12483 }, 12484 [ALC262_NEC] = { 12485 .mixers = { alc262_nec_mixer }, 12486 .init_verbs = { alc262_nec_verbs }, 12487 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12488 .dac_nids = alc262_dac_nids, 12489 .hp_nid = 0x03, 12490 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12491 .channel_mode = alc262_modes, 12492 .input_mux = &alc262_capture_source, 12493 }, 12494 [ALC262_TOSHIBA_S06] = { 12495 .mixers = { alc262_toshiba_s06_mixer }, 12496 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs, 12497 alc262_eapd_verbs }, 12498 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12499 .capsrc_nids = alc262_dmic_capsrc_nids, 12500 .dac_nids = alc262_dac_nids, 12501 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */ 12502 .num_adc_nids = 1, /* single ADC */ 12503 .dig_out_nid = ALC262_DIGOUT_NID, 12504 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12505 .channel_mode = alc262_modes, 12506 .unsol_event = alc_sku_unsol_event, 12507 .setup = alc262_toshiba_s06_setup, 12508 .init_hook = alc_inithook, 12509 }, 12510 [ALC262_TOSHIBA_RX1] = { 12511 .mixers = { alc262_toshiba_rx1_mixer }, 12512 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs }, 12513 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12514 .dac_nids = alc262_dac_nids, 12515 .hp_nid = 0x03, 12516 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12517 .channel_mode = alc262_modes, 12518 .input_mux = &alc262_capture_source, 12519 .unsol_event = alc262_hippo_unsol_event, 12520 .setup = alc262_hippo_setup, 12521 .init_hook = alc262_hippo_automute, 12522 }, 12523 [ALC262_TYAN] = { 12524 .mixers = { alc262_tyan_mixer }, 12525 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs}, 12526 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12527 .dac_nids = alc262_dac_nids, 12528 .hp_nid = 0x02, 12529 .dig_out_nid = ALC262_DIGOUT_NID, 12530 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12531 .channel_mode = alc262_modes, 12532 .input_mux = &alc262_capture_source, 12533 .unsol_event = alc_automute_amp_unsol_event, 12534 .setup = alc262_tyan_setup, 12535 .init_hook = alc_automute_amp, 12536 }, 12537}; 12538 12539static int patch_alc262(struct hda_codec *codec) 12540{ 12541 struct alc_spec *spec; 12542 int board_config; 12543 int err; 12544 12545 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 12546 if (spec == NULL) 12547 return -ENOMEM; 12548 12549 codec->spec = spec; 12550#if 0 12551 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is 12552 * under-run 12553 */ 12554 { 12555 int tmp; 12556 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7); 12557 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0); 12558 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7); 12559 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80); 12560 } 12561#endif 12562 alc_auto_parse_customize_define(codec); 12563 12564 alc_fix_pll_init(codec, 0x20, 0x0a, 10); 12565 12566 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST, 12567 alc262_models, 12568 alc262_cfg_tbl); 12569 12570 if (board_config < 0) { 12571 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 12572 codec->chip_name); 12573 board_config = ALC262_AUTO; 12574 } 12575 12576 if (board_config == ALC262_AUTO) { 12577 /* automatic parse from the BIOS config */ 12578 err = alc262_parse_auto_config(codec); 12579 if (err < 0) { 12580 alc_free(codec); 12581 return err; 12582 } else if (!err) { 12583 printk(KERN_INFO 12584 "hda_codec: Cannot set up configuration " 12585 "from BIOS. Using base mode...\n"); 12586 board_config = ALC262_BASIC; 12587 } 12588 } 12589 12590 if (!spec->no_analog && has_cdefine_beep(codec)) { 12591 err = snd_hda_attach_beep_device(codec, 0x1); 12592 if (err < 0) { 12593 alc_free(codec); 12594 return err; 12595 } 12596 } 12597 12598 if (board_config != ALC262_AUTO) 12599 setup_preset(codec, &alc262_presets[board_config]); 12600 12601 spec->stream_analog_playback = &alc262_pcm_analog_playback; 12602 spec->stream_analog_capture = &alc262_pcm_analog_capture; 12603 12604 spec->stream_digital_playback = &alc262_pcm_digital_playback; 12605 spec->stream_digital_capture = &alc262_pcm_digital_capture; 12606 12607 if (!spec->adc_nids && spec->input_mux) { 12608 int i; 12609 /* check whether the digital-mic has to be supported */ 12610 for (i = 0; i < spec->input_mux->num_items; i++) { 12611 if (spec->input_mux->items[i].index >= 9) 12612 break; 12613 } 12614 if (i < spec->input_mux->num_items) { 12615 /* use only ADC0 */ 12616 spec->adc_nids = alc262_dmic_adc_nids; 12617 spec->num_adc_nids = 1; 12618 spec->capsrc_nids = alc262_dmic_capsrc_nids; 12619 } else { 12620 /* all analog inputs */ 12621 /* check whether NID 0x07 is valid */ 12622 unsigned int wcap = get_wcaps(codec, 0x07); 12623 12624 /* get type */ 12625 wcap = get_wcaps_type(wcap); 12626 if (wcap != AC_WID_AUD_IN) { 12627 spec->adc_nids = alc262_adc_nids_alt; 12628 spec->num_adc_nids = 12629 ARRAY_SIZE(alc262_adc_nids_alt); 12630 spec->capsrc_nids = alc262_capsrc_nids_alt; 12631 } else { 12632 spec->adc_nids = alc262_adc_nids; 12633 spec->num_adc_nids = 12634 ARRAY_SIZE(alc262_adc_nids); 12635 spec->capsrc_nids = alc262_capsrc_nids; 12636 } 12637 } 12638 } 12639 if (!spec->cap_mixer && !spec->no_analog) 12640 set_capture_mixer(codec); 12641 if (!spec->no_analog && has_cdefine_beep(codec)) 12642 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 12643 12644 spec->vmaster_nid = 0x0c; 12645 12646 codec->patch_ops = alc_patch_ops; 12647 if (board_config == ALC262_AUTO) 12648 spec->init_hook = alc262_auto_init; 12649#ifdef CONFIG_SND_HDA_POWER_SAVE 12650 if (!spec->loopback.amplist) 12651 spec->loopback.amplist = alc262_loopbacks; 12652#endif 12653 12654 return 0; 12655} 12656 12657/* 12658 * ALC268 channel source setting (2 channel) 12659 */ 12660#define ALC268_DIGOUT_NID ALC880_DIGOUT_NID 12661#define alc268_modes alc260_modes 12662 12663static hda_nid_t alc268_dac_nids[2] = { 12664 /* front, hp */ 12665 0x02, 0x03 12666}; 12667 12668static hda_nid_t alc268_adc_nids[2] = { 12669 /* ADC0-1 */ 12670 0x08, 0x07 12671}; 12672 12673static hda_nid_t alc268_adc_nids_alt[1] = { 12674 /* ADC0 */ 12675 0x08 12676}; 12677 12678static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 }; 12679 12680static struct snd_kcontrol_new alc268_base_mixer[] = { 12681 /* output mixer control */ 12682 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), 12683 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 12684 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT), 12685 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 12686 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 12687 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 12688 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT), 12689 { } 12690}; 12691 12692static struct snd_kcontrol_new alc268_toshiba_mixer[] = { 12693 /* output mixer control */ 12694 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), 12695 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT), 12696 ALC262_HIPPO_MASTER_SWITCH, 12697 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 12698 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 12699 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT), 12700 { } 12701}; 12702 12703/* bind Beep switches of both NID 0x0f and 0x10 */ 12704static struct hda_bind_ctls alc268_bind_beep_sw = { 12705 .ops = &snd_hda_bind_sw, 12706 .values = { 12707 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT), 12708 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT), 12709 0 12710 }, 12711}; 12712 12713static struct snd_kcontrol_new alc268_beep_mixer[] = { 12714 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT), 12715 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw), 12716 { } 12717}; 12718 12719static struct hda_verb alc268_eapd_verbs[] = { 12720 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 12721 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, 12722 { } 12723}; 12724 12725/* Toshiba specific */ 12726static struct hda_verb alc268_toshiba_verbs[] = { 12727 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 12728 { } /* end */ 12729}; 12730 12731/* Acer specific */ 12732/* bind volumes of both NID 0x02 and 0x03 */ 12733static struct hda_bind_ctls alc268_acer_bind_master_vol = { 12734 .ops = &snd_hda_bind_vol, 12735 .values = { 12736 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), 12737 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT), 12738 0 12739 }, 12740}; 12741 12742/* mute/unmute internal speaker according to the hp jack and mute state */ 12743static void alc268_acer_automute(struct hda_codec *codec, int force) 12744{ 12745 struct alc_spec *spec = codec->spec; 12746 unsigned int mute; 12747 12748 if (force || !spec->sense_updated) { 12749 spec->jack_present = snd_hda_jack_detect(codec, 0x14); 12750 spec->sense_updated = 1; 12751 } 12752 if (spec->jack_present) 12753 mute = HDA_AMP_MUTE; /* mute internal speaker */ 12754 else /* unmute internal speaker if necessary */ 12755 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0); 12756 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 12757 HDA_AMP_MUTE, mute); 12758} 12759 12760 12761/* bind hp and internal speaker mute (with plug check) */ 12762static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol, 12763 struct snd_ctl_elem_value *ucontrol) 12764{ 12765 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 12766 long *valp = ucontrol->value.integer.value; 12767 int change; 12768 12769 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp); 12770 if (change) 12771 alc268_acer_automute(codec, 0); 12772 return change; 12773} 12774 12775static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = { 12776 /* output mixer control */ 12777 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), 12778 { 12779 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 12780 .name = "Master Playback Switch", 12781 .subdevice = HDA_SUBDEV_AMP_FLAG, 12782 .info = snd_hda_mixer_amp_switch_info, 12783 .get = snd_hda_mixer_amp_switch_get, 12784 .put = alc268_acer_master_sw_put, 12785 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 12786 }, 12787 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT), 12788 { } 12789}; 12790 12791static struct snd_kcontrol_new alc268_acer_mixer[] = { 12792 /* output mixer control */ 12793 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), 12794 { 12795 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 12796 .name = "Master Playback Switch", 12797 .subdevice = HDA_SUBDEV_AMP_FLAG, 12798 .info = snd_hda_mixer_amp_switch_info, 12799 .get = snd_hda_mixer_amp_switch_get, 12800 .put = alc268_acer_master_sw_put, 12801 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 12802 }, 12803 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 12804 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), 12805 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT), 12806 { } 12807}; 12808 12809static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = { 12810 /* output mixer control */ 12811 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), 12812 { 12813 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 12814 .name = "Master Playback Switch", 12815 .subdevice = HDA_SUBDEV_AMP_FLAG, 12816 .info = snd_hda_mixer_amp_switch_info, 12817 .get = snd_hda_mixer_amp_switch_get, 12818 .put = alc268_acer_master_sw_put, 12819 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 12820 }, 12821 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 12822 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT), 12823 { } 12824}; 12825 12826static struct hda_verb alc268_acer_aspire_one_verbs[] = { 12827 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 12828 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 12829 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 12830 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 12831 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06}, 12832 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017}, 12833 { } 12834}; 12835 12836static struct hda_verb alc268_acer_verbs[] = { 12837 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */ 12838 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 12839 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 12840 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 12841 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 12842 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 12843 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 12844 { } 12845}; 12846 12847/* unsolicited event for HP jack sensing */ 12848#define alc268_toshiba_unsol_event alc262_hippo_unsol_event 12849#define alc268_toshiba_setup alc262_hippo_setup 12850#define alc268_toshiba_automute alc262_hippo_automute 12851 12852static void alc268_acer_unsol_event(struct hda_codec *codec, 12853 unsigned int res) 12854{ 12855 if ((res >> 26) != ALC880_HP_EVENT) 12856 return; 12857 alc268_acer_automute(codec, 1); 12858} 12859 12860static void alc268_acer_init_hook(struct hda_codec *codec) 12861{ 12862 alc268_acer_automute(codec, 1); 12863} 12864 12865/* toggle speaker-output according to the hp-jack state */ 12866static void alc268_aspire_one_speaker_automute(struct hda_codec *codec) 12867{ 12868 unsigned int present; 12869 unsigned char bits; 12870 12871 present = snd_hda_jack_detect(codec, 0x15); 12872 bits = present ? HDA_AMP_MUTE : 0; 12873 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0, 12874 HDA_AMP_MUTE, bits); 12875 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1, 12876 HDA_AMP_MUTE, bits); 12877} 12878 12879static void alc268_acer_lc_unsol_event(struct hda_codec *codec, 12880 unsigned int res) 12881{ 12882 switch (res >> 26) { 12883 case ALC880_HP_EVENT: 12884 alc268_aspire_one_speaker_automute(codec); 12885 break; 12886 case ALC880_MIC_EVENT: 12887 alc_mic_automute(codec); 12888 break; 12889 } 12890} 12891 12892static void alc268_acer_lc_setup(struct hda_codec *codec) 12893{ 12894 struct alc_spec *spec = codec->spec; 12895 spec->ext_mic.pin = 0x18; 12896 spec->ext_mic.mux_idx = 0; 12897 spec->int_mic.pin = 0x12; 12898 spec->int_mic.mux_idx = 6; 12899 spec->auto_mic = 1; 12900} 12901 12902static void alc268_acer_lc_init_hook(struct hda_codec *codec) 12903{ 12904 alc268_aspire_one_speaker_automute(codec); 12905 alc_mic_automute(codec); 12906} 12907 12908static struct snd_kcontrol_new alc268_dell_mixer[] = { 12909 /* output mixer control */ 12910 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 12911 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 12912 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 12913 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 12914 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 12915 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), 12916 { } 12917}; 12918 12919static struct hda_verb alc268_dell_verbs[] = { 12920 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 12921 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 12922 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 12923 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, 12924 { } 12925}; 12926 12927/* mute/unmute internal speaker according to the hp jack and mute state */ 12928static void alc268_dell_setup(struct hda_codec *codec) 12929{ 12930 struct alc_spec *spec = codec->spec; 12931 12932 spec->autocfg.hp_pins[0] = 0x15; 12933 spec->autocfg.speaker_pins[0] = 0x14; 12934 spec->ext_mic.pin = 0x18; 12935 spec->ext_mic.mux_idx = 0; 12936 spec->int_mic.pin = 0x19; 12937 spec->int_mic.mux_idx = 1; 12938 spec->auto_mic = 1; 12939} 12940 12941static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = { 12942 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT), 12943 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 12944 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT), 12945 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 12946 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT), 12947 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT), 12948 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT), 12949 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 12950 { } 12951}; 12952 12953static struct hda_verb alc267_quanta_il1_verbs[] = { 12954 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 12955 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, 12956 { } 12957}; 12958 12959static void alc267_quanta_il1_setup(struct hda_codec *codec) 12960{ 12961 struct alc_spec *spec = codec->spec; 12962 spec->autocfg.hp_pins[0] = 0x15; 12963 spec->autocfg.speaker_pins[0] = 0x14; 12964 spec->ext_mic.pin = 0x18; 12965 spec->ext_mic.mux_idx = 0; 12966 spec->int_mic.pin = 0x19; 12967 spec->int_mic.mux_idx = 1; 12968 spec->auto_mic = 1; 12969} 12970 12971/* 12972 * generic initialization of ADC, input mixers and output mixers 12973 */ 12974static struct hda_verb alc268_base_init_verbs[] = { 12975 /* Unmute DAC0-1 and set vol = 0 */ 12976 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 12977 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 12978 12979 /* 12980 * Set up output mixers (0x0c - 0x0e) 12981 */ 12982 /* set vol=0 to output mixers */ 12983 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12984 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00}, 12985 12986 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12987 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12988 12989 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 12990 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 12991 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 12992 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 12993 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 12994 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 12995 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 12996 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 12997 12998 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 12999 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 13000 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 13001 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 13002 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 13003 13004 /* set PCBEEP vol = 0, mute connections */ 13005 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13006 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 13007 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 13008 13009 /* Unmute Selector 23h,24h and set the default input to mic-in */ 13010 13011 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00}, 13012 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 13013 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00}, 13014 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 13015 13016 { } 13017}; 13018 13019/* 13020 * generic initialization of ADC, input mixers and output mixers 13021 */ 13022static struct hda_verb alc268_volume_init_verbs[] = { 13023 /* set output DAC */ 13024 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 13025 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 13026 13027 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 13028 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 13029 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 13030 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 13031 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 13032 13033 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13034 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13035 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13036 13037 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 13038 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 13039 13040 /* set PCBEEP vol = 0, mute connections */ 13041 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13042 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 13043 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 13044 13045 { } 13046}; 13047 13048static struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = { 13049 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT), 13050 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT), 13051 { } /* end */ 13052}; 13053 13054static struct snd_kcontrol_new alc268_capture_alt_mixer[] = { 13055 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT), 13056 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT), 13057 _DEFINE_CAPSRC(1), 13058 { } /* end */ 13059}; 13060 13061static struct snd_kcontrol_new alc268_capture_mixer[] = { 13062 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT), 13063 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT), 13064 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT), 13065 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT), 13066 _DEFINE_CAPSRC(2), 13067 { } /* end */ 13068}; 13069 13070static struct hda_input_mux alc268_capture_source = { 13071 .num_items = 4, 13072 .items = { 13073 { "Mic", 0x0 }, 13074 { "Front Mic", 0x1 }, 13075 { "Line", 0x2 }, 13076 { "CD", 0x3 }, 13077 }, 13078}; 13079 13080static struct hda_input_mux alc268_acer_capture_source = { 13081 .num_items = 3, 13082 .items = { 13083 { "Mic", 0x0 }, 13084 { "Internal Mic", 0x1 }, 13085 { "Line", 0x2 }, 13086 }, 13087}; 13088 13089static struct hda_input_mux alc268_acer_dmic_capture_source = { 13090 .num_items = 3, 13091 .items = { 13092 { "Mic", 0x0 }, 13093 { "Internal Mic", 0x6 }, 13094 { "Line", 0x2 }, 13095 }, 13096}; 13097 13098#ifdef CONFIG_SND_DEBUG 13099static struct snd_kcontrol_new alc268_test_mixer[] = { 13100 /* Volume widgets */ 13101 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT), 13102 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT), 13103 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT), 13104 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT), 13105 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT), 13106 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT), 13107 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT), 13108 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT), 13109 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT), 13110 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT), 13111 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT), 13112 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT), 13113 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT), 13114 /* The below appears problematic on some hardwares */ 13115 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/ 13116 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT), 13117 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT), 13118 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT), 13119 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT), 13120 13121 /* Modes for retasking pin widgets */ 13122 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT), 13123 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT), 13124 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT), 13125 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT), 13126 13127 /* Controls for GPIO pins, assuming they are configured as outputs */ 13128 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01), 13129 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02), 13130 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04), 13131 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08), 13132 13133 /* Switches to allow the digital SPDIF output pin to be enabled. 13134 * The ALC268 does not have an SPDIF input. 13135 */ 13136 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01), 13137 13138 /* A switch allowing EAPD to be enabled. Some laptops seem to use 13139 * this output to turn on an external amplifier. 13140 */ 13141 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02), 13142 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02), 13143 13144 { } /* end */ 13145}; 13146#endif 13147 13148/* create input playback/capture controls for the given pin */ 13149static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid, 13150 const char *ctlname, int idx) 13151{ 13152 hda_nid_t dac; 13153 int err; 13154 13155 switch (nid) { 13156 case 0x14: 13157 case 0x16: 13158 dac = 0x02; 13159 break; 13160 case 0x15: 13161 case 0x1a: /* ALC259/269 only */ 13162 case 0x1b: /* ALC259/269 only */ 13163 case 0x21: /* ALC269vb has this pin, too */ 13164 dac = 0x03; 13165 break; 13166 default: 13167 snd_printd(KERN_WARNING "hda_codec: " 13168 "ignoring pin 0x%x as unknown\n", nid); 13169 return 0; 13170 } 13171 if (spec->multiout.dac_nids[0] != dac && 13172 spec->multiout.dac_nids[1] != dac) { 13173 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname, 13174 HDA_COMPOSE_AMP_VAL(dac, 3, idx, 13175 HDA_OUTPUT)); 13176 if (err < 0) 13177 return err; 13178 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac; 13179 } 13180 13181 if (nid != 0x16) 13182 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname, 13183 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT)); 13184 else /* mono */ 13185 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname, 13186 HDA_COMPOSE_AMP_VAL(nid, 2, idx, HDA_OUTPUT)); 13187 if (err < 0) 13188 return err; 13189 return 0; 13190} 13191 13192/* add playback controls from the parsed DAC table */ 13193static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec, 13194 const struct auto_pin_cfg *cfg) 13195{ 13196 hda_nid_t nid; 13197 int err; 13198 13199 spec->multiout.dac_nids = spec->private_dac_nids; 13200 13201 nid = cfg->line_out_pins[0]; 13202 if (nid) { 13203 const char *name; 13204 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) 13205 name = "Speaker"; 13206 else 13207 name = "Front"; 13208 err = alc268_new_analog_output(spec, nid, name, 0); 13209 if (err < 0) 13210 return err; 13211 } 13212 13213 nid = cfg->speaker_pins[0]; 13214 if (nid == 0x1d) { 13215 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, "Speaker", 13216 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT)); 13217 if (err < 0) 13218 return err; 13219 } else if (nid) { 13220 err = alc268_new_analog_output(spec, nid, "Speaker", 0); 13221 if (err < 0) 13222 return err; 13223 } 13224 nid = cfg->hp_pins[0]; 13225 if (nid) { 13226 err = alc268_new_analog_output(spec, nid, "Headphone", 0); 13227 if (err < 0) 13228 return err; 13229 } 13230 13231 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2]; 13232 if (nid == 0x16) { 13233 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, "Mono", 13234 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT)); 13235 if (err < 0) 13236 return err; 13237 } 13238 return 0; 13239} 13240 13241/* create playback/capture controls for input pins */ 13242static int alc268_auto_create_input_ctls(struct hda_codec *codec, 13243 const struct auto_pin_cfg *cfg) 13244{ 13245 return alc_auto_create_input_ctls(codec, cfg, 0, 0x23, 0x24); 13246} 13247 13248static void alc268_auto_set_output_and_unmute(struct hda_codec *codec, 13249 hda_nid_t nid, int pin_type) 13250{ 13251 int idx; 13252 13253 alc_set_pin_output(codec, nid, pin_type); 13254 if (nid == 0x14 || nid == 0x16) 13255 idx = 0; 13256 else 13257 idx = 1; 13258 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx); 13259} 13260 13261static void alc268_auto_init_multi_out(struct hda_codec *codec) 13262{ 13263 struct alc_spec *spec = codec->spec; 13264 hda_nid_t nid = spec->autocfg.line_out_pins[0]; 13265 if (nid) { 13266 int pin_type = get_pin_type(spec->autocfg.line_out_type); 13267 alc268_auto_set_output_and_unmute(codec, nid, pin_type); 13268 } 13269} 13270 13271static void alc268_auto_init_hp_out(struct hda_codec *codec) 13272{ 13273 struct alc_spec *spec = codec->spec; 13274 hda_nid_t pin; 13275 13276 pin = spec->autocfg.hp_pins[0]; 13277 if (pin) 13278 alc268_auto_set_output_and_unmute(codec, pin, PIN_HP); 13279 pin = spec->autocfg.speaker_pins[0]; 13280 if (pin) 13281 alc268_auto_set_output_and_unmute(codec, pin, PIN_OUT); 13282} 13283 13284static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec) 13285{ 13286 struct alc_spec *spec = codec->spec; 13287 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0]; 13288 hda_nid_t hp_nid = spec->autocfg.hp_pins[0]; 13289 hda_nid_t line_nid = spec->autocfg.line_out_pins[0]; 13290 unsigned int dac_vol1, dac_vol2; 13291 13292 if (line_nid == 0x1d || speaker_nid == 0x1d) { 13293 snd_hda_codec_write(codec, speaker_nid, 0, 13294 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); 13295 /* mute mixer inputs from 0x1d */ 13296 snd_hda_codec_write(codec, 0x0f, 0, 13297 AC_VERB_SET_AMP_GAIN_MUTE, 13298 AMP_IN_UNMUTE(1)); 13299 snd_hda_codec_write(codec, 0x10, 0, 13300 AC_VERB_SET_AMP_GAIN_MUTE, 13301 AMP_IN_UNMUTE(1)); 13302 } else { 13303 /* unmute mixer inputs from 0x1d */ 13304 snd_hda_codec_write(codec, 0x0f, 0, 13305 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)); 13306 snd_hda_codec_write(codec, 0x10, 0, 13307 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)); 13308 } 13309 13310 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */ 13311 if (line_nid == 0x14) 13312 dac_vol2 = AMP_OUT_ZERO; 13313 else if (line_nid == 0x15) 13314 dac_vol1 = AMP_OUT_ZERO; 13315 if (hp_nid == 0x14) 13316 dac_vol2 = AMP_OUT_ZERO; 13317 else if (hp_nid == 0x15) 13318 dac_vol1 = AMP_OUT_ZERO; 13319 if (line_nid != 0x16 || hp_nid != 0x16 || 13320 spec->autocfg.line_out_pins[1] != 0x16 || 13321 spec->autocfg.line_out_pins[2] != 0x16) 13322 dac_vol1 = dac_vol2 = AMP_OUT_ZERO; 13323 13324 snd_hda_codec_write(codec, 0x02, 0, 13325 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1); 13326 snd_hda_codec_write(codec, 0x03, 0, 13327 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2); 13328} 13329 13330/* pcm configuration: identical with ALC880 */ 13331#define alc268_pcm_analog_playback alc880_pcm_analog_playback 13332#define alc268_pcm_analog_capture alc880_pcm_analog_capture 13333#define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture 13334#define alc268_pcm_digital_playback alc880_pcm_digital_playback 13335 13336/* 13337 * BIOS auto configuration 13338 */ 13339static int alc268_parse_auto_config(struct hda_codec *codec) 13340{ 13341 struct alc_spec *spec = codec->spec; 13342 int err; 13343 static hda_nid_t alc268_ignore[] = { 0 }; 13344 13345 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 13346 alc268_ignore); 13347 if (err < 0) 13348 return err; 13349 if (!spec->autocfg.line_outs) { 13350 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) { 13351 spec->multiout.max_channels = 2; 13352 spec->no_analog = 1; 13353 goto dig_only; 13354 } 13355 return 0; /* can't find valid BIOS pin config */ 13356 } 13357 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg); 13358 if (err < 0) 13359 return err; 13360 err = alc268_auto_create_input_ctls(codec, &spec->autocfg); 13361 if (err < 0) 13362 return err; 13363 13364 spec->multiout.max_channels = 2; 13365 13366 dig_only: 13367 /* digital only support output */ 13368 alc_auto_parse_digital(codec); 13369 if (spec->kctls.list) 13370 add_mixer(spec, spec->kctls.list); 13371 13372 if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d) 13373 add_mixer(spec, alc268_beep_mixer); 13374 13375 add_verb(spec, alc268_volume_init_verbs); 13376 spec->num_mux_defs = 2; 13377 spec->input_mux = &spec->private_imux[0]; 13378 13379 err = alc_auto_add_mic_boost(codec); 13380 if (err < 0) 13381 return err; 13382 13383 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); 13384 13385 return 1; 13386} 13387 13388#define alc268_auto_init_analog_input alc882_auto_init_analog_input 13389 13390/* init callback for auto-configuration model -- overriding the default init */ 13391static void alc268_auto_init(struct hda_codec *codec) 13392{ 13393 struct alc_spec *spec = codec->spec; 13394 alc268_auto_init_multi_out(codec); 13395 alc268_auto_init_hp_out(codec); 13396 alc268_auto_init_mono_speaker_out(codec); 13397 alc268_auto_init_analog_input(codec); 13398 alc_auto_init_digital(codec); 13399 if (spec->unsol_event) 13400 alc_inithook(codec); 13401} 13402 13403/* 13404 * configuration and preset 13405 */ 13406static const char *alc268_models[ALC268_MODEL_LAST] = { 13407 [ALC267_QUANTA_IL1] = "quanta-il1", 13408 [ALC268_3ST] = "3stack", 13409 [ALC268_TOSHIBA] = "toshiba", 13410 [ALC268_ACER] = "acer", 13411 [ALC268_ACER_DMIC] = "acer-dmic", 13412 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire", 13413 [ALC268_DELL] = "dell", 13414 [ALC268_ZEPTO] = "zepto", 13415#ifdef CONFIG_SND_DEBUG 13416 [ALC268_TEST] = "test", 13417#endif 13418 [ALC268_AUTO] = "auto", 13419}; 13420 13421static struct snd_pci_quirk alc268_cfg_tbl[] = { 13422 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER), 13423 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER), 13424 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER), 13425 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER), 13426 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER), 13427 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One", 13428 ALC268_ACER_ASPIRE_ONE), 13429 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL), 13430 SND_PCI_QUIRK_MASK(0x1028, 0xfff0, 0x02b0, 13431 "Dell Inspiron Mini9/Vostro A90", ALC268_DELL), 13432 /* almost compatible with toshiba but with optional digital outs; 13433 * auto-probing seems working fine 13434 */ 13435 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series", 13436 ALC268_AUTO), 13437 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST), 13438 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO), 13439 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA), 13440 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER), 13441 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1), 13442 SND_PCI_QUIRK(0x1854, 0x1775, "LG R510", ALC268_DELL), 13443 {} 13444}; 13445 13446/* Toshiba laptops have no unique PCI SSID but only codec SSID */ 13447static struct snd_pci_quirk alc268_ssid_cfg_tbl[] = { 13448 SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO), 13449 SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO), 13450 SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05", 13451 ALC268_TOSHIBA), 13452 {} 13453}; 13454 13455static struct alc_config_preset alc268_presets[] = { 13456 [ALC267_QUANTA_IL1] = { 13457 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer, 13458 alc268_capture_nosrc_mixer }, 13459 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 13460 alc267_quanta_il1_verbs }, 13461 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 13462 .dac_nids = alc268_dac_nids, 13463 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 13464 .adc_nids = alc268_adc_nids_alt, 13465 .hp_nid = 0x03, 13466 .num_channel_mode = ARRAY_SIZE(alc268_modes), 13467 .channel_mode = alc268_modes, 13468 .unsol_event = alc_sku_unsol_event, 13469 .setup = alc267_quanta_il1_setup, 13470 .init_hook = alc_inithook, 13471 }, 13472 [ALC268_3ST] = { 13473 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer, 13474 alc268_beep_mixer }, 13475 .init_verbs = { alc268_base_init_verbs }, 13476 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 13477 .dac_nids = alc268_dac_nids, 13478 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 13479 .adc_nids = alc268_adc_nids_alt, 13480 .capsrc_nids = alc268_capsrc_nids, 13481 .hp_nid = 0x03, 13482 .dig_out_nid = ALC268_DIGOUT_NID, 13483 .num_channel_mode = ARRAY_SIZE(alc268_modes), 13484 .channel_mode = alc268_modes, 13485 .input_mux = &alc268_capture_source, 13486 }, 13487 [ALC268_TOSHIBA] = { 13488 .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer, 13489 alc268_beep_mixer }, 13490 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 13491 alc268_toshiba_verbs }, 13492 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 13493 .dac_nids = alc268_dac_nids, 13494 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 13495 .adc_nids = alc268_adc_nids_alt, 13496 .capsrc_nids = alc268_capsrc_nids, 13497 .hp_nid = 0x03, 13498 .num_channel_mode = ARRAY_SIZE(alc268_modes), 13499 .channel_mode = alc268_modes, 13500 .input_mux = &alc268_capture_source, 13501 .unsol_event = alc268_toshiba_unsol_event, 13502 .setup = alc268_toshiba_setup, 13503 .init_hook = alc268_toshiba_automute, 13504 }, 13505 [ALC268_ACER] = { 13506 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer, 13507 alc268_beep_mixer }, 13508 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 13509 alc268_acer_verbs }, 13510 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 13511 .dac_nids = alc268_dac_nids, 13512 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 13513 .adc_nids = alc268_adc_nids_alt, 13514 .capsrc_nids = alc268_capsrc_nids, 13515 .hp_nid = 0x02, 13516 .num_channel_mode = ARRAY_SIZE(alc268_modes), 13517 .channel_mode = alc268_modes, 13518 .input_mux = &alc268_acer_capture_source, 13519 .unsol_event = alc268_acer_unsol_event, 13520 .init_hook = alc268_acer_init_hook, 13521 }, 13522 [ALC268_ACER_DMIC] = { 13523 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer, 13524 alc268_beep_mixer }, 13525 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 13526 alc268_acer_verbs }, 13527 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 13528 .dac_nids = alc268_dac_nids, 13529 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 13530 .adc_nids = alc268_adc_nids_alt, 13531 .capsrc_nids = alc268_capsrc_nids, 13532 .hp_nid = 0x02, 13533 .num_channel_mode = ARRAY_SIZE(alc268_modes), 13534 .channel_mode = alc268_modes, 13535 .input_mux = &alc268_acer_dmic_capture_source, 13536 .unsol_event = alc268_acer_unsol_event, 13537 .init_hook = alc268_acer_init_hook, 13538 }, 13539 [ALC268_ACER_ASPIRE_ONE] = { 13540 .mixers = { alc268_acer_aspire_one_mixer, 13541 alc268_beep_mixer, 13542 alc268_capture_nosrc_mixer }, 13543 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 13544 alc268_acer_aspire_one_verbs }, 13545 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 13546 .dac_nids = alc268_dac_nids, 13547 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 13548 .adc_nids = alc268_adc_nids_alt, 13549 .capsrc_nids = alc268_capsrc_nids, 13550 .hp_nid = 0x03, 13551 .num_channel_mode = ARRAY_SIZE(alc268_modes), 13552 .channel_mode = alc268_modes, 13553 .unsol_event = alc268_acer_lc_unsol_event, 13554 .setup = alc268_acer_lc_setup, 13555 .init_hook = alc268_acer_lc_init_hook, 13556 }, 13557 [ALC268_DELL] = { 13558 .mixers = { alc268_dell_mixer, alc268_beep_mixer, 13559 alc268_capture_nosrc_mixer }, 13560 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 13561 alc268_dell_verbs }, 13562 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 13563 .dac_nids = alc268_dac_nids, 13564 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 13565 .adc_nids = alc268_adc_nids_alt, 13566 .capsrc_nids = alc268_capsrc_nids, 13567 .hp_nid = 0x02, 13568 .num_channel_mode = ARRAY_SIZE(alc268_modes), 13569 .channel_mode = alc268_modes, 13570 .unsol_event = alc_sku_unsol_event, 13571 .setup = alc268_dell_setup, 13572 .init_hook = alc_inithook, 13573 }, 13574 [ALC268_ZEPTO] = { 13575 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer, 13576 alc268_beep_mixer }, 13577 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 13578 alc268_toshiba_verbs }, 13579 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 13580 .dac_nids = alc268_dac_nids, 13581 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 13582 .adc_nids = alc268_adc_nids_alt, 13583 .capsrc_nids = alc268_capsrc_nids, 13584 .hp_nid = 0x03, 13585 .dig_out_nid = ALC268_DIGOUT_NID, 13586 .num_channel_mode = ARRAY_SIZE(alc268_modes), 13587 .channel_mode = alc268_modes, 13588 .input_mux = &alc268_capture_source, 13589 .setup = alc268_toshiba_setup, 13590 .init_hook = alc268_toshiba_automute, 13591 }, 13592#ifdef CONFIG_SND_DEBUG 13593 [ALC268_TEST] = { 13594 .mixers = { alc268_test_mixer, alc268_capture_mixer }, 13595 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 13596 alc268_volume_init_verbs }, 13597 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 13598 .dac_nids = alc268_dac_nids, 13599 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 13600 .adc_nids = alc268_adc_nids_alt, 13601 .capsrc_nids = alc268_capsrc_nids, 13602 .hp_nid = 0x03, 13603 .dig_out_nid = ALC268_DIGOUT_NID, 13604 .num_channel_mode = ARRAY_SIZE(alc268_modes), 13605 .channel_mode = alc268_modes, 13606 .input_mux = &alc268_capture_source, 13607 }, 13608#endif 13609}; 13610 13611static int patch_alc268(struct hda_codec *codec) 13612{ 13613 struct alc_spec *spec; 13614 int board_config; 13615 int i, has_beep, err; 13616 13617 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 13618 if (spec == NULL) 13619 return -ENOMEM; 13620 13621 codec->spec = spec; 13622 13623 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST, 13624 alc268_models, 13625 alc268_cfg_tbl); 13626 13627 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) 13628 board_config = snd_hda_check_board_codec_sid_config(codec, 13629 ALC268_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl); 13630 13631 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) { 13632 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 13633 codec->chip_name); 13634 board_config = ALC268_AUTO; 13635 } 13636 13637 if (board_config == ALC268_AUTO) { 13638 /* automatic parse from the BIOS config */ 13639 err = alc268_parse_auto_config(codec); 13640 if (err < 0) { 13641 alc_free(codec); 13642 return err; 13643 } else if (!err) { 13644 printk(KERN_INFO 13645 "hda_codec: Cannot set up configuration " 13646 "from BIOS. Using base mode...\n"); 13647 board_config = ALC268_3ST; 13648 } 13649 } 13650 13651 if (board_config != ALC268_AUTO) 13652 setup_preset(codec, &alc268_presets[board_config]); 13653 13654 spec->stream_analog_playback = &alc268_pcm_analog_playback; 13655 spec->stream_analog_capture = &alc268_pcm_analog_capture; 13656 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture; 13657 13658 spec->stream_digital_playback = &alc268_pcm_digital_playback; 13659 13660 has_beep = 0; 13661 for (i = 0; i < spec->num_mixers; i++) { 13662 if (spec->mixers[i] == alc268_beep_mixer) { 13663 has_beep = 1; 13664 break; 13665 } 13666 } 13667 13668 if (has_beep) { 13669 err = snd_hda_attach_beep_device(codec, 0x1); 13670 if (err < 0) { 13671 alc_free(codec); 13672 return err; 13673 } 13674 if (!query_amp_caps(codec, 0x1d, HDA_INPUT)) 13675 /* override the amp caps for beep generator */ 13676 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT, 13677 (0x0c << AC_AMPCAP_OFFSET_SHIFT) | 13678 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) | 13679 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) | 13680 (0 << AC_AMPCAP_MUTE_SHIFT)); 13681 } 13682 13683 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) { 13684 /* check whether NID 0x07 is valid */ 13685 unsigned int wcap = get_wcaps(codec, 0x07); 13686 int i; 13687 13688 spec->capsrc_nids = alc268_capsrc_nids; 13689 /* get type */ 13690 wcap = get_wcaps_type(wcap); 13691 if (spec->auto_mic || 13692 wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) { 13693 spec->adc_nids = alc268_adc_nids_alt; 13694 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt); 13695 if (spec->auto_mic) 13696 fixup_automic_adc(codec); 13697 if (spec->auto_mic || spec->input_mux->num_items == 1) 13698 add_mixer(spec, alc268_capture_nosrc_mixer); 13699 else 13700 add_mixer(spec, alc268_capture_alt_mixer); 13701 } else { 13702 spec->adc_nids = alc268_adc_nids; 13703 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids); 13704 add_mixer(spec, alc268_capture_mixer); 13705 } 13706 /* set default input source */ 13707 for (i = 0; i < spec->num_adc_nids; i++) 13708 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i], 13709 0, AC_VERB_SET_CONNECT_SEL, 13710 i < spec->num_mux_defs ? 13711 spec->input_mux[i].items[0].index : 13712 spec->input_mux->items[0].index); 13713 } 13714 13715 spec->vmaster_nid = 0x02; 13716 13717 codec->patch_ops = alc_patch_ops; 13718 if (board_config == ALC268_AUTO) 13719 spec->init_hook = alc268_auto_init; 13720 13721 return 0; 13722} 13723 13724/* 13725 * ALC269 channel source setting (2 channel) 13726 */ 13727#define ALC269_DIGOUT_NID ALC880_DIGOUT_NID 13728 13729#define alc269_dac_nids alc260_dac_nids 13730 13731static hda_nid_t alc269_adc_nids[1] = { 13732 /* ADC1 */ 13733 0x08, 13734}; 13735 13736static hda_nid_t alc269_capsrc_nids[1] = { 13737 0x23, 13738}; 13739 13740static hda_nid_t alc269vb_adc_nids[1] = { 13741 /* ADC1 */ 13742 0x09, 13743}; 13744 13745static hda_nid_t alc269vb_capsrc_nids[1] = { 13746 0x22, 13747}; 13748 13749static hda_nid_t alc269_adc_candidates[] = { 13750 0x08, 0x09, 0x07, 13751}; 13752 13753#define alc269_modes alc260_modes 13754#define alc269_capture_source alc880_lg_lw_capture_source 13755 13756static struct snd_kcontrol_new alc269_base_mixer[] = { 13757 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 13758 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 13759 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 13760 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 13761 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 13762 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 13763 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 13764 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 13765 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 13766 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 13767 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 13768 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT), 13769 { } /* end */ 13770}; 13771 13772static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = { 13773 /* output mixer control */ 13774 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), 13775 { 13776 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 13777 .name = "Master Playback Switch", 13778 .subdevice = HDA_SUBDEV_AMP_FLAG, 13779 .info = snd_hda_mixer_amp_switch_info, 13780 .get = snd_hda_mixer_amp_switch_get, 13781 .put = alc268_acer_master_sw_put, 13782 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 13783 }, 13784 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 13785 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 13786 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 13787 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 13788 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 13789 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), 13790 { } 13791}; 13792 13793static struct snd_kcontrol_new alc269_lifebook_mixer[] = { 13794 /* output mixer control */ 13795 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), 13796 { 13797 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 13798 .name = "Master Playback Switch", 13799 .subdevice = HDA_SUBDEV_AMP_FLAG, 13800 .info = snd_hda_mixer_amp_switch_info, 13801 .get = snd_hda_mixer_amp_switch_get, 13802 .put = alc268_acer_master_sw_put, 13803 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 13804 }, 13805 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 13806 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 13807 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 13808 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 13809 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 13810 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), 13811 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT), 13812 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT), 13813 HDA_CODEC_VOLUME("Dock Mic Boost", 0x1b, 0, HDA_INPUT), 13814 { } 13815}; 13816 13817static struct snd_kcontrol_new alc269_laptop_mixer[] = { 13818 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 13819 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 13820 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 13821 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 13822 { } /* end */ 13823}; 13824 13825static struct snd_kcontrol_new alc269vb_laptop_mixer[] = { 13826 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 13827 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 13828 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT), 13829 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 13830 { } /* end */ 13831}; 13832 13833/* capture mixer elements */ 13834static struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = { 13835 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 13836 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 13837 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 13838 HDA_CODEC_VOLUME("IntMic Boost", 0x19, 0, HDA_INPUT), 13839 { } /* end */ 13840}; 13841 13842static struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = { 13843 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 13844 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 13845 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 13846 { } /* end */ 13847}; 13848 13849static struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = { 13850 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), 13851 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), 13852 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 13853 HDA_CODEC_VOLUME("IntMic Boost", 0x19, 0, HDA_INPUT), 13854 { } /* end */ 13855}; 13856 13857static struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = { 13858 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), 13859 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), 13860 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 13861 { } /* end */ 13862}; 13863 13864/* FSC amilo */ 13865#define alc269_fujitsu_mixer alc269_laptop_mixer 13866 13867static struct hda_verb alc269_quanta_fl1_verbs[] = { 13868 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 13869 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 13870 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 13871 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 13872 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 13873 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 13874 { } 13875}; 13876 13877static struct hda_verb alc269_lifebook_verbs[] = { 13878 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 13879 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, 13880 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 13881 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 13882 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 13883 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 13884 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 13885 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 13886 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 13887 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 13888 { } 13889}; 13890 13891/* toggle speaker-output according to the hp-jack state */ 13892static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec) 13893{ 13894 unsigned int present; 13895 unsigned char bits; 13896 13897 present = snd_hda_jack_detect(codec, 0x15); 13898 bits = present ? HDA_AMP_MUTE : 0; 13899 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 13900 HDA_AMP_MUTE, bits); 13901 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 13902 HDA_AMP_MUTE, bits); 13903 13904 snd_hda_codec_write(codec, 0x20, 0, 13905 AC_VERB_SET_COEF_INDEX, 0x0c); 13906 snd_hda_codec_write(codec, 0x20, 0, 13907 AC_VERB_SET_PROC_COEF, 0x680); 13908 13909 snd_hda_codec_write(codec, 0x20, 0, 13910 AC_VERB_SET_COEF_INDEX, 0x0c); 13911 snd_hda_codec_write(codec, 0x20, 0, 13912 AC_VERB_SET_PROC_COEF, 0x480); 13913} 13914 13915/* toggle speaker-output according to the hp-jacks state */ 13916static void alc269_lifebook_speaker_automute(struct hda_codec *codec) 13917{ 13918 unsigned int present; 13919 unsigned char bits; 13920 13921 /* Check laptop headphone socket */ 13922 present = snd_hda_jack_detect(codec, 0x15); 13923 13924 /* Check port replicator headphone socket */ 13925 present |= snd_hda_jack_detect(codec, 0x1a); 13926 13927 bits = present ? HDA_AMP_MUTE : 0; 13928 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 13929 HDA_AMP_MUTE, bits); 13930 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 13931 HDA_AMP_MUTE, bits); 13932 13933 snd_hda_codec_write(codec, 0x20, 0, 13934 AC_VERB_SET_COEF_INDEX, 0x0c); 13935 snd_hda_codec_write(codec, 0x20, 0, 13936 AC_VERB_SET_PROC_COEF, 0x680); 13937 13938 snd_hda_codec_write(codec, 0x20, 0, 13939 AC_VERB_SET_COEF_INDEX, 0x0c); 13940 snd_hda_codec_write(codec, 0x20, 0, 13941 AC_VERB_SET_PROC_COEF, 0x480); 13942} 13943 13944static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec) 13945{ 13946 unsigned int present_laptop; 13947 unsigned int present_dock; 13948 13949 present_laptop = snd_hda_jack_detect(codec, 0x18); 13950 present_dock = snd_hda_jack_detect(codec, 0x1b); 13951 13952 /* Laptop mic port overrides dock mic port, design decision */ 13953 if (present_dock) 13954 snd_hda_codec_write(codec, 0x23, 0, 13955 AC_VERB_SET_CONNECT_SEL, 0x3); 13956 if (present_laptop) 13957 snd_hda_codec_write(codec, 0x23, 0, 13958 AC_VERB_SET_CONNECT_SEL, 0x0); 13959 if (!present_dock && !present_laptop) 13960 snd_hda_codec_write(codec, 0x23, 0, 13961 AC_VERB_SET_CONNECT_SEL, 0x1); 13962} 13963 13964static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec, 13965 unsigned int res) 13966{ 13967 switch (res >> 26) { 13968 case ALC880_HP_EVENT: 13969 alc269_quanta_fl1_speaker_automute(codec); 13970 break; 13971 case ALC880_MIC_EVENT: 13972 alc_mic_automute(codec); 13973 break; 13974 } 13975} 13976 13977static void alc269_lifebook_unsol_event(struct hda_codec *codec, 13978 unsigned int res) 13979{ 13980 if ((res >> 26) == ALC880_HP_EVENT) 13981 alc269_lifebook_speaker_automute(codec); 13982 if ((res >> 26) == ALC880_MIC_EVENT) 13983 alc269_lifebook_mic_autoswitch(codec); 13984} 13985 13986static void alc269_quanta_fl1_setup(struct hda_codec *codec) 13987{ 13988 struct alc_spec *spec = codec->spec; 13989 spec->autocfg.hp_pins[0] = 0x15; 13990 spec->autocfg.speaker_pins[0] = 0x14; 13991 spec->ext_mic.pin = 0x18; 13992 spec->ext_mic.mux_idx = 0; 13993 spec->int_mic.pin = 0x19; 13994 spec->int_mic.mux_idx = 1; 13995 spec->auto_mic = 1; 13996} 13997 13998static void alc269_quanta_fl1_init_hook(struct hda_codec *codec) 13999{ 14000 alc269_quanta_fl1_speaker_automute(codec); 14001 alc_mic_automute(codec); 14002} 14003 14004static void alc269_lifebook_init_hook(struct hda_codec *codec) 14005{ 14006 alc269_lifebook_speaker_automute(codec); 14007 alc269_lifebook_mic_autoswitch(codec); 14008} 14009 14010static struct hda_verb alc269_laptop_dmic_init_verbs[] = { 14011 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 14012 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05}, 14013 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 }, 14014 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))}, 14015 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14016 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 14017 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 14018 {} 14019}; 14020 14021static struct hda_verb alc269_laptop_amic_init_verbs[] = { 14022 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 14023 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01}, 14024 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 }, 14025 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))}, 14026 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 14027 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 14028 {} 14029}; 14030 14031static struct hda_verb alc269vb_laptop_dmic_init_verbs[] = { 14032 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, 14033 {0x22, AC_VERB_SET_CONNECT_SEL, 0x06}, 14034 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 }, 14035 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))}, 14036 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14037 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 14038 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 14039 {} 14040}; 14041 14042static struct hda_verb alc269vb_laptop_amic_init_verbs[] = { 14043 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, 14044 {0x22, AC_VERB_SET_CONNECT_SEL, 0x01}, 14045 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 }, 14046 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))}, 14047 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14048 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 14049 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 14050 {} 14051}; 14052 14053/* toggle speaker-output according to the hp-jack state */ 14054static void alc269_speaker_automute(struct hda_codec *codec) 14055{ 14056 struct alc_spec *spec = codec->spec; 14057 unsigned int nid = spec->autocfg.hp_pins[0]; 14058 unsigned int present; 14059 unsigned char bits; 14060 14061 present = snd_hda_jack_detect(codec, nid); 14062 bits = present ? HDA_AMP_MUTE : 0; 14063 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 14064 HDA_AMP_MUTE, bits); 14065 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 14066 HDA_AMP_MUTE, bits); 14067} 14068 14069/* unsolicited event for HP jack sensing */ 14070static void alc269_laptop_unsol_event(struct hda_codec *codec, 14071 unsigned int res) 14072{ 14073 switch (res >> 26) { 14074 case ALC880_HP_EVENT: 14075 alc269_speaker_automute(codec); 14076 break; 14077 case ALC880_MIC_EVENT: 14078 alc_mic_automute(codec); 14079 break; 14080 } 14081} 14082 14083static void alc269_laptop_amic_setup(struct hda_codec *codec) 14084{ 14085 struct alc_spec *spec = codec->spec; 14086 spec->autocfg.hp_pins[0] = 0x15; 14087 spec->autocfg.speaker_pins[0] = 0x14; 14088 spec->ext_mic.pin = 0x18; 14089 spec->ext_mic.mux_idx = 0; 14090 spec->int_mic.pin = 0x19; 14091 spec->int_mic.mux_idx = 1; 14092 spec->auto_mic = 1; 14093} 14094 14095static void alc269_laptop_dmic_setup(struct hda_codec *codec) 14096{ 14097 struct alc_spec *spec = codec->spec; 14098 spec->autocfg.hp_pins[0] = 0x15; 14099 spec->autocfg.speaker_pins[0] = 0x14; 14100 spec->ext_mic.pin = 0x18; 14101 spec->ext_mic.mux_idx = 0; 14102 spec->int_mic.pin = 0x12; 14103 spec->int_mic.mux_idx = 5; 14104 spec->auto_mic = 1; 14105} 14106 14107static void alc269vb_laptop_amic_setup(struct hda_codec *codec) 14108{ 14109 struct alc_spec *spec = codec->spec; 14110 spec->autocfg.hp_pins[0] = 0x21; 14111 spec->autocfg.speaker_pins[0] = 0x14; 14112 spec->ext_mic.pin = 0x18; 14113 spec->ext_mic.mux_idx = 0; 14114 spec->int_mic.pin = 0x19; 14115 spec->int_mic.mux_idx = 1; 14116 spec->auto_mic = 1; 14117} 14118 14119static void alc269vb_laptop_dmic_setup(struct hda_codec *codec) 14120{ 14121 struct alc_spec *spec = codec->spec; 14122 spec->autocfg.hp_pins[0] = 0x21; 14123 spec->autocfg.speaker_pins[0] = 0x14; 14124 spec->ext_mic.pin = 0x18; 14125 spec->ext_mic.mux_idx = 0; 14126 spec->int_mic.pin = 0x12; 14127 spec->int_mic.mux_idx = 6; 14128 spec->auto_mic = 1; 14129} 14130 14131static void alc269_laptop_inithook(struct hda_codec *codec) 14132{ 14133 alc269_speaker_automute(codec); 14134 alc_mic_automute(codec); 14135} 14136 14137/* 14138 * generic initialization of ADC, input mixers and output mixers 14139 */ 14140static struct hda_verb alc269_init_verbs[] = { 14141 /* 14142 * Unmute ADC0 and set the default input to mic-in 14143 */ 14144 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14145 14146 /* 14147 * Set up output mixers (0x02 - 0x03) 14148 */ 14149 /* set vol=0 to output mixers */ 14150 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 14151 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 14152 14153 /* set up input amps for analog loopback */ 14154 /* Amp Indices: DAC = 0, mixer = 1 */ 14155 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14156 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 14157 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14158 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 14159 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14160 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 14161 14162 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 14163 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 14164 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 14165 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 14166 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 14167 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14168 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14169 14170 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 14171 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 14172 14173 /* FIXME: use Mux-type input source selection */ 14174 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */ 14175 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 14176 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00}, 14177 14178 /* set EAPD */ 14179 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 14180 { } 14181}; 14182 14183static struct hda_verb alc269vb_init_verbs[] = { 14184 /* 14185 * Unmute ADC0 and set the default input to mic-in 14186 */ 14187 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14188 14189 /* 14190 * Set up output mixers (0x02 - 0x03) 14191 */ 14192 /* set vol=0 to output mixers */ 14193 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 14194 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 14195 14196 /* set up input amps for analog loopback */ 14197 /* Amp Indices: DAC = 0, mixer = 1 */ 14198 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14199 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 14200 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14201 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 14202 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14203 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 14204 14205 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 14206 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 14207 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 14208 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 14209 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 14210 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14211 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14212 14213 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 14214 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 14215 14216 /* FIXME: use Mux-type input source selection */ 14217 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */ 14218 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 14219 {0x22, AC_VERB_SET_CONNECT_SEL, 0x00}, 14220 14221 /* set EAPD */ 14222 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 14223 { } 14224}; 14225 14226#define alc269_auto_create_multi_out_ctls \ 14227 alc268_auto_create_multi_out_ctls 14228#define alc269_auto_create_input_ctls \ 14229 alc268_auto_create_input_ctls 14230 14231#ifdef CONFIG_SND_HDA_POWER_SAVE 14232#define alc269_loopbacks alc880_loopbacks 14233#endif 14234 14235/* pcm configuration: identical with ALC880 */ 14236#define alc269_pcm_analog_playback alc880_pcm_analog_playback 14237#define alc269_pcm_analog_capture alc880_pcm_analog_capture 14238#define alc269_pcm_digital_playback alc880_pcm_digital_playback 14239#define alc269_pcm_digital_capture alc880_pcm_digital_capture 14240 14241static struct hda_pcm_stream alc269_44k_pcm_analog_playback = { 14242 .substreams = 1, 14243 .channels_min = 2, 14244 .channels_max = 8, 14245 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */ 14246 /* NID is set in alc_build_pcms */ 14247 .ops = { 14248 .open = alc880_playback_pcm_open, 14249 .prepare = alc880_playback_pcm_prepare, 14250 .cleanup = alc880_playback_pcm_cleanup 14251 }, 14252}; 14253 14254static struct hda_pcm_stream alc269_44k_pcm_analog_capture = { 14255 .substreams = 1, 14256 .channels_min = 2, 14257 .channels_max = 2, 14258 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */ 14259 /* NID is set in alc_build_pcms */ 14260}; 14261 14262#ifdef CONFIG_SND_HDA_POWER_SAVE 14263static int alc269_mic2_for_mute_led(struct hda_codec *codec) 14264{ 14265 switch (codec->subsystem_id) { 14266 case 0x103c1586: 14267 return 1; 14268 } 14269 return 0; 14270} 14271 14272static int alc269_mic2_mute_check_ps(struct hda_codec *codec, hda_nid_t nid) 14273{ 14274 /* update mute-LED according to the speaker mute state */ 14275 if (nid == 0x01 || nid == 0x14) { 14276 int pinval; 14277 if (snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0) & 14278 HDA_AMP_MUTE) 14279 pinval = 0x24; 14280 else 14281 pinval = 0x20; 14282 /* mic2 vref pin is used for mute LED control */ 14283 snd_hda_codec_update_cache(codec, 0x19, 0, 14284 AC_VERB_SET_PIN_WIDGET_CONTROL, 14285 pinval); 14286 } 14287 return alc_check_power_status(codec, nid); 14288} 14289#endif /* CONFIG_SND_HDA_POWER_SAVE */ 14290 14291static int alc275_setup_dual_adc(struct hda_codec *codec) 14292{ 14293 struct alc_spec *spec = codec->spec; 14294 14295 if (codec->vendor_id != 0x10ec0275 || !spec->auto_mic) 14296 return 0; 14297 if ((spec->ext_mic.pin >= 0x18 && spec->int_mic.pin <= 0x13) || 14298 (spec->ext_mic.pin <= 0x12 && spec->int_mic.pin >= 0x18)) { 14299 if (spec->ext_mic.pin <= 0x12) { 14300 spec->private_adc_nids[0] = 0x08; 14301 spec->private_adc_nids[1] = 0x11; 14302 spec->private_capsrc_nids[0] = 0x23; 14303 spec->private_capsrc_nids[1] = 0x22; 14304 } else { 14305 spec->private_adc_nids[0] = 0x11; 14306 spec->private_adc_nids[1] = 0x08; 14307 spec->private_capsrc_nids[0] = 0x22; 14308 spec->private_capsrc_nids[1] = 0x23; 14309 } 14310 spec->adc_nids = spec->private_adc_nids; 14311 spec->capsrc_nids = spec->private_capsrc_nids; 14312 spec->num_adc_nids = 2; 14313 spec->dual_adc_switch = 1; 14314 snd_printdd("realtek: enabling dual ADC switchg (%02x:%02x)\n", 14315 spec->adc_nids[0], spec->adc_nids[1]); 14316 return 1; 14317 } 14318 return 0; 14319} 14320 14321/* 14322 * BIOS auto configuration 14323 */ 14324static int alc269_parse_auto_config(struct hda_codec *codec) 14325{ 14326 struct alc_spec *spec = codec->spec; 14327 int err; 14328 static hda_nid_t alc269_ignore[] = { 0x1d, 0 }; 14329 14330 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 14331 alc269_ignore); 14332 if (err < 0) 14333 return err; 14334 14335 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg); 14336 if (err < 0) 14337 return err; 14338 err = alc269_auto_create_input_ctls(codec, &spec->autocfg); 14339 if (err < 0) 14340 return err; 14341 14342 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 14343 14344 alc_auto_parse_digital(codec); 14345 14346 if (spec->kctls.list) 14347 add_mixer(spec, spec->kctls.list); 14348 14349 if ((alc_read_coef_idx(codec, 0) & 0x00f0) == 0x0010) { 14350 add_verb(spec, alc269vb_init_verbs); 14351 alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21); 14352 } else { 14353 add_verb(spec, alc269_init_verbs); 14354 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); 14355 } 14356 14357 spec->num_mux_defs = 1; 14358 spec->input_mux = &spec->private_imux[0]; 14359 14360 if (!alc275_setup_dual_adc(codec)) 14361 fillup_priv_adc_nids(codec, alc269_adc_candidates, 14362 sizeof(alc269_adc_candidates)); 14363 14364 /* set default input source */ 14365 if (!spec->dual_adc_switch) 14366 snd_hda_codec_write_cache(codec, spec->capsrc_nids[0], 14367 0, AC_VERB_SET_CONNECT_SEL, 14368 spec->input_mux->items[0].index); 14369 14370 err = alc_auto_add_mic_boost(codec); 14371 if (err < 0) 14372 return err; 14373 14374 if (!spec->cap_mixer && !spec->no_analog) 14375 set_capture_mixer(codec); 14376 14377 return 1; 14378} 14379 14380#define alc269_auto_init_multi_out alc268_auto_init_multi_out 14381#define alc269_auto_init_hp_out alc268_auto_init_hp_out 14382#define alc269_auto_init_analog_input alc882_auto_init_analog_input 14383 14384 14385/* init callback for auto-configuration model -- overriding the default init */ 14386static void alc269_auto_init(struct hda_codec *codec) 14387{ 14388 struct alc_spec *spec = codec->spec; 14389 alc269_auto_init_multi_out(codec); 14390 alc269_auto_init_hp_out(codec); 14391 alc269_auto_init_analog_input(codec); 14392 alc_auto_init_digital(codec); 14393 if (spec->unsol_event) 14394 alc_inithook(codec); 14395} 14396 14397enum { 14398 ALC269_FIXUP_SONY_VAIO, 14399}; 14400 14401static const struct hda_verb alc269_sony_vaio_fixup_verbs[] = { 14402 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD}, 14403 {} 14404}; 14405 14406static const struct alc_fixup alc269_fixups[] = { 14407 [ALC269_FIXUP_SONY_VAIO] = { 14408 .verbs = alc269_sony_vaio_fixup_verbs 14409 }, 14410}; 14411 14412static struct snd_pci_quirk alc269_fixup_tbl[] = { 14413 SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_FIXUP_SONY_VAIO), 14414 {} 14415}; 14416 14417 14418/* 14419 * configuration and preset 14420 */ 14421static const char *alc269_models[ALC269_MODEL_LAST] = { 14422 [ALC269_BASIC] = "basic", 14423 [ALC269_QUANTA_FL1] = "quanta", 14424 [ALC269_AMIC] = "laptop-amic", 14425 [ALC269_DMIC] = "laptop-dmic", 14426 [ALC269_FUJITSU] = "fujitsu", 14427 [ALC269_LIFEBOOK] = "lifebook", 14428 [ALC269_AUTO] = "auto", 14429}; 14430 14431static struct snd_pci_quirk alc269_cfg_tbl[] = { 14432 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1), 14433 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A", 14434 ALC269_AMIC), 14435 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269VB_AMIC), 14436 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269VB_AMIC), 14437 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269VB_AMIC), 14438 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_AMIC), 14439 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269VB_AMIC), 14440 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269VB_AMIC), 14441 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269VB_AMIC), 14442 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269VB_AMIC), 14443 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_AMIC), 14444 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82Jv", ALC269_AMIC), 14445 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_AMIC), 14446 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_AMIC), 14447 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_AMIC), 14448 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_AMIC), 14449 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_AMIC), 14450 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_AMIC), 14451 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_AMIC), 14452 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_AMIC), 14453 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_AMIC), 14454 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_AMIC), 14455 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_AMIC), 14456 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_AMIC), 14457 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_AMIC), 14458 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_AMIC), 14459 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_AMIC), 14460 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_AMIC), 14461 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_AMIC), 14462 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_AMIC), 14463 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_AMIC), 14464 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_AMIC), 14465 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_AMIC), 14466 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_DMIC), 14467 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_AMIC), 14468 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_AMIC), 14469 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_AMIC), 14470 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_AMIC), 14471 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901", 14472 ALC269_DMIC), 14473 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101", 14474 ALC269_DMIC), 14475 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC), 14476 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC), 14477 SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_AUTO), 14478 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK), 14479 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC), 14480 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU), 14481 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_AMIC), 14482 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_AMIC), 14483 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_DMIC), 14484 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_DMIC), 14485 {} 14486}; 14487 14488static struct alc_config_preset alc269_presets[] = { 14489 [ALC269_BASIC] = { 14490 .mixers = { alc269_base_mixer }, 14491 .init_verbs = { alc269_init_verbs }, 14492 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 14493 .dac_nids = alc269_dac_nids, 14494 .hp_nid = 0x03, 14495 .num_channel_mode = ARRAY_SIZE(alc269_modes), 14496 .channel_mode = alc269_modes, 14497 .input_mux = &alc269_capture_source, 14498 }, 14499 [ALC269_QUANTA_FL1] = { 14500 .mixers = { alc269_quanta_fl1_mixer }, 14501 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs }, 14502 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 14503 .dac_nids = alc269_dac_nids, 14504 .hp_nid = 0x03, 14505 .num_channel_mode = ARRAY_SIZE(alc269_modes), 14506 .channel_mode = alc269_modes, 14507 .input_mux = &alc269_capture_source, 14508 .unsol_event = alc269_quanta_fl1_unsol_event, 14509 .setup = alc269_quanta_fl1_setup, 14510 .init_hook = alc269_quanta_fl1_init_hook, 14511 }, 14512 [ALC269_AMIC] = { 14513 .mixers = { alc269_laptop_mixer }, 14514 .cap_mixer = alc269_laptop_analog_capture_mixer, 14515 .init_verbs = { alc269_init_verbs, 14516 alc269_laptop_amic_init_verbs }, 14517 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 14518 .dac_nids = alc269_dac_nids, 14519 .hp_nid = 0x03, 14520 .num_channel_mode = ARRAY_SIZE(alc269_modes), 14521 .channel_mode = alc269_modes, 14522 .unsol_event = alc269_laptop_unsol_event, 14523 .setup = alc269_laptop_amic_setup, 14524 .init_hook = alc269_laptop_inithook, 14525 }, 14526 [ALC269_DMIC] = { 14527 .mixers = { alc269_laptop_mixer }, 14528 .cap_mixer = alc269_laptop_digital_capture_mixer, 14529 .init_verbs = { alc269_init_verbs, 14530 alc269_laptop_dmic_init_verbs }, 14531 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 14532 .dac_nids = alc269_dac_nids, 14533 .hp_nid = 0x03, 14534 .num_channel_mode = ARRAY_SIZE(alc269_modes), 14535 .channel_mode = alc269_modes, 14536 .unsol_event = alc269_laptop_unsol_event, 14537 .setup = alc269_laptop_dmic_setup, 14538 .init_hook = alc269_laptop_inithook, 14539 }, 14540 [ALC269VB_AMIC] = { 14541 .mixers = { alc269vb_laptop_mixer }, 14542 .cap_mixer = alc269vb_laptop_analog_capture_mixer, 14543 .init_verbs = { alc269vb_init_verbs, 14544 alc269vb_laptop_amic_init_verbs }, 14545 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 14546 .dac_nids = alc269_dac_nids, 14547 .hp_nid = 0x03, 14548 .num_channel_mode = ARRAY_SIZE(alc269_modes), 14549 .channel_mode = alc269_modes, 14550 .unsol_event = alc269_laptop_unsol_event, 14551 .setup = alc269vb_laptop_amic_setup, 14552 .init_hook = alc269_laptop_inithook, 14553 }, 14554 [ALC269VB_DMIC] = { 14555 .mixers = { alc269vb_laptop_mixer }, 14556 .cap_mixer = alc269vb_laptop_digital_capture_mixer, 14557 .init_verbs = { alc269vb_init_verbs, 14558 alc269vb_laptop_dmic_init_verbs }, 14559 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 14560 .dac_nids = alc269_dac_nids, 14561 .hp_nid = 0x03, 14562 .num_channel_mode = ARRAY_SIZE(alc269_modes), 14563 .channel_mode = alc269_modes, 14564 .unsol_event = alc269_laptop_unsol_event, 14565 .setup = alc269vb_laptop_dmic_setup, 14566 .init_hook = alc269_laptop_inithook, 14567 }, 14568 [ALC269_FUJITSU] = { 14569 .mixers = { alc269_fujitsu_mixer }, 14570 .cap_mixer = alc269_laptop_digital_capture_mixer, 14571 .init_verbs = { alc269_init_verbs, 14572 alc269_laptop_dmic_init_verbs }, 14573 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 14574 .dac_nids = alc269_dac_nids, 14575 .hp_nid = 0x03, 14576 .num_channel_mode = ARRAY_SIZE(alc269_modes), 14577 .channel_mode = alc269_modes, 14578 .unsol_event = alc269_laptop_unsol_event, 14579 .setup = alc269_laptop_dmic_setup, 14580 .init_hook = alc269_laptop_inithook, 14581 }, 14582 [ALC269_LIFEBOOK] = { 14583 .mixers = { alc269_lifebook_mixer }, 14584 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs }, 14585 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 14586 .dac_nids = alc269_dac_nids, 14587 .hp_nid = 0x03, 14588 .num_channel_mode = ARRAY_SIZE(alc269_modes), 14589 .channel_mode = alc269_modes, 14590 .input_mux = &alc269_capture_source, 14591 .unsol_event = alc269_lifebook_unsol_event, 14592 .init_hook = alc269_lifebook_init_hook, 14593 }, 14594}; 14595 14596static int patch_alc269(struct hda_codec *codec) 14597{ 14598 struct alc_spec *spec; 14599 int board_config; 14600 int err; 14601 int is_alc269vb = 0; 14602 14603 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 14604 if (spec == NULL) 14605 return -ENOMEM; 14606 14607 codec->spec = spec; 14608 14609 alc_auto_parse_customize_define(codec); 14610 14611 if ((alc_read_coef_idx(codec, 0) & 0x00f0) == 0x0010){ 14612 if (codec->bus->pci->subsystem_vendor == 0x1025 && 14613 spec->cdefine.platform_type == 1) 14614 alc_codec_rename(codec, "ALC271X"); 14615 else 14616 alc_codec_rename(codec, "ALC259"); 14617 is_alc269vb = 1; 14618 } else 14619 alc_fix_pll_init(codec, 0x20, 0x04, 15); 14620 14621 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST, 14622 alc269_models, 14623 alc269_cfg_tbl); 14624 14625 if (board_config < 0) { 14626 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 14627 codec->chip_name); 14628 board_config = ALC269_AUTO; 14629 } 14630 14631 if (board_config == ALC269_AUTO) 14632 alc_pick_fixup(codec, alc269_fixup_tbl, alc269_fixups, 1); 14633 14634 if (board_config == ALC269_AUTO) { 14635 /* automatic parse from the BIOS config */ 14636 err = alc269_parse_auto_config(codec); 14637 if (err < 0) { 14638 alc_free(codec); 14639 return err; 14640 } else if (!err) { 14641 printk(KERN_INFO 14642 "hda_codec: Cannot set up configuration " 14643 "from BIOS. Using base mode...\n"); 14644 board_config = ALC269_BASIC; 14645 } 14646 } 14647 14648 if (has_cdefine_beep(codec)) { 14649 err = snd_hda_attach_beep_device(codec, 0x1); 14650 if (err < 0) { 14651 alc_free(codec); 14652 return err; 14653 } 14654 } 14655 14656 if (board_config != ALC269_AUTO) 14657 setup_preset(codec, &alc269_presets[board_config]); 14658 14659 if (board_config == ALC269_QUANTA_FL1) { 14660 /* Due to a hardware problem on Lenovo Ideadpad, we need to 14661 * fix the sample rate of analog I/O to 44.1kHz 14662 */ 14663 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback; 14664 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture; 14665 } else if (spec->dual_adc_switch) { 14666 spec->stream_analog_playback = &alc269_pcm_analog_playback; 14667 /* switch ADC dynamically */ 14668 spec->stream_analog_capture = &dualmic_pcm_analog_capture; 14669 } else { 14670 spec->stream_analog_playback = &alc269_pcm_analog_playback; 14671 spec->stream_analog_capture = &alc269_pcm_analog_capture; 14672 } 14673 spec->stream_digital_playback = &alc269_pcm_digital_playback; 14674 spec->stream_digital_capture = &alc269_pcm_digital_capture; 14675 14676 if (!spec->adc_nids) { /* wasn't filled automatically? use default */ 14677 if (!is_alc269vb) { 14678 spec->adc_nids = alc269_adc_nids; 14679 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids); 14680 spec->capsrc_nids = alc269_capsrc_nids; 14681 } else { 14682 spec->adc_nids = alc269vb_adc_nids; 14683 spec->num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids); 14684 spec->capsrc_nids = alc269vb_capsrc_nids; 14685 } 14686 } 14687 14688 if (!spec->cap_mixer) 14689 set_capture_mixer(codec); 14690 if (has_cdefine_beep(codec)) 14691 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); 14692 14693 if (board_config == ALC269_AUTO) 14694 alc_pick_fixup(codec, alc269_fixup_tbl, alc269_fixups, 0); 14695 14696 spec->vmaster_nid = 0x02; 14697 14698 codec->patch_ops = alc_patch_ops; 14699 if (board_config == ALC269_AUTO) 14700 spec->init_hook = alc269_auto_init; 14701#ifdef CONFIG_SND_HDA_POWER_SAVE 14702 if (!spec->loopback.amplist) 14703 spec->loopback.amplist = alc269_loopbacks; 14704 if (alc269_mic2_for_mute_led(codec)) 14705 codec->patch_ops.check_power_status = alc269_mic2_mute_check_ps; 14706#endif 14707 14708 return 0; 14709} 14710 14711/* 14712 * ALC861 channel source setting (2/6 channel selection for 3-stack) 14713 */ 14714 14715/* 14716 * set the path ways for 2 channel output 14717 * need to set the codec line out and mic 1 pin widgets to inputs 14718 */ 14719static struct hda_verb alc861_threestack_ch2_init[] = { 14720 /* set pin widget 1Ah (line in) for input */ 14721 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 14722 /* set pin widget 18h (mic1/2) for input, for mic also enable 14723 * the vref 14724 */ 14725 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 14726 14727 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, 14728#if 0 14729 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/ 14730 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/ 14731#endif 14732 { } /* end */ 14733}; 14734/* 14735 * 6ch mode 14736 * need to set the codec line out and mic 1 pin widgets to outputs 14737 */ 14738static struct hda_verb alc861_threestack_ch6_init[] = { 14739 /* set pin widget 1Ah (line in) for output (Back Surround)*/ 14740 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 14741 /* set pin widget 18h (mic1) for output (CLFE)*/ 14742 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 14743 14744 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 }, 14745 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 }, 14746 14747 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 }, 14748#if 0 14749 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/ 14750 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/ 14751#endif 14752 { } /* end */ 14753}; 14754 14755static struct hda_channel_mode alc861_threestack_modes[2] = { 14756 { 2, alc861_threestack_ch2_init }, 14757 { 6, alc861_threestack_ch6_init }, 14758}; 14759/* Set mic1 as input and unmute the mixer */ 14760static struct hda_verb alc861_uniwill_m31_ch2_init[] = { 14761 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 14762 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/ 14763 { } /* end */ 14764}; 14765/* Set mic1 as output and mute mixer */ 14766static struct hda_verb alc861_uniwill_m31_ch4_init[] = { 14767 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 14768 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/ 14769 { } /* end */ 14770}; 14771 14772static struct hda_channel_mode alc861_uniwill_m31_modes[2] = { 14773 { 2, alc861_uniwill_m31_ch2_init }, 14774 { 4, alc861_uniwill_m31_ch4_init }, 14775}; 14776 14777/* Set mic1 and line-in as input and unmute the mixer */ 14778static struct hda_verb alc861_asus_ch2_init[] = { 14779 /* set pin widget 1Ah (line in) for input */ 14780 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 14781 /* set pin widget 18h (mic1/2) for input, for mic also enable 14782 * the vref 14783 */ 14784 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 14785 14786 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, 14787#if 0 14788 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/ 14789 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/ 14790#endif 14791 { } /* end */ 14792}; 14793/* Set mic1 nad line-in as output and mute mixer */ 14794static struct hda_verb alc861_asus_ch6_init[] = { 14795 /* set pin widget 1Ah (line in) for output (Back Surround)*/ 14796 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 14797 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */ 14798 /* set pin widget 18h (mic1) for output (CLFE)*/ 14799 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 14800 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */ 14801 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 }, 14802 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 }, 14803 14804 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 }, 14805#if 0 14806 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/ 14807 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/ 14808#endif 14809 { } /* end */ 14810}; 14811 14812static struct hda_channel_mode alc861_asus_modes[2] = { 14813 { 2, alc861_asus_ch2_init }, 14814 { 6, alc861_asus_ch6_init }, 14815}; 14816 14817/* patch-ALC861 */ 14818 14819static struct snd_kcontrol_new alc861_base_mixer[] = { 14820 /* output mixer control */ 14821 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), 14822 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), 14823 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT), 14824 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT), 14825 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), 14826 14827 /*Input mixer control */ 14828 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT), 14829 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */ 14830 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), 14831 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), 14832 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT), 14833 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT), 14834 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), 14835 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), 14836 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), 14837 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT), 14838 14839 { } /* end */ 14840}; 14841 14842static struct snd_kcontrol_new alc861_3ST_mixer[] = { 14843 /* output mixer control */ 14844 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), 14845 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), 14846 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT), 14847 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT), 14848 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */ 14849 14850 /* Input mixer control */ 14851 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT), 14852 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */ 14853 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), 14854 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), 14855 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT), 14856 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT), 14857 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), 14858 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), 14859 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), 14860 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT), 14861 14862 { 14863 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 14864 .name = "Channel Mode", 14865 .info = alc_ch_mode_info, 14866 .get = alc_ch_mode_get, 14867 .put = alc_ch_mode_put, 14868 .private_value = ARRAY_SIZE(alc861_threestack_modes), 14869 }, 14870 { } /* end */ 14871}; 14872 14873static struct snd_kcontrol_new alc861_toshiba_mixer[] = { 14874 /* output mixer control */ 14875 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT), 14876 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), 14877 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), 14878 14879 { } /* end */ 14880}; 14881 14882static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = { 14883 /* output mixer control */ 14884 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), 14885 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), 14886 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT), 14887 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT), 14888 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */ 14889 14890 /* Input mixer control */ 14891 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT), 14892 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */ 14893 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), 14894 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), 14895 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT), 14896 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT), 14897 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), 14898 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), 14899 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), 14900 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT), 14901 14902 { 14903 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 14904 .name = "Channel Mode", 14905 .info = alc_ch_mode_info, 14906 .get = alc_ch_mode_get, 14907 .put = alc_ch_mode_put, 14908 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes), 14909 }, 14910 { } /* end */ 14911}; 14912 14913static struct snd_kcontrol_new alc861_asus_mixer[] = { 14914 /* output mixer control */ 14915 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), 14916 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), 14917 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT), 14918 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT), 14919 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), 14920 14921 /* Input mixer control */ 14922 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT), 14923 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), 14924 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), 14925 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), 14926 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT), 14927 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT), 14928 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), 14929 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), 14930 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), 14931 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT), 14932 14933 { 14934 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 14935 .name = "Channel Mode", 14936 .info = alc_ch_mode_info, 14937 .get = alc_ch_mode_get, 14938 .put = alc_ch_mode_put, 14939 .private_value = ARRAY_SIZE(alc861_asus_modes), 14940 }, 14941 { } 14942}; 14943 14944/* additional mixer */ 14945static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = { 14946 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), 14947 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), 14948 { } 14949}; 14950 14951/* 14952 * generic initialization of ADC, input mixers and output mixers 14953 */ 14954static struct hda_verb alc861_base_init_verbs[] = { 14955 /* 14956 * Unmute ADC0 and set the default input to mic-in 14957 */ 14958 /* port-A for surround (rear panel) */ 14959 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 14960 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 }, 14961 /* port-B for mic-in (rear panel) with vref */ 14962 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 14963 /* port-C for line-in (rear panel) */ 14964 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 14965 /* port-D for Front */ 14966 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 14967 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 }, 14968 /* port-E for HP out (front panel) */ 14969 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, 14970 /* route front PCM to HP */ 14971 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, 14972 /* port-F for mic-in (front panel) with vref */ 14973 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 14974 /* port-G for CLFE (rear panel) */ 14975 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 14976 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 }, 14977 /* port-H for side (rear panel) */ 14978 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 14979 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 }, 14980 /* CD-in */ 14981 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 14982 /* route front mic to ADC1*/ 14983 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 14984 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14985 14986 /* Unmute DAC0~3 & spdif out*/ 14987 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 14988 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 14989 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 14990 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 14991 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 14992 14993 /* Unmute Mixer 14 (mic) 1c (Line in)*/ 14994 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14995 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 14996 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14997 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 14998 14999 /* Unmute Stereo Mixer 15 */ 15000 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15001 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15002 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 15003 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */ 15004 15005 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15006 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15007 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15008 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15009 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15010 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15011 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15012 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15013 /* hp used DAC 3 (Front) */ 15014 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 15015 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 15016 15017 { } 15018}; 15019 15020static struct hda_verb alc861_threestack_init_verbs[] = { 15021 /* 15022 * Unmute ADC0 and set the default input to mic-in 15023 */ 15024 /* port-A for surround (rear panel) */ 15025 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 15026 /* port-B for mic-in (rear panel) with vref */ 15027 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15028 /* port-C for line-in (rear panel) */ 15029 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 15030 /* port-D for Front */ 15031 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15032 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15033 /* port-E for HP out (front panel) */ 15034 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, 15035 /* route front PCM to HP */ 15036 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15037 /* port-F for mic-in (front panel) with vref */ 15038 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15039 /* port-G for CLFE (rear panel) */ 15040 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 15041 /* port-H for side (rear panel) */ 15042 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 15043 /* CD-in */ 15044 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 15045 /* route front mic to ADC1*/ 15046 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 15047 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15048 /* Unmute DAC0~3 & spdif out*/ 15049 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15050 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15051 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15052 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15053 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15054 15055 /* Unmute Mixer 14 (mic) 1c (Line in)*/ 15056 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15057 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15058 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15059 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15060 15061 /* Unmute Stereo Mixer 15 */ 15062 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15063 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15064 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 15065 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */ 15066 15067 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15068 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15069 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15070 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15071 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15072 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15073 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15074 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15075 /* hp used DAC 3 (Front) */ 15076 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 15077 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 15078 { } 15079}; 15080 15081static struct hda_verb alc861_uniwill_m31_init_verbs[] = { 15082 /* 15083 * Unmute ADC0 and set the default input to mic-in 15084 */ 15085 /* port-A for surround (rear panel) */ 15086 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 15087 /* port-B for mic-in (rear panel) with vref */ 15088 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15089 /* port-C for line-in (rear panel) */ 15090 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 15091 /* port-D for Front */ 15092 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15093 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15094 /* port-E for HP out (front panel) */ 15095 /* this has to be set to VREF80 */ 15096 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15097 /* route front PCM to HP */ 15098 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15099 /* port-F for mic-in (front panel) with vref */ 15100 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15101 /* port-G for CLFE (rear panel) */ 15102 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 15103 /* port-H for side (rear panel) */ 15104 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 15105 /* CD-in */ 15106 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 15107 /* route front mic to ADC1*/ 15108 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 15109 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15110 /* Unmute DAC0~3 & spdif out*/ 15111 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15112 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15113 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15114 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15115 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15116 15117 /* Unmute Mixer 14 (mic) 1c (Line in)*/ 15118 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15119 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15120 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15121 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15122 15123 /* Unmute Stereo Mixer 15 */ 15124 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15125 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15126 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 15127 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */ 15128 15129 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15130 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15131 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15132 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15133 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15134 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15135 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15136 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15137 /* hp used DAC 3 (Front) */ 15138 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 15139 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 15140 { } 15141}; 15142 15143static struct hda_verb alc861_asus_init_verbs[] = { 15144 /* 15145 * Unmute ADC0 and set the default input to mic-in 15146 */ 15147 /* port-A for surround (rear panel) 15148 * according to codec#0 this is the HP jack 15149 */ 15150 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */ 15151 /* route front PCM to HP */ 15152 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 }, 15153 /* port-B for mic-in (rear panel) with vref */ 15154 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15155 /* port-C for line-in (rear panel) */ 15156 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 15157 /* port-D for Front */ 15158 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15159 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15160 /* port-E for HP out (front panel) */ 15161 /* this has to be set to VREF80 */ 15162 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15163 /* route front PCM to HP */ 15164 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15165 /* port-F for mic-in (front panel) with vref */ 15166 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15167 /* port-G for CLFE (rear panel) */ 15168 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15169 /* port-H for side (rear panel) */ 15170 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15171 /* CD-in */ 15172 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 15173 /* route front mic to ADC1*/ 15174 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 15175 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15176 /* Unmute DAC0~3 & spdif out*/ 15177 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15178 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15179 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15180 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15181 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15182 /* Unmute Mixer 14 (mic) 1c (Line in)*/ 15183 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15184 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15185 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15186 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15187 15188 /* Unmute Stereo Mixer 15 */ 15189 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15190 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15191 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 15192 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */ 15193 15194 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15195 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15196 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15197 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15198 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15199 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15200 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15201 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15202 /* hp used DAC 3 (Front) */ 15203 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 15204 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 15205 { } 15206}; 15207 15208/* additional init verbs for ASUS laptops */ 15209static struct hda_verb alc861_asus_laptop_init_verbs[] = { 15210 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */ 15211 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */ 15212 { } 15213}; 15214 15215/* 15216 * generic initialization of ADC, input mixers and output mixers 15217 */ 15218static struct hda_verb alc861_auto_init_verbs[] = { 15219 /* 15220 * Unmute ADC0 and set the default input to mic-in 15221 */ 15222 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */ 15223 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15224 15225 /* Unmute DAC0~3 & spdif out*/ 15226 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 15227 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 15228 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 15229 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 15230 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15231 15232 /* Unmute Mixer 14 (mic) 1c (Line in)*/ 15233 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15234 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15235 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15236 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15237 15238 /* Unmute Stereo Mixer 15 */ 15239 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15240 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15241 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 15242 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, 15243 15244 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 15245 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 15246 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 15247 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 15248 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 15249 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 15250 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 15251 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 15252 15253 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 15254 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 15255 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 15256 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 15257 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 15258 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 15259 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 15260 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 15261 15262 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */ 15263 15264 { } 15265}; 15266 15267static struct hda_verb alc861_toshiba_init_verbs[] = { 15268 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 15269 15270 { } 15271}; 15272 15273/* toggle speaker-output according to the hp-jack state */ 15274static void alc861_toshiba_automute(struct hda_codec *codec) 15275{ 15276 unsigned int present = snd_hda_jack_detect(codec, 0x0f); 15277 15278 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0, 15279 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 15280 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3, 15281 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE); 15282} 15283 15284static void alc861_toshiba_unsol_event(struct hda_codec *codec, 15285 unsigned int res) 15286{ 15287 if ((res >> 26) == ALC880_HP_EVENT) 15288 alc861_toshiba_automute(codec); 15289} 15290 15291/* pcm configuration: identical with ALC880 */ 15292#define alc861_pcm_analog_playback alc880_pcm_analog_playback 15293#define alc861_pcm_analog_capture alc880_pcm_analog_capture 15294#define alc861_pcm_digital_playback alc880_pcm_digital_playback 15295#define alc861_pcm_digital_capture alc880_pcm_digital_capture 15296 15297 15298#define ALC861_DIGOUT_NID 0x07 15299 15300static struct hda_channel_mode alc861_8ch_modes[1] = { 15301 { 8, NULL } 15302}; 15303 15304static hda_nid_t alc861_dac_nids[4] = { 15305 /* front, surround, clfe, side */ 15306 0x03, 0x06, 0x05, 0x04 15307}; 15308 15309static hda_nid_t alc660_dac_nids[3] = { 15310 /* front, clfe, surround */ 15311 0x03, 0x05, 0x06 15312}; 15313 15314static hda_nid_t alc861_adc_nids[1] = { 15315 /* ADC0-2 */ 15316 0x08, 15317}; 15318 15319static struct hda_input_mux alc861_capture_source = { 15320 .num_items = 5, 15321 .items = { 15322 { "Mic", 0x0 }, 15323 { "Front Mic", 0x3 }, 15324 { "Line", 0x1 }, 15325 { "CD", 0x4 }, 15326 { "Mixer", 0x5 }, 15327 }, 15328}; 15329 15330static hda_nid_t alc861_look_for_dac(struct hda_codec *codec, hda_nid_t pin) 15331{ 15332 struct alc_spec *spec = codec->spec; 15333 hda_nid_t mix, srcs[5]; 15334 int i, j, num; 15335 15336 if (snd_hda_get_connections(codec, pin, &mix, 1) != 1) 15337 return 0; 15338 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs)); 15339 if (num < 0) 15340 return 0; 15341 for (i = 0; i < num; i++) { 15342 unsigned int type; 15343 type = get_wcaps_type(get_wcaps(codec, srcs[i])); 15344 if (type != AC_WID_AUD_OUT) 15345 continue; 15346 for (j = 0; j < spec->multiout.num_dacs; j++) 15347 if (spec->multiout.dac_nids[j] == srcs[i]) 15348 break; 15349 if (j >= spec->multiout.num_dacs) 15350 return srcs[i]; 15351 } 15352 return 0; 15353} 15354 15355/* fill in the dac_nids table from the parsed pin configuration */ 15356static int alc861_auto_fill_dac_nids(struct hda_codec *codec, 15357 const struct auto_pin_cfg *cfg) 15358{ 15359 struct alc_spec *spec = codec->spec; 15360 int i; 15361 hda_nid_t nid, dac; 15362 15363 spec->multiout.dac_nids = spec->private_dac_nids; 15364 for (i = 0; i < cfg->line_outs; i++) { 15365 nid = cfg->line_out_pins[i]; 15366 dac = alc861_look_for_dac(codec, nid); 15367 if (!dac) 15368 continue; 15369 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac; 15370 } 15371 return 0; 15372} 15373 15374static int alc861_create_out_sw(struct hda_codec *codec, const char *pfx, 15375 hda_nid_t nid, unsigned int chs) 15376{ 15377 return add_pb_sw_ctrl(codec->spec, ALC_CTL_WIDGET_MUTE, pfx, 15378 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT)); 15379} 15380 15381/* add playback controls from the parsed DAC table */ 15382static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec, 15383 const struct auto_pin_cfg *cfg) 15384{ 15385 struct alc_spec *spec = codec->spec; 15386 static const char *chname[4] = { 15387 "Front", "Surround", NULL /*CLFE*/, "Side" 15388 }; 15389 hda_nid_t nid; 15390 int i, err; 15391 15392 if (cfg->line_outs == 1) { 15393 const char *pfx = NULL; 15394 if (!cfg->hp_outs) 15395 pfx = "Master"; 15396 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) 15397 pfx = "Speaker"; 15398 if (pfx) { 15399 nid = spec->multiout.dac_nids[0]; 15400 return alc861_create_out_sw(codec, pfx, nid, 3); 15401 } 15402 } 15403 15404 for (i = 0; i < cfg->line_outs; i++) { 15405 nid = spec->multiout.dac_nids[i]; 15406 if (!nid) 15407 continue; 15408 if (i == 2) { 15409 /* Center/LFE */ 15410 err = alc861_create_out_sw(codec, "Center", nid, 1); 15411 if (err < 0) 15412 return err; 15413 err = alc861_create_out_sw(codec, "LFE", nid, 2); 15414 if (err < 0) 15415 return err; 15416 } else { 15417 err = alc861_create_out_sw(codec, chname[i], nid, 3); 15418 if (err < 0) 15419 return err; 15420 } 15421 } 15422 return 0; 15423} 15424 15425static int alc861_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin) 15426{ 15427 struct alc_spec *spec = codec->spec; 15428 int err; 15429 hda_nid_t nid; 15430 15431 if (!pin) 15432 return 0; 15433 15434 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) { 15435 nid = alc861_look_for_dac(codec, pin); 15436 if (nid) { 15437 err = alc861_create_out_sw(codec, "Headphone", nid, 3); 15438 if (err < 0) 15439 return err; 15440 spec->multiout.hp_nid = nid; 15441 } 15442 } 15443 return 0; 15444} 15445 15446/* create playback/capture controls for input pins */ 15447static int alc861_auto_create_input_ctls(struct hda_codec *codec, 15448 const struct auto_pin_cfg *cfg) 15449{ 15450 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x08, 0); 15451} 15452 15453static void alc861_auto_set_output_and_unmute(struct hda_codec *codec, 15454 hda_nid_t nid, 15455 int pin_type, hda_nid_t dac) 15456{ 15457 hda_nid_t mix, srcs[5]; 15458 int i, num; 15459 15460 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 15461 pin_type); 15462 snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE, 15463 AMP_OUT_UNMUTE); 15464 if (snd_hda_get_connections(codec, nid, &mix, 1) != 1) 15465 return; 15466 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs)); 15467 if (num < 0) 15468 return; 15469 for (i = 0; i < num; i++) { 15470 unsigned int mute; 15471 if (srcs[i] == dac || srcs[i] == 0x15) 15472 mute = AMP_IN_UNMUTE(i); 15473 else 15474 mute = AMP_IN_MUTE(i); 15475 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE, 15476 mute); 15477 } 15478} 15479 15480static void alc861_auto_init_multi_out(struct hda_codec *codec) 15481{ 15482 struct alc_spec *spec = codec->spec; 15483 int i; 15484 15485 for (i = 0; i < spec->autocfg.line_outs; i++) { 15486 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 15487 int pin_type = get_pin_type(spec->autocfg.line_out_type); 15488 if (nid) 15489 alc861_auto_set_output_and_unmute(codec, nid, pin_type, 15490 spec->multiout.dac_nids[i]); 15491 } 15492} 15493 15494static void alc861_auto_init_hp_out(struct hda_codec *codec) 15495{ 15496 struct alc_spec *spec = codec->spec; 15497 15498 if (spec->autocfg.hp_outs) 15499 alc861_auto_set_output_and_unmute(codec, 15500 spec->autocfg.hp_pins[0], 15501 PIN_HP, 15502 spec->multiout.hp_nid); 15503 if (spec->autocfg.speaker_outs) 15504 alc861_auto_set_output_and_unmute(codec, 15505 spec->autocfg.speaker_pins[0], 15506 PIN_OUT, 15507 spec->multiout.dac_nids[0]); 15508} 15509 15510static void alc861_auto_init_analog_input(struct hda_codec *codec) 15511{ 15512 struct alc_spec *spec = codec->spec; 15513 int i; 15514 15515 for (i = 0; i < AUTO_PIN_LAST; i++) { 15516 hda_nid_t nid = spec->autocfg.input_pins[i]; 15517 if (nid >= 0x0c && nid <= 0x11) 15518 alc_set_input_pin(codec, nid, i); 15519 } 15520} 15521 15522/* parse the BIOS configuration and set up the alc_spec */ 15523/* return 1 if successful, 0 if the proper config is not found, 15524 * or a negative error code 15525 */ 15526static int alc861_parse_auto_config(struct hda_codec *codec) 15527{ 15528 struct alc_spec *spec = codec->spec; 15529 int err; 15530 static hda_nid_t alc861_ignore[] = { 0x1d, 0 }; 15531 15532 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 15533 alc861_ignore); 15534 if (err < 0) 15535 return err; 15536 if (!spec->autocfg.line_outs) 15537 return 0; /* can't find valid BIOS pin config */ 15538 15539 err = alc861_auto_fill_dac_nids(codec, &spec->autocfg); 15540 if (err < 0) 15541 return err; 15542 err = alc861_auto_create_multi_out_ctls(codec, &spec->autocfg); 15543 if (err < 0) 15544 return err; 15545 err = alc861_auto_create_hp_ctls(codec, spec->autocfg.hp_pins[0]); 15546 if (err < 0) 15547 return err; 15548 err = alc861_auto_create_input_ctls(codec, &spec->autocfg); 15549 if (err < 0) 15550 return err; 15551 15552 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 15553 15554 alc_auto_parse_digital(codec); 15555 15556 if (spec->kctls.list) 15557 add_mixer(spec, spec->kctls.list); 15558 15559 add_verb(spec, alc861_auto_init_verbs); 15560 15561 spec->num_mux_defs = 1; 15562 spec->input_mux = &spec->private_imux[0]; 15563 15564 spec->adc_nids = alc861_adc_nids; 15565 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids); 15566 set_capture_mixer(codec); 15567 15568 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b, 0); 15569 15570 return 1; 15571} 15572 15573/* additional initialization for auto-configuration model */ 15574static void alc861_auto_init(struct hda_codec *codec) 15575{ 15576 struct alc_spec *spec = codec->spec; 15577 alc861_auto_init_multi_out(codec); 15578 alc861_auto_init_hp_out(codec); 15579 alc861_auto_init_analog_input(codec); 15580 alc_auto_init_digital(codec); 15581 if (spec->unsol_event) 15582 alc_inithook(codec); 15583} 15584 15585#ifdef CONFIG_SND_HDA_POWER_SAVE 15586static struct hda_amp_list alc861_loopbacks[] = { 15587 { 0x15, HDA_INPUT, 0 }, 15588 { 0x15, HDA_INPUT, 1 }, 15589 { 0x15, HDA_INPUT, 2 }, 15590 { 0x15, HDA_INPUT, 3 }, 15591 { } /* end */ 15592}; 15593#endif 15594 15595 15596/* 15597 * configuration and preset 15598 */ 15599static const char *alc861_models[ALC861_MODEL_LAST] = { 15600 [ALC861_3ST] = "3stack", 15601 [ALC660_3ST] = "3stack-660", 15602 [ALC861_3ST_DIG] = "3stack-dig", 15603 [ALC861_6ST_DIG] = "6stack-dig", 15604 [ALC861_UNIWILL_M31] = "uniwill-m31", 15605 [ALC861_TOSHIBA] = "toshiba", 15606 [ALC861_ASUS] = "asus", 15607 [ALC861_ASUS_LAPTOP] = "asus-laptop", 15608 [ALC861_AUTO] = "auto", 15609}; 15610 15611static struct snd_pci_quirk alc861_cfg_tbl[] = { 15612 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST), 15613 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP), 15614 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP), 15615 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS), 15616 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP), 15617 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG), 15618 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA), 15619 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!) 15620 * Any other models that need this preset? 15621 */ 15622 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */ 15623 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST), 15624 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST), 15625 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31), 15626 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31), 15627 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP), 15628 /* FIXME: the below seems conflict */ 15629 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */ 15630 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST), 15631 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST), 15632 {} 15633}; 15634 15635static struct alc_config_preset alc861_presets[] = { 15636 [ALC861_3ST] = { 15637 .mixers = { alc861_3ST_mixer }, 15638 .init_verbs = { alc861_threestack_init_verbs }, 15639 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 15640 .dac_nids = alc861_dac_nids, 15641 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes), 15642 .channel_mode = alc861_threestack_modes, 15643 .need_dac_fix = 1, 15644 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 15645 .adc_nids = alc861_adc_nids, 15646 .input_mux = &alc861_capture_source, 15647 }, 15648 [ALC861_3ST_DIG] = { 15649 .mixers = { alc861_base_mixer }, 15650 .init_verbs = { alc861_threestack_init_verbs }, 15651 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 15652 .dac_nids = alc861_dac_nids, 15653 .dig_out_nid = ALC861_DIGOUT_NID, 15654 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes), 15655 .channel_mode = alc861_threestack_modes, 15656 .need_dac_fix = 1, 15657 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 15658 .adc_nids = alc861_adc_nids, 15659 .input_mux = &alc861_capture_source, 15660 }, 15661 [ALC861_6ST_DIG] = { 15662 .mixers = { alc861_base_mixer }, 15663 .init_verbs = { alc861_base_init_verbs }, 15664 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 15665 .dac_nids = alc861_dac_nids, 15666 .dig_out_nid = ALC861_DIGOUT_NID, 15667 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes), 15668 .channel_mode = alc861_8ch_modes, 15669 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 15670 .adc_nids = alc861_adc_nids, 15671 .input_mux = &alc861_capture_source, 15672 }, 15673 [ALC660_3ST] = { 15674 .mixers = { alc861_3ST_mixer }, 15675 .init_verbs = { alc861_threestack_init_verbs }, 15676 .num_dacs = ARRAY_SIZE(alc660_dac_nids), 15677 .dac_nids = alc660_dac_nids, 15678 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes), 15679 .channel_mode = alc861_threestack_modes, 15680 .need_dac_fix = 1, 15681 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 15682 .adc_nids = alc861_adc_nids, 15683 .input_mux = &alc861_capture_source, 15684 }, 15685 [ALC861_UNIWILL_M31] = { 15686 .mixers = { alc861_uniwill_m31_mixer }, 15687 .init_verbs = { alc861_uniwill_m31_init_verbs }, 15688 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 15689 .dac_nids = alc861_dac_nids, 15690 .dig_out_nid = ALC861_DIGOUT_NID, 15691 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes), 15692 .channel_mode = alc861_uniwill_m31_modes, 15693 .need_dac_fix = 1, 15694 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 15695 .adc_nids = alc861_adc_nids, 15696 .input_mux = &alc861_capture_source, 15697 }, 15698 [ALC861_TOSHIBA] = { 15699 .mixers = { alc861_toshiba_mixer }, 15700 .init_verbs = { alc861_base_init_verbs, 15701 alc861_toshiba_init_verbs }, 15702 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 15703 .dac_nids = alc861_dac_nids, 15704 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 15705 .channel_mode = alc883_3ST_2ch_modes, 15706 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 15707 .adc_nids = alc861_adc_nids, 15708 .input_mux = &alc861_capture_source, 15709 .unsol_event = alc861_toshiba_unsol_event, 15710 .init_hook = alc861_toshiba_automute, 15711 }, 15712 [ALC861_ASUS] = { 15713 .mixers = { alc861_asus_mixer }, 15714 .init_verbs = { alc861_asus_init_verbs }, 15715 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 15716 .dac_nids = alc861_dac_nids, 15717 .dig_out_nid = ALC861_DIGOUT_NID, 15718 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes), 15719 .channel_mode = alc861_asus_modes, 15720 .need_dac_fix = 1, 15721 .hp_nid = 0x06, 15722 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 15723 .adc_nids = alc861_adc_nids, 15724 .input_mux = &alc861_capture_source, 15725 }, 15726 [ALC861_ASUS_LAPTOP] = { 15727 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer }, 15728 .init_verbs = { alc861_asus_init_verbs, 15729 alc861_asus_laptop_init_verbs }, 15730 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 15731 .dac_nids = alc861_dac_nids, 15732 .dig_out_nid = ALC861_DIGOUT_NID, 15733 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 15734 .channel_mode = alc883_3ST_2ch_modes, 15735 .need_dac_fix = 1, 15736 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 15737 .adc_nids = alc861_adc_nids, 15738 .input_mux = &alc861_capture_source, 15739 }, 15740}; 15741 15742/* Pin config fixes */ 15743enum { 15744 PINFIX_FSC_AMILO_PI1505, 15745}; 15746 15747static struct alc_pincfg alc861_fsc_amilo_pi1505_pinfix[] = { 15748 { 0x0b, 0x0221101f }, /* HP */ 15749 { 0x0f, 0x90170310 }, /* speaker */ 15750 { } 15751}; 15752 15753static const struct alc_fixup alc861_fixups[] = { 15754 [PINFIX_FSC_AMILO_PI1505] = { 15755 .pins = alc861_fsc_amilo_pi1505_pinfix 15756 }, 15757}; 15758 15759static struct snd_pci_quirk alc861_fixup_tbl[] = { 15760 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505), 15761 {} 15762}; 15763 15764static int patch_alc861(struct hda_codec *codec) 15765{ 15766 struct alc_spec *spec; 15767 int board_config; 15768 int err; 15769 15770 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 15771 if (spec == NULL) 15772 return -ENOMEM; 15773 15774 codec->spec = spec; 15775 15776 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST, 15777 alc861_models, 15778 alc861_cfg_tbl); 15779 15780 if (board_config < 0) { 15781 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 15782 codec->chip_name); 15783 board_config = ALC861_AUTO; 15784 } 15785 15786 if (board_config == ALC861_AUTO) 15787 alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups, 1); 15788 15789 if (board_config == ALC861_AUTO) { 15790 /* automatic parse from the BIOS config */ 15791 err = alc861_parse_auto_config(codec); 15792 if (err < 0) { 15793 alc_free(codec); 15794 return err; 15795 } else if (!err) { 15796 printk(KERN_INFO 15797 "hda_codec: Cannot set up configuration " 15798 "from BIOS. Using base mode...\n"); 15799 board_config = ALC861_3ST_DIG; 15800 } 15801 } 15802 15803 err = snd_hda_attach_beep_device(codec, 0x23); 15804 if (err < 0) { 15805 alc_free(codec); 15806 return err; 15807 } 15808 15809 if (board_config != ALC861_AUTO) 15810 setup_preset(codec, &alc861_presets[board_config]); 15811 15812 spec->stream_analog_playback = &alc861_pcm_analog_playback; 15813 spec->stream_analog_capture = &alc861_pcm_analog_capture; 15814 15815 spec->stream_digital_playback = &alc861_pcm_digital_playback; 15816 spec->stream_digital_capture = &alc861_pcm_digital_capture; 15817 15818 if (!spec->cap_mixer) 15819 set_capture_mixer(codec); 15820 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT); 15821 15822 spec->vmaster_nid = 0x03; 15823 15824 if (board_config == ALC861_AUTO) 15825 alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups, 0); 15826 15827 codec->patch_ops = alc_patch_ops; 15828 if (board_config == ALC861_AUTO) { 15829 spec->init_hook = alc861_auto_init; 15830#ifdef CONFIG_SND_HDA_POWER_SAVE 15831 spec->power_hook = alc_power_eapd; 15832#endif 15833 } 15834#ifdef CONFIG_SND_HDA_POWER_SAVE 15835 if (!spec->loopback.amplist) 15836 spec->loopback.amplist = alc861_loopbacks; 15837#endif 15838 15839 return 0; 15840} 15841 15842/* 15843 * ALC861-VD support 15844 * 15845 * Based on ALC882 15846 * 15847 * In addition, an independent DAC 15848 */ 15849#define ALC861VD_DIGOUT_NID 0x06 15850 15851static hda_nid_t alc861vd_dac_nids[4] = { 15852 /* front, surr, clfe, side surr */ 15853 0x02, 0x03, 0x04, 0x05 15854}; 15855 15856/* dac_nids for ALC660vd are in a different order - according to 15857 * Realtek's driver. 15858 * This should probably result in a different mixer for 6stack models 15859 * of ALC660vd codecs, but for now there is only 3stack mixer 15860 * - and it is the same as in 861vd. 15861 * adc_nids in ALC660vd are (is) the same as in 861vd 15862 */ 15863static hda_nid_t alc660vd_dac_nids[3] = { 15864 /* front, rear, clfe, rear_surr */ 15865 0x02, 0x04, 0x03 15866}; 15867 15868static hda_nid_t alc861vd_adc_nids[1] = { 15869 /* ADC0 */ 15870 0x09, 15871}; 15872 15873static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 }; 15874 15875/* input MUX */ 15876/* FIXME: should be a matrix-type input source selection */ 15877static struct hda_input_mux alc861vd_capture_source = { 15878 .num_items = 4, 15879 .items = { 15880 { "Mic", 0x0 }, 15881 { "Front Mic", 0x1 }, 15882 { "Line", 0x2 }, 15883 { "CD", 0x4 }, 15884 }, 15885}; 15886 15887static struct hda_input_mux alc861vd_dallas_capture_source = { 15888 .num_items = 2, 15889 .items = { 15890 { "Ext Mic", 0x0 }, 15891 { "Int Mic", 0x1 }, 15892 }, 15893}; 15894 15895static struct hda_input_mux alc861vd_hp_capture_source = { 15896 .num_items = 2, 15897 .items = { 15898 { "Front Mic", 0x0 }, 15899 { "ATAPI Mic", 0x1 }, 15900 }, 15901}; 15902 15903/* 15904 * 2ch mode 15905 */ 15906static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = { 15907 { 2, NULL } 15908}; 15909 15910/* 15911 * 6ch mode 15912 */ 15913static struct hda_verb alc861vd_6stack_ch6_init[] = { 15914 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 15915 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 15916 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 15917 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 15918 { } /* end */ 15919}; 15920 15921/* 15922 * 8ch mode 15923 */ 15924static struct hda_verb alc861vd_6stack_ch8_init[] = { 15925 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 15926 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 15927 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 15928 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 15929 { } /* end */ 15930}; 15931 15932static struct hda_channel_mode alc861vd_6stack_modes[2] = { 15933 { 6, alc861vd_6stack_ch6_init }, 15934 { 8, alc861vd_6stack_ch8_init }, 15935}; 15936 15937static struct snd_kcontrol_new alc861vd_chmode_mixer[] = { 15938 { 15939 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 15940 .name = "Channel Mode", 15941 .info = alc_ch_mode_info, 15942 .get = alc_ch_mode_get, 15943 .put = alc_ch_mode_put, 15944 }, 15945 { } /* end */ 15946}; 15947 15948/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 15949 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b 15950 */ 15951static struct snd_kcontrol_new alc861vd_6st_mixer[] = { 15952 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 15953 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 15954 15955 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT), 15956 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 15957 15958 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, 15959 HDA_OUTPUT), 15960 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, 15961 HDA_OUTPUT), 15962 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 15963 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 15964 15965 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT), 15966 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 15967 15968 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 15969 15970 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 15971 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 15972 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 15973 15974 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 15975 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 15976 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 15977 15978 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 15979 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 15980 15981 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 15982 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 15983 15984 { } /* end */ 15985}; 15986 15987static struct snd_kcontrol_new alc861vd_3st_mixer[] = { 15988 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 15989 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 15990 15991 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 15992 15993 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 15994 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 15995 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 15996 15997 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 15998 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 15999 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 16000 16001 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 16002 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 16003 16004 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 16005 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 16006 16007 { } /* end */ 16008}; 16009 16010static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = { 16011 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 16012 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/ 16013 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 16014 16015 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 16016 16017 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 16018 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 16019 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 16020 16021 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 16022 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 16023 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 16024 16025 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 16026 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 16027 16028 { } /* end */ 16029}; 16030 16031/* Pin assignment: Speaker=0x14, HP = 0x15, 16032 * Ext Mic=0x18, Int Mic = 0x19, CD = 0x1c, PC Beep = 0x1d 16033 */ 16034static struct snd_kcontrol_new alc861vd_dallas_mixer[] = { 16035 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 16036 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT), 16037 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 16038 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT), 16039 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT), 16040 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 16041 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 16042 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 16043 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 16044 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 16045 { } /* end */ 16046}; 16047 16048/* Pin assignment: Speaker=0x14, Line-out = 0x15, 16049 * Front Mic=0x18, ATAPI Mic = 0x19, 16050 */ 16051static struct snd_kcontrol_new alc861vd_hp_mixer[] = { 16052 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 16053 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 16054 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 16055 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT), 16056 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 16057 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 16058 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 16059 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 16060 16061 { } /* end */ 16062}; 16063 16064/* 16065 * generic initialization of ADC, input mixers and output mixers 16066 */ 16067static struct hda_verb alc861vd_volume_init_verbs[] = { 16068 /* 16069 * Unmute ADC0 and set the default input to mic-in 16070 */ 16071 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 16072 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 16073 16074 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of 16075 * the analog-loopback mixer widget 16076 */ 16077 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 16078 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 16079 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 16080 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 16081 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 16082 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 16083 16084 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */ 16085 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 16086 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 16087 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 16088 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, 16089 16090 /* 16091 * Set up output mixers (0x02 - 0x05) 16092 */ 16093 /* set vol=0 to output mixers */ 16094 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 16095 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 16096 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 16097 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 16098 16099 /* set up input amps for analog loopback */ 16100 /* Amp Indices: DAC = 0, mixer = 1 */ 16101 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 16102 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 16103 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 16104 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 16105 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 16106 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 16107 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 16108 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 16109 16110 { } 16111}; 16112 16113/* 16114 * 3-stack pin configuration: 16115 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b 16116 */ 16117static struct hda_verb alc861vd_3stack_init_verbs[] = { 16118 /* 16119 * Set pin mode and muting 16120 */ 16121 /* set front pin widgets 0x14 for output */ 16122 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 16123 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 16124 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 16125 16126 /* Mic (rear) pin: input vref at 80% */ 16127 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 16128 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 16129 /* Front Mic pin: input vref at 80% */ 16130 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 16131 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 16132 /* Line In pin: input */ 16133 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 16134 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 16135 /* Line-2 In: Headphone output (output 0 - 0x0c) */ 16136 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 16137 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 16138 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 16139 /* CD pin widget for input */ 16140 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 16141 16142 { } 16143}; 16144 16145/* 16146 * 6-stack pin configuration: 16147 */ 16148static struct hda_verb alc861vd_6stack_init_verbs[] = { 16149 /* 16150 * Set pin mode and muting 16151 */ 16152 /* set front pin widgets 0x14 for output */ 16153 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 16154 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 16155 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 16156 16157 /* Rear Pin: output 1 (0x0d) */ 16158 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 16159 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 16160 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 16161 /* CLFE Pin: output 2 (0x0e) */ 16162 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 16163 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 16164 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, 16165 /* Side Pin: output 3 (0x0f) */ 16166 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 16167 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 16168 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, 16169 16170 /* Mic (rear) pin: input vref at 80% */ 16171 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 16172 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 16173 /* Front Mic pin: input vref at 80% */ 16174 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 16175 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 16176 /* Line In pin: input */ 16177 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 16178 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 16179 /* Line-2 In: Headphone output (output 0 - 0x0c) */ 16180 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 16181 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 16182 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 16183 /* CD pin widget for input */ 16184 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 16185 16186 { } 16187}; 16188 16189static struct hda_verb alc861vd_eapd_verbs[] = { 16190 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 16191 { } 16192}; 16193 16194static struct hda_verb alc660vd_eapd_verbs[] = { 16195 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 16196 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, 16197 { } 16198}; 16199 16200static struct hda_verb alc861vd_lenovo_unsol_verbs[] = { 16201 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 16202 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 16203 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, 16204 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 16205 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 16206 {} 16207}; 16208 16209static void alc861vd_lenovo_mic_automute(struct hda_codec *codec) 16210{ 16211 unsigned int present; 16212 unsigned char bits; 16213 16214 present = snd_hda_jack_detect(codec, 0x18); 16215 bits = present ? HDA_AMP_MUTE : 0; 16216 16217 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, 16218 HDA_AMP_MUTE, bits); 16219} 16220 16221static void alc861vd_lenovo_setup(struct hda_codec *codec) 16222{ 16223 struct alc_spec *spec = codec->spec; 16224 spec->autocfg.hp_pins[0] = 0x1b; 16225 spec->autocfg.speaker_pins[0] = 0x14; 16226} 16227 16228static void alc861vd_lenovo_init_hook(struct hda_codec *codec) 16229{ 16230 alc_automute_amp(codec); 16231 alc861vd_lenovo_mic_automute(codec); 16232} 16233 16234static void alc861vd_lenovo_unsol_event(struct hda_codec *codec, 16235 unsigned int res) 16236{ 16237 switch (res >> 26) { 16238 case ALC880_MIC_EVENT: 16239 alc861vd_lenovo_mic_automute(codec); 16240 break; 16241 default: 16242 alc_automute_amp_unsol_event(codec, res); 16243 break; 16244 } 16245} 16246 16247static struct hda_verb alc861vd_dallas_verbs[] = { 16248 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 16249 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 16250 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 16251 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 16252 16253 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 16254 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 16255 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 16256 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 16257 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 16258 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 16259 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 16260 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 16261 16262 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 16263 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 16264 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 16265 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 16266 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 16267 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 16268 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 16269 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 16270 16271 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, 16272 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 16273 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, 16274 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 16275 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 16276 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 16277 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 16278 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 16279 16280 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 16281 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 16282 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 16283 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 16284 16285 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 16286 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 16287 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 16288 16289 { } /* end */ 16290}; 16291 16292/* toggle speaker-output according to the hp-jack state */ 16293static void alc861vd_dallas_setup(struct hda_codec *codec) 16294{ 16295 struct alc_spec *spec = codec->spec; 16296 16297 spec->autocfg.hp_pins[0] = 0x15; 16298 spec->autocfg.speaker_pins[0] = 0x14; 16299} 16300 16301#ifdef CONFIG_SND_HDA_POWER_SAVE 16302#define alc861vd_loopbacks alc880_loopbacks 16303#endif 16304 16305/* pcm configuration: identical with ALC880 */ 16306#define alc861vd_pcm_analog_playback alc880_pcm_analog_playback 16307#define alc861vd_pcm_analog_capture alc880_pcm_analog_capture 16308#define alc861vd_pcm_digital_playback alc880_pcm_digital_playback 16309#define alc861vd_pcm_digital_capture alc880_pcm_digital_capture 16310 16311/* 16312 * configuration and preset 16313 */ 16314static const char *alc861vd_models[ALC861VD_MODEL_LAST] = { 16315 [ALC660VD_3ST] = "3stack-660", 16316 [ALC660VD_3ST_DIG] = "3stack-660-digout", 16317 [ALC660VD_ASUS_V1S] = "asus-v1s", 16318 [ALC861VD_3ST] = "3stack", 16319 [ALC861VD_3ST_DIG] = "3stack-digout", 16320 [ALC861VD_6ST_DIG] = "6stack-digout", 16321 [ALC861VD_LENOVO] = "lenovo", 16322 [ALC861VD_DALLAS] = "dallas", 16323 [ALC861VD_HP] = "hp", 16324 [ALC861VD_AUTO] = "auto", 16325}; 16326 16327static struct snd_pci_quirk alc861vd_cfg_tbl[] = { 16328 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST), 16329 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP), 16330 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST), 16331 /*SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),*/ /* auto */ 16332 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S), 16333 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG), 16334 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST), 16335 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO), 16336 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/ 16337 SND_PCI_QUIRK(0x1179, 0xff01, "Toshiba A135", ALC861VD_LENOVO), 16338 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO), 16339 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS), 16340 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG), 16341 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO), 16342 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG), 16343 {} 16344}; 16345 16346static struct alc_config_preset alc861vd_presets[] = { 16347 [ALC660VD_3ST] = { 16348 .mixers = { alc861vd_3st_mixer }, 16349 .init_verbs = { alc861vd_volume_init_verbs, 16350 alc861vd_3stack_init_verbs }, 16351 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids), 16352 .dac_nids = alc660vd_dac_nids, 16353 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 16354 .channel_mode = alc861vd_3stack_2ch_modes, 16355 .input_mux = &alc861vd_capture_source, 16356 }, 16357 [ALC660VD_3ST_DIG] = { 16358 .mixers = { alc861vd_3st_mixer }, 16359 .init_verbs = { alc861vd_volume_init_verbs, 16360 alc861vd_3stack_init_verbs }, 16361 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids), 16362 .dac_nids = alc660vd_dac_nids, 16363 .dig_out_nid = ALC861VD_DIGOUT_NID, 16364 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 16365 .channel_mode = alc861vd_3stack_2ch_modes, 16366 .input_mux = &alc861vd_capture_source, 16367 }, 16368 [ALC861VD_3ST] = { 16369 .mixers = { alc861vd_3st_mixer }, 16370 .init_verbs = { alc861vd_volume_init_verbs, 16371 alc861vd_3stack_init_verbs }, 16372 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids), 16373 .dac_nids = alc861vd_dac_nids, 16374 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 16375 .channel_mode = alc861vd_3stack_2ch_modes, 16376 .input_mux = &alc861vd_capture_source, 16377 }, 16378 [ALC861VD_3ST_DIG] = { 16379 .mixers = { alc861vd_3st_mixer }, 16380 .init_verbs = { alc861vd_volume_init_verbs, 16381 alc861vd_3stack_init_verbs }, 16382 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids), 16383 .dac_nids = alc861vd_dac_nids, 16384 .dig_out_nid = ALC861VD_DIGOUT_NID, 16385 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 16386 .channel_mode = alc861vd_3stack_2ch_modes, 16387 .input_mux = &alc861vd_capture_source, 16388 }, 16389 [ALC861VD_6ST_DIG] = { 16390 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer }, 16391 .init_verbs = { alc861vd_volume_init_verbs, 16392 alc861vd_6stack_init_verbs }, 16393 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids), 16394 .dac_nids = alc861vd_dac_nids, 16395 .dig_out_nid = ALC861VD_DIGOUT_NID, 16396 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes), 16397 .channel_mode = alc861vd_6stack_modes, 16398 .input_mux = &alc861vd_capture_source, 16399 }, 16400 [ALC861VD_LENOVO] = { 16401 .mixers = { alc861vd_lenovo_mixer }, 16402 .init_verbs = { alc861vd_volume_init_verbs, 16403 alc861vd_3stack_init_verbs, 16404 alc861vd_eapd_verbs, 16405 alc861vd_lenovo_unsol_verbs }, 16406 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids), 16407 .dac_nids = alc660vd_dac_nids, 16408 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 16409 .channel_mode = alc861vd_3stack_2ch_modes, 16410 .input_mux = &alc861vd_capture_source, 16411 .unsol_event = alc861vd_lenovo_unsol_event, 16412 .setup = alc861vd_lenovo_setup, 16413 .init_hook = alc861vd_lenovo_init_hook, 16414 }, 16415 [ALC861VD_DALLAS] = { 16416 .mixers = { alc861vd_dallas_mixer }, 16417 .init_verbs = { alc861vd_dallas_verbs }, 16418 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids), 16419 .dac_nids = alc861vd_dac_nids, 16420 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 16421 .channel_mode = alc861vd_3stack_2ch_modes, 16422 .input_mux = &alc861vd_dallas_capture_source, 16423 .unsol_event = alc_automute_amp_unsol_event, 16424 .setup = alc861vd_dallas_setup, 16425 .init_hook = alc_automute_amp, 16426 }, 16427 [ALC861VD_HP] = { 16428 .mixers = { alc861vd_hp_mixer }, 16429 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs }, 16430 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids), 16431 .dac_nids = alc861vd_dac_nids, 16432 .dig_out_nid = ALC861VD_DIGOUT_NID, 16433 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 16434 .channel_mode = alc861vd_3stack_2ch_modes, 16435 .input_mux = &alc861vd_hp_capture_source, 16436 .unsol_event = alc_automute_amp_unsol_event, 16437 .setup = alc861vd_dallas_setup, 16438 .init_hook = alc_automute_amp, 16439 }, 16440 [ALC660VD_ASUS_V1S] = { 16441 .mixers = { alc861vd_lenovo_mixer }, 16442 .init_verbs = { alc861vd_volume_init_verbs, 16443 alc861vd_3stack_init_verbs, 16444 alc861vd_eapd_verbs, 16445 alc861vd_lenovo_unsol_verbs }, 16446 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids), 16447 .dac_nids = alc660vd_dac_nids, 16448 .dig_out_nid = ALC861VD_DIGOUT_NID, 16449 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 16450 .channel_mode = alc861vd_3stack_2ch_modes, 16451 .input_mux = &alc861vd_capture_source, 16452 .unsol_event = alc861vd_lenovo_unsol_event, 16453 .setup = alc861vd_lenovo_setup, 16454 .init_hook = alc861vd_lenovo_init_hook, 16455 }, 16456}; 16457 16458/* 16459 * BIOS auto configuration 16460 */ 16461static int alc861vd_auto_create_input_ctls(struct hda_codec *codec, 16462 const struct auto_pin_cfg *cfg) 16463{ 16464 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x09, 0); 16465} 16466 16467 16468static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec, 16469 hda_nid_t nid, int pin_type, int dac_idx) 16470{ 16471 alc_set_pin_output(codec, nid, pin_type); 16472} 16473 16474static void alc861vd_auto_init_multi_out(struct hda_codec *codec) 16475{ 16476 struct alc_spec *spec = codec->spec; 16477 int i; 16478 16479 for (i = 0; i <= HDA_SIDE; i++) { 16480 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 16481 int pin_type = get_pin_type(spec->autocfg.line_out_type); 16482 if (nid) 16483 alc861vd_auto_set_output_and_unmute(codec, nid, 16484 pin_type, i); 16485 } 16486} 16487 16488 16489static void alc861vd_auto_init_hp_out(struct hda_codec *codec) 16490{ 16491 struct alc_spec *spec = codec->spec; 16492 hda_nid_t pin; 16493 16494 pin = spec->autocfg.hp_pins[0]; 16495 if (pin) /* connect to front and use dac 0 */ 16496 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); 16497 pin = spec->autocfg.speaker_pins[0]; 16498 if (pin) 16499 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0); 16500} 16501 16502#define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID 16503 16504static void alc861vd_auto_init_analog_input(struct hda_codec *codec) 16505{ 16506 struct alc_spec *spec = codec->spec; 16507 int i; 16508 16509 for (i = 0; i < AUTO_PIN_LAST; i++) { 16510 hda_nid_t nid = spec->autocfg.input_pins[i]; 16511 if (alc_is_input_pin(codec, nid)) { 16512 alc_set_input_pin(codec, nid, i); 16513 if (nid != ALC861VD_PIN_CD_NID && 16514 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)) 16515 snd_hda_codec_write(codec, nid, 0, 16516 AC_VERB_SET_AMP_GAIN_MUTE, 16517 AMP_OUT_MUTE); 16518 } 16519 } 16520} 16521 16522#define alc861vd_auto_init_input_src alc882_auto_init_input_src 16523 16524#define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02) 16525#define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c) 16526 16527/* add playback controls from the parsed DAC table */ 16528/* Based on ALC880 version. But ALC861VD has separate, 16529 * different NIDs for mute/unmute switch and volume control */ 16530static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec, 16531 const struct auto_pin_cfg *cfg) 16532{ 16533 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"}; 16534 hda_nid_t nid_v, nid_s; 16535 int i, err; 16536 16537 for (i = 0; i < cfg->line_outs; i++) { 16538 if (!spec->multiout.dac_nids[i]) 16539 continue; 16540 nid_v = alc861vd_idx_to_mixer_vol( 16541 alc880_dac_to_idx( 16542 spec->multiout.dac_nids[i])); 16543 nid_s = alc861vd_idx_to_mixer_switch( 16544 alc880_dac_to_idx( 16545 spec->multiout.dac_nids[i])); 16546 16547 if (i == 2) { 16548 /* Center/LFE */ 16549 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, 16550 "Center", 16551 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0, 16552 HDA_OUTPUT)); 16553 if (err < 0) 16554 return err; 16555 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, 16556 "LFE", 16557 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0, 16558 HDA_OUTPUT)); 16559 if (err < 0) 16560 return err; 16561 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, 16562 "Center", 16563 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2, 16564 HDA_INPUT)); 16565 if (err < 0) 16566 return err; 16567 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, 16568 "LFE", 16569 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2, 16570 HDA_INPUT)); 16571 if (err < 0) 16572 return err; 16573 } else { 16574 const char *pfx; 16575 if (cfg->line_outs == 1 && 16576 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) { 16577 if (!cfg->hp_pins) 16578 pfx = "Speaker"; 16579 else 16580 pfx = "PCM"; 16581 } else 16582 pfx = chname[i]; 16583 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, 16584 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, 16585 HDA_OUTPUT)); 16586 if (err < 0) 16587 return err; 16588 if (cfg->line_outs == 1 && 16589 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) 16590 pfx = "Speaker"; 16591 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx, 16592 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, 16593 HDA_INPUT)); 16594 if (err < 0) 16595 return err; 16596 } 16597 } 16598 return 0; 16599} 16600 16601/* add playback controls for speaker and HP outputs */ 16602/* Based on ALC880 version. But ALC861VD has separate, 16603 * different NIDs for mute/unmute switch and volume control */ 16604static int alc861vd_auto_create_extra_out(struct alc_spec *spec, 16605 hda_nid_t pin, const char *pfx) 16606{ 16607 hda_nid_t nid_v, nid_s; 16608 int err; 16609 16610 if (!pin) 16611 return 0; 16612 16613 if (alc880_is_fixed_pin(pin)) { 16614 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); 16615 /* specify the DAC as the extra output */ 16616 if (!spec->multiout.hp_nid) 16617 spec->multiout.hp_nid = nid_v; 16618 else 16619 spec->multiout.extra_out_nid[0] = nid_v; 16620 /* control HP volume/switch on the output mixer amp */ 16621 nid_v = alc861vd_idx_to_mixer_vol( 16622 alc880_fixed_pin_idx(pin)); 16623 nid_s = alc861vd_idx_to_mixer_switch( 16624 alc880_fixed_pin_idx(pin)); 16625 16626 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, 16627 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT)); 16628 if (err < 0) 16629 return err; 16630 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx, 16631 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT)); 16632 if (err < 0) 16633 return err; 16634 } else if (alc880_is_multi_pin(pin)) { 16635 /* set manual connection */ 16636 /* we have only a switch on HP-out PIN */ 16637 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, 16638 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); 16639 if (err < 0) 16640 return err; 16641 } 16642 return 0; 16643} 16644 16645/* parse the BIOS configuration and set up the alc_spec 16646 * return 1 if successful, 0 if the proper config is not found, 16647 * or a negative error code 16648 * Based on ALC880 version - had to change it to override 16649 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */ 16650static int alc861vd_parse_auto_config(struct hda_codec *codec) 16651{ 16652 struct alc_spec *spec = codec->spec; 16653 int err; 16654 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 }; 16655 16656 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 16657 alc861vd_ignore); 16658 if (err < 0) 16659 return err; 16660 if (!spec->autocfg.line_outs) 16661 return 0; /* can't find valid BIOS pin config */ 16662 16663 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); 16664 if (err < 0) 16665 return err; 16666 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg); 16667 if (err < 0) 16668 return err; 16669 err = alc861vd_auto_create_extra_out(spec, 16670 spec->autocfg.speaker_pins[0], 16671 "Speaker"); 16672 if (err < 0) 16673 return err; 16674 err = alc861vd_auto_create_extra_out(spec, 16675 spec->autocfg.hp_pins[0], 16676 "Headphone"); 16677 if (err < 0) 16678 return err; 16679 err = alc861vd_auto_create_input_ctls(codec, &spec->autocfg); 16680 if (err < 0) 16681 return err; 16682 16683 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 16684 16685 alc_auto_parse_digital(codec); 16686 16687 if (spec->kctls.list) 16688 add_mixer(spec, spec->kctls.list); 16689 16690 add_verb(spec, alc861vd_volume_init_verbs); 16691 16692 spec->num_mux_defs = 1; 16693 spec->input_mux = &spec->private_imux[0]; 16694 16695 err = alc_auto_add_mic_boost(codec); 16696 if (err < 0) 16697 return err; 16698 16699 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); 16700 16701 return 1; 16702} 16703 16704/* additional initialization for auto-configuration model */ 16705static void alc861vd_auto_init(struct hda_codec *codec) 16706{ 16707 struct alc_spec *spec = codec->spec; 16708 alc861vd_auto_init_multi_out(codec); 16709 alc861vd_auto_init_hp_out(codec); 16710 alc861vd_auto_init_analog_input(codec); 16711 alc861vd_auto_init_input_src(codec); 16712 alc_auto_init_digital(codec); 16713 if (spec->unsol_event) 16714 alc_inithook(codec); 16715} 16716 16717enum { 16718 ALC660VD_FIX_ASUS_GPIO1 16719}; 16720 16721/* reset GPIO1 */ 16722static const struct hda_verb alc660vd_fix_asus_gpio1_verbs[] = { 16723 {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, 16724 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, 16725 {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, 16726 { } 16727}; 16728 16729static const struct alc_fixup alc861vd_fixups[] = { 16730 [ALC660VD_FIX_ASUS_GPIO1] = { 16731 .verbs = alc660vd_fix_asus_gpio1_verbs, 16732 }, 16733}; 16734 16735static struct snd_pci_quirk alc861vd_fixup_tbl[] = { 16736 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1), 16737 {} 16738}; 16739 16740static int patch_alc861vd(struct hda_codec *codec) 16741{ 16742 struct alc_spec *spec; 16743 int err, board_config; 16744 16745 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 16746 if (spec == NULL) 16747 return -ENOMEM; 16748 16749 codec->spec = spec; 16750 16751 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST, 16752 alc861vd_models, 16753 alc861vd_cfg_tbl); 16754 16755 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) { 16756 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 16757 codec->chip_name); 16758 board_config = ALC861VD_AUTO; 16759 } 16760 16761 if (board_config == ALC861VD_AUTO) 16762 alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups, 1); 16763 16764 if (board_config == ALC861VD_AUTO) { 16765 /* automatic parse from the BIOS config */ 16766 err = alc861vd_parse_auto_config(codec); 16767 if (err < 0) { 16768 alc_free(codec); 16769 return err; 16770 } else if (!err) { 16771 printk(KERN_INFO 16772 "hda_codec: Cannot set up configuration " 16773 "from BIOS. Using base mode...\n"); 16774 board_config = ALC861VD_3ST; 16775 } 16776 } 16777 16778 err = snd_hda_attach_beep_device(codec, 0x23); 16779 if (err < 0) { 16780 alc_free(codec); 16781 return err; 16782 } 16783 16784 if (board_config != ALC861VD_AUTO) 16785 setup_preset(codec, &alc861vd_presets[board_config]); 16786 16787 if (codec->vendor_id == 0x10ec0660) { 16788 /* always turn on EAPD */ 16789 add_verb(spec, alc660vd_eapd_verbs); 16790 } 16791 16792 spec->stream_analog_playback = &alc861vd_pcm_analog_playback; 16793 spec->stream_analog_capture = &alc861vd_pcm_analog_capture; 16794 16795 spec->stream_digital_playback = &alc861vd_pcm_digital_playback; 16796 spec->stream_digital_capture = &alc861vd_pcm_digital_capture; 16797 16798 if (!spec->adc_nids) { 16799 spec->adc_nids = alc861vd_adc_nids; 16800 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids); 16801 } 16802 if (!spec->capsrc_nids) 16803 spec->capsrc_nids = alc861vd_capsrc_nids; 16804 16805 set_capture_mixer(codec); 16806 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 16807 16808 spec->vmaster_nid = 0x02; 16809 16810 if (board_config == ALC861VD_AUTO) 16811 alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups, 0); 16812 16813 codec->patch_ops = alc_patch_ops; 16814 16815 if (board_config == ALC861VD_AUTO) 16816 spec->init_hook = alc861vd_auto_init; 16817#ifdef CONFIG_SND_HDA_POWER_SAVE 16818 if (!spec->loopback.amplist) 16819 spec->loopback.amplist = alc861vd_loopbacks; 16820#endif 16821 16822 return 0; 16823} 16824 16825/* 16826 * ALC662 support 16827 * 16828 * ALC662 is almost identical with ALC880 but has cleaner and more flexible 16829 * configuration. Each pin widget can choose any input DACs and a mixer. 16830 * Each ADC is connected from a mixer of all inputs. This makes possible 16831 * 6-channel independent captures. 16832 * 16833 * In addition, an independent DAC for the multi-playback (not used in this 16834 * driver yet). 16835 */ 16836#define ALC662_DIGOUT_NID 0x06 16837#define ALC662_DIGIN_NID 0x0a 16838 16839static hda_nid_t alc662_dac_nids[4] = { 16840 /* front, rear, clfe, rear_surr */ 16841 0x02, 0x03, 0x04 16842}; 16843 16844static hda_nid_t alc272_dac_nids[2] = { 16845 0x02, 0x03 16846}; 16847 16848static hda_nid_t alc662_adc_nids[2] = { 16849 /* ADC1-2 */ 16850 0x09, 0x08 16851}; 16852 16853static hda_nid_t alc272_adc_nids[1] = { 16854 /* ADC1-2 */ 16855 0x08, 16856}; 16857 16858static hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 }; 16859static hda_nid_t alc272_capsrc_nids[1] = { 0x23 }; 16860 16861 16862/* input MUX */ 16863/* FIXME: should be a matrix-type input source selection */ 16864static struct hda_input_mux alc662_capture_source = { 16865 .num_items = 4, 16866 .items = { 16867 { "Mic", 0x0 }, 16868 { "Front Mic", 0x1 }, 16869 { "Line", 0x2 }, 16870 { "CD", 0x4 }, 16871 }, 16872}; 16873 16874static struct hda_input_mux alc662_lenovo_101e_capture_source = { 16875 .num_items = 2, 16876 .items = { 16877 { "Mic", 0x1 }, 16878 { "Line", 0x2 }, 16879 }, 16880}; 16881 16882static struct hda_input_mux alc663_capture_source = { 16883 .num_items = 3, 16884 .items = { 16885 { "Mic", 0x0 }, 16886 { "Front Mic", 0x1 }, 16887 { "Line", 0x2 }, 16888 }, 16889}; 16890 16891#if 0 /* set to 1 for testing other input sources below */ 16892static struct hda_input_mux alc272_nc10_capture_source = { 16893 .num_items = 16, 16894 .items = { 16895 { "Autoselect Mic", 0x0 }, 16896 { "Internal Mic", 0x1 }, 16897 { "In-0x02", 0x2 }, 16898 { "In-0x03", 0x3 }, 16899 { "In-0x04", 0x4 }, 16900 { "In-0x05", 0x5 }, 16901 { "In-0x06", 0x6 }, 16902 { "In-0x07", 0x7 }, 16903 { "In-0x08", 0x8 }, 16904 { "In-0x09", 0x9 }, 16905 { "In-0x0a", 0x0a }, 16906 { "In-0x0b", 0x0b }, 16907 { "In-0x0c", 0x0c }, 16908 { "In-0x0d", 0x0d }, 16909 { "In-0x0e", 0x0e }, 16910 { "In-0x0f", 0x0f }, 16911 }, 16912}; 16913#endif 16914 16915/* 16916 * 2ch mode 16917 */ 16918static struct hda_channel_mode alc662_3ST_2ch_modes[1] = { 16919 { 2, NULL } 16920}; 16921 16922/* 16923 * 2ch mode 16924 */ 16925static struct hda_verb alc662_3ST_ch2_init[] = { 16926 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 16927 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 16928 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 16929 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 16930 { } /* end */ 16931}; 16932 16933/* 16934 * 6ch mode 16935 */ 16936static struct hda_verb alc662_3ST_ch6_init[] = { 16937 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 16938 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 16939 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, 16940 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 16941 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 16942 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 16943 { } /* end */ 16944}; 16945 16946static struct hda_channel_mode alc662_3ST_6ch_modes[2] = { 16947 { 2, alc662_3ST_ch2_init }, 16948 { 6, alc662_3ST_ch6_init }, 16949}; 16950 16951/* 16952 * 2ch mode 16953 */ 16954static struct hda_verb alc662_sixstack_ch6_init[] = { 16955 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 16956 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 16957 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 16958 { } /* end */ 16959}; 16960 16961/* 16962 * 6ch mode 16963 */ 16964static struct hda_verb alc662_sixstack_ch8_init[] = { 16965 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 16966 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 16967 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 16968 { } /* end */ 16969}; 16970 16971static struct hda_channel_mode alc662_5stack_modes[2] = { 16972 { 2, alc662_sixstack_ch6_init }, 16973 { 6, alc662_sixstack_ch8_init }, 16974}; 16975 16976/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 16977 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b 16978 */ 16979 16980static struct snd_kcontrol_new alc662_base_mixer[] = { 16981 /* output mixer control */ 16982 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), 16983 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT), 16984 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT), 16985 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT), 16986 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT), 16987 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT), 16988 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT), 16989 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT), 16990 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 16991 16992 /*Input mixer control */ 16993 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT), 16994 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT), 16995 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT), 16996 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT), 16997 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT), 16998 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT), 16999 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT), 17000 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT), 17001 { } /* end */ 17002}; 17003 17004static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = { 17005 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 17006 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT), 17007 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 17008 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 17009 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 17010 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 17011 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 17012 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17013 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17014 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 17015 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 17016 { } /* end */ 17017}; 17018 17019static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = { 17020 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 17021 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT), 17022 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT), 17023 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT), 17024 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT), 17025 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT), 17026 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT), 17027 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT), 17028 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 17029 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 17030 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 17031 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 17032 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 17033 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17034 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17035 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 17036 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 17037 { } /* end */ 17038}; 17039 17040static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = { 17041 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 17042 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT), 17043 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT), 17044 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT), 17045 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 17046 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 17047 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 17048 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 17049 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 17050 { } /* end */ 17051}; 17052 17053static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = { 17054 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT), 17055 ALC262_HIPPO_MASTER_SWITCH, 17056 17057 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT), 17058 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17059 HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17060 17061 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT), 17062 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 17063 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 17064 { } /* end */ 17065}; 17066 17067static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = { 17068 ALC262_HIPPO_MASTER_SWITCH, 17069 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 17070 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT), 17071 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT), 17072 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT), 17073 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT), 17074 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 17075 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 17076 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17077 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17078 { } /* end */ 17079}; 17080 17081static struct hda_bind_ctls alc663_asus_bind_master_vol = { 17082 .ops = &snd_hda_bind_vol, 17083 .values = { 17084 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), 17085 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT), 17086 0 17087 }, 17088}; 17089 17090static struct hda_bind_ctls alc663_asus_one_bind_switch = { 17091 .ops = &snd_hda_bind_sw, 17092 .values = { 17093 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 17094 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT), 17095 0 17096 }, 17097}; 17098 17099static struct snd_kcontrol_new alc663_m51va_mixer[] = { 17100 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol), 17101 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch), 17102 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17103 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17104 { } /* end */ 17105}; 17106 17107static struct hda_bind_ctls alc663_asus_tree_bind_switch = { 17108 .ops = &snd_hda_bind_sw, 17109 .values = { 17110 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 17111 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT), 17112 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT), 17113 0 17114 }, 17115}; 17116 17117static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = { 17118 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol), 17119 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch), 17120 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17121 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17122 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 17123 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 17124 17125 { } /* end */ 17126}; 17127 17128static struct hda_bind_ctls alc663_asus_four_bind_switch = { 17129 .ops = &snd_hda_bind_sw, 17130 .values = { 17131 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 17132 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT), 17133 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT), 17134 0 17135 }, 17136}; 17137 17138static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = { 17139 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol), 17140 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch), 17141 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17142 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17143 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 17144 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 17145 { } /* end */ 17146}; 17147 17148static struct snd_kcontrol_new alc662_1bjd_mixer[] = { 17149 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 17150 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 17151 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 17152 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17153 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17154 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 17155 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 17156 { } /* end */ 17157}; 17158 17159static struct hda_bind_ctls alc663_asus_two_bind_master_vol = { 17160 .ops = &snd_hda_bind_vol, 17161 .values = { 17162 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), 17163 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT), 17164 0 17165 }, 17166}; 17167 17168static struct hda_bind_ctls alc663_asus_two_bind_switch = { 17169 .ops = &snd_hda_bind_sw, 17170 .values = { 17171 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 17172 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT), 17173 0 17174 }, 17175}; 17176 17177static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = { 17178 HDA_BIND_VOL("Master Playback Volume", 17179 &alc663_asus_two_bind_master_vol), 17180 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch), 17181 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 17182 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT), 17183 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17184 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17185 { } /* end */ 17186}; 17187 17188static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = { 17189 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol), 17190 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch), 17191 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 17192 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 17193 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17194 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17195 { } /* end */ 17196}; 17197 17198static struct snd_kcontrol_new alc663_g71v_mixer[] = { 17199 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 17200 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 17201 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT), 17202 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT), 17203 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT), 17204 17205 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17206 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17207 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 17208 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 17209 { } /* end */ 17210}; 17211 17212static struct snd_kcontrol_new alc663_g50v_mixer[] = { 17213 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 17214 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 17215 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT), 17216 17217 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17218 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17219 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 17220 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 17221 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 17222 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 17223 { } /* end */ 17224}; 17225 17226static struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = { 17227 .ops = &snd_hda_bind_sw, 17228 .values = { 17229 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 17230 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT), 17231 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT), 17232 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT), 17233 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT), 17234 0 17235 }, 17236}; 17237 17238static struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = { 17239 .ops = &snd_hda_bind_sw, 17240 .values = { 17241 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 17242 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT), 17243 0 17244 }, 17245}; 17246 17247static struct snd_kcontrol_new alc663_mode7_mixer[] = { 17248 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch), 17249 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol), 17250 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch), 17251 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 17252 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT), 17253 HDA_CODEC_VOLUME("IntMic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17254 HDA_CODEC_MUTE("IntMic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17255 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 17256 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 17257 { } /* end */ 17258}; 17259 17260static struct snd_kcontrol_new alc663_mode8_mixer[] = { 17261 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch), 17262 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol), 17263 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch), 17264 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x15, 0x0, HDA_OUTPUT), 17265 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT), 17266 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17267 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17268 { } /* end */ 17269}; 17270 17271 17272static struct snd_kcontrol_new alc662_chmode_mixer[] = { 17273 { 17274 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 17275 .name = "Channel Mode", 17276 .info = alc_ch_mode_info, 17277 .get = alc_ch_mode_get, 17278 .put = alc_ch_mode_put, 17279 }, 17280 { } /* end */ 17281}; 17282 17283static struct hda_verb alc662_init_verbs[] = { 17284 /* ADC: mute amp left and right */ 17285 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 17286 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 17287 17288 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 17289 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 17290 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 17291 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 17292 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 17293 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 17294 17295 /* Front Pin: output 0 (0x0c) */ 17296 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 17297 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17298 17299 /* Rear Pin: output 1 (0x0d) */ 17300 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 17301 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17302 17303 /* CLFE Pin: output 2 (0x0e) */ 17304 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 17305 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17306 17307 /* Mic (rear) pin: input vref at 80% */ 17308 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 17309 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 17310 /* Front Mic pin: input vref at 80% */ 17311 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 17312 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 17313 /* Line In pin: input */ 17314 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17315 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 17316 /* Line-2 In: Headphone output (output 0 - 0x0c) */ 17317 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17318 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17319 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 17320 /* CD pin widget for input */ 17321 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17322 17323 /* FIXME: use matrix-type input source selection */ 17324 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 17325 /* Input mixer */ 17326 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 17327 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 17328 17329 /* always trun on EAPD */ 17330 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 17331 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, 17332 17333 { } 17334}; 17335 17336static struct hda_verb alc663_init_verbs[] = { 17337 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 17338 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17339 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 17340 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17341 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 17342 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 17343 { } 17344}; 17345 17346static struct hda_verb alc272_init_verbs[] = { 17347 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17348 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 17349 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 17350 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17351 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 17352 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17353 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 17354 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 17355 { } 17356}; 17357 17358static struct hda_verb alc662_sue_init_verbs[] = { 17359 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT}, 17360 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT}, 17361 {} 17362}; 17363 17364static struct hda_verb alc662_eeepc_sue_init_verbs[] = { 17365 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 17366 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17367 {} 17368}; 17369 17370/* Set Unsolicited Event*/ 17371static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = { 17372 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 17373 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17374 {} 17375}; 17376 17377static struct hda_verb alc663_m51va_init_verbs[] = { 17378 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17379 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17380 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17381 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17382 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ 17383 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 17384 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)}, 17385 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 17386 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17387 {} 17388}; 17389 17390static struct hda_verb alc663_21jd_amic_init_verbs[] = { 17391 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17392 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17393 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ 17394 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 17395 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 17396 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 17397 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17398 {} 17399}; 17400 17401static struct hda_verb alc662_1bjd_amic_init_verbs[] = { 17402 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17403 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17404 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17405 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */ 17406 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 17407 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 17408 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 17409 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17410 {} 17411}; 17412 17413static struct hda_verb alc663_15jd_amic_init_verbs[] = { 17414 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17415 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17416 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ 17417 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 17418 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 17419 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 17420 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17421 {} 17422}; 17423 17424static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = { 17425 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17426 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17427 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17428 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */ 17429 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17430 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17431 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */ 17432 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 17433 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 17434 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 17435 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17436 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17437 {} 17438}; 17439 17440static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = { 17441 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17442 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17443 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17444 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ 17445 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17446 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17447 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ 17448 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 17449 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 17450 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 17451 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17452 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17453 {} 17454}; 17455 17456static struct hda_verb alc663_g71v_init_verbs[] = { 17457 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17458 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */ 17459 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */ 17460 17461 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17462 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17463 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */ 17464 17465 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT}, 17466 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT}, 17467 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT}, 17468 {} 17469}; 17470 17471static struct hda_verb alc663_g50v_init_verbs[] = { 17472 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17473 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17474 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */ 17475 17476 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 17477 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17478 {} 17479}; 17480 17481static struct hda_verb alc662_ecs_init_verbs[] = { 17482 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f}, 17483 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 17484 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 17485 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17486 {} 17487}; 17488 17489static struct hda_verb alc272_dell_zm1_init_verbs[] = { 17490 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17491 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17492 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17493 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17494 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17495 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17496 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ 17497 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 17498 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)}, 17499 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 17500 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17501 {} 17502}; 17503 17504static struct hda_verb alc272_dell_init_verbs[] = { 17505 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17506 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17507 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17508 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17509 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17510 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17511 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ 17512 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 17513 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)}, 17514 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 17515 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17516 {} 17517}; 17518 17519static struct hda_verb alc663_mode7_init_verbs[] = { 17520 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17521 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17522 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 17523 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17524 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17525 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17526 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, 17527 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17528 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17529 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ 17530 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 17531 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)}, 17532 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 17533 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17534 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17535 {} 17536}; 17537 17538static struct hda_verb alc663_mode8_init_verbs[] = { 17539 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17540 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17541 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17542 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 17543 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17544 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 17545 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17546 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17547 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17548 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17549 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ 17550 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 17551 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)}, 17552 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17553 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 17554 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17555 {} 17556}; 17557 17558static struct snd_kcontrol_new alc662_auto_capture_mixer[] = { 17559 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), 17560 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), 17561 { } /* end */ 17562}; 17563 17564static struct snd_kcontrol_new alc272_auto_capture_mixer[] = { 17565 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 17566 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 17567 { } /* end */ 17568}; 17569 17570static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec) 17571{ 17572 unsigned int present; 17573 unsigned char bits; 17574 17575 present = snd_hda_jack_detect(codec, 0x14); 17576 bits = present ? HDA_AMP_MUTE : 0; 17577 17578 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 17579 HDA_AMP_MUTE, bits); 17580} 17581 17582static void alc662_lenovo_101e_all_automute(struct hda_codec *codec) 17583{ 17584 unsigned int present; 17585 unsigned char bits; 17586 17587 present = snd_hda_jack_detect(codec, 0x1b); 17588 bits = present ? HDA_AMP_MUTE : 0; 17589 17590 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 17591 HDA_AMP_MUTE, bits); 17592 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 17593 HDA_AMP_MUTE, bits); 17594} 17595 17596static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec, 17597 unsigned int res) 17598{ 17599 if ((res >> 26) == ALC880_HP_EVENT) 17600 alc662_lenovo_101e_all_automute(codec); 17601 if ((res >> 26) == ALC880_FRONT_EVENT) 17602 alc662_lenovo_101e_ispeaker_automute(codec); 17603} 17604 17605/* unsolicited event for HP jack sensing */ 17606static void alc662_eeepc_unsol_event(struct hda_codec *codec, 17607 unsigned int res) 17608{ 17609 if ((res >> 26) == ALC880_MIC_EVENT) 17610 alc_mic_automute(codec); 17611 else 17612 alc262_hippo_unsol_event(codec, res); 17613} 17614 17615static void alc662_eeepc_setup(struct hda_codec *codec) 17616{ 17617 struct alc_spec *spec = codec->spec; 17618 17619 alc262_hippo1_setup(codec); 17620 spec->ext_mic.pin = 0x18; 17621 spec->ext_mic.mux_idx = 0; 17622 spec->int_mic.pin = 0x19; 17623 spec->int_mic.mux_idx = 1; 17624 spec->auto_mic = 1; 17625} 17626 17627static void alc662_eeepc_inithook(struct hda_codec *codec) 17628{ 17629 alc262_hippo_automute(codec); 17630 alc_mic_automute(codec); 17631} 17632 17633static void alc662_eeepc_ep20_setup(struct hda_codec *codec) 17634{ 17635 struct alc_spec *spec = codec->spec; 17636 17637 spec->autocfg.hp_pins[0] = 0x14; 17638 spec->autocfg.speaker_pins[0] = 0x1b; 17639} 17640 17641#define alc662_eeepc_ep20_inithook alc262_hippo_master_update 17642 17643static void alc663_m51va_speaker_automute(struct hda_codec *codec) 17644{ 17645 unsigned int present; 17646 unsigned char bits; 17647 17648 present = snd_hda_jack_detect(codec, 0x21); 17649 bits = present ? HDA_AMP_MUTE : 0; 17650 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 17651 HDA_AMP_MUTE, bits); 17652 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 17653 HDA_AMP_MUTE, bits); 17654} 17655 17656static void alc663_21jd_two_speaker_automute(struct hda_codec *codec) 17657{ 17658 unsigned int present; 17659 unsigned char bits; 17660 17661 present = snd_hda_jack_detect(codec, 0x21); 17662 bits = present ? HDA_AMP_MUTE : 0; 17663 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 17664 HDA_AMP_MUTE, bits); 17665 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 17666 HDA_AMP_MUTE, bits); 17667 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0, 17668 HDA_AMP_MUTE, bits); 17669 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1, 17670 HDA_AMP_MUTE, bits); 17671} 17672 17673static void alc663_15jd_two_speaker_automute(struct hda_codec *codec) 17674{ 17675 unsigned int present; 17676 unsigned char bits; 17677 17678 present = snd_hda_jack_detect(codec, 0x15); 17679 bits = present ? HDA_AMP_MUTE : 0; 17680 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 17681 HDA_AMP_MUTE, bits); 17682 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 17683 HDA_AMP_MUTE, bits); 17684 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0, 17685 HDA_AMP_MUTE, bits); 17686 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1, 17687 HDA_AMP_MUTE, bits); 17688} 17689 17690static void alc662_f5z_speaker_automute(struct hda_codec *codec) 17691{ 17692 unsigned int present; 17693 unsigned char bits; 17694 17695 present = snd_hda_jack_detect(codec, 0x1b); 17696 bits = present ? 0 : PIN_OUT; 17697 snd_hda_codec_write(codec, 0x14, 0, 17698 AC_VERB_SET_PIN_WIDGET_CONTROL, bits); 17699} 17700 17701static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec) 17702{ 17703 unsigned int present1, present2; 17704 17705 present1 = snd_hda_jack_detect(codec, 0x21); 17706 present2 = snd_hda_jack_detect(codec, 0x15); 17707 17708 if (present1 || present2) { 17709 snd_hda_codec_write_cache(codec, 0x14, 0, 17710 AC_VERB_SET_PIN_WIDGET_CONTROL, 0); 17711 } else { 17712 snd_hda_codec_write_cache(codec, 0x14, 0, 17713 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); 17714 } 17715} 17716 17717static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec) 17718{ 17719 unsigned int present1, present2; 17720 17721 present1 = snd_hda_jack_detect(codec, 0x1b); 17722 present2 = snd_hda_jack_detect(codec, 0x15); 17723 17724 if (present1 || present2) { 17725 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 17726 HDA_AMP_MUTE, HDA_AMP_MUTE); 17727 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 17728 HDA_AMP_MUTE, HDA_AMP_MUTE); 17729 } else { 17730 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 17731 HDA_AMP_MUTE, 0); 17732 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 17733 HDA_AMP_MUTE, 0); 17734 } 17735} 17736 17737static void alc663_two_hp_m7_speaker_automute(struct hda_codec *codec) 17738{ 17739 unsigned int present1, present2; 17740 17741 present1 = snd_hda_codec_read(codec, 0x1b, 0, 17742 AC_VERB_GET_PIN_SENSE, 0) 17743 & AC_PINSENSE_PRESENCE; 17744 present2 = snd_hda_codec_read(codec, 0x21, 0, 17745 AC_VERB_GET_PIN_SENSE, 0) 17746 & AC_PINSENSE_PRESENCE; 17747 17748 if (present1 || present2) { 17749 snd_hda_codec_write_cache(codec, 0x14, 0, 17750 AC_VERB_SET_PIN_WIDGET_CONTROL, 0); 17751 snd_hda_codec_write_cache(codec, 0x17, 0, 17752 AC_VERB_SET_PIN_WIDGET_CONTROL, 0); 17753 } else { 17754 snd_hda_codec_write_cache(codec, 0x14, 0, 17755 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); 17756 snd_hda_codec_write_cache(codec, 0x17, 0, 17757 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); 17758 } 17759} 17760 17761static void alc663_two_hp_m8_speaker_automute(struct hda_codec *codec) 17762{ 17763 unsigned int present1, present2; 17764 17765 present1 = snd_hda_codec_read(codec, 0x21, 0, 17766 AC_VERB_GET_PIN_SENSE, 0) 17767 & AC_PINSENSE_PRESENCE; 17768 present2 = snd_hda_codec_read(codec, 0x15, 0, 17769 AC_VERB_GET_PIN_SENSE, 0) 17770 & AC_PINSENSE_PRESENCE; 17771 17772 if (present1 || present2) { 17773 snd_hda_codec_write_cache(codec, 0x14, 0, 17774 AC_VERB_SET_PIN_WIDGET_CONTROL, 0); 17775 snd_hda_codec_write_cache(codec, 0x17, 0, 17776 AC_VERB_SET_PIN_WIDGET_CONTROL, 0); 17777 } else { 17778 snd_hda_codec_write_cache(codec, 0x14, 0, 17779 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); 17780 snd_hda_codec_write_cache(codec, 0x17, 0, 17781 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); 17782 } 17783} 17784 17785static void alc663_m51va_unsol_event(struct hda_codec *codec, 17786 unsigned int res) 17787{ 17788 switch (res >> 26) { 17789 case ALC880_HP_EVENT: 17790 alc663_m51va_speaker_automute(codec); 17791 break; 17792 case ALC880_MIC_EVENT: 17793 alc_mic_automute(codec); 17794 break; 17795 } 17796} 17797 17798static void alc663_m51va_setup(struct hda_codec *codec) 17799{ 17800 struct alc_spec *spec = codec->spec; 17801 spec->ext_mic.pin = 0x18; 17802 spec->ext_mic.mux_idx = 0; 17803 spec->int_mic.pin = 0x12; 17804 spec->int_mic.mux_idx = 9; 17805 spec->auto_mic = 1; 17806} 17807 17808static void alc663_m51va_inithook(struct hda_codec *codec) 17809{ 17810 alc663_m51va_speaker_automute(codec); 17811 alc_mic_automute(codec); 17812} 17813 17814/* ***************** Mode1 ******************************/ 17815#define alc663_mode1_unsol_event alc663_m51va_unsol_event 17816 17817static void alc663_mode1_setup(struct hda_codec *codec) 17818{ 17819 struct alc_spec *spec = codec->spec; 17820 spec->ext_mic.pin = 0x18; 17821 spec->ext_mic.mux_idx = 0; 17822 spec->int_mic.pin = 0x19; 17823 spec->int_mic.mux_idx = 1; 17824 spec->auto_mic = 1; 17825} 17826 17827#define alc663_mode1_inithook alc663_m51va_inithook 17828 17829/* ***************** Mode2 ******************************/ 17830static void alc662_mode2_unsol_event(struct hda_codec *codec, 17831 unsigned int res) 17832{ 17833 switch (res >> 26) { 17834 case ALC880_HP_EVENT: 17835 alc662_f5z_speaker_automute(codec); 17836 break; 17837 case ALC880_MIC_EVENT: 17838 alc_mic_automute(codec); 17839 break; 17840 } 17841} 17842 17843#define alc662_mode2_setup alc663_mode1_setup 17844 17845static void alc662_mode2_inithook(struct hda_codec *codec) 17846{ 17847 alc662_f5z_speaker_automute(codec); 17848 alc_mic_automute(codec); 17849} 17850/* ***************** Mode3 ******************************/ 17851static void alc663_mode3_unsol_event(struct hda_codec *codec, 17852 unsigned int res) 17853{ 17854 switch (res >> 26) { 17855 case ALC880_HP_EVENT: 17856 alc663_two_hp_m1_speaker_automute(codec); 17857 break; 17858 case ALC880_MIC_EVENT: 17859 alc_mic_automute(codec); 17860 break; 17861 } 17862} 17863 17864#define alc663_mode3_setup alc663_mode1_setup 17865 17866static void alc663_mode3_inithook(struct hda_codec *codec) 17867{ 17868 alc663_two_hp_m1_speaker_automute(codec); 17869 alc_mic_automute(codec); 17870} 17871/* ***************** Mode4 ******************************/ 17872static void alc663_mode4_unsol_event(struct hda_codec *codec, 17873 unsigned int res) 17874{ 17875 switch (res >> 26) { 17876 case ALC880_HP_EVENT: 17877 alc663_21jd_two_speaker_automute(codec); 17878 break; 17879 case ALC880_MIC_EVENT: 17880 alc_mic_automute(codec); 17881 break; 17882 } 17883} 17884 17885#define alc663_mode4_setup alc663_mode1_setup 17886 17887static void alc663_mode4_inithook(struct hda_codec *codec) 17888{ 17889 alc663_21jd_two_speaker_automute(codec); 17890 alc_mic_automute(codec); 17891} 17892/* ***************** Mode5 ******************************/ 17893static void alc663_mode5_unsol_event(struct hda_codec *codec, 17894 unsigned int res) 17895{ 17896 switch (res >> 26) { 17897 case ALC880_HP_EVENT: 17898 alc663_15jd_two_speaker_automute(codec); 17899 break; 17900 case ALC880_MIC_EVENT: 17901 alc_mic_automute(codec); 17902 break; 17903 } 17904} 17905 17906#define alc663_mode5_setup alc663_mode1_setup 17907 17908static void alc663_mode5_inithook(struct hda_codec *codec) 17909{ 17910 alc663_15jd_two_speaker_automute(codec); 17911 alc_mic_automute(codec); 17912} 17913/* ***************** Mode6 ******************************/ 17914static void alc663_mode6_unsol_event(struct hda_codec *codec, 17915 unsigned int res) 17916{ 17917 switch (res >> 26) { 17918 case ALC880_HP_EVENT: 17919 alc663_two_hp_m2_speaker_automute(codec); 17920 break; 17921 case ALC880_MIC_EVENT: 17922 alc_mic_automute(codec); 17923 break; 17924 } 17925} 17926 17927#define alc663_mode6_setup alc663_mode1_setup 17928 17929static void alc663_mode6_inithook(struct hda_codec *codec) 17930{ 17931 alc663_two_hp_m2_speaker_automute(codec); 17932 alc_mic_automute(codec); 17933} 17934 17935/* ***************** Mode7 ******************************/ 17936static void alc663_mode7_unsol_event(struct hda_codec *codec, 17937 unsigned int res) 17938{ 17939 switch (res >> 26) { 17940 case ALC880_HP_EVENT: 17941 alc663_two_hp_m7_speaker_automute(codec); 17942 break; 17943 case ALC880_MIC_EVENT: 17944 alc_mic_automute(codec); 17945 break; 17946 } 17947} 17948 17949#define alc663_mode7_setup alc663_mode1_setup 17950 17951static void alc663_mode7_inithook(struct hda_codec *codec) 17952{ 17953 alc663_two_hp_m7_speaker_automute(codec); 17954 alc_mic_automute(codec); 17955} 17956 17957/* ***************** Mode8 ******************************/ 17958static void alc663_mode8_unsol_event(struct hda_codec *codec, 17959 unsigned int res) 17960{ 17961 switch (res >> 26) { 17962 case ALC880_HP_EVENT: 17963 alc663_two_hp_m8_speaker_automute(codec); 17964 break; 17965 case ALC880_MIC_EVENT: 17966 alc_mic_automute(codec); 17967 break; 17968 } 17969} 17970 17971#define alc663_mode8_setup alc663_m51va_setup 17972 17973static void alc663_mode8_inithook(struct hda_codec *codec) 17974{ 17975 alc663_two_hp_m8_speaker_automute(codec); 17976 alc_mic_automute(codec); 17977} 17978 17979static void alc663_g71v_hp_automute(struct hda_codec *codec) 17980{ 17981 unsigned int present; 17982 unsigned char bits; 17983 17984 present = snd_hda_jack_detect(codec, 0x21); 17985 bits = present ? HDA_AMP_MUTE : 0; 17986 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 17987 HDA_AMP_MUTE, bits); 17988 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 17989 HDA_AMP_MUTE, bits); 17990} 17991 17992static void alc663_g71v_front_automute(struct hda_codec *codec) 17993{ 17994 unsigned int present; 17995 unsigned char bits; 17996 17997 present = snd_hda_jack_detect(codec, 0x15); 17998 bits = present ? HDA_AMP_MUTE : 0; 17999 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 18000 HDA_AMP_MUTE, bits); 18001} 18002 18003static void alc663_g71v_unsol_event(struct hda_codec *codec, 18004 unsigned int res) 18005{ 18006 switch (res >> 26) { 18007 case ALC880_HP_EVENT: 18008 alc663_g71v_hp_automute(codec); 18009 break; 18010 case ALC880_FRONT_EVENT: 18011 alc663_g71v_front_automute(codec); 18012 break; 18013 case ALC880_MIC_EVENT: 18014 alc_mic_automute(codec); 18015 break; 18016 } 18017} 18018 18019#define alc663_g71v_setup alc663_m51va_setup 18020 18021static void alc663_g71v_inithook(struct hda_codec *codec) 18022{ 18023 alc663_g71v_front_automute(codec); 18024 alc663_g71v_hp_automute(codec); 18025 alc_mic_automute(codec); 18026} 18027 18028static void alc663_g50v_unsol_event(struct hda_codec *codec, 18029 unsigned int res) 18030{ 18031 switch (res >> 26) { 18032 case ALC880_HP_EVENT: 18033 alc663_m51va_speaker_automute(codec); 18034 break; 18035 case ALC880_MIC_EVENT: 18036 alc_mic_automute(codec); 18037 break; 18038 } 18039} 18040 18041#define alc663_g50v_setup alc663_m51va_setup 18042 18043static void alc663_g50v_inithook(struct hda_codec *codec) 18044{ 18045 alc663_m51va_speaker_automute(codec); 18046 alc_mic_automute(codec); 18047} 18048 18049static struct snd_kcontrol_new alc662_ecs_mixer[] = { 18050 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT), 18051 ALC262_HIPPO_MASTER_SWITCH, 18052 18053 HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT), 18054 HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT), 18055 HDA_CODEC_MUTE("e-Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT), 18056 18057 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT), 18058 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 18059 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 18060 { } /* end */ 18061}; 18062 18063static struct snd_kcontrol_new alc272_nc10_mixer[] = { 18064 /* Master Playback automatically created from Speaker and Headphone */ 18065 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 18066 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 18067 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 18068 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT), 18069 18070 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 18071 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 18072 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT), 18073 18074 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 18075 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 18076 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 18077 { } /* end */ 18078}; 18079 18080#ifdef CONFIG_SND_HDA_POWER_SAVE 18081#define alc662_loopbacks alc880_loopbacks 18082#endif 18083 18084 18085/* pcm configuration: identical with ALC880 */ 18086#define alc662_pcm_analog_playback alc880_pcm_analog_playback 18087#define alc662_pcm_analog_capture alc880_pcm_analog_capture 18088#define alc662_pcm_digital_playback alc880_pcm_digital_playback 18089#define alc662_pcm_digital_capture alc880_pcm_digital_capture 18090 18091/* 18092 * configuration and preset 18093 */ 18094static const char *alc662_models[ALC662_MODEL_LAST] = { 18095 [ALC662_3ST_2ch_DIG] = "3stack-dig", 18096 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig", 18097 [ALC662_3ST_6ch] = "3stack-6ch", 18098 [ALC662_5ST_DIG] = "6stack-dig", 18099 [ALC662_LENOVO_101E] = "lenovo-101e", 18100 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701", 18101 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20", 18102 [ALC662_ECS] = "ecs", 18103 [ALC663_ASUS_M51VA] = "m51va", 18104 [ALC663_ASUS_G71V] = "g71v", 18105 [ALC663_ASUS_H13] = "h13", 18106 [ALC663_ASUS_G50V] = "g50v", 18107 [ALC663_ASUS_MODE1] = "asus-mode1", 18108 [ALC662_ASUS_MODE2] = "asus-mode2", 18109 [ALC663_ASUS_MODE3] = "asus-mode3", 18110 [ALC663_ASUS_MODE4] = "asus-mode4", 18111 [ALC663_ASUS_MODE5] = "asus-mode5", 18112 [ALC663_ASUS_MODE6] = "asus-mode6", 18113 [ALC663_ASUS_MODE7] = "asus-mode7", 18114 [ALC663_ASUS_MODE8] = "asus-mode8", 18115 [ALC272_DELL] = "dell", 18116 [ALC272_DELL_ZM1] = "dell-zm1", 18117 [ALC272_SAMSUNG_NC10] = "samsung-nc10", 18118 [ALC662_AUTO] = "auto", 18119}; 18120 18121static struct snd_pci_quirk alc662_cfg_tbl[] = { 18122 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS), 18123 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL), 18124 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1), 18125 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1), 18126 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3), 18127 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC663_ASUS_MODE1), 18128 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3), 18129 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1), 18130 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2), 18131 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1), 18132 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC663_ASUS_MODE1), 18133 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC663_ASUS_MODE1), 18134 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2), 18135 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC663_ASUS_MODE7), 18136 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC663_ASUS_MODE7), 18137 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC663_ASUS_MODE8), 18138 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC663_ASUS_MODE3), 18139 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC663_ASUS_MODE1), 18140 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2), 18141 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_ASUS_MODE2), 18142 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC663_ASUS_MODE1), 18143 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2), 18144 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6), 18145 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6), 18146 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2), 18147 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC663_ASUS_MODE1), 18148 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3), 18149 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA), 18150 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2), 18151 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2), 18152 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5), 18153 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6), 18154 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2), 18155 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1), 18156 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2), 18157 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2), 18158 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA), 18159 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/ 18160 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3), 18161 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3), 18162 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1), 18163 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC663_ASUS_MODE1), 18164 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1), 18165 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1), 18166 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1), 18167 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2), 18168 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2), 18169 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1), 18170 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1), 18171 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3), 18172 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1), 18173 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1), 18174 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V), 18175 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/ 18176 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1), 18177 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2), 18178 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA), 18179 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1), 18180 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4), 18181 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG), 18182 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701), 18183 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20), 18184 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS), 18185 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K", 18186 ALC662_3ST_6ch_DIG), 18187 SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO), 18188 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10), 18189 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L", 18190 ALC662_3ST_6ch_DIG), 18191 SND_PCI_QUIRK(0x152d, 0x2304, "Quanta WH1", ALC663_ASUS_H13), 18192 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG), 18193 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA), 18194 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E), 18195 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0", 18196 ALC662_3ST_6ch_DIG), 18197 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x", 18198 ALC663_ASUS_H13), 18199 {} 18200}; 18201 18202static struct alc_config_preset alc662_presets[] = { 18203 [ALC662_3ST_2ch_DIG] = { 18204 .mixers = { alc662_3ST_2ch_mixer }, 18205 .init_verbs = { alc662_init_verbs }, 18206 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18207 .dac_nids = alc662_dac_nids, 18208 .dig_out_nid = ALC662_DIGOUT_NID, 18209 .dig_in_nid = ALC662_DIGIN_NID, 18210 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18211 .channel_mode = alc662_3ST_2ch_modes, 18212 .input_mux = &alc662_capture_source, 18213 }, 18214 [ALC662_3ST_6ch_DIG] = { 18215 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer }, 18216 .init_verbs = { alc662_init_verbs }, 18217 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18218 .dac_nids = alc662_dac_nids, 18219 .dig_out_nid = ALC662_DIGOUT_NID, 18220 .dig_in_nid = ALC662_DIGIN_NID, 18221 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), 18222 .channel_mode = alc662_3ST_6ch_modes, 18223 .need_dac_fix = 1, 18224 .input_mux = &alc662_capture_source, 18225 }, 18226 [ALC662_3ST_6ch] = { 18227 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer }, 18228 .init_verbs = { alc662_init_verbs }, 18229 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18230 .dac_nids = alc662_dac_nids, 18231 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), 18232 .channel_mode = alc662_3ST_6ch_modes, 18233 .need_dac_fix = 1, 18234 .input_mux = &alc662_capture_source, 18235 }, 18236 [ALC662_5ST_DIG] = { 18237 .mixers = { alc662_base_mixer, alc662_chmode_mixer }, 18238 .init_verbs = { alc662_init_verbs }, 18239 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18240 .dac_nids = alc662_dac_nids, 18241 .dig_out_nid = ALC662_DIGOUT_NID, 18242 .dig_in_nid = ALC662_DIGIN_NID, 18243 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes), 18244 .channel_mode = alc662_5stack_modes, 18245 .input_mux = &alc662_capture_source, 18246 }, 18247 [ALC662_LENOVO_101E] = { 18248 .mixers = { alc662_lenovo_101e_mixer }, 18249 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs }, 18250 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18251 .dac_nids = alc662_dac_nids, 18252 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18253 .channel_mode = alc662_3ST_2ch_modes, 18254 .input_mux = &alc662_lenovo_101e_capture_source, 18255 .unsol_event = alc662_lenovo_101e_unsol_event, 18256 .init_hook = alc662_lenovo_101e_all_automute, 18257 }, 18258 [ALC662_ASUS_EEEPC_P701] = { 18259 .mixers = { alc662_eeepc_p701_mixer }, 18260 .init_verbs = { alc662_init_verbs, 18261 alc662_eeepc_sue_init_verbs }, 18262 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18263 .dac_nids = alc662_dac_nids, 18264 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18265 .channel_mode = alc662_3ST_2ch_modes, 18266 .unsol_event = alc662_eeepc_unsol_event, 18267 .setup = alc662_eeepc_setup, 18268 .init_hook = alc662_eeepc_inithook, 18269 }, 18270 [ALC662_ASUS_EEEPC_EP20] = { 18271 .mixers = { alc662_eeepc_ep20_mixer, 18272 alc662_chmode_mixer }, 18273 .init_verbs = { alc662_init_verbs, 18274 alc662_eeepc_ep20_sue_init_verbs }, 18275 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18276 .dac_nids = alc662_dac_nids, 18277 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), 18278 .channel_mode = alc662_3ST_6ch_modes, 18279 .input_mux = &alc662_lenovo_101e_capture_source, 18280 .unsol_event = alc662_eeepc_unsol_event, 18281 .setup = alc662_eeepc_ep20_setup, 18282 .init_hook = alc662_eeepc_ep20_inithook, 18283 }, 18284 [ALC662_ECS] = { 18285 .mixers = { alc662_ecs_mixer }, 18286 .init_verbs = { alc662_init_verbs, 18287 alc662_ecs_init_verbs }, 18288 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18289 .dac_nids = alc662_dac_nids, 18290 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18291 .channel_mode = alc662_3ST_2ch_modes, 18292 .unsol_event = alc662_eeepc_unsol_event, 18293 .setup = alc662_eeepc_setup, 18294 .init_hook = alc662_eeepc_inithook, 18295 }, 18296 [ALC663_ASUS_M51VA] = { 18297 .mixers = { alc663_m51va_mixer }, 18298 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs }, 18299 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18300 .dac_nids = alc662_dac_nids, 18301 .dig_out_nid = ALC662_DIGOUT_NID, 18302 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18303 .channel_mode = alc662_3ST_2ch_modes, 18304 .unsol_event = alc663_m51va_unsol_event, 18305 .setup = alc663_m51va_setup, 18306 .init_hook = alc663_m51va_inithook, 18307 }, 18308 [ALC663_ASUS_G71V] = { 18309 .mixers = { alc663_g71v_mixer }, 18310 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs }, 18311 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18312 .dac_nids = alc662_dac_nids, 18313 .dig_out_nid = ALC662_DIGOUT_NID, 18314 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18315 .channel_mode = alc662_3ST_2ch_modes, 18316 .unsol_event = alc663_g71v_unsol_event, 18317 .setup = alc663_g71v_setup, 18318 .init_hook = alc663_g71v_inithook, 18319 }, 18320 [ALC663_ASUS_H13] = { 18321 .mixers = { alc663_m51va_mixer }, 18322 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs }, 18323 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18324 .dac_nids = alc662_dac_nids, 18325 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18326 .channel_mode = alc662_3ST_2ch_modes, 18327 .unsol_event = alc663_m51va_unsol_event, 18328 .init_hook = alc663_m51va_inithook, 18329 }, 18330 [ALC663_ASUS_G50V] = { 18331 .mixers = { alc663_g50v_mixer }, 18332 .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs }, 18333 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18334 .dac_nids = alc662_dac_nids, 18335 .dig_out_nid = ALC662_DIGOUT_NID, 18336 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), 18337 .channel_mode = alc662_3ST_6ch_modes, 18338 .input_mux = &alc663_capture_source, 18339 .unsol_event = alc663_g50v_unsol_event, 18340 .setup = alc663_g50v_setup, 18341 .init_hook = alc663_g50v_inithook, 18342 }, 18343 [ALC663_ASUS_MODE1] = { 18344 .mixers = { alc663_m51va_mixer }, 18345 .cap_mixer = alc662_auto_capture_mixer, 18346 .init_verbs = { alc662_init_verbs, 18347 alc663_21jd_amic_init_verbs }, 18348 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18349 .hp_nid = 0x03, 18350 .dac_nids = alc662_dac_nids, 18351 .dig_out_nid = ALC662_DIGOUT_NID, 18352 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18353 .channel_mode = alc662_3ST_2ch_modes, 18354 .unsol_event = alc663_mode1_unsol_event, 18355 .setup = alc663_mode1_setup, 18356 .init_hook = alc663_mode1_inithook, 18357 }, 18358 [ALC662_ASUS_MODE2] = { 18359 .mixers = { alc662_1bjd_mixer }, 18360 .cap_mixer = alc662_auto_capture_mixer, 18361 .init_verbs = { alc662_init_verbs, 18362 alc662_1bjd_amic_init_verbs }, 18363 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18364 .dac_nids = alc662_dac_nids, 18365 .dig_out_nid = ALC662_DIGOUT_NID, 18366 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18367 .channel_mode = alc662_3ST_2ch_modes, 18368 .unsol_event = alc662_mode2_unsol_event, 18369 .setup = alc662_mode2_setup, 18370 .init_hook = alc662_mode2_inithook, 18371 }, 18372 [ALC663_ASUS_MODE3] = { 18373 .mixers = { alc663_two_hp_m1_mixer }, 18374 .cap_mixer = alc662_auto_capture_mixer, 18375 .init_verbs = { alc662_init_verbs, 18376 alc663_two_hp_amic_m1_init_verbs }, 18377 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18378 .hp_nid = 0x03, 18379 .dac_nids = alc662_dac_nids, 18380 .dig_out_nid = ALC662_DIGOUT_NID, 18381 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18382 .channel_mode = alc662_3ST_2ch_modes, 18383 .unsol_event = alc663_mode3_unsol_event, 18384 .setup = alc663_mode3_setup, 18385 .init_hook = alc663_mode3_inithook, 18386 }, 18387 [ALC663_ASUS_MODE4] = { 18388 .mixers = { alc663_asus_21jd_clfe_mixer }, 18389 .cap_mixer = alc662_auto_capture_mixer, 18390 .init_verbs = { alc662_init_verbs, 18391 alc663_21jd_amic_init_verbs}, 18392 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18393 .hp_nid = 0x03, 18394 .dac_nids = alc662_dac_nids, 18395 .dig_out_nid = ALC662_DIGOUT_NID, 18396 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18397 .channel_mode = alc662_3ST_2ch_modes, 18398 .unsol_event = alc663_mode4_unsol_event, 18399 .setup = alc663_mode4_setup, 18400 .init_hook = alc663_mode4_inithook, 18401 }, 18402 [ALC663_ASUS_MODE5] = { 18403 .mixers = { alc663_asus_15jd_clfe_mixer }, 18404 .cap_mixer = alc662_auto_capture_mixer, 18405 .init_verbs = { alc662_init_verbs, 18406 alc663_15jd_amic_init_verbs }, 18407 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18408 .hp_nid = 0x03, 18409 .dac_nids = alc662_dac_nids, 18410 .dig_out_nid = ALC662_DIGOUT_NID, 18411 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18412 .channel_mode = alc662_3ST_2ch_modes, 18413 .unsol_event = alc663_mode5_unsol_event, 18414 .setup = alc663_mode5_setup, 18415 .init_hook = alc663_mode5_inithook, 18416 }, 18417 [ALC663_ASUS_MODE6] = { 18418 .mixers = { alc663_two_hp_m2_mixer }, 18419 .cap_mixer = alc662_auto_capture_mixer, 18420 .init_verbs = { alc662_init_verbs, 18421 alc663_two_hp_amic_m2_init_verbs }, 18422 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18423 .hp_nid = 0x03, 18424 .dac_nids = alc662_dac_nids, 18425 .dig_out_nid = ALC662_DIGOUT_NID, 18426 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18427 .channel_mode = alc662_3ST_2ch_modes, 18428 .unsol_event = alc663_mode6_unsol_event, 18429 .setup = alc663_mode6_setup, 18430 .init_hook = alc663_mode6_inithook, 18431 }, 18432 [ALC663_ASUS_MODE7] = { 18433 .mixers = { alc663_mode7_mixer }, 18434 .cap_mixer = alc662_auto_capture_mixer, 18435 .init_verbs = { alc662_init_verbs, 18436 alc663_mode7_init_verbs }, 18437 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18438 .hp_nid = 0x03, 18439 .dac_nids = alc662_dac_nids, 18440 .dig_out_nid = ALC662_DIGOUT_NID, 18441 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18442 .channel_mode = alc662_3ST_2ch_modes, 18443 .unsol_event = alc663_mode7_unsol_event, 18444 .setup = alc663_mode7_setup, 18445 .init_hook = alc663_mode7_inithook, 18446 }, 18447 [ALC663_ASUS_MODE8] = { 18448 .mixers = { alc663_mode8_mixer }, 18449 .cap_mixer = alc662_auto_capture_mixer, 18450 .init_verbs = { alc662_init_verbs, 18451 alc663_mode8_init_verbs }, 18452 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18453 .hp_nid = 0x03, 18454 .dac_nids = alc662_dac_nids, 18455 .dig_out_nid = ALC662_DIGOUT_NID, 18456 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18457 .channel_mode = alc662_3ST_2ch_modes, 18458 .unsol_event = alc663_mode8_unsol_event, 18459 .setup = alc663_mode8_setup, 18460 .init_hook = alc663_mode8_inithook, 18461 }, 18462 [ALC272_DELL] = { 18463 .mixers = { alc663_m51va_mixer }, 18464 .cap_mixer = alc272_auto_capture_mixer, 18465 .init_verbs = { alc662_init_verbs, alc272_dell_init_verbs }, 18466 .num_dacs = ARRAY_SIZE(alc272_dac_nids), 18467 .dac_nids = alc662_dac_nids, 18468 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18469 .adc_nids = alc272_adc_nids, 18470 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids), 18471 .capsrc_nids = alc272_capsrc_nids, 18472 .channel_mode = alc662_3ST_2ch_modes, 18473 .unsol_event = alc663_m51va_unsol_event, 18474 .setup = alc663_m51va_setup, 18475 .init_hook = alc663_m51va_inithook, 18476 }, 18477 [ALC272_DELL_ZM1] = { 18478 .mixers = { alc663_m51va_mixer }, 18479 .cap_mixer = alc662_auto_capture_mixer, 18480 .init_verbs = { alc662_init_verbs, alc272_dell_zm1_init_verbs }, 18481 .num_dacs = ARRAY_SIZE(alc272_dac_nids), 18482 .dac_nids = alc662_dac_nids, 18483 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18484 .adc_nids = alc662_adc_nids, 18485 .num_adc_nids = 1, 18486 .capsrc_nids = alc662_capsrc_nids, 18487 .channel_mode = alc662_3ST_2ch_modes, 18488 .unsol_event = alc663_m51va_unsol_event, 18489 .setup = alc663_m51va_setup, 18490 .init_hook = alc663_m51va_inithook, 18491 }, 18492 [ALC272_SAMSUNG_NC10] = { 18493 .mixers = { alc272_nc10_mixer }, 18494 .init_verbs = { alc662_init_verbs, 18495 alc663_21jd_amic_init_verbs }, 18496 .num_dacs = ARRAY_SIZE(alc272_dac_nids), 18497 .dac_nids = alc272_dac_nids, 18498 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18499 .channel_mode = alc662_3ST_2ch_modes, 18500 /*.input_mux = &alc272_nc10_capture_source,*/ 18501 .unsol_event = alc663_mode4_unsol_event, 18502 .setup = alc663_mode4_setup, 18503 .init_hook = alc663_mode4_inithook, 18504 }, 18505}; 18506 18507 18508/* 18509 * BIOS auto configuration 18510 */ 18511 18512/* convert from MIX nid to DAC */ 18513static inline hda_nid_t alc662_mix_to_dac(hda_nid_t nid) 18514{ 18515 if (nid == 0x0f) 18516 return 0x02; 18517 else if (nid >= 0x0c && nid <= 0x0e) 18518 return nid - 0x0c + 0x02; 18519 else 18520 return 0; 18521} 18522 18523/* get MIX nid connected to the given pin targeted to DAC */ 18524static hda_nid_t alc662_dac_to_mix(struct hda_codec *codec, hda_nid_t pin, 18525 hda_nid_t dac) 18526{ 18527 hda_nid_t mix[4]; 18528 int i, num; 18529 18530 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix)); 18531 for (i = 0; i < num; i++) { 18532 if (alc662_mix_to_dac(mix[i]) == dac) 18533 return mix[i]; 18534 } 18535 return 0; 18536} 18537 18538/* look for an empty DAC slot */ 18539static hda_nid_t alc662_look_for_dac(struct hda_codec *codec, hda_nid_t pin) 18540{ 18541 struct alc_spec *spec = codec->spec; 18542 hda_nid_t srcs[5]; 18543 int i, j, num; 18544 18545 num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs)); 18546 if (num < 0) 18547 return 0; 18548 for (i = 0; i < num; i++) { 18549 hda_nid_t nid = alc662_mix_to_dac(srcs[i]); 18550 if (!nid) 18551 continue; 18552 for (j = 0; j < spec->multiout.num_dacs; j++) 18553 if (spec->multiout.dac_nids[j] == nid) 18554 break; 18555 if (j >= spec->multiout.num_dacs) 18556 return nid; 18557 } 18558 return 0; 18559} 18560 18561/* fill in the dac_nids table from the parsed pin configuration */ 18562static int alc662_auto_fill_dac_nids(struct hda_codec *codec, 18563 const struct auto_pin_cfg *cfg) 18564{ 18565 struct alc_spec *spec = codec->spec; 18566 int i; 18567 hda_nid_t dac; 18568 18569 spec->multiout.dac_nids = spec->private_dac_nids; 18570 for (i = 0; i < cfg->line_outs; i++) { 18571 dac = alc662_look_for_dac(codec, cfg->line_out_pins[i]); 18572 if (!dac) 18573 continue; 18574 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac; 18575 } 18576 return 0; 18577} 18578 18579static inline int alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx, 18580 hda_nid_t nid, unsigned int chs) 18581{ 18582 return add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, 18583 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT)); 18584} 18585 18586static inline int alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx, 18587 hda_nid_t nid, unsigned int chs) 18588{ 18589 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, 18590 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT)); 18591} 18592 18593#define alc662_add_stereo_vol(spec, pfx, nid) \ 18594 alc662_add_vol_ctl(spec, pfx, nid, 3) 18595#define alc662_add_stereo_sw(spec, pfx, nid) \ 18596 alc662_add_sw_ctl(spec, pfx, nid, 3) 18597 18598/* add playback controls from the parsed DAC table */ 18599static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec, 18600 const struct auto_pin_cfg *cfg) 18601{ 18602 struct alc_spec *spec = codec->spec; 18603 static const char *chname[4] = { 18604 "Front", "Surround", NULL /*CLFE*/, "Side" 18605 }; 18606 hda_nid_t nid, mix; 18607 int i, err; 18608 18609 for (i = 0; i < cfg->line_outs; i++) { 18610 nid = spec->multiout.dac_nids[i]; 18611 if (!nid) 18612 continue; 18613 mix = alc662_dac_to_mix(codec, cfg->line_out_pins[i], nid); 18614 if (!mix) 18615 continue; 18616 if (i == 2) { 18617 /* Center/LFE */ 18618 err = alc662_add_vol_ctl(spec, "Center", nid, 1); 18619 if (err < 0) 18620 return err; 18621 err = alc662_add_vol_ctl(spec, "LFE", nid, 2); 18622 if (err < 0) 18623 return err; 18624 err = alc662_add_sw_ctl(spec, "Center", mix, 1); 18625 if (err < 0) 18626 return err; 18627 err = alc662_add_sw_ctl(spec, "LFE", mix, 2); 18628 if (err < 0) 18629 return err; 18630 } else { 18631 const char *pfx; 18632 if (cfg->line_outs == 1 && 18633 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) { 18634 if (cfg->hp_outs) 18635 pfx = "Speaker"; 18636 else 18637 pfx = "PCM"; 18638 } else 18639 pfx = chname[i]; 18640 err = alc662_add_vol_ctl(spec, pfx, nid, 3); 18641 if (err < 0) 18642 return err; 18643 if (cfg->line_outs == 1 && 18644 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) 18645 pfx = "Speaker"; 18646 err = alc662_add_sw_ctl(spec, pfx, mix, 3); 18647 if (err < 0) 18648 return err; 18649 } 18650 } 18651 return 0; 18652} 18653 18654/* add playback controls for speaker and HP outputs */ 18655/* return DAC nid if any new DAC is assigned */ 18656static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin, 18657 const char *pfx) 18658{ 18659 struct alc_spec *spec = codec->spec; 18660 hda_nid_t nid, mix; 18661 int err; 18662 18663 if (!pin) 18664 return 0; 18665 nid = alc662_look_for_dac(codec, pin); 18666 if (!nid) { 18667 /* the corresponding DAC is already occupied */ 18668 if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP)) 18669 return 0; /* no way */ 18670 /* create a switch only */ 18671 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, 18672 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); 18673 } 18674 18675 mix = alc662_dac_to_mix(codec, pin, nid); 18676 if (!mix) 18677 return 0; 18678 err = alc662_add_vol_ctl(spec, pfx, nid, 3); 18679 if (err < 0) 18680 return err; 18681 err = alc662_add_sw_ctl(spec, pfx, mix, 3); 18682 if (err < 0) 18683 return err; 18684 return nid; 18685} 18686 18687/* create playback/capture controls for input pins */ 18688#define alc662_auto_create_input_ctls \ 18689 alc882_auto_create_input_ctls 18690 18691static void alc662_auto_set_output_and_unmute(struct hda_codec *codec, 18692 hda_nid_t nid, int pin_type, 18693 hda_nid_t dac) 18694{ 18695 int i, num; 18696 hda_nid_t srcs[HDA_MAX_CONNECTIONS]; 18697 18698 alc_set_pin_output(codec, nid, pin_type); 18699 /* need the manual connection? */ 18700 num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs)); 18701 if (num <= 1) 18702 return; 18703 for (i = 0; i < num; i++) { 18704 if (alc662_mix_to_dac(srcs[i]) != dac) 18705 continue; 18706 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, i); 18707 return; 18708 } 18709} 18710 18711static void alc662_auto_init_multi_out(struct hda_codec *codec) 18712{ 18713 struct alc_spec *spec = codec->spec; 18714 int pin_type = get_pin_type(spec->autocfg.line_out_type); 18715 int i; 18716 18717 for (i = 0; i <= HDA_SIDE; i++) { 18718 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 18719 if (nid) 18720 alc662_auto_set_output_and_unmute(codec, nid, pin_type, 18721 spec->multiout.dac_nids[i]); 18722 } 18723} 18724 18725static void alc662_auto_init_hp_out(struct hda_codec *codec) 18726{ 18727 struct alc_spec *spec = codec->spec; 18728 hda_nid_t pin; 18729 18730 pin = spec->autocfg.hp_pins[0]; 18731 if (pin) 18732 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 18733 spec->multiout.hp_nid); 18734 pin = spec->autocfg.speaker_pins[0]; 18735 if (pin) 18736 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT, 18737 spec->multiout.extra_out_nid[0]); 18738} 18739 18740#define ALC662_PIN_CD_NID ALC880_PIN_CD_NID 18741 18742static void alc662_auto_init_analog_input(struct hda_codec *codec) 18743{ 18744 struct alc_spec *spec = codec->spec; 18745 int i; 18746 18747 for (i = 0; i < AUTO_PIN_LAST; i++) { 18748 hda_nid_t nid = spec->autocfg.input_pins[i]; 18749 if (alc_is_input_pin(codec, nid)) { 18750 alc_set_input_pin(codec, nid, i); 18751 if (nid != ALC662_PIN_CD_NID && 18752 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)) 18753 snd_hda_codec_write(codec, nid, 0, 18754 AC_VERB_SET_AMP_GAIN_MUTE, 18755 AMP_OUT_MUTE); 18756 } 18757 } 18758} 18759 18760#define alc662_auto_init_input_src alc882_auto_init_input_src 18761 18762static int alc662_parse_auto_config(struct hda_codec *codec) 18763{ 18764 struct alc_spec *spec = codec->spec; 18765 int err; 18766 static hda_nid_t alc662_ignore[] = { 0x1d, 0 }; 18767 18768 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 18769 alc662_ignore); 18770 if (err < 0) 18771 return err; 18772 if (!spec->autocfg.line_outs) 18773 return 0; /* can't find valid BIOS pin config */ 18774 18775 err = alc662_auto_fill_dac_nids(codec, &spec->autocfg); 18776 if (err < 0) 18777 return err; 18778 err = alc662_auto_create_multi_out_ctls(codec, &spec->autocfg); 18779 if (err < 0) 18780 return err; 18781 err = alc662_auto_create_extra_out(codec, 18782 spec->autocfg.speaker_pins[0], 18783 "Speaker"); 18784 if (err < 0) 18785 return err; 18786 if (err) 18787 spec->multiout.extra_out_nid[0] = err; 18788 err = alc662_auto_create_extra_out(codec, spec->autocfg.hp_pins[0], 18789 "Headphone"); 18790 if (err < 0) 18791 return err; 18792 if (err) 18793 spec->multiout.hp_nid = err; 18794 err = alc662_auto_create_input_ctls(codec, &spec->autocfg); 18795 if (err < 0) 18796 return err; 18797 18798 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 18799 18800 alc_auto_parse_digital(codec); 18801 18802 if (spec->kctls.list) 18803 add_mixer(spec, spec->kctls.list); 18804 18805 spec->num_mux_defs = 1; 18806 spec->input_mux = &spec->private_imux[0]; 18807 18808 add_verb(spec, alc662_init_verbs); 18809 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 || 18810 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670) 18811 add_verb(spec, alc663_init_verbs); 18812 18813 if (codec->vendor_id == 0x10ec0272) 18814 add_verb(spec, alc272_init_verbs); 18815 18816 err = alc_auto_add_mic_boost(codec); 18817 if (err < 0) 18818 return err; 18819 18820 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 || 18821 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670) 18822 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0x21); 18823 else 18824 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); 18825 18826 return 1; 18827} 18828 18829/* additional initialization for auto-configuration model */ 18830static void alc662_auto_init(struct hda_codec *codec) 18831{ 18832 struct alc_spec *spec = codec->spec; 18833 alc662_auto_init_multi_out(codec); 18834 alc662_auto_init_hp_out(codec); 18835 alc662_auto_init_analog_input(codec); 18836 alc662_auto_init_input_src(codec); 18837 alc_auto_init_digital(codec); 18838 if (spec->unsol_event) 18839 alc_inithook(codec); 18840} 18841 18842static int patch_alc662(struct hda_codec *codec) 18843{ 18844 struct alc_spec *spec; 18845 int err, board_config; 18846 18847 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 18848 if (!spec) 18849 return -ENOMEM; 18850 18851 codec->spec = spec; 18852 18853 alc_auto_parse_customize_define(codec); 18854 18855 alc_fix_pll_init(codec, 0x20, 0x04, 15); 18856 18857 if (alc_read_coef_idx(codec, 0) == 0x8020) 18858 alc_codec_rename(codec, "ALC661"); 18859 else if ((alc_read_coef_idx(codec, 0) & (1 << 14)) && 18860 codec->bus->pci->subsystem_vendor == 0x1025 && 18861 spec->cdefine.platform_type == 1) 18862 alc_codec_rename(codec, "ALC272X"); 18863 18864 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST, 18865 alc662_models, 18866 alc662_cfg_tbl); 18867 if (board_config < 0) { 18868 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 18869 codec->chip_name); 18870 board_config = ALC662_AUTO; 18871 } 18872 18873 if (board_config == ALC662_AUTO) { 18874 /* automatic parse from the BIOS config */ 18875 err = alc662_parse_auto_config(codec); 18876 if (err < 0) { 18877 alc_free(codec); 18878 return err; 18879 } else if (!err) { 18880 printk(KERN_INFO 18881 "hda_codec: Cannot set up configuration " 18882 "from BIOS. Using base mode...\n"); 18883 board_config = ALC662_3ST_2ch_DIG; 18884 } 18885 } 18886 18887 if (has_cdefine_beep(codec)) { 18888 err = snd_hda_attach_beep_device(codec, 0x1); 18889 if (err < 0) { 18890 alc_free(codec); 18891 return err; 18892 } 18893 } 18894 18895 if (board_config != ALC662_AUTO) 18896 setup_preset(codec, &alc662_presets[board_config]); 18897 18898 spec->stream_analog_playback = &alc662_pcm_analog_playback; 18899 spec->stream_analog_capture = &alc662_pcm_analog_capture; 18900 18901 spec->stream_digital_playback = &alc662_pcm_digital_playback; 18902 spec->stream_digital_capture = &alc662_pcm_digital_capture; 18903 18904 if (!spec->adc_nids) { 18905 spec->adc_nids = alc662_adc_nids; 18906 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids); 18907 } 18908 if (!spec->capsrc_nids) 18909 spec->capsrc_nids = alc662_capsrc_nids; 18910 18911 if (!spec->cap_mixer) 18912 set_capture_mixer(codec); 18913 18914 if (has_cdefine_beep(codec)) { 18915 switch (codec->vendor_id) { 18916 case 0x10ec0662: 18917 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 18918 break; 18919 case 0x10ec0272: 18920 case 0x10ec0663: 18921 case 0x10ec0665: 18922 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); 18923 break; 18924 case 0x10ec0273: 18925 set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT); 18926 break; 18927 } 18928 } 18929 spec->vmaster_nid = 0x02; 18930 18931 codec->patch_ops = alc_patch_ops; 18932 if (board_config == ALC662_AUTO) 18933 spec->init_hook = alc662_auto_init; 18934#ifdef CONFIG_SND_HDA_POWER_SAVE 18935 if (!spec->loopback.amplist) 18936 spec->loopback.amplist = alc662_loopbacks; 18937#endif 18938 18939 return 0; 18940} 18941 18942static int patch_alc888(struct hda_codec *codec) 18943{ 18944 if ((alc_read_coef_idx(codec, 0) & 0x00f0)==0x0030){ 18945 kfree(codec->chip_name); 18946 codec->chip_name = kstrdup("ALC888-VD", GFP_KERNEL); 18947 if (!codec->chip_name) { 18948 alc_free(codec); 18949 return -ENOMEM; 18950 } 18951 return patch_alc662(codec); 18952 } 18953 return patch_alc882(codec); 18954} 18955 18956/* 18957 * ALC680 support 18958 */ 18959#define ALC680_DIGOUT_NID ALC880_DIGOUT_NID 18960#define alc680_modes alc260_modes 18961 18962static hda_nid_t alc680_dac_nids[3] = { 18963 /* Lout1, Lout2, hp */ 18964 0x02, 0x03, 0x04 18965}; 18966 18967static hda_nid_t alc680_adc_nids[3] = { 18968 /* ADC0-2 */ 18969 /* DMIC, MIC, Line-in*/ 18970 0x07, 0x08, 0x09 18971}; 18972 18973static struct snd_kcontrol_new alc680_base_mixer[] = { 18974 /* output mixer control */ 18975 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), 18976 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 18977 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT), 18978 HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT), 18979 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 18980 { } 18981}; 18982 18983static struct snd_kcontrol_new alc680_capture_mixer[] = { 18984 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT), 18985 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT), 18986 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT), 18987 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT), 18988 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT), 18989 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT), 18990 { } /* end */ 18991}; 18992 18993/* 18994 * generic initialization of ADC, input mixers and output mixers 18995 */ 18996static struct hda_verb alc680_init_verbs[] = { 18997 /* Unmute DAC0-1 and set vol = 0 */ 18998 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 18999 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 19000 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 19001 19002 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 19003 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 19004 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 19005 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 19006 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 19007 19008 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 19009 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 19010 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 19011 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 19012 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 19013 { } 19014}; 19015 19016/* create input playback/capture controls for the given pin */ 19017static int alc680_new_analog_output(struct alc_spec *spec, hda_nid_t nid, 19018 const char *ctlname, int idx) 19019{ 19020 hda_nid_t dac; 19021 int err; 19022 19023 switch (nid) { 19024 case 0x14: 19025 dac = 0x02; 19026 break; 19027 case 0x15: 19028 dac = 0x03; 19029 break; 19030 case 0x16: 19031 dac = 0x04; 19032 break; 19033 default: 19034 return 0; 19035 } 19036 if (spec->multiout.dac_nids[0] != dac && 19037 spec->multiout.dac_nids[1] != dac) { 19038 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname, 19039 HDA_COMPOSE_AMP_VAL(dac, 3, idx, 19040 HDA_OUTPUT)); 19041 if (err < 0) 19042 return err; 19043 19044 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname, 19045 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT)); 19046 19047 if (err < 0) 19048 return err; 19049 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac; 19050 } 19051 19052 return 0; 19053} 19054 19055/* add playback controls from the parsed DAC table */ 19056static int alc680_auto_create_multi_out_ctls(struct alc_spec *spec, 19057 const struct auto_pin_cfg *cfg) 19058{ 19059 hda_nid_t nid; 19060 int err; 19061 19062 spec->multiout.dac_nids = spec->private_dac_nids; 19063 19064 nid = cfg->line_out_pins[0]; 19065 if (nid) { 19066 const char *name; 19067 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) 19068 name = "Speaker"; 19069 else 19070 name = "Front"; 19071 err = alc680_new_analog_output(spec, nid, name, 0); 19072 if (err < 0) 19073 return err; 19074 } 19075 19076 nid = cfg->speaker_pins[0]; 19077 if (nid) { 19078 err = alc680_new_analog_output(spec, nid, "Speaker", 0); 19079 if (err < 0) 19080 return err; 19081 } 19082 nid = cfg->hp_pins[0]; 19083 if (nid) { 19084 err = alc680_new_analog_output(spec, nid, "Headphone", 0); 19085 if (err < 0) 19086 return err; 19087 } 19088 19089 return 0; 19090} 19091 19092static void alc680_auto_set_output_and_unmute(struct hda_codec *codec, 19093 hda_nid_t nid, int pin_type) 19094{ 19095 alc_set_pin_output(codec, nid, pin_type); 19096} 19097 19098static void alc680_auto_init_multi_out(struct hda_codec *codec) 19099{ 19100 struct alc_spec *spec = codec->spec; 19101 hda_nid_t nid = spec->autocfg.line_out_pins[0]; 19102 if (nid) { 19103 int pin_type = get_pin_type(spec->autocfg.line_out_type); 19104 alc680_auto_set_output_and_unmute(codec, nid, pin_type); 19105 } 19106} 19107 19108static void alc680_auto_init_hp_out(struct hda_codec *codec) 19109{ 19110 struct alc_spec *spec = codec->spec; 19111 hda_nid_t pin; 19112 19113 pin = spec->autocfg.hp_pins[0]; 19114 if (pin) 19115 alc680_auto_set_output_and_unmute(codec, pin, PIN_HP); 19116 pin = spec->autocfg.speaker_pins[0]; 19117 if (pin) 19118 alc680_auto_set_output_and_unmute(codec, pin, PIN_OUT); 19119} 19120 19121/* pcm configuration: identical with ALC880 */ 19122#define alc680_pcm_analog_playback alc880_pcm_analog_playback 19123#define alc680_pcm_analog_capture alc880_pcm_analog_capture 19124#define alc680_pcm_analog_alt_capture alc880_pcm_analog_alt_capture 19125#define alc680_pcm_digital_playback alc880_pcm_digital_playback 19126 19127static struct hda_input_mux alc680_capture_source = { 19128 .num_items = 1, 19129 .items = { 19130 { "Mic", 0x0 }, 19131 }, 19132}; 19133 19134/* 19135 * BIOS auto configuration 19136 */ 19137static int alc680_parse_auto_config(struct hda_codec *codec) 19138{ 19139 struct alc_spec *spec = codec->spec; 19140 int err; 19141 static hda_nid_t alc680_ignore[] = { 0 }; 19142 19143 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 19144 alc680_ignore); 19145 if (err < 0) 19146 return err; 19147 if (!spec->autocfg.line_outs) { 19148 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) { 19149 spec->multiout.max_channels = 2; 19150 spec->no_analog = 1; 19151 goto dig_only; 19152 } 19153 return 0; /* can't find valid BIOS pin config */ 19154 } 19155 err = alc680_auto_create_multi_out_ctls(spec, &spec->autocfg); 19156 if (err < 0) 19157 return err; 19158 19159 spec->multiout.max_channels = 2; 19160 19161 dig_only: 19162 /* digital only support output */ 19163 alc_auto_parse_digital(codec); 19164 if (spec->kctls.list) 19165 add_mixer(spec, spec->kctls.list); 19166 19167 add_verb(spec, alc680_init_verbs); 19168 spec->num_mux_defs = 1; 19169 spec->input_mux = &alc680_capture_source; 19170 19171 err = alc_auto_add_mic_boost(codec); 19172 if (err < 0) 19173 return err; 19174 19175 return 1; 19176} 19177 19178#define alc680_auto_init_analog_input alc882_auto_init_analog_input 19179 19180/* init callback for auto-configuration model -- overriding the default init */ 19181static void alc680_auto_init(struct hda_codec *codec) 19182{ 19183 struct alc_spec *spec = codec->spec; 19184 alc680_auto_init_multi_out(codec); 19185 alc680_auto_init_hp_out(codec); 19186 alc680_auto_init_analog_input(codec); 19187 alc_auto_init_digital(codec); 19188 if (spec->unsol_event) 19189 alc_inithook(codec); 19190} 19191 19192/* 19193 * configuration and preset 19194 */ 19195static const char *alc680_models[ALC680_MODEL_LAST] = { 19196 [ALC680_BASE] = "base", 19197 [ALC680_AUTO] = "auto", 19198}; 19199 19200static struct snd_pci_quirk alc680_cfg_tbl[] = { 19201 SND_PCI_QUIRK(0x1043, 0x12f3, "ASUS NX90", ALC680_BASE), 19202 {} 19203}; 19204 19205static struct alc_config_preset alc680_presets[] = { 19206 [ALC680_BASE] = { 19207 .mixers = { alc680_base_mixer }, 19208 .cap_mixer = alc680_capture_mixer, 19209 .init_verbs = { alc680_init_verbs }, 19210 .num_dacs = ARRAY_SIZE(alc680_dac_nids), 19211 .dac_nids = alc680_dac_nids, 19212 .num_adc_nids = ARRAY_SIZE(alc680_adc_nids), 19213 .adc_nids = alc680_adc_nids, 19214 .hp_nid = 0x04, 19215 .dig_out_nid = ALC680_DIGOUT_NID, 19216 .num_channel_mode = ARRAY_SIZE(alc680_modes), 19217 .channel_mode = alc680_modes, 19218 .input_mux = &alc680_capture_source, 19219 }, 19220}; 19221 19222static int patch_alc680(struct hda_codec *codec) 19223{ 19224 struct alc_spec *spec; 19225 int board_config; 19226 int err; 19227 19228 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 19229 if (spec == NULL) 19230 return -ENOMEM; 19231 19232 codec->spec = spec; 19233 19234 board_config = snd_hda_check_board_config(codec, ALC680_MODEL_LAST, 19235 alc680_models, 19236 alc680_cfg_tbl); 19237 19238 if (board_config < 0 || board_config >= ALC680_MODEL_LAST) { 19239 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 19240 codec->chip_name); 19241 board_config = ALC680_AUTO; 19242 } 19243 19244 if (board_config == ALC680_AUTO) { 19245 /* automatic parse from the BIOS config */ 19246 err = alc680_parse_auto_config(codec); 19247 if (err < 0) { 19248 alc_free(codec); 19249 return err; 19250 } else if (!err) { 19251 printk(KERN_INFO 19252 "hda_codec: Cannot set up configuration " 19253 "from BIOS. Using base mode...\n"); 19254 board_config = ALC680_BASE; 19255 } 19256 } 19257 19258 if (board_config != ALC680_AUTO) 19259 setup_preset(codec, &alc680_presets[board_config]); 19260 19261 spec->stream_analog_playback = &alc680_pcm_analog_playback; 19262 spec->stream_analog_capture = &alc680_pcm_analog_capture; 19263 spec->stream_analog_alt_capture = &alc680_pcm_analog_alt_capture; 19264 spec->stream_digital_playback = &alc680_pcm_digital_playback; 19265 19266 if (!spec->adc_nids) { 19267 spec->adc_nids = alc680_adc_nids; 19268 spec->num_adc_nids = ARRAY_SIZE(alc680_adc_nids); 19269 } 19270 19271 if (!spec->cap_mixer) 19272 set_capture_mixer(codec); 19273 19274 spec->vmaster_nid = 0x02; 19275 19276 codec->patch_ops = alc_patch_ops; 19277 if (board_config == ALC680_AUTO) 19278 spec->init_hook = alc680_auto_init; 19279 19280 return 0; 19281} 19282 19283/* 19284 * patch entries 19285 */ 19286static struct hda_codec_preset snd_hda_preset_realtek[] = { 19287 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 }, 19288 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 }, 19289 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 }, 19290 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 }, 19291 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 }, 19292 { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 }, 19293 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 }, 19294 { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 }, 19295 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660", 19296 .patch = patch_alc861 }, 19297 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd }, 19298 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 }, 19299 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd }, 19300 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2", 19301 .patch = patch_alc882 }, 19302 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1", 19303 .patch = patch_alc662 }, 19304 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 }, 19305 { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 }, 19306 { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 }, 19307 { .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 }, 19308 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 }, 19309 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 }, 19310 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 }, 19311 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A", 19312 .patch = patch_alc882 }, 19313 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A", 19314 .patch = patch_alc882 }, 19315 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 }, 19316 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc882 }, 19317 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200", 19318 .patch = patch_alc882 }, 19319 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc888 }, 19320 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 }, 19321 { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 }, 19322 {} /* terminator */ 19323}; 19324 19325MODULE_ALIAS("snd-hda-codec-id:10ec*"); 19326 19327MODULE_LICENSE("GPL"); 19328MODULE_DESCRIPTION("Realtek HD-audio codec"); 19329 19330static struct hda_codec_preset_list realtek_list = { 19331 .preset = snd_hda_preset_realtek, 19332 .owner = THIS_MODULE, 19333}; 19334 19335static int __init patch_realtek_init(void) 19336{ 19337 return snd_hda_add_codec_preset(&realtek_list); 19338} 19339 19340static void __exit patch_realtek_exit(void) 19341{ 19342 snd_hda_delete_codec_preset(&realtek_list); 19343} 19344 19345module_init(patch_realtek_init) 19346module_exit(patch_realtek_exit) 19347