patch_realtek.c revision dfed0ef9b3ff9e37903920b6938ed33344ad0b3d
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_ASUS_EEEPC_P703, 135 ALC269_ASUS_EEEPC_P901, 136 ALC269_FUJITSU, 137 ALC269_LIFEBOOK, 138 ALC269_AUTO, 139 ALC269_MODEL_LAST /* last tag */ 140}; 141 142/* ALC861 models */ 143enum { 144 ALC861_3ST, 145 ALC660_3ST, 146 ALC861_3ST_DIG, 147 ALC861_6ST_DIG, 148 ALC861_UNIWILL_M31, 149 ALC861_TOSHIBA, 150 ALC861_ASUS, 151 ALC861_ASUS_LAPTOP, 152 ALC861_AUTO, 153 ALC861_MODEL_LAST, 154}; 155 156/* ALC861-VD models */ 157enum { 158 ALC660VD_3ST, 159 ALC660VD_3ST_DIG, 160 ALC660VD_ASUS_V1S, 161 ALC861VD_3ST, 162 ALC861VD_3ST_DIG, 163 ALC861VD_6ST_DIG, 164 ALC861VD_LENOVO, 165 ALC861VD_DALLAS, 166 ALC861VD_HP, 167 ALC861VD_AUTO, 168 ALC861VD_MODEL_LAST, 169}; 170 171/* ALC662 models */ 172enum { 173 ALC662_3ST_2ch_DIG, 174 ALC662_3ST_6ch_DIG, 175 ALC662_3ST_6ch, 176 ALC662_5ST_DIG, 177 ALC662_LENOVO_101E, 178 ALC662_ASUS_EEEPC_P701, 179 ALC662_ASUS_EEEPC_EP20, 180 ALC663_ASUS_M51VA, 181 ALC663_ASUS_G71V, 182 ALC663_ASUS_H13, 183 ALC663_ASUS_G50V, 184 ALC662_ECS, 185 ALC663_ASUS_MODE1, 186 ALC662_ASUS_MODE2, 187 ALC663_ASUS_MODE3, 188 ALC663_ASUS_MODE4, 189 ALC663_ASUS_MODE5, 190 ALC663_ASUS_MODE6, 191 ALC272_DELL, 192 ALC272_DELL_ZM1, 193 ALC662_AUTO, 194 ALC662_MODEL_LAST, 195}; 196 197/* ALC882 models */ 198enum { 199 ALC882_3ST_DIG, 200 ALC882_6ST_DIG, 201 ALC882_ARIMA, 202 ALC882_W2JC, 203 ALC882_TARGA, 204 ALC882_ASUS_A7J, 205 ALC882_ASUS_A7M, 206 ALC885_MACPRO, 207 ALC885_MBP3, 208 ALC885_IMAC24, 209 ALC882_AUTO, 210 ALC882_MODEL_LAST, 211}; 212 213/* ALC883 models */ 214enum { 215 ALC883_3ST_2ch_DIG, 216 ALC883_3ST_6ch_DIG, 217 ALC883_3ST_6ch, 218 ALC883_6ST_DIG, 219 ALC883_TARGA_DIG, 220 ALC883_TARGA_2ch_DIG, 221 ALC883_ACER, 222 ALC883_ACER_ASPIRE, 223 ALC888_ACER_ASPIRE_4930G, 224 ALC883_MEDION, 225 ALC883_MEDION_MD2, 226 ALC883_LAPTOP_EAPD, 227 ALC883_LENOVO_101E_2ch, 228 ALC883_LENOVO_NB0763, 229 ALC888_LENOVO_MS7195_DIG, 230 ALC888_LENOVO_SKY, 231 ALC883_HAIER_W66, 232 ALC888_3ST_HP, 233 ALC888_6ST_DELL, 234 ALC883_MITAC, 235 ALC883_CLEVO_M720, 236 ALC883_FUJITSU_PI2515, 237 ALC888_FUJITSU_XA3530, 238 ALC883_3ST_6ch_INTEL, 239 ALC888_ASUS_M90V, 240 ALC888_ASUS_EEE1601, 241 ALC1200_ASUS_P5Q, 242 ALC883_AUTO, 243 ALC883_MODEL_LAST, 244}; 245 246/* styles of capture selection */ 247enum { 248 CAPT_MUX = 0, /* only mux based */ 249 CAPT_MIX, /* only mixer based */ 250 CAPT_1MUX_MIX, /* first mux and other mixers */ 251}; 252 253/* for GPIO Poll */ 254#define GPIO_MASK 0x03 255 256struct alc_spec { 257 /* codec parameterization */ 258 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */ 259 unsigned int num_mixers; 260 struct snd_kcontrol_new *cap_mixer; /* capture mixer */ 261 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */ 262 263 const struct hda_verb *init_verbs[5]; /* initialization verbs 264 * don't forget NULL 265 * termination! 266 */ 267 unsigned int num_init_verbs; 268 269 char *stream_name_analog; /* analog PCM stream */ 270 struct hda_pcm_stream *stream_analog_playback; 271 struct hda_pcm_stream *stream_analog_capture; 272 struct hda_pcm_stream *stream_analog_alt_playback; 273 struct hda_pcm_stream *stream_analog_alt_capture; 274 275 char *stream_name_digital; /* digital PCM stream */ 276 struct hda_pcm_stream *stream_digital_playback; 277 struct hda_pcm_stream *stream_digital_capture; 278 279 /* playback */ 280 struct hda_multi_out multiout; /* playback set-up 281 * max_channels, dacs must be set 282 * dig_out_nid and hp_nid are optional 283 */ 284 hda_nid_t alt_dac_nid; 285 hda_nid_t slave_dig_outs[3]; /* optional - for auto-parsing */ 286 int dig_out_type; 287 288 /* capture */ 289 unsigned int num_adc_nids; 290 hda_nid_t *adc_nids; 291 hda_nid_t *capsrc_nids; 292 hda_nid_t dig_in_nid; /* digital-in NID; optional */ 293 int capture_style; /* capture style (CAPT_*) */ 294 295 /* capture source */ 296 unsigned int num_mux_defs; 297 const struct hda_input_mux *input_mux; 298 unsigned int cur_mux[3]; 299 300 /* channel model */ 301 const struct hda_channel_mode *channel_mode; 302 int num_channel_mode; 303 int need_dac_fix; 304 305 /* PCM information */ 306 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */ 307 308 /* dynamic controls, init_verbs and input_mux */ 309 struct auto_pin_cfg autocfg; 310 struct snd_array kctls; 311 struct hda_input_mux private_imux[3]; 312 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; 313 314 /* hooks */ 315 void (*init_hook)(struct hda_codec *codec); 316 void (*unsol_event)(struct hda_codec *codec, unsigned int res); 317 318 /* for pin sensing */ 319 unsigned int sense_updated: 1; 320 unsigned int jack_present: 1; 321 unsigned int master_sw: 1; 322 323 /* other flags */ 324 unsigned int no_analog :1; /* digital I/O only */ 325 326 /* for virtual master */ 327 hda_nid_t vmaster_nid; 328#ifdef CONFIG_SND_HDA_POWER_SAVE 329 struct hda_loopback_check loopback; 330#endif 331 332 /* for PLL fix */ 333 hda_nid_t pll_nid; 334 unsigned int pll_coef_idx, pll_coef_bit; 335}; 336 337/* 338 * configuration template - to be copied to the spec instance 339 */ 340struct alc_config_preset { 341 struct snd_kcontrol_new *mixers[5]; /* should be identical size 342 * with spec 343 */ 344 struct snd_kcontrol_new *cap_mixer; /* capture mixer */ 345 const struct hda_verb *init_verbs[5]; 346 unsigned int num_dacs; 347 hda_nid_t *dac_nids; 348 hda_nid_t dig_out_nid; /* optional */ 349 hda_nid_t hp_nid; /* optional */ 350 hda_nid_t *slave_dig_outs; 351 unsigned int num_adc_nids; 352 hda_nid_t *adc_nids; 353 hda_nid_t *capsrc_nids; 354 hda_nid_t dig_in_nid; 355 unsigned int num_channel_mode; 356 const struct hda_channel_mode *channel_mode; 357 int need_dac_fix; 358 unsigned int num_mux_defs; 359 const struct hda_input_mux *input_mux; 360 void (*unsol_event)(struct hda_codec *, unsigned int); 361 void (*init_hook)(struct hda_codec *); 362#ifdef CONFIG_SND_HDA_POWER_SAVE 363 struct hda_amp_list *loopbacks; 364#endif 365}; 366 367 368/* 369 * input MUX handling 370 */ 371static int alc_mux_enum_info(struct snd_kcontrol *kcontrol, 372 struct snd_ctl_elem_info *uinfo) 373{ 374 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 375 struct alc_spec *spec = codec->spec; 376 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id); 377 if (mux_idx >= spec->num_mux_defs) 378 mux_idx = 0; 379 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo); 380} 381 382static int alc_mux_enum_get(struct snd_kcontrol *kcontrol, 383 struct snd_ctl_elem_value *ucontrol) 384{ 385 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 386 struct alc_spec *spec = codec->spec; 387 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 388 389 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx]; 390 return 0; 391} 392 393static int alc_mux_enum_put(struct snd_kcontrol *kcontrol, 394 struct snd_ctl_elem_value *ucontrol) 395{ 396 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 397 struct alc_spec *spec = codec->spec; 398 const struct hda_input_mux *imux; 399 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 400 unsigned int mux_idx; 401 hda_nid_t nid = spec->capsrc_nids ? 402 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx]; 403 404 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx; 405 imux = &spec->input_mux[mux_idx]; 406 407 if (spec->capture_style && 408 !(spec->capture_style == CAPT_1MUX_MIX && !adc_idx)) { 409 /* Matrix-mixer style (e.g. ALC882) */ 410 unsigned int *cur_val = &spec->cur_mux[adc_idx]; 411 unsigned int i, idx; 412 413 idx = ucontrol->value.enumerated.item[0]; 414 if (idx >= imux->num_items) 415 idx = imux->num_items - 1; 416 if (*cur_val == idx) 417 return 0; 418 for (i = 0; i < imux->num_items; i++) { 419 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE; 420 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 421 imux->items[i].index, 422 HDA_AMP_MUTE, v); 423 } 424 *cur_val = idx; 425 return 1; 426 } else { 427 /* MUX style (e.g. ALC880) */ 428 return snd_hda_input_mux_put(codec, imux, ucontrol, nid, 429 &spec->cur_mux[adc_idx]); 430 } 431} 432 433/* 434 * channel mode setting 435 */ 436static int alc_ch_mode_info(struct snd_kcontrol *kcontrol, 437 struct snd_ctl_elem_info *uinfo) 438{ 439 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 440 struct alc_spec *spec = codec->spec; 441 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode, 442 spec->num_channel_mode); 443} 444 445static int alc_ch_mode_get(struct snd_kcontrol *kcontrol, 446 struct snd_ctl_elem_value *ucontrol) 447{ 448 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 449 struct alc_spec *spec = codec->spec; 450 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode, 451 spec->num_channel_mode, 452 spec->multiout.max_channels); 453} 454 455static int alc_ch_mode_put(struct snd_kcontrol *kcontrol, 456 struct snd_ctl_elem_value *ucontrol) 457{ 458 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 459 struct alc_spec *spec = codec->spec; 460 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode, 461 spec->num_channel_mode, 462 &spec->multiout.max_channels); 463 if (err >= 0 && spec->need_dac_fix) 464 spec->multiout.num_dacs = spec->multiout.max_channels / 2; 465 return err; 466} 467 468/* 469 * Control the mode of pin widget settings via the mixer. "pc" is used 470 * instead of "%" to avoid consequences of accidently treating the % as 471 * being part of a format specifier. Maximum allowed length of a value is 472 * 63 characters plus NULL terminator. 473 * 474 * Note: some retasking pin complexes seem to ignore requests for input 475 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these 476 * are requested. Therefore order this list so that this behaviour will not 477 * cause problems when mixer clients move through the enum sequentially. 478 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of 479 * March 2006. 480 */ 481static char *alc_pin_mode_names[] = { 482 "Mic 50pc bias", "Mic 80pc bias", 483 "Line in", "Line out", "Headphone out", 484}; 485static unsigned char alc_pin_mode_values[] = { 486 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP, 487}; 488/* The control can present all 5 options, or it can limit the options based 489 * in the pin being assumed to be exclusively an input or an output pin. In 490 * addition, "input" pins may or may not process the mic bias option 491 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to 492 * accept requests for bias as of chip versions up to March 2006) and/or 493 * wiring in the computer. 494 */ 495#define ALC_PIN_DIR_IN 0x00 496#define ALC_PIN_DIR_OUT 0x01 497#define ALC_PIN_DIR_INOUT 0x02 498#define ALC_PIN_DIR_IN_NOMICBIAS 0x03 499#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04 500 501/* Info about the pin modes supported by the different pin direction modes. 502 * For each direction the minimum and maximum values are given. 503 */ 504static signed char alc_pin_mode_dir_info[5][2] = { 505 { 0, 2 }, /* ALC_PIN_DIR_IN */ 506 { 3, 4 }, /* ALC_PIN_DIR_OUT */ 507 { 0, 4 }, /* ALC_PIN_DIR_INOUT */ 508 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */ 509 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */ 510}; 511#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0]) 512#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1]) 513#define alc_pin_mode_n_items(_dir) \ 514 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1) 515 516static int alc_pin_mode_info(struct snd_kcontrol *kcontrol, 517 struct snd_ctl_elem_info *uinfo) 518{ 519 unsigned int item_num = uinfo->value.enumerated.item; 520 unsigned char dir = (kcontrol->private_value >> 16) & 0xff; 521 522 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 523 uinfo->count = 1; 524 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir); 525 526 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir)) 527 item_num = alc_pin_mode_min(dir); 528 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]); 529 return 0; 530} 531 532static int alc_pin_mode_get(struct snd_kcontrol *kcontrol, 533 struct snd_ctl_elem_value *ucontrol) 534{ 535 unsigned int i; 536 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 537 hda_nid_t nid = kcontrol->private_value & 0xffff; 538 unsigned char dir = (kcontrol->private_value >> 16) & 0xff; 539 long *valp = ucontrol->value.integer.value; 540 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0, 541 AC_VERB_GET_PIN_WIDGET_CONTROL, 542 0x00); 543 544 /* Find enumerated value for current pinctl setting */ 545 i = alc_pin_mode_min(dir); 546 while (alc_pin_mode_values[i] != pinctl && i <= alc_pin_mode_max(dir)) 547 i++; 548 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir); 549 return 0; 550} 551 552static int alc_pin_mode_put(struct snd_kcontrol *kcontrol, 553 struct snd_ctl_elem_value *ucontrol) 554{ 555 signed int change; 556 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 557 hda_nid_t nid = kcontrol->private_value & 0xffff; 558 unsigned char dir = (kcontrol->private_value >> 16) & 0xff; 559 long val = *ucontrol->value.integer.value; 560 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0, 561 AC_VERB_GET_PIN_WIDGET_CONTROL, 562 0x00); 563 564 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir)) 565 val = alc_pin_mode_min(dir); 566 567 change = pinctl != alc_pin_mode_values[val]; 568 if (change) { 569 /* Set pin mode to that requested */ 570 snd_hda_codec_write_cache(codec, nid, 0, 571 AC_VERB_SET_PIN_WIDGET_CONTROL, 572 alc_pin_mode_values[val]); 573 574 /* Also enable the retasking pin's input/output as required 575 * for the requested pin mode. Enum values of 2 or less are 576 * input modes. 577 * 578 * Dynamically switching the input/output buffers probably 579 * reduces noise slightly (particularly on input) so we'll 580 * do it. However, having both input and output buffers 581 * enabled simultaneously doesn't seem to be problematic if 582 * this turns out to be necessary in the future. 583 */ 584 if (val <= 2) { 585 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, 586 HDA_AMP_MUTE, HDA_AMP_MUTE); 587 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0, 588 HDA_AMP_MUTE, 0); 589 } else { 590 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0, 591 HDA_AMP_MUTE, HDA_AMP_MUTE); 592 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, 593 HDA_AMP_MUTE, 0); 594 } 595 } 596 return change; 597} 598 599#define ALC_PIN_MODE(xname, nid, dir) \ 600 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 601 .info = alc_pin_mode_info, \ 602 .get = alc_pin_mode_get, \ 603 .put = alc_pin_mode_put, \ 604 .private_value = nid | (dir<<16) } 605 606/* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged 607 * together using a mask with more than one bit set. This control is 608 * currently used only by the ALC260 test model. At this stage they are not 609 * needed for any "production" models. 610 */ 611#ifdef CONFIG_SND_DEBUG 612#define alc_gpio_data_info snd_ctl_boolean_mono_info 613 614static int alc_gpio_data_get(struct snd_kcontrol *kcontrol, 615 struct snd_ctl_elem_value *ucontrol) 616{ 617 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 618 hda_nid_t nid = kcontrol->private_value & 0xffff; 619 unsigned char mask = (kcontrol->private_value >> 16) & 0xff; 620 long *valp = ucontrol->value.integer.value; 621 unsigned int val = snd_hda_codec_read(codec, nid, 0, 622 AC_VERB_GET_GPIO_DATA, 0x00); 623 624 *valp = (val & mask) != 0; 625 return 0; 626} 627static int alc_gpio_data_put(struct snd_kcontrol *kcontrol, 628 struct snd_ctl_elem_value *ucontrol) 629{ 630 signed int change; 631 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 632 hda_nid_t nid = kcontrol->private_value & 0xffff; 633 unsigned char mask = (kcontrol->private_value >> 16) & 0xff; 634 long val = *ucontrol->value.integer.value; 635 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0, 636 AC_VERB_GET_GPIO_DATA, 637 0x00); 638 639 /* Set/unset the masked GPIO bit(s) as needed */ 640 change = (val == 0 ? 0 : mask) != (gpio_data & mask); 641 if (val == 0) 642 gpio_data &= ~mask; 643 else 644 gpio_data |= mask; 645 snd_hda_codec_write_cache(codec, nid, 0, 646 AC_VERB_SET_GPIO_DATA, gpio_data); 647 648 return change; 649} 650#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \ 651 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 652 .info = alc_gpio_data_info, \ 653 .get = alc_gpio_data_get, \ 654 .put = alc_gpio_data_put, \ 655 .private_value = nid | (mask<<16) } 656#endif /* CONFIG_SND_DEBUG */ 657 658/* A switch control to allow the enabling of the digital IO pins on the 659 * ALC260. This is incredibly simplistic; the intention of this control is 660 * to provide something in the test model allowing digital outputs to be 661 * identified if present. If models are found which can utilise these 662 * outputs a more complete mixer control can be devised for those models if 663 * necessary. 664 */ 665#ifdef CONFIG_SND_DEBUG 666#define alc_spdif_ctrl_info snd_ctl_boolean_mono_info 667 668static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol, 669 struct snd_ctl_elem_value *ucontrol) 670{ 671 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 672 hda_nid_t nid = kcontrol->private_value & 0xffff; 673 unsigned char mask = (kcontrol->private_value >> 16) & 0xff; 674 long *valp = ucontrol->value.integer.value; 675 unsigned int val = snd_hda_codec_read(codec, nid, 0, 676 AC_VERB_GET_DIGI_CONVERT_1, 0x00); 677 678 *valp = (val & mask) != 0; 679 return 0; 680} 681static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol, 682 struct snd_ctl_elem_value *ucontrol) 683{ 684 signed int change; 685 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 686 hda_nid_t nid = kcontrol->private_value & 0xffff; 687 unsigned char mask = (kcontrol->private_value >> 16) & 0xff; 688 long val = *ucontrol->value.integer.value; 689 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0, 690 AC_VERB_GET_DIGI_CONVERT_1, 691 0x00); 692 693 /* Set/unset the masked control bit(s) as needed */ 694 change = (val == 0 ? 0 : mask) != (ctrl_data & mask); 695 if (val==0) 696 ctrl_data &= ~mask; 697 else 698 ctrl_data |= mask; 699 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, 700 ctrl_data); 701 702 return change; 703} 704#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \ 705 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 706 .info = alc_spdif_ctrl_info, \ 707 .get = alc_spdif_ctrl_get, \ 708 .put = alc_spdif_ctrl_put, \ 709 .private_value = nid | (mask<<16) } 710#endif /* CONFIG_SND_DEBUG */ 711 712/* A switch control to allow the enabling EAPD digital outputs on the ALC26x. 713 * Again, this is only used in the ALC26x test models to help identify when 714 * the EAPD line must be asserted for features to work. 715 */ 716#ifdef CONFIG_SND_DEBUG 717#define alc_eapd_ctrl_info snd_ctl_boolean_mono_info 718 719static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol, 720 struct snd_ctl_elem_value *ucontrol) 721{ 722 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 723 hda_nid_t nid = kcontrol->private_value & 0xffff; 724 unsigned char mask = (kcontrol->private_value >> 16) & 0xff; 725 long *valp = ucontrol->value.integer.value; 726 unsigned int val = snd_hda_codec_read(codec, nid, 0, 727 AC_VERB_GET_EAPD_BTLENABLE, 0x00); 728 729 *valp = (val & mask) != 0; 730 return 0; 731} 732 733static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol, 734 struct snd_ctl_elem_value *ucontrol) 735{ 736 int change; 737 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 738 hda_nid_t nid = kcontrol->private_value & 0xffff; 739 unsigned char mask = (kcontrol->private_value >> 16) & 0xff; 740 long val = *ucontrol->value.integer.value; 741 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0, 742 AC_VERB_GET_EAPD_BTLENABLE, 743 0x00); 744 745 /* Set/unset the masked control bit(s) as needed */ 746 change = (!val ? 0 : mask) != (ctrl_data & mask); 747 if (!val) 748 ctrl_data &= ~mask; 749 else 750 ctrl_data |= mask; 751 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE, 752 ctrl_data); 753 754 return change; 755} 756 757#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \ 758 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 759 .info = alc_eapd_ctrl_info, \ 760 .get = alc_eapd_ctrl_get, \ 761 .put = alc_eapd_ctrl_put, \ 762 .private_value = nid | (mask<<16) } 763#endif /* CONFIG_SND_DEBUG */ 764 765/* 766 * set up the input pin config (depending on the given auto-pin type) 767 */ 768static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid, 769 int auto_pin_type) 770{ 771 unsigned int val = PIN_IN; 772 773 if (auto_pin_type <= AUTO_PIN_FRONT_MIC) { 774 unsigned int pincap; 775 pincap = snd_hda_query_pin_caps(codec, nid); 776 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT; 777 if (pincap & AC_PINCAP_VREF_80) 778 val = PIN_VREF80; 779 } 780 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val); 781} 782 783/* 784 */ 785static void add_mixer(struct alc_spec *spec, struct snd_kcontrol_new *mix) 786{ 787 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers))) 788 return; 789 spec->mixers[spec->num_mixers++] = mix; 790} 791 792static void add_verb(struct alc_spec *spec, const struct hda_verb *verb) 793{ 794 if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs))) 795 return; 796 spec->init_verbs[spec->num_init_verbs++] = verb; 797} 798 799#ifdef CONFIG_PROC_FS 800/* 801 * hook for proc 802 */ 803static void print_realtek_coef(struct snd_info_buffer *buffer, 804 struct hda_codec *codec, hda_nid_t nid) 805{ 806 int coeff; 807 808 if (nid != 0x20) 809 return; 810 coeff = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PROC_COEF, 0); 811 snd_iprintf(buffer, " Processing Coefficient: 0x%02x\n", coeff); 812 coeff = snd_hda_codec_read(codec, nid, 0, 813 AC_VERB_GET_COEF_INDEX, 0); 814 snd_iprintf(buffer, " Coefficient Index: 0x%02x\n", coeff); 815} 816#else 817#define print_realtek_coef NULL 818#endif 819 820/* 821 * set up from the preset table 822 */ 823static void setup_preset(struct alc_spec *spec, 824 const struct alc_config_preset *preset) 825{ 826 int i; 827 828 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++) 829 add_mixer(spec, preset->mixers[i]); 830 spec->cap_mixer = preset->cap_mixer; 831 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i]; 832 i++) 833 add_verb(spec, preset->init_verbs[i]); 834 835 spec->channel_mode = preset->channel_mode; 836 spec->num_channel_mode = preset->num_channel_mode; 837 spec->need_dac_fix = preset->need_dac_fix; 838 839 spec->multiout.max_channels = spec->channel_mode[0].channels; 840 841 spec->multiout.num_dacs = preset->num_dacs; 842 spec->multiout.dac_nids = preset->dac_nids; 843 spec->multiout.dig_out_nid = preset->dig_out_nid; 844 spec->multiout.slave_dig_outs = preset->slave_dig_outs; 845 spec->multiout.hp_nid = preset->hp_nid; 846 847 spec->num_mux_defs = preset->num_mux_defs; 848 if (!spec->num_mux_defs) 849 spec->num_mux_defs = 1; 850 spec->input_mux = preset->input_mux; 851 852 spec->num_adc_nids = preset->num_adc_nids; 853 spec->adc_nids = preset->adc_nids; 854 spec->capsrc_nids = preset->capsrc_nids; 855 spec->dig_in_nid = preset->dig_in_nid; 856 857 spec->unsol_event = preset->unsol_event; 858 spec->init_hook = preset->init_hook; 859#ifdef CONFIG_SND_HDA_POWER_SAVE 860 spec->loopback.amplist = preset->loopbacks; 861#endif 862} 863 864/* Enable GPIO mask and set output */ 865static struct hda_verb alc_gpio1_init_verbs[] = { 866 {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, 867 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, 868 {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, 869 { } 870}; 871 872static struct hda_verb alc_gpio2_init_verbs[] = { 873 {0x01, AC_VERB_SET_GPIO_MASK, 0x02}, 874 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02}, 875 {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, 876 { } 877}; 878 879static struct hda_verb alc_gpio3_init_verbs[] = { 880 {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, 881 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03}, 882 {0x01, AC_VERB_SET_GPIO_DATA, 0x03}, 883 { } 884}; 885 886/* 887 * Fix hardware PLL issue 888 * On some codecs, the analog PLL gating control must be off while 889 * the default value is 1. 890 */ 891static void alc_fix_pll(struct hda_codec *codec) 892{ 893 struct alc_spec *spec = codec->spec; 894 unsigned int val; 895 896 if (!spec->pll_nid) 897 return; 898 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX, 899 spec->pll_coef_idx); 900 val = snd_hda_codec_read(codec, spec->pll_nid, 0, 901 AC_VERB_GET_PROC_COEF, 0); 902 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX, 903 spec->pll_coef_idx); 904 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF, 905 val & ~(1 << spec->pll_coef_bit)); 906} 907 908static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid, 909 unsigned int coef_idx, unsigned int coef_bit) 910{ 911 struct alc_spec *spec = codec->spec; 912 spec->pll_nid = nid; 913 spec->pll_coef_idx = coef_idx; 914 spec->pll_coef_bit = coef_bit; 915 alc_fix_pll(codec); 916} 917 918static void alc_sku_automute(struct hda_codec *codec) 919{ 920 struct alc_spec *spec = codec->spec; 921 unsigned int present; 922 unsigned int hp_nid = spec->autocfg.hp_pins[0]; 923 unsigned int sp_nid = spec->autocfg.speaker_pins[0]; 924 925 /* need to execute and sync at first */ 926 snd_hda_codec_read(codec, hp_nid, 0, AC_VERB_SET_PIN_SENSE, 0); 927 present = snd_hda_codec_read(codec, hp_nid, 0, 928 AC_VERB_GET_PIN_SENSE, 0); 929 spec->jack_present = (present & 0x80000000) != 0; 930 snd_hda_codec_write(codec, sp_nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 931 spec->jack_present ? 0 : PIN_OUT); 932} 933 934#if 0 /* it's broken in some acses -- temporarily disabled */ 935static void alc_mic_automute(struct hda_codec *codec) 936{ 937 struct alc_spec *spec = codec->spec; 938 unsigned int present; 939 unsigned int mic_nid = spec->autocfg.input_pins[AUTO_PIN_MIC]; 940 unsigned int fmic_nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC]; 941 unsigned int mix_nid = spec->capsrc_nids[0]; 942 unsigned int capsrc_idx_mic, capsrc_idx_fmic; 943 944 capsrc_idx_mic = mic_nid - 0x18; 945 capsrc_idx_fmic = fmic_nid - 0x18; 946 present = snd_hda_codec_read(codec, mic_nid, 0, 947 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 948 snd_hda_codec_write(codec, mix_nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, 949 0x7000 | (capsrc_idx_mic << 8) | (present ? 0 : 0x80)); 950 snd_hda_codec_write(codec, mix_nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, 951 0x7000 | (capsrc_idx_fmic << 8) | (present ? 0x80 : 0)); 952 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, capsrc_idx_fmic, 953 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 954} 955#else 956#define alc_mic_automute(codec) do {} while(0) /* NOP */ 957#endif /* disabled */ 958 959/* unsolicited event for HP jack sensing */ 960static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res) 961{ 962 if (codec->vendor_id == 0x10ec0880) 963 res >>= 28; 964 else 965 res >>= 26; 966 if (res == ALC880_HP_EVENT) 967 alc_sku_automute(codec); 968 969 if (res == ALC880_MIC_EVENT) 970 alc_mic_automute(codec); 971} 972 973static void alc_inithook(struct hda_codec *codec) 974{ 975 alc_sku_automute(codec); 976 alc_mic_automute(codec); 977} 978 979/* additional initialization for ALC888 variants */ 980static void alc888_coef_init(struct hda_codec *codec) 981{ 982 unsigned int tmp; 983 984 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0); 985 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0); 986 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7); 987 if ((tmp & 0xf0) == 0x20) 988 /* alc888S-VC */ 989 snd_hda_codec_read(codec, 0x20, 0, 990 AC_VERB_SET_PROC_COEF, 0x830); 991 else 992 /* alc888-VB */ 993 snd_hda_codec_read(codec, 0x20, 0, 994 AC_VERB_SET_PROC_COEF, 0x3030); 995} 996 997/* 32-bit subsystem ID for BIOS loading in HD Audio codec. 998 * 31 ~ 16 : Manufacture ID 999 * 15 ~ 8 : SKU ID 1000 * 7 ~ 0 : Assembly ID 1001 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36 1002 */ 1003static void alc_subsystem_id(struct hda_codec *codec, 1004 unsigned int porta, unsigned int porte, 1005 unsigned int portd) 1006{ 1007 unsigned int ass, tmp, i; 1008 unsigned nid; 1009 struct alc_spec *spec = codec->spec; 1010 1011 ass = codec->subsystem_id & 0xffff; 1012 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1)) 1013 goto do_sku; 1014 1015 /* 1016 * 31~30 : port conetcivity 1017 * 29~21 : reserve 1018 * 20 : PCBEEP input 1019 * 19~16 : Check sum (15:1) 1020 * 15~1 : Custom 1021 * 0 : override 1022 */ 1023 nid = 0x1d; 1024 if (codec->vendor_id == 0x10ec0260) 1025 nid = 0x17; 1026 ass = snd_hda_codec_get_pincfg(codec, nid); 1027 snd_printd("realtek: No valid SSID, " 1028 "checking pincfg 0x%08x for NID 0x%x\n", 1029 ass, nid); 1030 if (!(ass & 1) && !(ass & 0x100000)) 1031 return; 1032 if ((ass >> 30) != 1) /* no physical connection */ 1033 return; 1034 1035 /* check sum */ 1036 tmp = 0; 1037 for (i = 1; i < 16; i++) { 1038 if ((ass >> i) & 1) 1039 tmp++; 1040 } 1041 if (((ass >> 16) & 0xf) != tmp) 1042 return; 1043do_sku: 1044 snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n", 1045 ass & 0xffff, codec->vendor_id); 1046 /* 1047 * 0 : override 1048 * 1 : Swap Jack 1049 * 2 : 0 --> Desktop, 1 --> Laptop 1050 * 3~5 : External Amplifier control 1051 * 7~6 : Reserved 1052 */ 1053 tmp = (ass & 0x38) >> 3; /* external Amp control */ 1054 switch (tmp) { 1055 case 1: 1056 snd_hda_sequence_write(codec, alc_gpio1_init_verbs); 1057 break; 1058 case 3: 1059 snd_hda_sequence_write(codec, alc_gpio2_init_verbs); 1060 break; 1061 case 7: 1062 snd_hda_sequence_write(codec, alc_gpio3_init_verbs); 1063 break; 1064 case 5: /* set EAPD output high */ 1065 switch (codec->vendor_id) { 1066 case 0x10ec0260: 1067 snd_hda_codec_write(codec, 0x0f, 0, 1068 AC_VERB_SET_EAPD_BTLENABLE, 2); 1069 snd_hda_codec_write(codec, 0x10, 0, 1070 AC_VERB_SET_EAPD_BTLENABLE, 2); 1071 break; 1072 case 0x10ec0262: 1073 case 0x10ec0267: 1074 case 0x10ec0268: 1075 case 0x10ec0269: 1076 case 0x10ec0272: 1077 case 0x10ec0660: 1078 case 0x10ec0662: 1079 case 0x10ec0663: 1080 case 0x10ec0862: 1081 case 0x10ec0889: 1082 snd_hda_codec_write(codec, 0x14, 0, 1083 AC_VERB_SET_EAPD_BTLENABLE, 2); 1084 snd_hda_codec_write(codec, 0x15, 0, 1085 AC_VERB_SET_EAPD_BTLENABLE, 2); 1086 break; 1087 } 1088 switch (codec->vendor_id) { 1089 case 0x10ec0260: 1090 snd_hda_codec_write(codec, 0x1a, 0, 1091 AC_VERB_SET_COEF_INDEX, 7); 1092 tmp = snd_hda_codec_read(codec, 0x1a, 0, 1093 AC_VERB_GET_PROC_COEF, 0); 1094 snd_hda_codec_write(codec, 0x1a, 0, 1095 AC_VERB_SET_COEF_INDEX, 7); 1096 snd_hda_codec_write(codec, 0x1a, 0, 1097 AC_VERB_SET_PROC_COEF, 1098 tmp | 0x2010); 1099 break; 1100 case 0x10ec0262: 1101 case 0x10ec0880: 1102 case 0x10ec0882: 1103 case 0x10ec0883: 1104 case 0x10ec0885: 1105 case 0x10ec0887: 1106 case 0x10ec0889: 1107 snd_hda_codec_write(codec, 0x20, 0, 1108 AC_VERB_SET_COEF_INDEX, 7); 1109 tmp = snd_hda_codec_read(codec, 0x20, 0, 1110 AC_VERB_GET_PROC_COEF, 0); 1111 snd_hda_codec_write(codec, 0x20, 0, 1112 AC_VERB_SET_COEF_INDEX, 7); 1113 snd_hda_codec_write(codec, 0x20, 0, 1114 AC_VERB_SET_PROC_COEF, 1115 tmp | 0x2010); 1116 break; 1117 case 0x10ec0888: 1118 /*alc888_coef_init(codec);*/ /* called in alc_init() */ 1119 break; 1120 case 0x10ec0267: 1121 case 0x10ec0268: 1122 snd_hda_codec_write(codec, 0x20, 0, 1123 AC_VERB_SET_COEF_INDEX, 7); 1124 tmp = snd_hda_codec_read(codec, 0x20, 0, 1125 AC_VERB_GET_PROC_COEF, 0); 1126 snd_hda_codec_write(codec, 0x20, 0, 1127 AC_VERB_SET_COEF_INDEX, 7); 1128 snd_hda_codec_write(codec, 0x20, 0, 1129 AC_VERB_SET_PROC_COEF, 1130 tmp | 0x3000); 1131 break; 1132 } 1133 default: 1134 break; 1135 } 1136 1137 /* is laptop or Desktop and enable the function "Mute internal speaker 1138 * when the external headphone out jack is plugged" 1139 */ 1140 if (!(ass & 0x8000)) 1141 return; 1142 /* 1143 * 10~8 : Jack location 1144 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered 1145 * 14~13: Resvered 1146 * 15 : 1 --> enable the function "Mute internal speaker 1147 * when the external headphone out jack is plugged" 1148 */ 1149 if (!spec->autocfg.speaker_pins[0]) { 1150 if (spec->autocfg.line_out_pins[0]) 1151 spec->autocfg.speaker_pins[0] = 1152 spec->autocfg.line_out_pins[0]; 1153 else 1154 return; 1155 } 1156 1157 if (!spec->autocfg.hp_pins[0]) { 1158 tmp = (ass >> 11) & 0x3; /* HP to chassis */ 1159 if (tmp == 0) 1160 spec->autocfg.hp_pins[0] = porta; 1161 else if (tmp == 1) 1162 spec->autocfg.hp_pins[0] = porte; 1163 else if (tmp == 2) 1164 spec->autocfg.hp_pins[0] = portd; 1165 else 1166 return; 1167 } 1168 if (spec->autocfg.hp_pins[0]) 1169 snd_hda_codec_write(codec, spec->autocfg.hp_pins[0], 0, 1170 AC_VERB_SET_UNSOLICITED_ENABLE, 1171 AC_USRSP_EN | ALC880_HP_EVENT); 1172 1173#if 0 /* it's broken in some acses -- temporarily disabled */ 1174 if (spec->autocfg.input_pins[AUTO_PIN_MIC] && 1175 spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC]) 1176 snd_hda_codec_write(codec, 1177 spec->autocfg.input_pins[AUTO_PIN_MIC], 0, 1178 AC_VERB_SET_UNSOLICITED_ENABLE, 1179 AC_USRSP_EN | ALC880_MIC_EVENT); 1180#endif /* disabled */ 1181 1182 spec->unsol_event = alc_sku_unsol_event; 1183} 1184 1185/* 1186 * Fix-up pin default configurations 1187 */ 1188 1189struct alc_pincfg { 1190 hda_nid_t nid; 1191 u32 val; 1192}; 1193 1194static void alc_fix_pincfg(struct hda_codec *codec, 1195 const struct snd_pci_quirk *quirk, 1196 const struct alc_pincfg **pinfix) 1197{ 1198 const struct alc_pincfg *cfg; 1199 1200 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk); 1201 if (!quirk) 1202 return; 1203 1204 cfg = pinfix[quirk->value]; 1205 for (; cfg->nid; cfg++) 1206 snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val); 1207} 1208 1209/* 1210 * ALC888 1211 */ 1212 1213/* 1214 * 2ch mode 1215 */ 1216static struct hda_verb alc888_4ST_ch2_intel_init[] = { 1217/* Mic-in jack as mic in */ 1218 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 1219 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 1220/* Line-in jack as Line in */ 1221 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 1222 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 1223/* Line-Out as Front */ 1224 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00}, 1225 { } /* end */ 1226}; 1227 1228/* 1229 * 4ch mode 1230 */ 1231static struct hda_verb alc888_4ST_ch4_intel_init[] = { 1232/* Mic-in jack as mic in */ 1233 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 1234 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 1235/* Line-in jack as Surround */ 1236 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 1237 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 1238/* Line-Out as Front */ 1239 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00}, 1240 { } /* end */ 1241}; 1242 1243/* 1244 * 6ch mode 1245 */ 1246static struct hda_verb alc888_4ST_ch6_intel_init[] = { 1247/* Mic-in jack as CLFE */ 1248 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 1249 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 1250/* Line-in jack as Surround */ 1251 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 1252 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 1253/* Line-Out as CLFE (workaround because Mic-in is not loud enough) */ 1254 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, 1255 { } /* end */ 1256}; 1257 1258/* 1259 * 8ch mode 1260 */ 1261static struct hda_verb alc888_4ST_ch8_intel_init[] = { 1262/* Mic-in jack as CLFE */ 1263 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 1264 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 1265/* Line-in jack as Surround */ 1266 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 1267 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 1268/* Line-Out as Side */ 1269 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, 1270 { } /* end */ 1271}; 1272 1273static struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = { 1274 { 2, alc888_4ST_ch2_intel_init }, 1275 { 4, alc888_4ST_ch4_intel_init }, 1276 { 6, alc888_4ST_ch6_intel_init }, 1277 { 8, alc888_4ST_ch8_intel_init }, 1278}; 1279 1280/* 1281 * ALC888 Fujitsu Siemens Amillo xa3530 1282 */ 1283 1284static struct hda_verb alc888_fujitsu_xa3530_verbs[] = { 1285/* Front Mic: set to PIN_IN (empty by default) */ 1286 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1287/* Connect Internal HP to Front */ 1288 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1289 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1290 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 1291/* Connect Bass HP to Front */ 1292 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1293 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1294 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 1295/* Connect Line-Out side jack (SPDIF) to Side */ 1296 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1297 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1298 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, 1299/* Connect Mic jack to CLFE */ 1300 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1301 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1302 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, 1303/* Connect Line-in jack to Surround */ 1304 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1305 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1306 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, 1307/* Connect HP out jack to Front */ 1308 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1309 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1310 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 1311/* Enable unsolicited event for HP jack and Line-out jack */ 1312 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 1313 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 1314 {} 1315}; 1316 1317static void alc888_fujitsu_xa3530_automute(struct hda_codec *codec) 1318{ 1319 unsigned int present; 1320 unsigned int bits; 1321 /* Line out presence */ 1322 present = snd_hda_codec_read(codec, 0x17, 0, 1323 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 1324 /* HP out presence */ 1325 present = present || snd_hda_codec_read(codec, 0x1b, 0, 1326 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 1327 bits = present ? HDA_AMP_MUTE : 0; 1328 /* Toggle internal speakers muting */ 1329 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 1330 HDA_AMP_MUTE, bits); 1331 /* Toggle internal bass muting */ 1332 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 1333 HDA_AMP_MUTE, bits); 1334} 1335 1336static void alc888_fujitsu_xa3530_unsol_event(struct hda_codec *codec, 1337 unsigned int res) 1338{ 1339 if (res >> 26 == ALC880_HP_EVENT) 1340 alc888_fujitsu_xa3530_automute(codec); 1341} 1342 1343 1344/* 1345 * ALC888 Acer Aspire 4930G model 1346 */ 1347 1348static struct hda_verb alc888_acer_aspire_4930g_verbs[] = { 1349/* Front Mic: set to PIN_IN (empty by default) */ 1350 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1351/* Unselect Front Mic by default in input mixer 3 */ 1352 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)}, 1353/* Enable unsolicited event for HP jack */ 1354 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 1355/* Connect Internal HP to front */ 1356 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1357 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1358 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 1359/* Connect HP out to front */ 1360 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1361 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1362 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 1363 { } 1364}; 1365 1366static struct hda_input_mux alc888_2_capture_sources[2] = { 1367 /* Front mic only available on one ADC */ 1368 { 1369 .num_items = 4, 1370 .items = { 1371 { "Mic", 0x0 }, 1372 { "Line", 0x2 }, 1373 { "CD", 0x4 }, 1374 { "Front Mic", 0xb }, 1375 }, 1376 }, 1377 { 1378 .num_items = 3, 1379 .items = { 1380 { "Mic", 0x0 }, 1381 { "Line", 0x2 }, 1382 { "CD", 0x4 }, 1383 }, 1384 } 1385}; 1386 1387static struct snd_kcontrol_new alc888_base_mixer[] = { 1388 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 1389 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 1390 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 1391 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 1392 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, 1393 HDA_OUTPUT), 1394 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 1395 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 1396 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 1397 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 1398 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 1399 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 1400 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 1401 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 1402 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 1403 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 1404 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 1405 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 1406 { } /* end */ 1407}; 1408 1409static void alc888_acer_aspire_4930g_automute(struct hda_codec *codec) 1410{ 1411 unsigned int present; 1412 unsigned int bits; 1413 present = snd_hda_codec_read(codec, 0x15, 0, 1414 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 1415 bits = present ? HDA_AMP_MUTE : 0; 1416 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 1417 HDA_AMP_MUTE, bits); 1418} 1419 1420static void alc888_acer_aspire_4930g_unsol_event(struct hda_codec *codec, 1421 unsigned int res) 1422{ 1423 if (res >> 26 == ALC880_HP_EVENT) 1424 alc888_acer_aspire_4930g_automute(codec); 1425} 1426 1427/* 1428 * ALC880 3-stack model 1429 * 1430 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e) 1431 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18, 1432 * F-Mic = 0x1b, HP = 0x19 1433 */ 1434 1435static hda_nid_t alc880_dac_nids[4] = { 1436 /* front, rear, clfe, rear_surr */ 1437 0x02, 0x05, 0x04, 0x03 1438}; 1439 1440static hda_nid_t alc880_adc_nids[3] = { 1441 /* ADC0-2 */ 1442 0x07, 0x08, 0x09, 1443}; 1444 1445/* The datasheet says the node 0x07 is connected from inputs, 1446 * but it shows zero connection in the real implementation on some devices. 1447 * Note: this is a 915GAV bug, fixed on 915GLV 1448 */ 1449static hda_nid_t alc880_adc_nids_alt[2] = { 1450 /* ADC1-2 */ 1451 0x08, 0x09, 1452}; 1453 1454#define ALC880_DIGOUT_NID 0x06 1455#define ALC880_DIGIN_NID 0x0a 1456 1457static struct hda_input_mux alc880_capture_source = { 1458 .num_items = 4, 1459 .items = { 1460 { "Mic", 0x0 }, 1461 { "Front Mic", 0x3 }, 1462 { "Line", 0x2 }, 1463 { "CD", 0x4 }, 1464 }, 1465}; 1466 1467/* channel source setting (2/6 channel selection for 3-stack) */ 1468/* 2ch mode */ 1469static struct hda_verb alc880_threestack_ch2_init[] = { 1470 /* set line-in to input, mute it */ 1471 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 1472 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 1473 /* set mic-in to input vref 80%, mute it */ 1474 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 1475 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 1476 { } /* end */ 1477}; 1478 1479/* 6ch mode */ 1480static struct hda_verb alc880_threestack_ch6_init[] = { 1481 /* set line-in to output, unmute it */ 1482 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 1483 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 1484 /* set mic-in to output, unmute it */ 1485 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 1486 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 1487 { } /* end */ 1488}; 1489 1490static struct hda_channel_mode alc880_threestack_modes[2] = { 1491 { 2, alc880_threestack_ch2_init }, 1492 { 6, alc880_threestack_ch6_init }, 1493}; 1494 1495static struct snd_kcontrol_new alc880_three_stack_mixer[] = { 1496 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 1497 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 1498 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 1499 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT), 1500 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 1501 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 1502 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 1503 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 1504 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 1505 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 1506 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 1507 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 1508 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 1509 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 1510 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT), 1511 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT), 1512 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT), 1513 { 1514 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1515 .name = "Channel Mode", 1516 .info = alc_ch_mode_info, 1517 .get = alc_ch_mode_get, 1518 .put = alc_ch_mode_put, 1519 }, 1520 { } /* end */ 1521}; 1522 1523/* capture mixer elements */ 1524static int alc_cap_vol_info(struct snd_kcontrol *kcontrol, 1525 struct snd_ctl_elem_info *uinfo) 1526{ 1527 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 1528 struct alc_spec *spec = codec->spec; 1529 int err; 1530 1531 mutex_lock(&codec->control_mutex); 1532 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0, 1533 HDA_INPUT); 1534 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo); 1535 mutex_unlock(&codec->control_mutex); 1536 return err; 1537} 1538 1539static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag, 1540 unsigned int size, unsigned int __user *tlv) 1541{ 1542 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 1543 struct alc_spec *spec = codec->spec; 1544 int err; 1545 1546 mutex_lock(&codec->control_mutex); 1547 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0, 1548 HDA_INPUT); 1549 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv); 1550 mutex_unlock(&codec->control_mutex); 1551 return err; 1552} 1553 1554typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol, 1555 struct snd_ctl_elem_value *ucontrol); 1556 1557static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol, 1558 struct snd_ctl_elem_value *ucontrol, 1559 getput_call_t func) 1560{ 1561 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 1562 struct alc_spec *spec = codec->spec; 1563 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 1564 int err; 1565 1566 mutex_lock(&codec->control_mutex); 1567 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx], 1568 3, 0, HDA_INPUT); 1569 err = func(kcontrol, ucontrol); 1570 mutex_unlock(&codec->control_mutex); 1571 return err; 1572} 1573 1574static int alc_cap_vol_get(struct snd_kcontrol *kcontrol, 1575 struct snd_ctl_elem_value *ucontrol) 1576{ 1577 return alc_cap_getput_caller(kcontrol, ucontrol, 1578 snd_hda_mixer_amp_volume_get); 1579} 1580 1581static int alc_cap_vol_put(struct snd_kcontrol *kcontrol, 1582 struct snd_ctl_elem_value *ucontrol) 1583{ 1584 return alc_cap_getput_caller(kcontrol, ucontrol, 1585 snd_hda_mixer_amp_volume_put); 1586} 1587 1588/* capture mixer elements */ 1589#define alc_cap_sw_info snd_ctl_boolean_stereo_info 1590 1591static int alc_cap_sw_get(struct snd_kcontrol *kcontrol, 1592 struct snd_ctl_elem_value *ucontrol) 1593{ 1594 return alc_cap_getput_caller(kcontrol, ucontrol, 1595 snd_hda_mixer_amp_switch_get); 1596} 1597 1598static int alc_cap_sw_put(struct snd_kcontrol *kcontrol, 1599 struct snd_ctl_elem_value *ucontrol) 1600{ 1601 return alc_cap_getput_caller(kcontrol, ucontrol, 1602 snd_hda_mixer_amp_switch_put); 1603} 1604 1605#define _DEFINE_CAPMIX(num) \ 1606 { \ 1607 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 1608 .name = "Capture Switch", \ 1609 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \ 1610 .count = num, \ 1611 .info = alc_cap_sw_info, \ 1612 .get = alc_cap_sw_get, \ 1613 .put = alc_cap_sw_put, \ 1614 }, \ 1615 { \ 1616 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 1617 .name = "Capture Volume", \ 1618 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \ 1619 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \ 1620 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \ 1621 .count = num, \ 1622 .info = alc_cap_vol_info, \ 1623 .get = alc_cap_vol_get, \ 1624 .put = alc_cap_vol_put, \ 1625 .tlv = { .c = alc_cap_vol_tlv }, \ 1626 } 1627 1628#define _DEFINE_CAPSRC(num) \ 1629 { \ 1630 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 1631 /* .name = "Capture Source", */ \ 1632 .name = "Input Source", \ 1633 .count = num, \ 1634 .info = alc_mux_enum_info, \ 1635 .get = alc_mux_enum_get, \ 1636 .put = alc_mux_enum_put, \ 1637 } 1638 1639#define DEFINE_CAPMIX(num) \ 1640static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \ 1641 _DEFINE_CAPMIX(num), \ 1642 _DEFINE_CAPSRC(num), \ 1643 { } /* end */ \ 1644} 1645 1646#define DEFINE_CAPMIX_NOSRC(num) \ 1647static struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \ 1648 _DEFINE_CAPMIX(num), \ 1649 { } /* end */ \ 1650} 1651 1652/* up to three ADCs */ 1653DEFINE_CAPMIX(1); 1654DEFINE_CAPMIX(2); 1655DEFINE_CAPMIX(3); 1656DEFINE_CAPMIX_NOSRC(1); 1657DEFINE_CAPMIX_NOSRC(2); 1658DEFINE_CAPMIX_NOSRC(3); 1659 1660/* 1661 * ALC880 5-stack model 1662 * 1663 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d), 1664 * Side = 0x02 (0xd) 1665 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16 1666 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19 1667 */ 1668 1669/* additional mixers to alc880_three_stack_mixer */ 1670static struct snd_kcontrol_new alc880_five_stack_mixer[] = { 1671 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 1672 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT), 1673 { } /* end */ 1674}; 1675 1676/* channel source setting (6/8 channel selection for 5-stack) */ 1677/* 6ch mode */ 1678static struct hda_verb alc880_fivestack_ch6_init[] = { 1679 /* set line-in to input, mute it */ 1680 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 1681 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 1682 { } /* end */ 1683}; 1684 1685/* 8ch mode */ 1686static struct hda_verb alc880_fivestack_ch8_init[] = { 1687 /* set line-in to output, unmute it */ 1688 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 1689 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 1690 { } /* end */ 1691}; 1692 1693static struct hda_channel_mode alc880_fivestack_modes[2] = { 1694 { 6, alc880_fivestack_ch6_init }, 1695 { 8, alc880_fivestack_ch8_init }, 1696}; 1697 1698 1699/* 1700 * ALC880 6-stack model 1701 * 1702 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e), 1703 * Side = 0x05 (0x0f) 1704 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17, 1705 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b 1706 */ 1707 1708static hda_nid_t alc880_6st_dac_nids[4] = { 1709 /* front, rear, clfe, rear_surr */ 1710 0x02, 0x03, 0x04, 0x05 1711}; 1712 1713static struct hda_input_mux alc880_6stack_capture_source = { 1714 .num_items = 4, 1715 .items = { 1716 { "Mic", 0x0 }, 1717 { "Front Mic", 0x1 }, 1718 { "Line", 0x2 }, 1719 { "CD", 0x4 }, 1720 }, 1721}; 1722 1723/* fixed 8-channels */ 1724static struct hda_channel_mode alc880_sixstack_modes[1] = { 1725 { 8, NULL }, 1726}; 1727 1728static struct snd_kcontrol_new alc880_six_stack_mixer[] = { 1729 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 1730 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 1731 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 1732 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 1733 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 1734 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 1735 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 1736 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 1737 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 1738 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 1739 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 1740 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 1741 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 1742 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 1743 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 1744 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 1745 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 1746 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 1747 { 1748 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1749 .name = "Channel Mode", 1750 .info = alc_ch_mode_info, 1751 .get = alc_ch_mode_get, 1752 .put = alc_ch_mode_put, 1753 }, 1754 { } /* end */ 1755}; 1756 1757 1758/* 1759 * ALC880 W810 model 1760 * 1761 * W810 has rear IO for: 1762 * Front (DAC 02) 1763 * Surround (DAC 03) 1764 * Center/LFE (DAC 04) 1765 * Digital out (06) 1766 * 1767 * The system also has a pair of internal speakers, and a headphone jack. 1768 * These are both connected to Line2 on the codec, hence to DAC 02. 1769 * 1770 * There is a variable resistor to control the speaker or headphone 1771 * volume. This is a hardware-only device without a software API. 1772 * 1773 * Plugging headphones in will disable the internal speakers. This is 1774 * implemented in hardware, not via the driver using jack sense. In 1775 * a similar fashion, plugging into the rear socket marked "front" will 1776 * disable both the speakers and headphones. 1777 * 1778 * For input, there's a microphone jack, and an "audio in" jack. 1779 * These may not do anything useful with this driver yet, because I 1780 * haven't setup any initialization verbs for these yet... 1781 */ 1782 1783static hda_nid_t alc880_w810_dac_nids[3] = { 1784 /* front, rear/surround, clfe */ 1785 0x02, 0x03, 0x04 1786}; 1787 1788/* fixed 6 channels */ 1789static struct hda_channel_mode alc880_w810_modes[1] = { 1790 { 6, NULL } 1791}; 1792 1793/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */ 1794static struct snd_kcontrol_new alc880_w810_base_mixer[] = { 1795 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 1796 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 1797 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 1798 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 1799 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 1800 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 1801 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 1802 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 1803 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 1804 { } /* end */ 1805}; 1806 1807 1808/* 1809 * Z710V model 1810 * 1811 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d) 1812 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?), 1813 * Line = 0x1a 1814 */ 1815 1816static hda_nid_t alc880_z71v_dac_nids[1] = { 1817 0x02 1818}; 1819#define ALC880_Z71V_HP_DAC 0x03 1820 1821/* fixed 2 channels */ 1822static struct hda_channel_mode alc880_2_jack_modes[1] = { 1823 { 2, NULL } 1824}; 1825 1826static struct snd_kcontrol_new alc880_z71v_mixer[] = { 1827 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 1828 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 1829 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 1830 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT), 1831 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 1832 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 1833 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 1834 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 1835 { } /* end */ 1836}; 1837 1838 1839/* 1840 * ALC880 F1734 model 1841 * 1842 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d) 1843 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18 1844 */ 1845 1846static hda_nid_t alc880_f1734_dac_nids[1] = { 1847 0x03 1848}; 1849#define ALC880_F1734_HP_DAC 0x02 1850 1851static struct snd_kcontrol_new alc880_f1734_mixer[] = { 1852 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 1853 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), 1854 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 1855 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 1856 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 1857 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 1858 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 1859 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 1860 { } /* end */ 1861}; 1862 1863static struct hda_input_mux alc880_f1734_capture_source = { 1864 .num_items = 2, 1865 .items = { 1866 { "Mic", 0x1 }, 1867 { "CD", 0x4 }, 1868 }, 1869}; 1870 1871 1872/* 1873 * ALC880 ASUS model 1874 * 1875 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e) 1876 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16, 1877 * Mic = 0x18, Line = 0x1a 1878 */ 1879 1880#define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */ 1881#define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */ 1882 1883static struct snd_kcontrol_new alc880_asus_mixer[] = { 1884 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 1885 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 1886 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 1887 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 1888 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 1889 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 1890 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 1891 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 1892 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 1893 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 1894 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 1895 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 1896 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 1897 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 1898 { 1899 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1900 .name = "Channel Mode", 1901 .info = alc_ch_mode_info, 1902 .get = alc_ch_mode_get, 1903 .put = alc_ch_mode_put, 1904 }, 1905 { } /* end */ 1906}; 1907 1908/* 1909 * ALC880 ASUS W1V model 1910 * 1911 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e) 1912 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16, 1913 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b 1914 */ 1915 1916/* additional mixers to alc880_asus_mixer */ 1917static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = { 1918 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT), 1919 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT), 1920 { } /* end */ 1921}; 1922 1923/* TCL S700 */ 1924static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = { 1925 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 1926 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 1927 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 1928 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT), 1929 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT), 1930 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT), 1931 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT), 1932 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 1933 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 1934 { } /* end */ 1935}; 1936 1937/* Uniwill */ 1938static struct snd_kcontrol_new alc880_uniwill_mixer[] = { 1939 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 1940 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), 1941 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 1942 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 1943 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 1944 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 1945 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 1946 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 1947 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 1948 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 1949 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 1950 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 1951 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 1952 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 1953 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 1954 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 1955 { 1956 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1957 .name = "Channel Mode", 1958 .info = alc_ch_mode_info, 1959 .get = alc_ch_mode_get, 1960 .put = alc_ch_mode_put, 1961 }, 1962 { } /* end */ 1963}; 1964 1965static struct snd_kcontrol_new alc880_fujitsu_mixer[] = { 1966 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 1967 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), 1968 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 1969 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 1970 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 1971 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 1972 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 1973 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 1974 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 1975 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 1976 { } /* end */ 1977}; 1978 1979static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = { 1980 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 1981 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), 1982 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 1983 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 1984 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 1985 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 1986 { } /* end */ 1987}; 1988 1989/* 1990 * virtual master controls 1991 */ 1992 1993/* 1994 * slave controls for virtual master 1995 */ 1996static const char *alc_slave_vols[] = { 1997 "Front Playback Volume", 1998 "Surround Playback Volume", 1999 "Center Playback Volume", 2000 "LFE Playback Volume", 2001 "Side Playback Volume", 2002 "Headphone Playback Volume", 2003 "Speaker Playback Volume", 2004 "Mono Playback Volume", 2005 "Line-Out Playback Volume", 2006 "PCM Playback Volume", 2007 NULL, 2008}; 2009 2010static const char *alc_slave_sws[] = { 2011 "Front Playback Switch", 2012 "Surround Playback Switch", 2013 "Center Playback Switch", 2014 "LFE Playback Switch", 2015 "Side Playback Switch", 2016 "Headphone Playback Switch", 2017 "Speaker Playback Switch", 2018 "Mono Playback Switch", 2019 "IEC958 Playback Switch", 2020 NULL, 2021}; 2022 2023/* 2024 * build control elements 2025 */ 2026 2027static void alc_free_kctls(struct hda_codec *codec); 2028 2029/* additional beep mixers; the actual parameters are overwritten at build */ 2030static struct snd_kcontrol_new alc_beep_mixer[] = { 2031 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT), 2032 HDA_CODEC_MUTE("Beep Playback Switch", 0, 0, HDA_INPUT), 2033 { } /* end */ 2034}; 2035 2036static int alc_build_controls(struct hda_codec *codec) 2037{ 2038 struct alc_spec *spec = codec->spec; 2039 int err; 2040 int i; 2041 2042 for (i = 0; i < spec->num_mixers; i++) { 2043 err = snd_hda_add_new_ctls(codec, spec->mixers[i]); 2044 if (err < 0) 2045 return err; 2046 } 2047 if (spec->cap_mixer) { 2048 err = snd_hda_add_new_ctls(codec, spec->cap_mixer); 2049 if (err < 0) 2050 return err; 2051 } 2052 if (spec->multiout.dig_out_nid) { 2053 err = snd_hda_create_spdif_out_ctls(codec, 2054 spec->multiout.dig_out_nid); 2055 if (err < 0) 2056 return err; 2057 if (!spec->no_analog) { 2058 err = snd_hda_create_spdif_share_sw(codec, 2059 &spec->multiout); 2060 if (err < 0) 2061 return err; 2062 spec->multiout.share_spdif = 1; 2063 } 2064 } 2065 if (spec->dig_in_nid) { 2066 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid); 2067 if (err < 0) 2068 return err; 2069 } 2070 2071 /* create beep controls if needed */ 2072 if (spec->beep_amp) { 2073 struct snd_kcontrol_new *knew; 2074 for (knew = alc_beep_mixer; knew->name; knew++) { 2075 struct snd_kcontrol *kctl; 2076 kctl = snd_ctl_new1(knew, codec); 2077 if (!kctl) 2078 return -ENOMEM; 2079 kctl->private_value = spec->beep_amp; 2080 err = snd_hda_ctl_add(codec, kctl); 2081 if (err < 0) 2082 return err; 2083 } 2084 } 2085 2086 /* if we have no master control, let's create it */ 2087 if (!spec->no_analog && 2088 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) { 2089 unsigned int vmaster_tlv[4]; 2090 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid, 2091 HDA_OUTPUT, vmaster_tlv); 2092 err = snd_hda_add_vmaster(codec, "Master Playback Volume", 2093 vmaster_tlv, alc_slave_vols); 2094 if (err < 0) 2095 return err; 2096 } 2097 if (!spec->no_analog && 2098 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) { 2099 err = snd_hda_add_vmaster(codec, "Master Playback Switch", 2100 NULL, alc_slave_sws); 2101 if (err < 0) 2102 return err; 2103 } 2104 2105 alc_free_kctls(codec); /* no longer needed */ 2106 return 0; 2107} 2108 2109 2110/* 2111 * initialize the codec volumes, etc 2112 */ 2113 2114/* 2115 * generic initialization of ADC, input mixers and output mixers 2116 */ 2117static struct hda_verb alc880_volume_init_verbs[] = { 2118 /* 2119 * Unmute ADC0-2 and set the default input to mic-in 2120 */ 2121 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 2122 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 2123 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 2124 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 2125 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 2126 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 2127 2128 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 2129 * mixer widget 2130 * Note: PASD motherboards uses the Line In 2 as the input for front 2131 * panel mic (mic 2) 2132 */ 2133 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 2134 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 2135 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 2136 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 2137 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 2138 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 2139 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, 2140 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, 2141 2142 /* 2143 * Set up output mixers (0x0c - 0x0f) 2144 */ 2145 /* set vol=0 to output mixers */ 2146 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 2147 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 2148 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 2149 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 2150 /* set up input amps for analog loopback */ 2151 /* Amp Indices: DAC = 0, mixer = 1 */ 2152 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 2153 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 2154 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 2155 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 2156 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 2157 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 2158 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 2159 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 2160 2161 { } 2162}; 2163 2164/* 2165 * 3-stack pin configuration: 2166 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b 2167 */ 2168static struct hda_verb alc880_pin_3stack_init_verbs[] = { 2169 /* 2170 * preset connection lists of input pins 2171 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround 2172 */ 2173 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ 2174 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 2175 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */ 2176 2177 /* 2178 * Set pin mode and muting 2179 */ 2180 /* set front pin widgets 0x14 for output */ 2181 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2182 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2183 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 2184 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2185 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2186 /* Mic2 (as headphone out) for HP output */ 2187 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 2188 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2189 /* Line In pin widget for input */ 2190 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2191 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2192 /* Line2 (as front mic) pin widget for input and vref at 80% */ 2193 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2194 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2195 /* CD pin widget for input */ 2196 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2197 2198 { } 2199}; 2200 2201/* 2202 * 5-stack pin configuration: 2203 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19, 2204 * line-in/side = 0x1a, f-mic = 0x1b 2205 */ 2206static struct hda_verb alc880_pin_5stack_init_verbs[] = { 2207 /* 2208 * preset connection lists of input pins 2209 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround 2210 */ 2211 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 2212 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */ 2213 2214 /* 2215 * Set pin mode and muting 2216 */ 2217 /* set pin widgets 0x14-0x17 for output */ 2218 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2219 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2220 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2221 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2222 /* unmute pins for output (no gain on this amp) */ 2223 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2224 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2225 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2226 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2227 2228 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 2229 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2230 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2231 /* Mic2 (as headphone out) for HP output */ 2232 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 2233 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2234 /* Line In pin widget for input */ 2235 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2236 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2237 /* Line2 (as front mic) pin widget for input and vref at 80% */ 2238 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2239 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2240 /* CD pin widget for input */ 2241 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2242 2243 { } 2244}; 2245 2246/* 2247 * W810 pin configuration: 2248 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b 2249 */ 2250static struct hda_verb alc880_pin_w810_init_verbs[] = { 2251 /* hphone/speaker input selector: front DAC */ 2252 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0}, 2253 2254 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2255 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2256 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2257 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2258 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2259 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2260 2261 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 2262 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2263 2264 { } 2265}; 2266 2267/* 2268 * Z71V pin configuration: 2269 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?) 2270 */ 2271static struct hda_verb alc880_pin_z71v_init_verbs[] = { 2272 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2273 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2274 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 2275 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2276 2277 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2278 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2279 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2280 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2281 2282 { } 2283}; 2284 2285/* 2286 * 6-stack pin configuration: 2287 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18, 2288 * f-mic = 0x19, line = 0x1a, HP = 0x1b 2289 */ 2290static struct hda_verb alc880_pin_6stack_init_verbs[] = { 2291 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 2292 2293 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2294 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2295 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2296 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2297 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2298 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2299 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2300 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2301 2302 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2303 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2304 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2305 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2306 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2307 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2308 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 2309 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2310 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2311 2312 { } 2313}; 2314 2315/* 2316 * Uniwill pin configuration: 2317 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19, 2318 * line = 0x1a 2319 */ 2320static struct hda_verb alc880_uniwill_init_verbs[] = { 2321 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 2322 2323 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 2324 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2325 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 2326 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2327 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 2328 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2329 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2330 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2331 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 2332 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 2333 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 2334 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 2335 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 2336 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 2337 2338 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2339 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2340 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2341 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2342 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2343 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2344 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */ 2345 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */ 2346 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2347 2348 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 2349 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 2350 2351 { } 2352}; 2353 2354/* 2355* Uniwill P53 2356* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19, 2357 */ 2358static struct hda_verb alc880_uniwill_p53_init_verbs[] = { 2359 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 2360 2361 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 2362 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2363 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 2364 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2365 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 2366 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2367 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 2368 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 2369 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 2370 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 2371 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 2372 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 2373 2374 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2375 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2376 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2377 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2378 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2379 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2380 2381 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 2382 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT}, 2383 2384 { } 2385}; 2386 2387static struct hda_verb alc880_beep_init_verbs[] = { 2388 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) }, 2389 { } 2390}; 2391 2392/* toggle speaker-output according to the hp-jack state */ 2393static void alc880_uniwill_hp_automute(struct hda_codec *codec) 2394{ 2395 unsigned int present; 2396 unsigned char bits; 2397 2398 present = snd_hda_codec_read(codec, 0x14, 0, 2399 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 2400 bits = present ? HDA_AMP_MUTE : 0; 2401 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 2402 HDA_AMP_MUTE, bits); 2403 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0, 2404 HDA_AMP_MUTE, bits); 2405} 2406 2407/* auto-toggle front mic */ 2408static void alc880_uniwill_mic_automute(struct hda_codec *codec) 2409{ 2410 unsigned int present; 2411 unsigned char bits; 2412 2413 present = snd_hda_codec_read(codec, 0x18, 0, 2414 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 2415 bits = present ? HDA_AMP_MUTE : 0; 2416 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits); 2417} 2418 2419static void alc880_uniwill_automute(struct hda_codec *codec) 2420{ 2421 alc880_uniwill_hp_automute(codec); 2422 alc880_uniwill_mic_automute(codec); 2423} 2424 2425static void alc880_uniwill_unsol_event(struct hda_codec *codec, 2426 unsigned int res) 2427{ 2428 /* Looks like the unsol event is incompatible with the standard 2429 * definition. 4bit tag is placed at 28 bit! 2430 */ 2431 switch (res >> 28) { 2432 case ALC880_HP_EVENT: 2433 alc880_uniwill_hp_automute(codec); 2434 break; 2435 case ALC880_MIC_EVENT: 2436 alc880_uniwill_mic_automute(codec); 2437 break; 2438 } 2439} 2440 2441static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec) 2442{ 2443 unsigned int present; 2444 unsigned char bits; 2445 2446 present = snd_hda_codec_read(codec, 0x14, 0, 2447 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 2448 bits = present ? HDA_AMP_MUTE : 0; 2449 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, HDA_AMP_MUTE, bits); 2450} 2451 2452static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec) 2453{ 2454 unsigned int present; 2455 2456 present = snd_hda_codec_read(codec, 0x21, 0, 2457 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0); 2458 present &= HDA_AMP_VOLMASK; 2459 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0, 2460 HDA_AMP_VOLMASK, present); 2461 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0, 2462 HDA_AMP_VOLMASK, present); 2463} 2464 2465static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec, 2466 unsigned int res) 2467{ 2468 /* Looks like the unsol event is incompatible with the standard 2469 * definition. 4bit tag is placed at 28 bit! 2470 */ 2471 if ((res >> 28) == ALC880_HP_EVENT) 2472 alc880_uniwill_p53_hp_automute(codec); 2473 if ((res >> 28) == ALC880_DCVOL_EVENT) 2474 alc880_uniwill_p53_dcvol_automute(codec); 2475} 2476 2477/* 2478 * F1734 pin configuration: 2479 * HP = 0x14, speaker-out = 0x15, mic = 0x18 2480 */ 2481static struct hda_verb alc880_pin_f1734_init_verbs[] = { 2482 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01}, 2483 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, 2484 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, 2485 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, 2486 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, 2487 2488 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 2489 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2490 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2491 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2492 2493 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2494 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2495 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, 2496 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2497 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2498 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2499 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2500 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2501 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2502 2503 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT}, 2504 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT}, 2505 2506 { } 2507}; 2508 2509/* 2510 * ASUS pin configuration: 2511 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a 2512 */ 2513static struct hda_verb alc880_pin_asus_init_verbs[] = { 2514 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, 2515 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, 2516 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, 2517 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, 2518 2519 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 2520 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2521 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2522 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2523 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2524 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2525 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2526 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2527 2528 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2529 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2530 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2531 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2532 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2533 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2534 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2535 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2536 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2537 2538 { } 2539}; 2540 2541/* Enable GPIO mask and set output */ 2542#define alc880_gpio1_init_verbs alc_gpio1_init_verbs 2543#define alc880_gpio2_init_verbs alc_gpio2_init_verbs 2544 2545/* Clevo m520g init */ 2546static struct hda_verb alc880_pin_clevo_init_verbs[] = { 2547 /* headphone output */ 2548 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01}, 2549 /* line-out */ 2550 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2551 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2552 /* Line-in */ 2553 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2554 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2555 /* CD */ 2556 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2557 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2558 /* Mic1 (rear panel) */ 2559 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2560 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2561 /* Mic2 (front panel) */ 2562 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2563 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2564 /* headphone */ 2565 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 2566 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2567 /* change to EAPD mode */ 2568 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 2569 {0x20, AC_VERB_SET_PROC_COEF, 0x3060}, 2570 2571 { } 2572}; 2573 2574static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = { 2575 /* change to EAPD mode */ 2576 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 2577 {0x20, AC_VERB_SET_PROC_COEF, 0x3060}, 2578 2579 /* Headphone output */ 2580 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 2581 /* Front output*/ 2582 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2583 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 2584 2585 /* Line In pin widget for input */ 2586 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2587 /* CD pin widget for input */ 2588 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2589 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 2590 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2591 2592 /* change to EAPD mode */ 2593 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 2594 {0x20, AC_VERB_SET_PROC_COEF, 0x3070}, 2595 2596 { } 2597}; 2598 2599/* 2600 * LG m1 express dual 2601 * 2602 * Pin assignment: 2603 * Rear Line-In/Out (blue): 0x14 2604 * Build-in Mic-In: 0x15 2605 * Speaker-out: 0x17 2606 * HP-Out (green): 0x1b 2607 * Mic-In/Out (red): 0x19 2608 * SPDIF-Out: 0x1e 2609 */ 2610 2611/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */ 2612static hda_nid_t alc880_lg_dac_nids[3] = { 2613 0x05, 0x02, 0x03 2614}; 2615 2616/* seems analog CD is not working */ 2617static struct hda_input_mux alc880_lg_capture_source = { 2618 .num_items = 3, 2619 .items = { 2620 { "Mic", 0x1 }, 2621 { "Line", 0x5 }, 2622 { "Internal Mic", 0x6 }, 2623 }, 2624}; 2625 2626/* 2,4,6 channel modes */ 2627static struct hda_verb alc880_lg_ch2_init[] = { 2628 /* set line-in and mic-in to input */ 2629 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 2630 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 2631 { } 2632}; 2633 2634static struct hda_verb alc880_lg_ch4_init[] = { 2635 /* set line-in to out and mic-in to input */ 2636 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, 2637 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 2638 { } 2639}; 2640 2641static struct hda_verb alc880_lg_ch6_init[] = { 2642 /* set line-in and mic-in to output */ 2643 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, 2644 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, 2645 { } 2646}; 2647 2648static struct hda_channel_mode alc880_lg_ch_modes[3] = { 2649 { 2, alc880_lg_ch2_init }, 2650 { 4, alc880_lg_ch4_init }, 2651 { 6, alc880_lg_ch6_init }, 2652}; 2653 2654static struct snd_kcontrol_new alc880_lg_mixer[] = { 2655 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 2656 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT), 2657 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2658 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT), 2659 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT), 2660 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT), 2661 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT), 2662 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT), 2663 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 2664 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 2665 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT), 2666 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT), 2667 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT), 2668 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT), 2669 { 2670 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2671 .name = "Channel Mode", 2672 .info = alc_ch_mode_info, 2673 .get = alc_ch_mode_get, 2674 .put = alc_ch_mode_put, 2675 }, 2676 { } /* end */ 2677}; 2678 2679static struct hda_verb alc880_lg_init_verbs[] = { 2680 /* set capture source to mic-in */ 2681 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 2682 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 2683 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 2684 /* mute all amp mixer inputs */ 2685 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)}, 2686 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, 2687 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, 2688 /* line-in to input */ 2689 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2690 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2691 /* built-in mic */ 2692 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2693 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2694 /* speaker-out */ 2695 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 2696 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2697 /* mic-in to input */ 2698 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01}, 2699 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2700 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2701 /* HP-out */ 2702 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03}, 2703 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 2704 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2705 /* jack sense */ 2706 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1}, 2707 { } 2708}; 2709 2710/* toggle speaker-output according to the hp-jack state */ 2711static void alc880_lg_automute(struct hda_codec *codec) 2712{ 2713 unsigned int present; 2714 unsigned char bits; 2715 2716 present = snd_hda_codec_read(codec, 0x1b, 0, 2717 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 2718 bits = present ? HDA_AMP_MUTE : 0; 2719 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0, 2720 HDA_AMP_MUTE, bits); 2721} 2722 2723static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res) 2724{ 2725 /* Looks like the unsol event is incompatible with the standard 2726 * definition. 4bit tag is placed at 28 bit! 2727 */ 2728 if ((res >> 28) == 0x01) 2729 alc880_lg_automute(codec); 2730} 2731 2732/* 2733 * LG LW20 2734 * 2735 * Pin assignment: 2736 * Speaker-out: 0x14 2737 * Mic-In: 0x18 2738 * Built-in Mic-In: 0x19 2739 * Line-In: 0x1b 2740 * HP-Out: 0x1a 2741 * SPDIF-Out: 0x1e 2742 */ 2743 2744static struct hda_input_mux alc880_lg_lw_capture_source = { 2745 .num_items = 3, 2746 .items = { 2747 { "Mic", 0x0 }, 2748 { "Internal Mic", 0x1 }, 2749 { "Line In", 0x2 }, 2750 }, 2751}; 2752 2753#define alc880_lg_lw_modes alc880_threestack_modes 2754 2755static struct snd_kcontrol_new alc880_lg_lw_mixer[] = { 2756 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2757 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 2758 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 2759 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT), 2760 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 2761 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 2762 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 2763 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 2764 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 2765 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 2766 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 2767 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 2768 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 2769 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 2770 { 2771 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2772 .name = "Channel Mode", 2773 .info = alc_ch_mode_info, 2774 .get = alc_ch_mode_get, 2775 .put = alc_ch_mode_put, 2776 }, 2777 { } /* end */ 2778}; 2779 2780static struct hda_verb alc880_lg_lw_init_verbs[] = { 2781 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 2782 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ 2783 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */ 2784 2785 /* set capture source to mic-in */ 2786 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 2787 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 2788 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 2789 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, 2790 /* speaker-out */ 2791 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 2792 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2793 /* HP-out */ 2794 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 2795 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2796 /* mic-in to input */ 2797 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2798 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2799 /* built-in mic */ 2800 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2801 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2802 /* jack sense */ 2803 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1}, 2804 { } 2805}; 2806 2807/* toggle speaker-output according to the hp-jack state */ 2808static void alc880_lg_lw_automute(struct hda_codec *codec) 2809{ 2810 unsigned int present; 2811 unsigned char bits; 2812 2813 present = snd_hda_codec_read(codec, 0x1b, 0, 2814 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 2815 bits = present ? HDA_AMP_MUTE : 0; 2816 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 2817 HDA_AMP_MUTE, bits); 2818} 2819 2820static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res) 2821{ 2822 /* Looks like the unsol event is incompatible with the standard 2823 * definition. 4bit tag is placed at 28 bit! 2824 */ 2825 if ((res >> 28) == 0x01) 2826 alc880_lg_lw_automute(codec); 2827} 2828 2829static struct snd_kcontrol_new alc880_medion_rim_mixer[] = { 2830 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2831 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT), 2832 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 2833 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 2834 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 2835 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT), 2836 { } /* end */ 2837}; 2838 2839static struct hda_input_mux alc880_medion_rim_capture_source = { 2840 .num_items = 2, 2841 .items = { 2842 { "Mic", 0x0 }, 2843 { "Internal Mic", 0x1 }, 2844 }, 2845}; 2846 2847static struct hda_verb alc880_medion_rim_init_verbs[] = { 2848 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 2849 2850 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 2851 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2852 2853 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 2854 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2855 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2856 /* Mic2 (as headphone out) for HP output */ 2857 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 2858 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2859 /* Internal Speaker */ 2860 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2861 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2862 2863 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 2864 {0x20, AC_VERB_SET_PROC_COEF, 0x3060}, 2865 2866 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 2867 { } 2868}; 2869 2870/* toggle speaker-output according to the hp-jack state */ 2871static void alc880_medion_rim_automute(struct hda_codec *codec) 2872{ 2873 unsigned int present; 2874 unsigned char bits; 2875 2876 present = snd_hda_codec_read(codec, 0x14, 0, 2877 AC_VERB_GET_PIN_SENSE, 0) 2878 & AC_PINSENSE_PRESENCE; 2879 bits = present ? HDA_AMP_MUTE : 0; 2880 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0, 2881 HDA_AMP_MUTE, bits); 2882 if (present) 2883 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0); 2884 else 2885 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2); 2886} 2887 2888static void alc880_medion_rim_unsol_event(struct hda_codec *codec, 2889 unsigned int res) 2890{ 2891 /* Looks like the unsol event is incompatible with the standard 2892 * definition. 4bit tag is placed at 28 bit! 2893 */ 2894 if ((res >> 28) == ALC880_HP_EVENT) 2895 alc880_medion_rim_automute(codec); 2896} 2897 2898#ifdef CONFIG_SND_HDA_POWER_SAVE 2899static struct hda_amp_list alc880_loopbacks[] = { 2900 { 0x0b, HDA_INPUT, 0 }, 2901 { 0x0b, HDA_INPUT, 1 }, 2902 { 0x0b, HDA_INPUT, 2 }, 2903 { 0x0b, HDA_INPUT, 3 }, 2904 { 0x0b, HDA_INPUT, 4 }, 2905 { } /* end */ 2906}; 2907 2908static struct hda_amp_list alc880_lg_loopbacks[] = { 2909 { 0x0b, HDA_INPUT, 1 }, 2910 { 0x0b, HDA_INPUT, 6 }, 2911 { 0x0b, HDA_INPUT, 7 }, 2912 { } /* end */ 2913}; 2914#endif 2915 2916/* 2917 * Common callbacks 2918 */ 2919 2920static int alc_init(struct hda_codec *codec) 2921{ 2922 struct alc_spec *spec = codec->spec; 2923 unsigned int i; 2924 2925 alc_fix_pll(codec); 2926 if (codec->vendor_id == 0x10ec0888) 2927 alc888_coef_init(codec); 2928 2929 for (i = 0; i < spec->num_init_verbs; i++) 2930 snd_hda_sequence_write(codec, spec->init_verbs[i]); 2931 2932 if (spec->init_hook) 2933 spec->init_hook(codec); 2934 2935 return 0; 2936} 2937 2938static void alc_unsol_event(struct hda_codec *codec, unsigned int res) 2939{ 2940 struct alc_spec *spec = codec->spec; 2941 2942 if (spec->unsol_event) 2943 spec->unsol_event(codec, res); 2944} 2945 2946#ifdef CONFIG_SND_HDA_POWER_SAVE 2947static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid) 2948{ 2949 struct alc_spec *spec = codec->spec; 2950 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid); 2951} 2952#endif 2953 2954/* 2955 * Analog playback callbacks 2956 */ 2957static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo, 2958 struct hda_codec *codec, 2959 struct snd_pcm_substream *substream) 2960{ 2961 struct alc_spec *spec = codec->spec; 2962 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream, 2963 hinfo); 2964} 2965 2966static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo, 2967 struct hda_codec *codec, 2968 unsigned int stream_tag, 2969 unsigned int format, 2970 struct snd_pcm_substream *substream) 2971{ 2972 struct alc_spec *spec = codec->spec; 2973 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, 2974 stream_tag, format, substream); 2975} 2976 2977static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, 2978 struct hda_codec *codec, 2979 struct snd_pcm_substream *substream) 2980{ 2981 struct alc_spec *spec = codec->spec; 2982 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); 2983} 2984 2985/* 2986 * Digital out 2987 */ 2988static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo, 2989 struct hda_codec *codec, 2990 struct snd_pcm_substream *substream) 2991{ 2992 struct alc_spec *spec = codec->spec; 2993 return snd_hda_multi_out_dig_open(codec, &spec->multiout); 2994} 2995 2996static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, 2997 struct hda_codec *codec, 2998 unsigned int stream_tag, 2999 unsigned int format, 3000 struct snd_pcm_substream *substream) 3001{ 3002 struct alc_spec *spec = codec->spec; 3003 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, 3004 stream_tag, format, substream); 3005} 3006 3007static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, 3008 struct hda_codec *codec, 3009 struct snd_pcm_substream *substream) 3010{ 3011 struct alc_spec *spec = codec->spec; 3012 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout); 3013} 3014 3015static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, 3016 struct hda_codec *codec, 3017 struct snd_pcm_substream *substream) 3018{ 3019 struct alc_spec *spec = codec->spec; 3020 return snd_hda_multi_out_dig_close(codec, &spec->multiout); 3021} 3022 3023/* 3024 * Analog capture 3025 */ 3026static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo, 3027 struct hda_codec *codec, 3028 unsigned int stream_tag, 3029 unsigned int format, 3030 struct snd_pcm_substream *substream) 3031{ 3032 struct alc_spec *spec = codec->spec; 3033 3034 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1], 3035 stream_tag, 0, format); 3036 return 0; 3037} 3038 3039static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, 3040 struct hda_codec *codec, 3041 struct snd_pcm_substream *substream) 3042{ 3043 struct alc_spec *spec = codec->spec; 3044 3045 snd_hda_codec_cleanup_stream(codec, 3046 spec->adc_nids[substream->number + 1]); 3047 return 0; 3048} 3049 3050 3051/* 3052 */ 3053static struct hda_pcm_stream alc880_pcm_analog_playback = { 3054 .substreams = 1, 3055 .channels_min = 2, 3056 .channels_max = 8, 3057 /* NID is set in alc_build_pcms */ 3058 .ops = { 3059 .open = alc880_playback_pcm_open, 3060 .prepare = alc880_playback_pcm_prepare, 3061 .cleanup = alc880_playback_pcm_cleanup 3062 }, 3063}; 3064 3065static struct hda_pcm_stream alc880_pcm_analog_capture = { 3066 .substreams = 1, 3067 .channels_min = 2, 3068 .channels_max = 2, 3069 /* NID is set in alc_build_pcms */ 3070}; 3071 3072static struct hda_pcm_stream alc880_pcm_analog_alt_playback = { 3073 .substreams = 1, 3074 .channels_min = 2, 3075 .channels_max = 2, 3076 /* NID is set in alc_build_pcms */ 3077}; 3078 3079static struct hda_pcm_stream alc880_pcm_analog_alt_capture = { 3080 .substreams = 2, /* can be overridden */ 3081 .channels_min = 2, 3082 .channels_max = 2, 3083 /* NID is set in alc_build_pcms */ 3084 .ops = { 3085 .prepare = alc880_alt_capture_pcm_prepare, 3086 .cleanup = alc880_alt_capture_pcm_cleanup 3087 }, 3088}; 3089 3090static struct hda_pcm_stream alc880_pcm_digital_playback = { 3091 .substreams = 1, 3092 .channels_min = 2, 3093 .channels_max = 2, 3094 /* NID is set in alc_build_pcms */ 3095 .ops = { 3096 .open = alc880_dig_playback_pcm_open, 3097 .close = alc880_dig_playback_pcm_close, 3098 .prepare = alc880_dig_playback_pcm_prepare, 3099 .cleanup = alc880_dig_playback_pcm_cleanup 3100 }, 3101}; 3102 3103static struct hda_pcm_stream alc880_pcm_digital_capture = { 3104 .substreams = 1, 3105 .channels_min = 2, 3106 .channels_max = 2, 3107 /* NID is set in alc_build_pcms */ 3108}; 3109 3110/* Used by alc_build_pcms to flag that a PCM has no playback stream */ 3111static struct hda_pcm_stream alc_pcm_null_stream = { 3112 .substreams = 0, 3113 .channels_min = 0, 3114 .channels_max = 0, 3115}; 3116 3117static int alc_build_pcms(struct hda_codec *codec) 3118{ 3119 struct alc_spec *spec = codec->spec; 3120 struct hda_pcm *info = spec->pcm_rec; 3121 int i; 3122 3123 codec->num_pcms = 1; 3124 codec->pcm_info = info; 3125 3126 if (spec->no_analog) 3127 goto skip_analog; 3128 3129 info->name = spec->stream_name_analog; 3130 if (spec->stream_analog_playback) { 3131 if (snd_BUG_ON(!spec->multiout.dac_nids)) 3132 return -EINVAL; 3133 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback); 3134 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0]; 3135 } 3136 if (spec->stream_analog_capture) { 3137 if (snd_BUG_ON(!spec->adc_nids)) 3138 return -EINVAL; 3139 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture); 3140 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0]; 3141 } 3142 3143 if (spec->channel_mode) { 3144 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0; 3145 for (i = 0; i < spec->num_channel_mode; i++) { 3146 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) { 3147 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels; 3148 } 3149 } 3150 } 3151 3152 skip_analog: 3153 /* SPDIF for stream index #1 */ 3154 if (spec->multiout.dig_out_nid || spec->dig_in_nid) { 3155 codec->num_pcms = 2; 3156 codec->slave_dig_outs = spec->multiout.slave_dig_outs; 3157 info = spec->pcm_rec + 1; 3158 info->name = spec->stream_name_digital; 3159 if (spec->dig_out_type) 3160 info->pcm_type = spec->dig_out_type; 3161 else 3162 info->pcm_type = HDA_PCM_TYPE_SPDIF; 3163 if (spec->multiout.dig_out_nid && 3164 spec->stream_digital_playback) { 3165 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback); 3166 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid; 3167 } 3168 if (spec->dig_in_nid && 3169 spec->stream_digital_capture) { 3170 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture); 3171 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid; 3172 } 3173 /* FIXME: do we need this for all Realtek codec models? */ 3174 codec->spdif_status_reset = 1; 3175 } 3176 3177 if (spec->no_analog) 3178 return 0; 3179 3180 /* If the use of more than one ADC is requested for the current 3181 * model, configure a second analog capture-only PCM. 3182 */ 3183 /* Additional Analaog capture for index #2 */ 3184 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) || 3185 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) { 3186 codec->num_pcms = 3; 3187 info = spec->pcm_rec + 2; 3188 info->name = spec->stream_name_analog; 3189 if (spec->alt_dac_nid) { 3190 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = 3191 *spec->stream_analog_alt_playback; 3192 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 3193 spec->alt_dac_nid; 3194 } else { 3195 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = 3196 alc_pcm_null_stream; 3197 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0; 3198 } 3199 if (spec->num_adc_nids > 1) { 3200 info->stream[SNDRV_PCM_STREAM_CAPTURE] = 3201 *spec->stream_analog_alt_capture; 3202 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 3203 spec->adc_nids[1]; 3204 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = 3205 spec->num_adc_nids - 1; 3206 } else { 3207 info->stream[SNDRV_PCM_STREAM_CAPTURE] = 3208 alc_pcm_null_stream; 3209 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0; 3210 } 3211 } 3212 3213 return 0; 3214} 3215 3216static void alc_free_kctls(struct hda_codec *codec) 3217{ 3218 struct alc_spec *spec = codec->spec; 3219 3220 if (spec->kctls.list) { 3221 struct snd_kcontrol_new *kctl = spec->kctls.list; 3222 int i; 3223 for (i = 0; i < spec->kctls.used; i++) 3224 kfree(kctl[i].name); 3225 } 3226 snd_array_free(&spec->kctls); 3227} 3228 3229static void alc_free(struct hda_codec *codec) 3230{ 3231 struct alc_spec *spec = codec->spec; 3232 3233 if (!spec) 3234 return; 3235 3236 alc_free_kctls(codec); 3237 kfree(spec); 3238 snd_hda_detach_beep_device(codec); 3239} 3240 3241#ifdef SND_HDA_NEEDS_RESUME 3242static int alc_resume(struct hda_codec *codec) 3243{ 3244 codec->patch_ops.init(codec); 3245 snd_hda_codec_resume_amp(codec); 3246 snd_hda_codec_resume_cache(codec); 3247 return 0; 3248} 3249#endif 3250 3251/* 3252 */ 3253static struct hda_codec_ops alc_patch_ops = { 3254 .build_controls = alc_build_controls, 3255 .build_pcms = alc_build_pcms, 3256 .init = alc_init, 3257 .free = alc_free, 3258 .unsol_event = alc_unsol_event, 3259#ifdef SND_HDA_NEEDS_RESUME 3260 .resume = alc_resume, 3261#endif 3262#ifdef CONFIG_SND_HDA_POWER_SAVE 3263 .check_power_status = alc_check_power_status, 3264#endif 3265}; 3266 3267 3268/* 3269 * Test configuration for debugging 3270 * 3271 * Almost all inputs/outputs are enabled. I/O pins can be configured via 3272 * enum controls. 3273 */ 3274#ifdef CONFIG_SND_DEBUG 3275static hda_nid_t alc880_test_dac_nids[4] = { 3276 0x02, 0x03, 0x04, 0x05 3277}; 3278 3279static struct hda_input_mux alc880_test_capture_source = { 3280 .num_items = 7, 3281 .items = { 3282 { "In-1", 0x0 }, 3283 { "In-2", 0x1 }, 3284 { "In-3", 0x2 }, 3285 { "In-4", 0x3 }, 3286 { "CD", 0x4 }, 3287 { "Front", 0x5 }, 3288 { "Surround", 0x6 }, 3289 }, 3290}; 3291 3292static struct hda_channel_mode alc880_test_modes[4] = { 3293 { 2, NULL }, 3294 { 4, NULL }, 3295 { 6, NULL }, 3296 { 8, NULL }, 3297}; 3298 3299static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol, 3300 struct snd_ctl_elem_info *uinfo) 3301{ 3302 static char *texts[] = { 3303 "N/A", "Line Out", "HP Out", 3304 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%" 3305 }; 3306 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 3307 uinfo->count = 1; 3308 uinfo->value.enumerated.items = 8; 3309 if (uinfo->value.enumerated.item >= 8) 3310 uinfo->value.enumerated.item = 7; 3311 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); 3312 return 0; 3313} 3314 3315static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol, 3316 struct snd_ctl_elem_value *ucontrol) 3317{ 3318 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 3319 hda_nid_t nid = (hda_nid_t)kcontrol->private_value; 3320 unsigned int pin_ctl, item = 0; 3321 3322 pin_ctl = snd_hda_codec_read(codec, nid, 0, 3323 AC_VERB_GET_PIN_WIDGET_CONTROL, 0); 3324 if (pin_ctl & AC_PINCTL_OUT_EN) { 3325 if (pin_ctl & AC_PINCTL_HP_EN) 3326 item = 2; 3327 else 3328 item = 1; 3329 } else if (pin_ctl & AC_PINCTL_IN_EN) { 3330 switch (pin_ctl & AC_PINCTL_VREFEN) { 3331 case AC_PINCTL_VREF_HIZ: item = 3; break; 3332 case AC_PINCTL_VREF_50: item = 4; break; 3333 case AC_PINCTL_VREF_GRD: item = 5; break; 3334 case AC_PINCTL_VREF_80: item = 6; break; 3335 case AC_PINCTL_VREF_100: item = 7; break; 3336 } 3337 } 3338 ucontrol->value.enumerated.item[0] = item; 3339 return 0; 3340} 3341 3342static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol, 3343 struct snd_ctl_elem_value *ucontrol) 3344{ 3345 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 3346 hda_nid_t nid = (hda_nid_t)kcontrol->private_value; 3347 static unsigned int ctls[] = { 3348 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN, 3349 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ, 3350 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50, 3351 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD, 3352 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80, 3353 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100, 3354 }; 3355 unsigned int old_ctl, new_ctl; 3356 3357 old_ctl = snd_hda_codec_read(codec, nid, 0, 3358 AC_VERB_GET_PIN_WIDGET_CONTROL, 0); 3359 new_ctl = ctls[ucontrol->value.enumerated.item[0]]; 3360 if (old_ctl != new_ctl) { 3361 int val; 3362 snd_hda_codec_write_cache(codec, nid, 0, 3363 AC_VERB_SET_PIN_WIDGET_CONTROL, 3364 new_ctl); 3365 val = ucontrol->value.enumerated.item[0] >= 3 ? 3366 HDA_AMP_MUTE : 0; 3367 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, 3368 HDA_AMP_MUTE, val); 3369 return 1; 3370 } 3371 return 0; 3372} 3373 3374static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol, 3375 struct snd_ctl_elem_info *uinfo) 3376{ 3377 static char *texts[] = { 3378 "Front", "Surround", "CLFE", "Side" 3379 }; 3380 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 3381 uinfo->count = 1; 3382 uinfo->value.enumerated.items = 4; 3383 if (uinfo->value.enumerated.item >= 4) 3384 uinfo->value.enumerated.item = 3; 3385 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); 3386 return 0; 3387} 3388 3389static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol, 3390 struct snd_ctl_elem_value *ucontrol) 3391{ 3392 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 3393 hda_nid_t nid = (hda_nid_t)kcontrol->private_value; 3394 unsigned int sel; 3395 3396 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0); 3397 ucontrol->value.enumerated.item[0] = sel & 3; 3398 return 0; 3399} 3400 3401static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol, 3402 struct snd_ctl_elem_value *ucontrol) 3403{ 3404 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 3405 hda_nid_t nid = (hda_nid_t)kcontrol->private_value; 3406 unsigned int sel; 3407 3408 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3; 3409 if (ucontrol->value.enumerated.item[0] != sel) { 3410 sel = ucontrol->value.enumerated.item[0] & 3; 3411 snd_hda_codec_write_cache(codec, nid, 0, 3412 AC_VERB_SET_CONNECT_SEL, sel); 3413 return 1; 3414 } 3415 return 0; 3416} 3417 3418#define PIN_CTL_TEST(xname,nid) { \ 3419 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 3420 .name = xname, \ 3421 .info = alc_test_pin_ctl_info, \ 3422 .get = alc_test_pin_ctl_get, \ 3423 .put = alc_test_pin_ctl_put, \ 3424 .private_value = nid \ 3425 } 3426 3427#define PIN_SRC_TEST(xname,nid) { \ 3428 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 3429 .name = xname, \ 3430 .info = alc_test_pin_src_info, \ 3431 .get = alc_test_pin_src_get, \ 3432 .put = alc_test_pin_src_put, \ 3433 .private_value = nid \ 3434 } 3435 3436static struct snd_kcontrol_new alc880_test_mixer[] = { 3437 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 3438 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 3439 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT), 3440 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 3441 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 3442 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 3443 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT), 3444 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 3445 PIN_CTL_TEST("Front Pin Mode", 0x14), 3446 PIN_CTL_TEST("Surround Pin Mode", 0x15), 3447 PIN_CTL_TEST("CLFE Pin Mode", 0x16), 3448 PIN_CTL_TEST("Side Pin Mode", 0x17), 3449 PIN_CTL_TEST("In-1 Pin Mode", 0x18), 3450 PIN_CTL_TEST("In-2 Pin Mode", 0x19), 3451 PIN_CTL_TEST("In-3 Pin Mode", 0x1a), 3452 PIN_CTL_TEST("In-4 Pin Mode", 0x1b), 3453 PIN_SRC_TEST("In-1 Pin Source", 0x18), 3454 PIN_SRC_TEST("In-2 Pin Source", 0x19), 3455 PIN_SRC_TEST("In-3 Pin Source", 0x1a), 3456 PIN_SRC_TEST("In-4 Pin Source", 0x1b), 3457 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT), 3458 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT), 3459 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT), 3460 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT), 3461 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT), 3462 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT), 3463 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT), 3464 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT), 3465 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT), 3466 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT), 3467 { 3468 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 3469 .name = "Channel Mode", 3470 .info = alc_ch_mode_info, 3471 .get = alc_ch_mode_get, 3472 .put = alc_ch_mode_put, 3473 }, 3474 { } /* end */ 3475}; 3476 3477static struct hda_verb alc880_test_init_verbs[] = { 3478 /* Unmute inputs of 0x0c - 0x0f */ 3479 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3480 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 3481 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3482 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 3483 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3484 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 3485 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3486 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 3487 /* Vol output for 0x0c-0x0f */ 3488 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3489 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3490 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3491 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3492 /* Set output pins 0x14-0x17 */ 3493 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3494 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3495 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3496 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3497 /* Unmute output pins 0x14-0x17 */ 3498 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3499 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3500 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3501 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3502 /* Set input pins 0x18-0x1c */ 3503 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3504 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3505 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3506 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3507 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3508 /* Mute input pins 0x18-0x1b */ 3509 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3510 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3511 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3512 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3513 /* ADC set up */ 3514 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3515 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 3516 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3517 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 3518 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3519 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 3520 /* Analog input/passthru */ 3521 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3522 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 3523 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 3524 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 3525 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 3526 { } 3527}; 3528#endif 3529 3530/* 3531 */ 3532 3533static const char *alc880_models[ALC880_MODEL_LAST] = { 3534 [ALC880_3ST] = "3stack", 3535 [ALC880_TCL_S700] = "tcl", 3536 [ALC880_3ST_DIG] = "3stack-digout", 3537 [ALC880_CLEVO] = "clevo", 3538 [ALC880_5ST] = "5stack", 3539 [ALC880_5ST_DIG] = "5stack-digout", 3540 [ALC880_W810] = "w810", 3541 [ALC880_Z71V] = "z71v", 3542 [ALC880_6ST] = "6stack", 3543 [ALC880_6ST_DIG] = "6stack-digout", 3544 [ALC880_ASUS] = "asus", 3545 [ALC880_ASUS_W1V] = "asus-w1v", 3546 [ALC880_ASUS_DIG] = "asus-dig", 3547 [ALC880_ASUS_DIG2] = "asus-dig2", 3548 [ALC880_UNIWILL_DIG] = "uniwill", 3549 [ALC880_UNIWILL_P53] = "uniwill-p53", 3550 [ALC880_FUJITSU] = "fujitsu", 3551 [ALC880_F1734] = "F1734", 3552 [ALC880_LG] = "lg", 3553 [ALC880_LG_LW] = "lg-lw", 3554 [ALC880_MEDION_RIM] = "medion", 3555#ifdef CONFIG_SND_DEBUG 3556 [ALC880_TEST] = "test", 3557#endif 3558 [ALC880_AUTO] = "auto", 3559}; 3560 3561static struct snd_pci_quirk alc880_cfg_tbl[] = { 3562 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810), 3563 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG), 3564 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST), 3565 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG), 3566 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG), 3567 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG), 3568 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG), 3569 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG), 3570 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST), 3571 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG), 3572 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST), 3573 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V), 3574 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG), 3575 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG), 3576 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG), 3577 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG), 3578 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG), 3579 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V), 3580 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */ 3581 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG), 3582 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG), 3583 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG), 3584 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG), 3585 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST), 3586 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST), 3587 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */ 3588 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST), 3589 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST), 3590 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST), 3591 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST), 3592 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST), 3593 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG), 3594 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG), 3595 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG), 3596 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG), 3597 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO), 3598 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO), 3599 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2), 3600 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG), 3601 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG), 3602 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734), 3603 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL), 3604 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53), 3605 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810), 3606 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM), 3607 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG), 3608 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG), 3609 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734), 3610 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU), 3611 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL), 3612 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU), 3613 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW), 3614 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG), 3615 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG), 3616 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW), 3617 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700), 3618 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */ 3619 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG), 3620 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG), 3621 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG), 3622 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG), 3623 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG), 3624 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG), 3625 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG), 3626 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG), 3627 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG), 3628 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG), 3629 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG), 3630 /* default Intel */ 3631 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST), 3632 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG), 3633 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG), 3634 {} 3635}; 3636 3637/* 3638 * ALC880 codec presets 3639 */ 3640static struct alc_config_preset alc880_presets[] = { 3641 [ALC880_3ST] = { 3642 .mixers = { alc880_three_stack_mixer }, 3643 .init_verbs = { alc880_volume_init_verbs, 3644 alc880_pin_3stack_init_verbs }, 3645 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 3646 .dac_nids = alc880_dac_nids, 3647 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), 3648 .channel_mode = alc880_threestack_modes, 3649 .need_dac_fix = 1, 3650 .input_mux = &alc880_capture_source, 3651 }, 3652 [ALC880_3ST_DIG] = { 3653 .mixers = { alc880_three_stack_mixer }, 3654 .init_verbs = { alc880_volume_init_verbs, 3655 alc880_pin_3stack_init_verbs }, 3656 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 3657 .dac_nids = alc880_dac_nids, 3658 .dig_out_nid = ALC880_DIGOUT_NID, 3659 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), 3660 .channel_mode = alc880_threestack_modes, 3661 .need_dac_fix = 1, 3662 .input_mux = &alc880_capture_source, 3663 }, 3664 [ALC880_TCL_S700] = { 3665 .mixers = { alc880_tcl_s700_mixer }, 3666 .init_verbs = { alc880_volume_init_verbs, 3667 alc880_pin_tcl_S700_init_verbs, 3668 alc880_gpio2_init_verbs }, 3669 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 3670 .dac_nids = alc880_dac_nids, 3671 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */ 3672 .num_adc_nids = 1, /* single ADC */ 3673 .hp_nid = 0x03, 3674 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), 3675 .channel_mode = alc880_2_jack_modes, 3676 .input_mux = &alc880_capture_source, 3677 }, 3678 [ALC880_5ST] = { 3679 .mixers = { alc880_three_stack_mixer, 3680 alc880_five_stack_mixer}, 3681 .init_verbs = { alc880_volume_init_verbs, 3682 alc880_pin_5stack_init_verbs }, 3683 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 3684 .dac_nids = alc880_dac_nids, 3685 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes), 3686 .channel_mode = alc880_fivestack_modes, 3687 .input_mux = &alc880_capture_source, 3688 }, 3689 [ALC880_5ST_DIG] = { 3690 .mixers = { alc880_three_stack_mixer, 3691 alc880_five_stack_mixer }, 3692 .init_verbs = { alc880_volume_init_verbs, 3693 alc880_pin_5stack_init_verbs }, 3694 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 3695 .dac_nids = alc880_dac_nids, 3696 .dig_out_nid = ALC880_DIGOUT_NID, 3697 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes), 3698 .channel_mode = alc880_fivestack_modes, 3699 .input_mux = &alc880_capture_source, 3700 }, 3701 [ALC880_6ST] = { 3702 .mixers = { alc880_six_stack_mixer }, 3703 .init_verbs = { alc880_volume_init_verbs, 3704 alc880_pin_6stack_init_verbs }, 3705 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids), 3706 .dac_nids = alc880_6st_dac_nids, 3707 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes), 3708 .channel_mode = alc880_sixstack_modes, 3709 .input_mux = &alc880_6stack_capture_source, 3710 }, 3711 [ALC880_6ST_DIG] = { 3712 .mixers = { alc880_six_stack_mixer }, 3713 .init_verbs = { alc880_volume_init_verbs, 3714 alc880_pin_6stack_init_verbs }, 3715 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids), 3716 .dac_nids = alc880_6st_dac_nids, 3717 .dig_out_nid = ALC880_DIGOUT_NID, 3718 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes), 3719 .channel_mode = alc880_sixstack_modes, 3720 .input_mux = &alc880_6stack_capture_source, 3721 }, 3722 [ALC880_W810] = { 3723 .mixers = { alc880_w810_base_mixer }, 3724 .init_verbs = { alc880_volume_init_verbs, 3725 alc880_pin_w810_init_verbs, 3726 alc880_gpio2_init_verbs }, 3727 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids), 3728 .dac_nids = alc880_w810_dac_nids, 3729 .dig_out_nid = ALC880_DIGOUT_NID, 3730 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes), 3731 .channel_mode = alc880_w810_modes, 3732 .input_mux = &alc880_capture_source, 3733 }, 3734 [ALC880_Z71V] = { 3735 .mixers = { alc880_z71v_mixer }, 3736 .init_verbs = { alc880_volume_init_verbs, 3737 alc880_pin_z71v_init_verbs }, 3738 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids), 3739 .dac_nids = alc880_z71v_dac_nids, 3740 .dig_out_nid = ALC880_DIGOUT_NID, 3741 .hp_nid = 0x03, 3742 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), 3743 .channel_mode = alc880_2_jack_modes, 3744 .input_mux = &alc880_capture_source, 3745 }, 3746 [ALC880_F1734] = { 3747 .mixers = { alc880_f1734_mixer }, 3748 .init_verbs = { alc880_volume_init_verbs, 3749 alc880_pin_f1734_init_verbs }, 3750 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids), 3751 .dac_nids = alc880_f1734_dac_nids, 3752 .hp_nid = 0x02, 3753 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), 3754 .channel_mode = alc880_2_jack_modes, 3755 .input_mux = &alc880_f1734_capture_source, 3756 .unsol_event = alc880_uniwill_p53_unsol_event, 3757 .init_hook = alc880_uniwill_p53_hp_automute, 3758 }, 3759 [ALC880_ASUS] = { 3760 .mixers = { alc880_asus_mixer }, 3761 .init_verbs = { alc880_volume_init_verbs, 3762 alc880_pin_asus_init_verbs, 3763 alc880_gpio1_init_verbs }, 3764 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 3765 .dac_nids = alc880_asus_dac_nids, 3766 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), 3767 .channel_mode = alc880_asus_modes, 3768 .need_dac_fix = 1, 3769 .input_mux = &alc880_capture_source, 3770 }, 3771 [ALC880_ASUS_DIG] = { 3772 .mixers = { alc880_asus_mixer }, 3773 .init_verbs = { alc880_volume_init_verbs, 3774 alc880_pin_asus_init_verbs, 3775 alc880_gpio1_init_verbs }, 3776 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 3777 .dac_nids = alc880_asus_dac_nids, 3778 .dig_out_nid = ALC880_DIGOUT_NID, 3779 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), 3780 .channel_mode = alc880_asus_modes, 3781 .need_dac_fix = 1, 3782 .input_mux = &alc880_capture_source, 3783 }, 3784 [ALC880_ASUS_DIG2] = { 3785 .mixers = { alc880_asus_mixer }, 3786 .init_verbs = { alc880_volume_init_verbs, 3787 alc880_pin_asus_init_verbs, 3788 alc880_gpio2_init_verbs }, /* use GPIO2 */ 3789 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 3790 .dac_nids = alc880_asus_dac_nids, 3791 .dig_out_nid = ALC880_DIGOUT_NID, 3792 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), 3793 .channel_mode = alc880_asus_modes, 3794 .need_dac_fix = 1, 3795 .input_mux = &alc880_capture_source, 3796 }, 3797 [ALC880_ASUS_W1V] = { 3798 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer }, 3799 .init_verbs = { alc880_volume_init_verbs, 3800 alc880_pin_asus_init_verbs, 3801 alc880_gpio1_init_verbs }, 3802 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 3803 .dac_nids = alc880_asus_dac_nids, 3804 .dig_out_nid = ALC880_DIGOUT_NID, 3805 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), 3806 .channel_mode = alc880_asus_modes, 3807 .need_dac_fix = 1, 3808 .input_mux = &alc880_capture_source, 3809 }, 3810 [ALC880_UNIWILL_DIG] = { 3811 .mixers = { alc880_asus_mixer }, 3812 .init_verbs = { alc880_volume_init_verbs, 3813 alc880_pin_asus_init_verbs }, 3814 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 3815 .dac_nids = alc880_asus_dac_nids, 3816 .dig_out_nid = ALC880_DIGOUT_NID, 3817 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), 3818 .channel_mode = alc880_asus_modes, 3819 .need_dac_fix = 1, 3820 .input_mux = &alc880_capture_source, 3821 }, 3822 [ALC880_UNIWILL] = { 3823 .mixers = { alc880_uniwill_mixer }, 3824 .init_verbs = { alc880_volume_init_verbs, 3825 alc880_uniwill_init_verbs }, 3826 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 3827 .dac_nids = alc880_asus_dac_nids, 3828 .dig_out_nid = ALC880_DIGOUT_NID, 3829 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), 3830 .channel_mode = alc880_threestack_modes, 3831 .need_dac_fix = 1, 3832 .input_mux = &alc880_capture_source, 3833 .unsol_event = alc880_uniwill_unsol_event, 3834 .init_hook = alc880_uniwill_automute, 3835 }, 3836 [ALC880_UNIWILL_P53] = { 3837 .mixers = { alc880_uniwill_p53_mixer }, 3838 .init_verbs = { alc880_volume_init_verbs, 3839 alc880_uniwill_p53_init_verbs }, 3840 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 3841 .dac_nids = alc880_asus_dac_nids, 3842 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes), 3843 .channel_mode = alc880_threestack_modes, 3844 .input_mux = &alc880_capture_source, 3845 .unsol_event = alc880_uniwill_p53_unsol_event, 3846 .init_hook = alc880_uniwill_p53_hp_automute, 3847 }, 3848 [ALC880_FUJITSU] = { 3849 .mixers = { alc880_fujitsu_mixer }, 3850 .init_verbs = { alc880_volume_init_verbs, 3851 alc880_uniwill_p53_init_verbs, 3852 alc880_beep_init_verbs }, 3853 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 3854 .dac_nids = alc880_dac_nids, 3855 .dig_out_nid = ALC880_DIGOUT_NID, 3856 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), 3857 .channel_mode = alc880_2_jack_modes, 3858 .input_mux = &alc880_capture_source, 3859 .unsol_event = alc880_uniwill_p53_unsol_event, 3860 .init_hook = alc880_uniwill_p53_hp_automute, 3861 }, 3862 [ALC880_CLEVO] = { 3863 .mixers = { alc880_three_stack_mixer }, 3864 .init_verbs = { alc880_volume_init_verbs, 3865 alc880_pin_clevo_init_verbs }, 3866 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 3867 .dac_nids = alc880_dac_nids, 3868 .hp_nid = 0x03, 3869 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), 3870 .channel_mode = alc880_threestack_modes, 3871 .need_dac_fix = 1, 3872 .input_mux = &alc880_capture_source, 3873 }, 3874 [ALC880_LG] = { 3875 .mixers = { alc880_lg_mixer }, 3876 .init_verbs = { alc880_volume_init_verbs, 3877 alc880_lg_init_verbs }, 3878 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids), 3879 .dac_nids = alc880_lg_dac_nids, 3880 .dig_out_nid = ALC880_DIGOUT_NID, 3881 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes), 3882 .channel_mode = alc880_lg_ch_modes, 3883 .need_dac_fix = 1, 3884 .input_mux = &alc880_lg_capture_source, 3885 .unsol_event = alc880_lg_unsol_event, 3886 .init_hook = alc880_lg_automute, 3887#ifdef CONFIG_SND_HDA_POWER_SAVE 3888 .loopbacks = alc880_lg_loopbacks, 3889#endif 3890 }, 3891 [ALC880_LG_LW] = { 3892 .mixers = { alc880_lg_lw_mixer }, 3893 .init_verbs = { alc880_volume_init_verbs, 3894 alc880_lg_lw_init_verbs }, 3895 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 3896 .dac_nids = alc880_dac_nids, 3897 .dig_out_nid = ALC880_DIGOUT_NID, 3898 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes), 3899 .channel_mode = alc880_lg_lw_modes, 3900 .input_mux = &alc880_lg_lw_capture_source, 3901 .unsol_event = alc880_lg_lw_unsol_event, 3902 .init_hook = alc880_lg_lw_automute, 3903 }, 3904 [ALC880_MEDION_RIM] = { 3905 .mixers = { alc880_medion_rim_mixer }, 3906 .init_verbs = { alc880_volume_init_verbs, 3907 alc880_medion_rim_init_verbs, 3908 alc_gpio2_init_verbs }, 3909 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 3910 .dac_nids = alc880_dac_nids, 3911 .dig_out_nid = ALC880_DIGOUT_NID, 3912 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), 3913 .channel_mode = alc880_2_jack_modes, 3914 .input_mux = &alc880_medion_rim_capture_source, 3915 .unsol_event = alc880_medion_rim_unsol_event, 3916 .init_hook = alc880_medion_rim_automute, 3917 }, 3918#ifdef CONFIG_SND_DEBUG 3919 [ALC880_TEST] = { 3920 .mixers = { alc880_test_mixer }, 3921 .init_verbs = { alc880_test_init_verbs }, 3922 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids), 3923 .dac_nids = alc880_test_dac_nids, 3924 .dig_out_nid = ALC880_DIGOUT_NID, 3925 .num_channel_mode = ARRAY_SIZE(alc880_test_modes), 3926 .channel_mode = alc880_test_modes, 3927 .input_mux = &alc880_test_capture_source, 3928 }, 3929#endif 3930}; 3931 3932/* 3933 * Automatic parse of I/O pins from the BIOS configuration 3934 */ 3935 3936enum { 3937 ALC_CTL_WIDGET_VOL, 3938 ALC_CTL_WIDGET_MUTE, 3939 ALC_CTL_BIND_MUTE, 3940}; 3941static struct snd_kcontrol_new alc880_control_templates[] = { 3942 HDA_CODEC_VOLUME(NULL, 0, 0, 0), 3943 HDA_CODEC_MUTE(NULL, 0, 0, 0), 3944 HDA_BIND_MUTE(NULL, 0, 0, 0), 3945}; 3946 3947/* add dynamic controls */ 3948static int add_control(struct alc_spec *spec, int type, const char *name, 3949 unsigned long val) 3950{ 3951 struct snd_kcontrol_new *knew; 3952 3953 snd_array_init(&spec->kctls, sizeof(*knew), 32); 3954 knew = snd_array_new(&spec->kctls); 3955 if (!knew) 3956 return -ENOMEM; 3957 *knew = alc880_control_templates[type]; 3958 knew->name = kstrdup(name, GFP_KERNEL); 3959 if (!knew->name) 3960 return -ENOMEM; 3961 knew->private_value = val; 3962 return 0; 3963} 3964 3965#define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17) 3966#define alc880_fixed_pin_idx(nid) ((nid) - 0x14) 3967#define alc880_is_multi_pin(nid) ((nid) >= 0x18) 3968#define alc880_multi_pin_idx(nid) ((nid) - 0x18) 3969#define alc880_is_input_pin(nid) ((nid) >= 0x18) 3970#define alc880_input_pin_idx(nid) ((nid) - 0x18) 3971#define alc880_idx_to_dac(nid) ((nid) + 0x02) 3972#define alc880_dac_to_idx(nid) ((nid) - 0x02) 3973#define alc880_idx_to_mixer(nid) ((nid) + 0x0c) 3974#define alc880_idx_to_selector(nid) ((nid) + 0x10) 3975#define ALC880_PIN_CD_NID 0x1c 3976 3977/* fill in the dac_nids table from the parsed pin configuration */ 3978static int alc880_auto_fill_dac_nids(struct alc_spec *spec, 3979 const struct auto_pin_cfg *cfg) 3980{ 3981 hda_nid_t nid; 3982 int assigned[4]; 3983 int i, j; 3984 3985 memset(assigned, 0, sizeof(assigned)); 3986 spec->multiout.dac_nids = spec->private_dac_nids; 3987 3988 /* check the pins hardwired to audio widget */ 3989 for (i = 0; i < cfg->line_outs; i++) { 3990 nid = cfg->line_out_pins[i]; 3991 if (alc880_is_fixed_pin(nid)) { 3992 int idx = alc880_fixed_pin_idx(nid); 3993 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx); 3994 assigned[idx] = 1; 3995 } 3996 } 3997 /* left pins can be connect to any audio widget */ 3998 for (i = 0; i < cfg->line_outs; i++) { 3999 nid = cfg->line_out_pins[i]; 4000 if (alc880_is_fixed_pin(nid)) 4001 continue; 4002 /* search for an empty channel */ 4003 for (j = 0; j < cfg->line_outs; j++) { 4004 if (!assigned[j]) { 4005 spec->multiout.dac_nids[i] = 4006 alc880_idx_to_dac(j); 4007 assigned[j] = 1; 4008 break; 4009 } 4010 } 4011 } 4012 spec->multiout.num_dacs = cfg->line_outs; 4013 return 0; 4014} 4015 4016/* add playback controls from the parsed DAC table */ 4017static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec, 4018 const struct auto_pin_cfg *cfg) 4019{ 4020 char name[32]; 4021 static const char *chname[4] = { 4022 "Front", "Surround", NULL /*CLFE*/, "Side" 4023 }; 4024 hda_nid_t nid; 4025 int i, err; 4026 4027 for (i = 0; i < cfg->line_outs; i++) { 4028 if (!spec->multiout.dac_nids[i]) 4029 continue; 4030 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i])); 4031 if (i == 2) { 4032 /* Center/LFE */ 4033 err = add_control(spec, ALC_CTL_WIDGET_VOL, 4034 "Center Playback Volume", 4035 HDA_COMPOSE_AMP_VAL(nid, 1, 0, 4036 HDA_OUTPUT)); 4037 if (err < 0) 4038 return err; 4039 err = add_control(spec, ALC_CTL_WIDGET_VOL, 4040 "LFE Playback Volume", 4041 HDA_COMPOSE_AMP_VAL(nid, 2, 0, 4042 HDA_OUTPUT)); 4043 if (err < 0) 4044 return err; 4045 err = add_control(spec, ALC_CTL_BIND_MUTE, 4046 "Center Playback Switch", 4047 HDA_COMPOSE_AMP_VAL(nid, 1, 2, 4048 HDA_INPUT)); 4049 if (err < 0) 4050 return err; 4051 err = add_control(spec, ALC_CTL_BIND_MUTE, 4052 "LFE Playback Switch", 4053 HDA_COMPOSE_AMP_VAL(nid, 2, 2, 4054 HDA_INPUT)); 4055 if (err < 0) 4056 return err; 4057 } else { 4058 sprintf(name, "%s Playback Volume", chname[i]); 4059 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, 4060 HDA_COMPOSE_AMP_VAL(nid, 3, 0, 4061 HDA_OUTPUT)); 4062 if (err < 0) 4063 return err; 4064 sprintf(name, "%s Playback Switch", chname[i]); 4065 err = add_control(spec, ALC_CTL_BIND_MUTE, name, 4066 HDA_COMPOSE_AMP_VAL(nid, 3, 2, 4067 HDA_INPUT)); 4068 if (err < 0) 4069 return err; 4070 } 4071 } 4072 return 0; 4073} 4074 4075/* add playback controls for speaker and HP outputs */ 4076static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin, 4077 const char *pfx) 4078{ 4079 hda_nid_t nid; 4080 int err; 4081 char name[32]; 4082 4083 if (!pin) 4084 return 0; 4085 4086 if (alc880_is_fixed_pin(pin)) { 4087 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); 4088 /* specify the DAC as the extra output */ 4089 if (!spec->multiout.hp_nid) 4090 spec->multiout.hp_nid = nid; 4091 else 4092 spec->multiout.extra_out_nid[0] = nid; 4093 /* control HP volume/switch on the output mixer amp */ 4094 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin)); 4095 sprintf(name, "%s Playback Volume", pfx); 4096 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, 4097 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); 4098 if (err < 0) 4099 return err; 4100 sprintf(name, "%s Playback Switch", pfx); 4101 err = add_control(spec, ALC_CTL_BIND_MUTE, name, 4102 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT)); 4103 if (err < 0) 4104 return err; 4105 } else if (alc880_is_multi_pin(pin)) { 4106 /* set manual connection */ 4107 /* we have only a switch on HP-out PIN */ 4108 sprintf(name, "%s Playback Switch", pfx); 4109 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, 4110 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); 4111 if (err < 0) 4112 return err; 4113 } 4114 return 0; 4115} 4116 4117/* create input playback/capture controls for the given pin */ 4118static int new_analog_input(struct alc_spec *spec, hda_nid_t pin, 4119 const char *ctlname, 4120 int idx, hda_nid_t mix_nid) 4121{ 4122 char name[32]; 4123 int err; 4124 4125 sprintf(name, "%s Playback Volume", ctlname); 4126 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, 4127 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT)); 4128 if (err < 0) 4129 return err; 4130 sprintf(name, "%s Playback Switch", ctlname); 4131 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, 4132 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT)); 4133 if (err < 0) 4134 return err; 4135 return 0; 4136} 4137 4138/* create playback/capture controls for input pins */ 4139static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec, 4140 const struct auto_pin_cfg *cfg) 4141{ 4142 struct hda_input_mux *imux = &spec->private_imux[0]; 4143 int i, err, idx; 4144 4145 for (i = 0; i < AUTO_PIN_LAST; i++) { 4146 if (alc880_is_input_pin(cfg->input_pins[i])) { 4147 idx = alc880_input_pin_idx(cfg->input_pins[i]); 4148 err = new_analog_input(spec, cfg->input_pins[i], 4149 auto_pin_cfg_labels[i], 4150 idx, 0x0b); 4151 if (err < 0) 4152 return err; 4153 imux->items[imux->num_items].label = 4154 auto_pin_cfg_labels[i]; 4155 imux->items[imux->num_items].index = 4156 alc880_input_pin_idx(cfg->input_pins[i]); 4157 imux->num_items++; 4158 } 4159 } 4160 return 0; 4161} 4162 4163static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid, 4164 unsigned int pin_type) 4165{ 4166 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 4167 pin_type); 4168 /* unmute pin */ 4169 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, 4170 AMP_OUT_UNMUTE); 4171} 4172 4173static void alc880_auto_set_output_and_unmute(struct hda_codec *codec, 4174 hda_nid_t nid, int pin_type, 4175 int dac_idx) 4176{ 4177 alc_set_pin_output(codec, nid, pin_type); 4178 /* need the manual connection? */ 4179 if (alc880_is_multi_pin(nid)) { 4180 struct alc_spec *spec = codec->spec; 4181 int idx = alc880_multi_pin_idx(nid); 4182 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0, 4183 AC_VERB_SET_CONNECT_SEL, 4184 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx])); 4185 } 4186} 4187 4188static int get_pin_type(int line_out_type) 4189{ 4190 if (line_out_type == AUTO_PIN_HP_OUT) 4191 return PIN_HP; 4192 else 4193 return PIN_OUT; 4194} 4195 4196static void alc880_auto_init_multi_out(struct hda_codec *codec) 4197{ 4198 struct alc_spec *spec = codec->spec; 4199 int i; 4200 4201 alc_subsystem_id(codec, 0x15, 0x1b, 0x14); 4202 for (i = 0; i < spec->autocfg.line_outs; i++) { 4203 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 4204 int pin_type = get_pin_type(spec->autocfg.line_out_type); 4205 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i); 4206 } 4207} 4208 4209static void alc880_auto_init_extra_out(struct hda_codec *codec) 4210{ 4211 struct alc_spec *spec = codec->spec; 4212 hda_nid_t pin; 4213 4214 pin = spec->autocfg.speaker_pins[0]; 4215 if (pin) /* connect to front */ 4216 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0); 4217 pin = spec->autocfg.hp_pins[0]; 4218 if (pin) /* connect to front */ 4219 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); 4220} 4221 4222static void alc880_auto_init_analog_input(struct hda_codec *codec) 4223{ 4224 struct alc_spec *spec = codec->spec; 4225 int i; 4226 4227 for (i = 0; i < AUTO_PIN_LAST; i++) { 4228 hda_nid_t nid = spec->autocfg.input_pins[i]; 4229 if (alc880_is_input_pin(nid)) { 4230 alc_set_input_pin(codec, nid, i); 4231 if (nid != ALC880_PIN_CD_NID && 4232 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)) 4233 snd_hda_codec_write(codec, nid, 0, 4234 AC_VERB_SET_AMP_GAIN_MUTE, 4235 AMP_OUT_MUTE); 4236 } 4237 } 4238} 4239 4240/* parse the BIOS configuration and set up the alc_spec */ 4241/* return 1 if successful, 0 if the proper config is not found, 4242 * or a negative error code 4243 */ 4244static int alc880_parse_auto_config(struct hda_codec *codec) 4245{ 4246 struct alc_spec *spec = codec->spec; 4247 int i, err; 4248 static hda_nid_t alc880_ignore[] = { 0x1d, 0 }; 4249 4250 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 4251 alc880_ignore); 4252 if (err < 0) 4253 return err; 4254 if (!spec->autocfg.line_outs) 4255 return 0; /* can't find valid BIOS pin config */ 4256 4257 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); 4258 if (err < 0) 4259 return err; 4260 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg); 4261 if (err < 0) 4262 return err; 4263 err = alc880_auto_create_extra_out(spec, 4264 spec->autocfg.speaker_pins[0], 4265 "Speaker"); 4266 if (err < 0) 4267 return err; 4268 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0], 4269 "Headphone"); 4270 if (err < 0) 4271 return err; 4272 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg); 4273 if (err < 0) 4274 return err; 4275 4276 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 4277 4278 /* check multiple SPDIF-out (for recent codecs) */ 4279 for (i = 0; i < spec->autocfg.dig_outs; i++) { 4280 hda_nid_t dig_nid; 4281 err = snd_hda_get_connections(codec, 4282 spec->autocfg.dig_out_pins[i], 4283 &dig_nid, 1); 4284 if (err < 0) 4285 continue; 4286 if (!i) 4287 spec->multiout.dig_out_nid = dig_nid; 4288 else { 4289 spec->multiout.slave_dig_outs = spec->slave_dig_outs; 4290 spec->slave_dig_outs[i - 1] = dig_nid; 4291 if (i == ARRAY_SIZE(spec->slave_dig_outs) - 1) 4292 break; 4293 } 4294 } 4295 if (spec->autocfg.dig_in_pin) 4296 spec->dig_in_nid = ALC880_DIGIN_NID; 4297 4298 if (spec->kctls.list) 4299 add_mixer(spec, spec->kctls.list); 4300 4301 add_verb(spec, alc880_volume_init_verbs); 4302 4303 spec->num_mux_defs = 1; 4304 spec->input_mux = &spec->private_imux[0]; 4305 4306 return 1; 4307} 4308 4309/* additional initialization for auto-configuration model */ 4310static void alc880_auto_init(struct hda_codec *codec) 4311{ 4312 struct alc_spec *spec = codec->spec; 4313 alc880_auto_init_multi_out(codec); 4314 alc880_auto_init_extra_out(codec); 4315 alc880_auto_init_analog_input(codec); 4316 if (spec->unsol_event) 4317 alc_inithook(codec); 4318} 4319 4320static void set_capture_mixer(struct alc_spec *spec) 4321{ 4322 static struct snd_kcontrol_new *caps[2][3] = { 4323 { alc_capture_mixer_nosrc1, 4324 alc_capture_mixer_nosrc2, 4325 alc_capture_mixer_nosrc3 }, 4326 { alc_capture_mixer1, 4327 alc_capture_mixer2, 4328 alc_capture_mixer3 }, 4329 }; 4330 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) { 4331 int mux; 4332 if (spec->input_mux && spec->input_mux->num_items > 1) 4333 mux = 1; 4334 else 4335 mux = 0; 4336 spec->cap_mixer = caps[mux][spec->num_adc_nids - 1]; 4337 } 4338} 4339 4340#define set_beep_amp(spec, nid, idx, dir) \ 4341 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir)) 4342 4343/* 4344 * OK, here we have finally the patch for ALC880 4345 */ 4346 4347static int patch_alc880(struct hda_codec *codec) 4348{ 4349 struct alc_spec *spec; 4350 int board_config; 4351 int err; 4352 4353 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 4354 if (spec == NULL) 4355 return -ENOMEM; 4356 4357 codec->spec = spec; 4358 4359 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST, 4360 alc880_models, 4361 alc880_cfg_tbl); 4362 if (board_config < 0) { 4363 printk(KERN_INFO "hda_codec: Unknown model for ALC880, " 4364 "trying auto-probe from BIOS...\n"); 4365 board_config = ALC880_AUTO; 4366 } 4367 4368 if (board_config == ALC880_AUTO) { 4369 /* automatic parse from the BIOS config */ 4370 err = alc880_parse_auto_config(codec); 4371 if (err < 0) { 4372 alc_free(codec); 4373 return err; 4374 } else if (!err) { 4375 printk(KERN_INFO 4376 "hda_codec: Cannot set up configuration " 4377 "from BIOS. Using 3-stack mode...\n"); 4378 board_config = ALC880_3ST; 4379 } 4380 } 4381 4382 err = snd_hda_attach_beep_device(codec, 0x1); 4383 if (err < 0) { 4384 alc_free(codec); 4385 return err; 4386 } 4387 4388 if (board_config != ALC880_AUTO) 4389 setup_preset(spec, &alc880_presets[board_config]); 4390 4391 spec->stream_name_analog = "ALC880 Analog"; 4392 spec->stream_analog_playback = &alc880_pcm_analog_playback; 4393 spec->stream_analog_capture = &alc880_pcm_analog_capture; 4394 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture; 4395 4396 spec->stream_name_digital = "ALC880 Digital"; 4397 spec->stream_digital_playback = &alc880_pcm_digital_playback; 4398 spec->stream_digital_capture = &alc880_pcm_digital_capture; 4399 4400 if (!spec->adc_nids && spec->input_mux) { 4401 /* check whether NID 0x07 is valid */ 4402 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]); 4403 /* get type */ 4404 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; 4405 if (wcap != AC_WID_AUD_IN) { 4406 spec->adc_nids = alc880_adc_nids_alt; 4407 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt); 4408 } else { 4409 spec->adc_nids = alc880_adc_nids; 4410 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids); 4411 } 4412 } 4413 set_capture_mixer(spec); 4414 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 4415 4416 spec->vmaster_nid = 0x0c; 4417 4418 codec->patch_ops = alc_patch_ops; 4419 if (board_config == ALC880_AUTO) 4420 spec->init_hook = alc880_auto_init; 4421#ifdef CONFIG_SND_HDA_POWER_SAVE 4422 if (!spec->loopback.amplist) 4423 spec->loopback.amplist = alc880_loopbacks; 4424#endif 4425 codec->proc_widget_hook = print_realtek_coef; 4426 4427 return 0; 4428} 4429 4430 4431/* 4432 * ALC260 support 4433 */ 4434 4435static hda_nid_t alc260_dac_nids[1] = { 4436 /* front */ 4437 0x02, 4438}; 4439 4440static hda_nid_t alc260_adc_nids[1] = { 4441 /* ADC0 */ 4442 0x04, 4443}; 4444 4445static hda_nid_t alc260_adc_nids_alt[1] = { 4446 /* ADC1 */ 4447 0x05, 4448}; 4449 4450/* NIDs used when simultaneous access to both ADCs makes sense. Note that 4451 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC. 4452 */ 4453static hda_nid_t alc260_dual_adc_nids[2] = { 4454 /* ADC0, ADC1 */ 4455 0x04, 0x05 4456}; 4457 4458#define ALC260_DIGOUT_NID 0x03 4459#define ALC260_DIGIN_NID 0x06 4460 4461static struct hda_input_mux alc260_capture_source = { 4462 .num_items = 4, 4463 .items = { 4464 { "Mic", 0x0 }, 4465 { "Front Mic", 0x1 }, 4466 { "Line", 0x2 }, 4467 { "CD", 0x4 }, 4468 }, 4469}; 4470 4471/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack, 4472 * headphone jack and the internal CD lines since these are the only pins at 4473 * which audio can appear. For flexibility, also allow the option of 4474 * recording the mixer output on the second ADC (ADC0 doesn't have a 4475 * connection to the mixer output). 4476 */ 4477static struct hda_input_mux alc260_fujitsu_capture_sources[2] = { 4478 { 4479 .num_items = 3, 4480 .items = { 4481 { "Mic/Line", 0x0 }, 4482 { "CD", 0x4 }, 4483 { "Headphone", 0x2 }, 4484 }, 4485 }, 4486 { 4487 .num_items = 4, 4488 .items = { 4489 { "Mic/Line", 0x0 }, 4490 { "CD", 0x4 }, 4491 { "Headphone", 0x2 }, 4492 { "Mixer", 0x5 }, 4493 }, 4494 }, 4495 4496}; 4497 4498/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to 4499 * the Fujitsu S702x, but jacks are marked differently. 4500 */ 4501static struct hda_input_mux alc260_acer_capture_sources[2] = { 4502 { 4503 .num_items = 4, 4504 .items = { 4505 { "Mic", 0x0 }, 4506 { "Line", 0x2 }, 4507 { "CD", 0x4 }, 4508 { "Headphone", 0x5 }, 4509 }, 4510 }, 4511 { 4512 .num_items = 5, 4513 .items = { 4514 { "Mic", 0x0 }, 4515 { "Line", 0x2 }, 4516 { "CD", 0x4 }, 4517 { "Headphone", 0x6 }, 4518 { "Mixer", 0x5 }, 4519 }, 4520 }, 4521}; 4522 4523/* Maxdata Favorit 100XS */ 4524static struct hda_input_mux alc260_favorit100_capture_sources[2] = { 4525 { 4526 .num_items = 2, 4527 .items = { 4528 { "Line/Mic", 0x0 }, 4529 { "CD", 0x4 }, 4530 }, 4531 }, 4532 { 4533 .num_items = 3, 4534 .items = { 4535 { "Line/Mic", 0x0 }, 4536 { "CD", 0x4 }, 4537 { "Mixer", 0x5 }, 4538 }, 4539 }, 4540}; 4541 4542/* 4543 * This is just place-holder, so there's something for alc_build_pcms to look 4544 * at when it calculates the maximum number of channels. ALC260 has no mixer 4545 * element which allows changing the channel mode, so the verb list is 4546 * never used. 4547 */ 4548static struct hda_channel_mode alc260_modes[1] = { 4549 { 2, NULL }, 4550}; 4551 4552 4553/* Mixer combinations 4554 * 4555 * basic: base_output + input + pc_beep + capture 4556 * HP: base_output + input + capture_alt 4557 * HP_3013: hp_3013 + input + capture 4558 * fujitsu: fujitsu + capture 4559 * acer: acer + capture 4560 */ 4561 4562static struct snd_kcontrol_new alc260_base_output_mixer[] = { 4563 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT), 4564 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT), 4565 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT), 4566 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT), 4567 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), 4568 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT), 4569 { } /* end */ 4570}; 4571 4572static struct snd_kcontrol_new alc260_input_mixer[] = { 4573 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), 4574 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), 4575 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), 4576 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT), 4577 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), 4578 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT), 4579 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT), 4580 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT), 4581 { } /* end */ 4582}; 4583 4584/* update HP, line and mono out pins according to the master switch */ 4585static void alc260_hp_master_update(struct hda_codec *codec, 4586 hda_nid_t hp, hda_nid_t line, 4587 hda_nid_t mono) 4588{ 4589 struct alc_spec *spec = codec->spec; 4590 unsigned int val = spec->master_sw ? PIN_HP : 0; 4591 /* change HP and line-out pins */ 4592 snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 4593 val); 4594 snd_hda_codec_write(codec, line, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 4595 val); 4596 /* mono (speaker) depending on the HP jack sense */ 4597 val = (val && !spec->jack_present) ? PIN_OUT : 0; 4598 snd_hda_codec_write(codec, mono, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 4599 val); 4600} 4601 4602static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol, 4603 struct snd_ctl_elem_value *ucontrol) 4604{ 4605 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 4606 struct alc_spec *spec = codec->spec; 4607 *ucontrol->value.integer.value = spec->master_sw; 4608 return 0; 4609} 4610 4611static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol, 4612 struct snd_ctl_elem_value *ucontrol) 4613{ 4614 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 4615 struct alc_spec *spec = codec->spec; 4616 int val = !!*ucontrol->value.integer.value; 4617 hda_nid_t hp, line, mono; 4618 4619 if (val == spec->master_sw) 4620 return 0; 4621 spec->master_sw = val; 4622 hp = (kcontrol->private_value >> 16) & 0xff; 4623 line = (kcontrol->private_value >> 8) & 0xff; 4624 mono = kcontrol->private_value & 0xff; 4625 alc260_hp_master_update(codec, hp, line, mono); 4626 return 1; 4627} 4628 4629static struct snd_kcontrol_new alc260_hp_output_mixer[] = { 4630 { 4631 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 4632 .name = "Master Playback Switch", 4633 .info = snd_ctl_boolean_mono_info, 4634 .get = alc260_hp_master_sw_get, 4635 .put = alc260_hp_master_sw_put, 4636 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11 4637 }, 4638 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT), 4639 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT), 4640 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT), 4641 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT), 4642 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, 4643 HDA_OUTPUT), 4644 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT), 4645 { } /* end */ 4646}; 4647 4648static struct hda_verb alc260_hp_unsol_verbs[] = { 4649 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 4650 {}, 4651}; 4652 4653static void alc260_hp_automute(struct hda_codec *codec) 4654{ 4655 struct alc_spec *spec = codec->spec; 4656 unsigned int present; 4657 4658 present = snd_hda_codec_read(codec, 0x10, 0, 4659 AC_VERB_GET_PIN_SENSE, 0); 4660 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0; 4661 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11); 4662} 4663 4664static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res) 4665{ 4666 if ((res >> 26) == ALC880_HP_EVENT) 4667 alc260_hp_automute(codec); 4668} 4669 4670static struct snd_kcontrol_new alc260_hp_3013_mixer[] = { 4671 { 4672 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 4673 .name = "Master Playback Switch", 4674 .info = snd_ctl_boolean_mono_info, 4675 .get = alc260_hp_master_sw_get, 4676 .put = alc260_hp_master_sw_put, 4677 .private_value = (0x15 << 16) | (0x10 << 8) | 0x11 4678 }, 4679 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT), 4680 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT), 4681 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT), 4682 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT), 4683 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT), 4684 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 4685 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), 4686 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT), 4687 { } /* end */ 4688}; 4689 4690static struct hda_bind_ctls alc260_dc7600_bind_master_vol = { 4691 .ops = &snd_hda_bind_vol, 4692 .values = { 4693 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT), 4694 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT), 4695 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT), 4696 0 4697 }, 4698}; 4699 4700static struct hda_bind_ctls alc260_dc7600_bind_switch = { 4701 .ops = &snd_hda_bind_sw, 4702 .values = { 4703 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT), 4704 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT), 4705 0 4706 }, 4707}; 4708 4709static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = { 4710 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol), 4711 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch), 4712 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT), 4713 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT), 4714 { } /* end */ 4715}; 4716 4717static struct hda_verb alc260_hp_3013_unsol_verbs[] = { 4718 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 4719 {}, 4720}; 4721 4722static void alc260_hp_3013_automute(struct hda_codec *codec) 4723{ 4724 struct alc_spec *spec = codec->spec; 4725 unsigned int present; 4726 4727 present = snd_hda_codec_read(codec, 0x15, 0, 4728 AC_VERB_GET_PIN_SENSE, 0); 4729 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0; 4730 alc260_hp_master_update(codec, 0x15, 0x10, 0x11); 4731} 4732 4733static void alc260_hp_3013_unsol_event(struct hda_codec *codec, 4734 unsigned int res) 4735{ 4736 if ((res >> 26) == ALC880_HP_EVENT) 4737 alc260_hp_3013_automute(codec); 4738} 4739 4740static void alc260_hp_3012_automute(struct hda_codec *codec) 4741{ 4742 unsigned int present, bits; 4743 4744 present = snd_hda_codec_read(codec, 0x10, 0, 4745 AC_VERB_GET_PIN_SENSE, 0) & AC_PINSENSE_PRESENCE; 4746 4747 bits = present ? 0 : PIN_OUT; 4748 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 4749 bits); 4750 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 4751 bits); 4752 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 4753 bits); 4754} 4755 4756static void alc260_hp_3012_unsol_event(struct hda_codec *codec, 4757 unsigned int res) 4758{ 4759 if ((res >> 26) == ALC880_HP_EVENT) 4760 alc260_hp_3012_automute(codec); 4761} 4762 4763/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12, 4764 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10. 4765 */ 4766static struct snd_kcontrol_new alc260_fujitsu_mixer[] = { 4767 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT), 4768 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT), 4769 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT), 4770 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), 4771 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), 4772 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT), 4773 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT), 4774 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN), 4775 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT), 4776 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT), 4777 { } /* end */ 4778}; 4779 4780/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current 4781 * versions of the ALC260 don't act on requests to enable mic bias from NID 4782 * 0x0f (used to drive the headphone jack in these laptops). The ALC260 4783 * datasheet doesn't mention this restriction. At this stage it's not clear 4784 * whether this behaviour is intentional or is a hardware bug in chip 4785 * revisions available in early 2006. Therefore for now allow the 4786 * "Headphone Jack Mode" control to span all choices, but if it turns out 4787 * that the lack of mic bias for this NID is intentional we could change the 4788 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS. 4789 * 4790 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006 4791 * don't appear to make the mic bias available from the "line" jack, even 4792 * though the NID used for this jack (0x14) can supply it. The theory is 4793 * that perhaps Acer have included blocking capacitors between the ALC260 4794 * and the output jack. If this turns out to be the case for all such 4795 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT 4796 * to ALC_PIN_DIR_INOUT_NOMICBIAS. 4797 * 4798 * The C20x Tablet series have a mono internal speaker which is controlled 4799 * via the chip's Mono sum widget and pin complex, so include the necessary 4800 * controls for such models. On models without a "mono speaker" the control 4801 * won't do anything. 4802 */ 4803static struct snd_kcontrol_new alc260_acer_mixer[] = { 4804 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), 4805 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT), 4806 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT), 4807 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, 4808 HDA_OUTPUT), 4809 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, 4810 HDA_INPUT), 4811 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), 4812 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), 4813 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), 4814 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT), 4815 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN), 4816 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), 4817 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT), 4818 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT), 4819 { } /* end */ 4820}; 4821 4822/* Maxdata Favorit 100XS: one output and one input (0x12) jack 4823 */ 4824static struct snd_kcontrol_new alc260_favorit100_mixer[] = { 4825 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), 4826 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT), 4827 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT), 4828 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT), 4829 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT), 4830 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN), 4831 { } /* end */ 4832}; 4833 4834/* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12, 4835 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17. 4836 */ 4837static struct snd_kcontrol_new alc260_will_mixer[] = { 4838 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), 4839 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT), 4840 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), 4841 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT), 4842 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN), 4843 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), 4844 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT), 4845 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT), 4846 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), 4847 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), 4848 { } /* end */ 4849}; 4850 4851/* Replacer 672V ALC260 pin usage: Mic jack = 0x12, 4852 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f. 4853 */ 4854static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = { 4855 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), 4856 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT), 4857 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), 4858 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT), 4859 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN), 4860 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT), 4861 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT), 4862 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), 4863 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT), 4864 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT), 4865 { } /* end */ 4866}; 4867 4868/* 4869 * initialization verbs 4870 */ 4871static struct hda_verb alc260_init_verbs[] = { 4872 /* Line In pin widget for input */ 4873 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 4874 /* CD pin widget for input */ 4875 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 4876 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 4877 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 4878 /* Mic2 (front panel) pin widget for input and vref at 80% */ 4879 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 4880 /* LINE-2 is used for line-out in rear */ 4881 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4882 /* select line-out */ 4883 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00}, 4884 /* LINE-OUT pin */ 4885 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4886 /* enable HP */ 4887 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 4888 /* enable Mono */ 4889 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4890 /* mute capture amp left and right */ 4891 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4892 /* set connection select to line in (default select for this ADC) */ 4893 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02}, 4894 /* mute capture amp left and right */ 4895 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4896 /* set connection select to line in (default select for this ADC) */ 4897 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02}, 4898 /* set vol=0 Line-Out mixer amp left and right */ 4899 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4900 /* unmute pin widget amp left and right (no gain on this amp) */ 4901 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4902 /* set vol=0 HP mixer amp left and right */ 4903 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4904 /* unmute pin widget amp left and right (no gain on this amp) */ 4905 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4906 /* set vol=0 Mono mixer amp left and right */ 4907 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4908 /* unmute pin widget amp left and right (no gain on this amp) */ 4909 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4910 /* unmute LINE-2 out pin */ 4911 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4912 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & 4913 * Line In 2 = 0x03 4914 */ 4915 /* mute analog inputs */ 4916 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4917 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4918 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 4919 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 4920 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 4921 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */ 4922 /* mute Front out path */ 4923 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4924 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4925 /* mute Headphone out path */ 4926 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4927 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4928 /* mute Mono out path */ 4929 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4930 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4931 { } 4932}; 4933 4934#if 0 /* should be identical with alc260_init_verbs? */ 4935static struct hda_verb alc260_hp_init_verbs[] = { 4936 /* Headphone and output */ 4937 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 4938 /* mono output */ 4939 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 4940 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 4941 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 4942 /* Mic2 (front panel) pin widget for input and vref at 80% */ 4943 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 4944 /* Line In pin widget for input */ 4945 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 4946 /* Line-2 pin widget for output */ 4947 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 4948 /* CD pin widget for input */ 4949 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 4950 /* unmute amp left and right */ 4951 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000}, 4952 /* set connection select to line in (default select for this ADC) */ 4953 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02}, 4954 /* unmute Line-Out mixer amp left and right (volume = 0) */ 4955 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 4956 /* mute pin widget amp left and right (no gain on this amp) */ 4957 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 4958 /* unmute HP mixer amp left and right (volume = 0) */ 4959 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 4960 /* mute pin widget amp left and right (no gain on this amp) */ 4961 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 4962 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & 4963 * Line In 2 = 0x03 4964 */ 4965 /* mute analog inputs */ 4966 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4967 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4968 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 4969 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 4970 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 4971 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */ 4972 /* Unmute Front out path */ 4973 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 4974 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 4975 /* Unmute Headphone out path */ 4976 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 4977 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 4978 /* Unmute Mono out path */ 4979 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 4980 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 4981 { } 4982}; 4983#endif 4984 4985static struct hda_verb alc260_hp_3013_init_verbs[] = { 4986 /* Line out and output */ 4987 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 4988 /* mono output */ 4989 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 4990 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 4991 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 4992 /* Mic2 (front panel) pin widget for input and vref at 80% */ 4993 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 4994 /* Line In pin widget for input */ 4995 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 4996 /* Headphone pin widget for output */ 4997 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 4998 /* CD pin widget for input */ 4999 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 5000 /* unmute amp left and right */ 5001 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000}, 5002 /* set connection select to line in (default select for this ADC) */ 5003 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02}, 5004 /* unmute Line-Out mixer amp left and right (volume = 0) */ 5005 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 5006 /* mute pin widget amp left and right (no gain on this amp) */ 5007 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 5008 /* unmute HP mixer amp left and right (volume = 0) */ 5009 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 5010 /* mute pin widget amp left and right (no gain on this amp) */ 5011 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 5012 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & 5013 * Line In 2 = 0x03 5014 */ 5015 /* mute analog inputs */ 5016 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5017 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 5018 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 5019 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 5020 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 5021 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */ 5022 /* Unmute Front out path */ 5023 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 5024 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 5025 /* Unmute Headphone out path */ 5026 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 5027 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 5028 /* Unmute Mono out path */ 5029 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 5030 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 5031 { } 5032}; 5033 5034/* Initialisation sequence for ALC260 as configured in Fujitsu S702x 5035 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD 5036 * audio = 0x16, internal speaker = 0x10. 5037 */ 5038static struct hda_verb alc260_fujitsu_init_verbs[] = { 5039 /* Disable all GPIOs */ 5040 {0x01, AC_VERB_SET_GPIO_MASK, 0}, 5041 /* Internal speaker is connected to headphone pin */ 5042 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 5043 /* Headphone/Line-out jack connects to Line1 pin; make it an output */ 5044 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5045 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */ 5046 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 5047 /* Ensure all other unused pins are disabled and muted. */ 5048 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 5049 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5050 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 5051 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5052 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 5053 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5054 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 5055 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5056 5057 /* Disable digital (SPDIF) pins */ 5058 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0}, 5059 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0}, 5060 5061 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus 5062 * when acting as an output. 5063 */ 5064 {0x0d, AC_VERB_SET_CONNECT_SEL, 0}, 5065 5066 /* Start with output sum widgets muted and their output gains at min */ 5067 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5068 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 5069 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5070 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5071 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 5072 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5073 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5074 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 5075 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5076 5077 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */ 5078 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5079 /* Unmute Line1 pin widget output buffer since it starts as an output. 5080 * If the pin mode is changed by the user the pin mode control will 5081 * take care of enabling the pin's input/output buffers as needed. 5082 * Therefore there's no need to enable the input buffer at this 5083 * stage. 5084 */ 5085 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5086 /* Unmute input buffer of pin widget used for Line-in (no equiv 5087 * mixer ctrl) 5088 */ 5089 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5090 5091 /* Mute capture amp left and right */ 5092 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5093 /* Set ADC connection select to match default mixer setting - line 5094 * in (on mic1 pin) 5095 */ 5096 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, 5097 5098 /* Do the same for the second ADC: mute capture input amp and 5099 * set ADC connection to line in (on mic1 pin) 5100 */ 5101 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5102 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, 5103 5104 /* Mute all inputs to mixer widget (even unconnected ones) */ 5105 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */ 5106 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */ 5107 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */ 5108 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */ 5109 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */ 5110 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */ 5111 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */ 5112 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */ 5113 5114 { } 5115}; 5116 5117/* Initialisation sequence for ALC260 as configured in Acer TravelMate and 5118 * similar laptops (adapted from Fujitsu init verbs). 5119 */ 5120static struct hda_verb alc260_acer_init_verbs[] = { 5121 /* On TravelMate laptops, GPIO 0 enables the internal speaker and 5122 * the headphone jack. Turn this on and rely on the standard mute 5123 * methods whenever the user wants to turn these outputs off. 5124 */ 5125 {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, 5126 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, 5127 {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, 5128 /* Internal speaker/Headphone jack is connected to Line-out pin */ 5129 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 5130 /* Internal microphone/Mic jack is connected to Mic1 pin */ 5131 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, 5132 /* Line In jack is connected to Line1 pin */ 5133 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 5134 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */ 5135 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 5136 /* Ensure all other unused pins are disabled and muted. */ 5137 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 5138 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5139 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 5140 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5141 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 5142 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5143 /* Disable digital (SPDIF) pins */ 5144 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0}, 5145 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0}, 5146 5147 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum 5148 * bus when acting as outputs. 5149 */ 5150 {0x0b, AC_VERB_SET_CONNECT_SEL, 0}, 5151 {0x0d, AC_VERB_SET_CONNECT_SEL, 0}, 5152 5153 /* Start with output sum widgets muted and their output gains at min */ 5154 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5155 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 5156 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5157 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5158 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 5159 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5160 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5161 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 5162 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5163 5164 /* Unmute Line-out pin widget amp left and right 5165 * (no equiv mixer ctrl) 5166 */ 5167 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5168 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */ 5169 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5170 /* Unmute Mic1 and Line1 pin widget input buffers since they start as 5171 * inputs. If the pin mode is changed by the user the pin mode control 5172 * will take care of enabling the pin's input/output buffers as needed. 5173 * Therefore there's no need to enable the input buffer at this 5174 * stage. 5175 */ 5176 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5177 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5178 5179 /* Mute capture amp left and right */ 5180 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5181 /* Set ADC connection select to match default mixer setting - mic 5182 * (on mic1 pin) 5183 */ 5184 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, 5185 5186 /* Do similar with the second ADC: mute capture input amp and 5187 * set ADC connection to mic to match ALSA's default state. 5188 */ 5189 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5190 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, 5191 5192 /* Mute all inputs to mixer widget (even unconnected ones) */ 5193 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */ 5194 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */ 5195 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */ 5196 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */ 5197 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */ 5198 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */ 5199 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */ 5200 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */ 5201 5202 { } 5203}; 5204 5205/* Initialisation sequence for Maxdata Favorit 100XS 5206 * (adapted from Acer init verbs). 5207 */ 5208static struct hda_verb alc260_favorit100_init_verbs[] = { 5209 /* GPIO 0 enables the output jack. 5210 * Turn this on and rely on the standard mute 5211 * methods whenever the user wants to turn these outputs off. 5212 */ 5213 {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, 5214 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, 5215 {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, 5216 /* Line/Mic input jack is connected to Mic1 pin */ 5217 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, 5218 /* Ensure all other unused pins are disabled and muted. */ 5219 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 5220 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5221 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 5222 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5223 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 5224 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5225 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 5226 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5227 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 5228 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5229 /* Disable digital (SPDIF) pins */ 5230 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0}, 5231 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0}, 5232 5233 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum 5234 * bus when acting as outputs. 5235 */ 5236 {0x0b, AC_VERB_SET_CONNECT_SEL, 0}, 5237 {0x0d, AC_VERB_SET_CONNECT_SEL, 0}, 5238 5239 /* Start with output sum widgets muted and their output gains at min */ 5240 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5241 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 5242 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5243 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5244 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 5245 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5246 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5247 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 5248 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5249 5250 /* Unmute Line-out pin widget amp left and right 5251 * (no equiv mixer ctrl) 5252 */ 5253 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5254 /* Unmute Mic1 and Line1 pin widget input buffers since they start as 5255 * inputs. If the pin mode is changed by the user the pin mode control 5256 * will take care of enabling the pin's input/output buffers as needed. 5257 * Therefore there's no need to enable the input buffer at this 5258 * stage. 5259 */ 5260 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5261 5262 /* Mute capture amp left and right */ 5263 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5264 /* Set ADC connection select to match default mixer setting - mic 5265 * (on mic1 pin) 5266 */ 5267 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, 5268 5269 /* Do similar with the second ADC: mute capture input amp and 5270 * set ADC connection to mic to match ALSA's default state. 5271 */ 5272 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5273 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, 5274 5275 /* Mute all inputs to mixer widget (even unconnected ones) */ 5276 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */ 5277 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */ 5278 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */ 5279 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */ 5280 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */ 5281 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */ 5282 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */ 5283 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */ 5284 5285 { } 5286}; 5287 5288static struct hda_verb alc260_will_verbs[] = { 5289 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 5290 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00}, 5291 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00}, 5292 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02}, 5293 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07}, 5294 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040}, 5295 {} 5296}; 5297 5298static struct hda_verb alc260_replacer_672v_verbs[] = { 5299 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02}, 5300 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07}, 5301 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050}, 5302 5303 {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, 5304 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, 5305 {0x01, AC_VERB_SET_GPIO_DATA, 0x00}, 5306 5307 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 5308 {} 5309}; 5310 5311/* toggle speaker-output according to the hp-jack state */ 5312static void alc260_replacer_672v_automute(struct hda_codec *codec) 5313{ 5314 unsigned int present; 5315 5316 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */ 5317 present = snd_hda_codec_read(codec, 0x0f, 0, 5318 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 5319 if (present) { 5320 snd_hda_codec_write_cache(codec, 0x01, 0, 5321 AC_VERB_SET_GPIO_DATA, 1); 5322 snd_hda_codec_write_cache(codec, 0x0f, 0, 5323 AC_VERB_SET_PIN_WIDGET_CONTROL, 5324 PIN_HP); 5325 } else { 5326 snd_hda_codec_write_cache(codec, 0x01, 0, 5327 AC_VERB_SET_GPIO_DATA, 0); 5328 snd_hda_codec_write_cache(codec, 0x0f, 0, 5329 AC_VERB_SET_PIN_WIDGET_CONTROL, 5330 PIN_OUT); 5331 } 5332} 5333 5334static void alc260_replacer_672v_unsol_event(struct hda_codec *codec, 5335 unsigned int res) 5336{ 5337 if ((res >> 26) == ALC880_HP_EVENT) 5338 alc260_replacer_672v_automute(codec); 5339} 5340 5341static struct hda_verb alc260_hp_dc7600_verbs[] = { 5342 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01}, 5343 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 5344 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5345 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 5346 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5347 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5348 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 5349 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 5350 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 5351 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 5352 {} 5353}; 5354 5355/* Test configuration for debugging, modelled after the ALC880 test 5356 * configuration. 5357 */ 5358#ifdef CONFIG_SND_DEBUG 5359static hda_nid_t alc260_test_dac_nids[1] = { 5360 0x02, 5361}; 5362static hda_nid_t alc260_test_adc_nids[2] = { 5363 0x04, 0x05, 5364}; 5365/* For testing the ALC260, each input MUX needs its own definition since 5366 * the signal assignments are different. This assumes that the first ADC 5367 * is NID 0x04. 5368 */ 5369static struct hda_input_mux alc260_test_capture_sources[2] = { 5370 { 5371 .num_items = 7, 5372 .items = { 5373 { "MIC1 pin", 0x0 }, 5374 { "MIC2 pin", 0x1 }, 5375 { "LINE1 pin", 0x2 }, 5376 { "LINE2 pin", 0x3 }, 5377 { "CD pin", 0x4 }, 5378 { "LINE-OUT pin", 0x5 }, 5379 { "HP-OUT pin", 0x6 }, 5380 }, 5381 }, 5382 { 5383 .num_items = 8, 5384 .items = { 5385 { "MIC1 pin", 0x0 }, 5386 { "MIC2 pin", 0x1 }, 5387 { "LINE1 pin", 0x2 }, 5388 { "LINE2 pin", 0x3 }, 5389 { "CD pin", 0x4 }, 5390 { "Mixer", 0x5 }, 5391 { "LINE-OUT pin", 0x6 }, 5392 { "HP-OUT pin", 0x7 }, 5393 }, 5394 }, 5395}; 5396static struct snd_kcontrol_new alc260_test_mixer[] = { 5397 /* Output driver widgets */ 5398 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), 5399 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT), 5400 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT), 5401 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT), 5402 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT), 5403 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT), 5404 5405 /* Modes for retasking pin widgets 5406 * Note: the ALC260 doesn't seem to act on requests to enable mic 5407 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't 5408 * mention this restriction. At this stage it's not clear whether 5409 * this behaviour is intentional or is a hardware bug in chip 5410 * revisions available at least up until early 2006. Therefore for 5411 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all 5412 * choices, but if it turns out that the lack of mic bias for these 5413 * NIDs is intentional we could change their modes from 5414 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS. 5415 */ 5416 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT), 5417 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT), 5418 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT), 5419 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT), 5420 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT), 5421 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT), 5422 5423 /* Loopback mixer controls */ 5424 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT), 5425 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT), 5426 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT), 5427 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT), 5428 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT), 5429 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT), 5430 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT), 5431 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT), 5432 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), 5433 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), 5434 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT), 5435 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT), 5436 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT), 5437 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT), 5438 5439 /* Controls for GPIO pins, assuming they are configured as outputs */ 5440 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01), 5441 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02), 5442 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04), 5443 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08), 5444 5445 /* Switches to allow the digital IO pins to be enabled. The datasheet 5446 * is ambigious as to which NID is which; testing on laptops which 5447 * make this output available should provide clarification. 5448 */ 5449 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01), 5450 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01), 5451 5452 /* A switch allowing EAPD to be enabled. Some laptops seem to use 5453 * this output to turn on an external amplifier. 5454 */ 5455 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02), 5456 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02), 5457 5458 { } /* end */ 5459}; 5460static struct hda_verb alc260_test_init_verbs[] = { 5461 /* Enable all GPIOs as outputs with an initial value of 0 */ 5462 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f}, 5463 {0x01, AC_VERB_SET_GPIO_DATA, 0x00}, 5464 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f}, 5465 5466 /* Enable retasking pins as output, initially without power amp */ 5467 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5468 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5469 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5470 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5471 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5472 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5473 5474 /* Disable digital (SPDIF) pins initially, but users can enable 5475 * them via a mixer switch. In the case of SPDIF-out, this initverb 5476 * payload also sets the generation to 0, output to be in "consumer" 5477 * PCM format, copyright asserted, no pre-emphasis and no validity 5478 * control. 5479 */ 5480 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0}, 5481 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0}, 5482 5483 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the 5484 * OUT1 sum bus when acting as an output. 5485 */ 5486 {0x0b, AC_VERB_SET_CONNECT_SEL, 0}, 5487 {0x0c, AC_VERB_SET_CONNECT_SEL, 0}, 5488 {0x0d, AC_VERB_SET_CONNECT_SEL, 0}, 5489 {0x0e, AC_VERB_SET_CONNECT_SEL, 0}, 5490 5491 /* Start with output sum widgets muted and their output gains at min */ 5492 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5493 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 5494 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5495 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5496 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 5497 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5498 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5499 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 5500 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5501 5502 /* Unmute retasking pin widget output buffers since the default 5503 * state appears to be output. As the pin mode is changed by the 5504 * user the pin mode control will take care of enabling the pin's 5505 * input/output buffers as needed. 5506 */ 5507 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5508 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5509 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5510 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5511 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5512 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5513 /* Also unmute the mono-out pin widget */ 5514 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5515 5516 /* Mute capture amp left and right */ 5517 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5518 /* Set ADC connection select to match default mixer setting (mic1 5519 * pin) 5520 */ 5521 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, 5522 5523 /* Do the same for the second ADC: mute capture input amp and 5524 * set ADC connection to mic1 pin 5525 */ 5526 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5527 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, 5528 5529 /* Mute all inputs to mixer widget (even unconnected ones) */ 5530 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */ 5531 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */ 5532 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */ 5533 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */ 5534 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */ 5535 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */ 5536 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */ 5537 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */ 5538 5539 { } 5540}; 5541#endif 5542 5543#define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback 5544#define alc260_pcm_analog_capture alc880_pcm_analog_capture 5545 5546#define alc260_pcm_digital_playback alc880_pcm_digital_playback 5547#define alc260_pcm_digital_capture alc880_pcm_digital_capture 5548 5549/* 5550 * for BIOS auto-configuration 5551 */ 5552 5553static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid, 5554 const char *pfx, int *vol_bits) 5555{ 5556 hda_nid_t nid_vol; 5557 unsigned long vol_val, sw_val; 5558 char name[32]; 5559 int err; 5560 5561 if (nid >= 0x0f && nid < 0x11) { 5562 nid_vol = nid - 0x7; 5563 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT); 5564 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT); 5565 } else if (nid == 0x11) { 5566 nid_vol = nid - 0x7; 5567 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT); 5568 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT); 5569 } else if (nid >= 0x12 && nid <= 0x15) { 5570 nid_vol = 0x08; 5571 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT); 5572 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT); 5573 } else 5574 return 0; /* N/A */ 5575 5576 if (!(*vol_bits & (1 << nid_vol))) { 5577 /* first control for the volume widget */ 5578 snprintf(name, sizeof(name), "%s Playback Volume", pfx); 5579 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val); 5580 if (err < 0) 5581 return err; 5582 *vol_bits |= (1 << nid_vol); 5583 } 5584 snprintf(name, sizeof(name), "%s Playback Switch", pfx); 5585 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val); 5586 if (err < 0) 5587 return err; 5588 return 1; 5589} 5590 5591/* add playback controls from the parsed DAC table */ 5592static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec, 5593 const struct auto_pin_cfg *cfg) 5594{ 5595 hda_nid_t nid; 5596 int err; 5597 int vols = 0; 5598 5599 spec->multiout.num_dacs = 1; 5600 spec->multiout.dac_nids = spec->private_dac_nids; 5601 spec->multiout.dac_nids[0] = 0x02; 5602 5603 nid = cfg->line_out_pins[0]; 5604 if (nid) { 5605 err = alc260_add_playback_controls(spec, nid, "Front", &vols); 5606 if (err < 0) 5607 return err; 5608 } 5609 5610 nid = cfg->speaker_pins[0]; 5611 if (nid) { 5612 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols); 5613 if (err < 0) 5614 return err; 5615 } 5616 5617 nid = cfg->hp_pins[0]; 5618 if (nid) { 5619 err = alc260_add_playback_controls(spec, nid, "Headphone", 5620 &vols); 5621 if (err < 0) 5622 return err; 5623 } 5624 return 0; 5625} 5626 5627/* create playback/capture controls for input pins */ 5628static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec, 5629 const struct auto_pin_cfg *cfg) 5630{ 5631 struct hda_input_mux *imux = &spec->private_imux[0]; 5632 int i, err, idx; 5633 5634 for (i = 0; i < AUTO_PIN_LAST; i++) { 5635 if (cfg->input_pins[i] >= 0x12) { 5636 idx = cfg->input_pins[i] - 0x12; 5637 err = new_analog_input(spec, cfg->input_pins[i], 5638 auto_pin_cfg_labels[i], idx, 5639 0x07); 5640 if (err < 0) 5641 return err; 5642 imux->items[imux->num_items].label = 5643 auto_pin_cfg_labels[i]; 5644 imux->items[imux->num_items].index = idx; 5645 imux->num_items++; 5646 } 5647 if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){ 5648 idx = cfg->input_pins[i] - 0x09; 5649 err = new_analog_input(spec, cfg->input_pins[i], 5650 auto_pin_cfg_labels[i], idx, 5651 0x07); 5652 if (err < 0) 5653 return err; 5654 imux->items[imux->num_items].label = 5655 auto_pin_cfg_labels[i]; 5656 imux->items[imux->num_items].index = idx; 5657 imux->num_items++; 5658 } 5659 } 5660 return 0; 5661} 5662 5663static void alc260_auto_set_output_and_unmute(struct hda_codec *codec, 5664 hda_nid_t nid, int pin_type, 5665 int sel_idx) 5666{ 5667 alc_set_pin_output(codec, nid, pin_type); 5668 /* need the manual connection? */ 5669 if (nid >= 0x12) { 5670 int idx = nid - 0x12; 5671 snd_hda_codec_write(codec, idx + 0x0b, 0, 5672 AC_VERB_SET_CONNECT_SEL, sel_idx); 5673 } 5674} 5675 5676static void alc260_auto_init_multi_out(struct hda_codec *codec) 5677{ 5678 struct alc_spec *spec = codec->spec; 5679 hda_nid_t nid; 5680 5681 alc_subsystem_id(codec, 0x10, 0x15, 0x0f); 5682 nid = spec->autocfg.line_out_pins[0]; 5683 if (nid) { 5684 int pin_type = get_pin_type(spec->autocfg.line_out_type); 5685 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0); 5686 } 5687 5688 nid = spec->autocfg.speaker_pins[0]; 5689 if (nid) 5690 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0); 5691 5692 nid = spec->autocfg.hp_pins[0]; 5693 if (nid) 5694 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0); 5695} 5696 5697#define ALC260_PIN_CD_NID 0x16 5698static void alc260_auto_init_analog_input(struct hda_codec *codec) 5699{ 5700 struct alc_spec *spec = codec->spec; 5701 int i; 5702 5703 for (i = 0; i < AUTO_PIN_LAST; i++) { 5704 hda_nid_t nid = spec->autocfg.input_pins[i]; 5705 if (nid >= 0x12) { 5706 alc_set_input_pin(codec, nid, i); 5707 if (nid != ALC260_PIN_CD_NID && 5708 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)) 5709 snd_hda_codec_write(codec, nid, 0, 5710 AC_VERB_SET_AMP_GAIN_MUTE, 5711 AMP_OUT_MUTE); 5712 } 5713 } 5714} 5715 5716/* 5717 * generic initialization of ADC, input mixers and output mixers 5718 */ 5719static struct hda_verb alc260_volume_init_verbs[] = { 5720 /* 5721 * Unmute ADC0-1 and set the default input to mic-in 5722 */ 5723 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, 5724 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5725 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, 5726 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5727 5728 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 5729 * mixer widget 5730 * Note: PASD motherboards uses the Line In 2 as the input for 5731 * front panel mic (mic 2) 5732 */ 5733 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 5734 /* mute analog inputs */ 5735 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5736 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 5737 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 5738 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 5739 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 5740 5741 /* 5742 * Set up output mixers (0x08 - 0x0a) 5743 */ 5744 /* set vol=0 to output mixers */ 5745 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5746 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5747 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5748 /* set up input amps for analog loopback */ 5749 /* Amp Indices: DAC = 0, mixer = 1 */ 5750 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5751 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 5752 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5753 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 5754 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5755 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 5756 5757 { } 5758}; 5759 5760static int alc260_parse_auto_config(struct hda_codec *codec) 5761{ 5762 struct alc_spec *spec = codec->spec; 5763 int err; 5764 static hda_nid_t alc260_ignore[] = { 0x17, 0 }; 5765 5766 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 5767 alc260_ignore); 5768 if (err < 0) 5769 return err; 5770 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg); 5771 if (err < 0) 5772 return err; 5773 if (!spec->kctls.list) 5774 return 0; /* can't find valid BIOS pin config */ 5775 err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg); 5776 if (err < 0) 5777 return err; 5778 5779 spec->multiout.max_channels = 2; 5780 5781 if (spec->autocfg.dig_outs) 5782 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID; 5783 if (spec->kctls.list) 5784 add_mixer(spec, spec->kctls.list); 5785 5786 add_verb(spec, alc260_volume_init_verbs); 5787 5788 spec->num_mux_defs = 1; 5789 spec->input_mux = &spec->private_imux[0]; 5790 5791 return 1; 5792} 5793 5794/* additional initialization for auto-configuration model */ 5795static void alc260_auto_init(struct hda_codec *codec) 5796{ 5797 struct alc_spec *spec = codec->spec; 5798 alc260_auto_init_multi_out(codec); 5799 alc260_auto_init_analog_input(codec); 5800 if (spec->unsol_event) 5801 alc_inithook(codec); 5802} 5803 5804#ifdef CONFIG_SND_HDA_POWER_SAVE 5805static struct hda_amp_list alc260_loopbacks[] = { 5806 { 0x07, HDA_INPUT, 0 }, 5807 { 0x07, HDA_INPUT, 1 }, 5808 { 0x07, HDA_INPUT, 2 }, 5809 { 0x07, HDA_INPUT, 3 }, 5810 { 0x07, HDA_INPUT, 4 }, 5811 { } /* end */ 5812}; 5813#endif 5814 5815/* 5816 * ALC260 configurations 5817 */ 5818static const char *alc260_models[ALC260_MODEL_LAST] = { 5819 [ALC260_BASIC] = "basic", 5820 [ALC260_HP] = "hp", 5821 [ALC260_HP_3013] = "hp-3013", 5822 [ALC260_HP_DC7600] = "hp-dc7600", 5823 [ALC260_FUJITSU_S702X] = "fujitsu", 5824 [ALC260_ACER] = "acer", 5825 [ALC260_WILL] = "will", 5826 [ALC260_REPLACER_672V] = "replacer", 5827 [ALC260_FAVORIT100] = "favorit100", 5828#ifdef CONFIG_SND_DEBUG 5829 [ALC260_TEST] = "test", 5830#endif 5831 [ALC260_AUTO] = "auto", 5832}; 5833 5834static struct snd_pci_quirk alc260_cfg_tbl[] = { 5835 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER), 5836 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER), 5837 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100), 5838 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013), 5839 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013), 5840 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013), 5841 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013), 5842 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600), 5843 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013), 5844 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP), 5845 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP), 5846 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP), 5847 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC), 5848 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC), 5849 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC), 5850 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X), 5851 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC), 5852 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V), 5853 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL), 5854 {} 5855}; 5856 5857static struct alc_config_preset alc260_presets[] = { 5858 [ALC260_BASIC] = { 5859 .mixers = { alc260_base_output_mixer, 5860 alc260_input_mixer }, 5861 .init_verbs = { alc260_init_verbs }, 5862 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 5863 .dac_nids = alc260_dac_nids, 5864 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids), 5865 .adc_nids = alc260_adc_nids, 5866 .num_channel_mode = ARRAY_SIZE(alc260_modes), 5867 .channel_mode = alc260_modes, 5868 .input_mux = &alc260_capture_source, 5869 }, 5870 [ALC260_HP] = { 5871 .mixers = { alc260_hp_output_mixer, 5872 alc260_input_mixer }, 5873 .init_verbs = { alc260_init_verbs, 5874 alc260_hp_unsol_verbs }, 5875 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 5876 .dac_nids = alc260_dac_nids, 5877 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt), 5878 .adc_nids = alc260_adc_nids_alt, 5879 .num_channel_mode = ARRAY_SIZE(alc260_modes), 5880 .channel_mode = alc260_modes, 5881 .input_mux = &alc260_capture_source, 5882 .unsol_event = alc260_hp_unsol_event, 5883 .init_hook = alc260_hp_automute, 5884 }, 5885 [ALC260_HP_DC7600] = { 5886 .mixers = { alc260_hp_dc7600_mixer, 5887 alc260_input_mixer }, 5888 .init_verbs = { alc260_init_verbs, 5889 alc260_hp_dc7600_verbs }, 5890 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 5891 .dac_nids = alc260_dac_nids, 5892 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt), 5893 .adc_nids = alc260_adc_nids_alt, 5894 .num_channel_mode = ARRAY_SIZE(alc260_modes), 5895 .channel_mode = alc260_modes, 5896 .input_mux = &alc260_capture_source, 5897 .unsol_event = alc260_hp_3012_unsol_event, 5898 .init_hook = alc260_hp_3012_automute, 5899 }, 5900 [ALC260_HP_3013] = { 5901 .mixers = { alc260_hp_3013_mixer, 5902 alc260_input_mixer }, 5903 .init_verbs = { alc260_hp_3013_init_verbs, 5904 alc260_hp_3013_unsol_verbs }, 5905 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 5906 .dac_nids = alc260_dac_nids, 5907 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt), 5908 .adc_nids = alc260_adc_nids_alt, 5909 .num_channel_mode = ARRAY_SIZE(alc260_modes), 5910 .channel_mode = alc260_modes, 5911 .input_mux = &alc260_capture_source, 5912 .unsol_event = alc260_hp_3013_unsol_event, 5913 .init_hook = alc260_hp_3013_automute, 5914 }, 5915 [ALC260_FUJITSU_S702X] = { 5916 .mixers = { alc260_fujitsu_mixer }, 5917 .init_verbs = { alc260_fujitsu_init_verbs }, 5918 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 5919 .dac_nids = alc260_dac_nids, 5920 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids), 5921 .adc_nids = alc260_dual_adc_nids, 5922 .num_channel_mode = ARRAY_SIZE(alc260_modes), 5923 .channel_mode = alc260_modes, 5924 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources), 5925 .input_mux = alc260_fujitsu_capture_sources, 5926 }, 5927 [ALC260_ACER] = { 5928 .mixers = { alc260_acer_mixer }, 5929 .init_verbs = { alc260_acer_init_verbs }, 5930 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 5931 .dac_nids = alc260_dac_nids, 5932 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids), 5933 .adc_nids = alc260_dual_adc_nids, 5934 .num_channel_mode = ARRAY_SIZE(alc260_modes), 5935 .channel_mode = alc260_modes, 5936 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources), 5937 .input_mux = alc260_acer_capture_sources, 5938 }, 5939 [ALC260_FAVORIT100] = { 5940 .mixers = { alc260_favorit100_mixer }, 5941 .init_verbs = { alc260_favorit100_init_verbs }, 5942 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 5943 .dac_nids = alc260_dac_nids, 5944 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids), 5945 .adc_nids = alc260_dual_adc_nids, 5946 .num_channel_mode = ARRAY_SIZE(alc260_modes), 5947 .channel_mode = alc260_modes, 5948 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources), 5949 .input_mux = alc260_favorit100_capture_sources, 5950 }, 5951 [ALC260_WILL] = { 5952 .mixers = { alc260_will_mixer }, 5953 .init_verbs = { alc260_init_verbs, alc260_will_verbs }, 5954 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 5955 .dac_nids = alc260_dac_nids, 5956 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids), 5957 .adc_nids = alc260_adc_nids, 5958 .dig_out_nid = ALC260_DIGOUT_NID, 5959 .num_channel_mode = ARRAY_SIZE(alc260_modes), 5960 .channel_mode = alc260_modes, 5961 .input_mux = &alc260_capture_source, 5962 }, 5963 [ALC260_REPLACER_672V] = { 5964 .mixers = { alc260_replacer_672v_mixer }, 5965 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs }, 5966 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 5967 .dac_nids = alc260_dac_nids, 5968 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids), 5969 .adc_nids = alc260_adc_nids, 5970 .dig_out_nid = ALC260_DIGOUT_NID, 5971 .num_channel_mode = ARRAY_SIZE(alc260_modes), 5972 .channel_mode = alc260_modes, 5973 .input_mux = &alc260_capture_source, 5974 .unsol_event = alc260_replacer_672v_unsol_event, 5975 .init_hook = alc260_replacer_672v_automute, 5976 }, 5977#ifdef CONFIG_SND_DEBUG 5978 [ALC260_TEST] = { 5979 .mixers = { alc260_test_mixer }, 5980 .init_verbs = { alc260_test_init_verbs }, 5981 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids), 5982 .dac_nids = alc260_test_dac_nids, 5983 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids), 5984 .adc_nids = alc260_test_adc_nids, 5985 .num_channel_mode = ARRAY_SIZE(alc260_modes), 5986 .channel_mode = alc260_modes, 5987 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources), 5988 .input_mux = alc260_test_capture_sources, 5989 }, 5990#endif 5991}; 5992 5993static int patch_alc260(struct hda_codec *codec) 5994{ 5995 struct alc_spec *spec; 5996 int err, board_config; 5997 5998 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 5999 if (spec == NULL) 6000 return -ENOMEM; 6001 6002 codec->spec = spec; 6003 6004 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST, 6005 alc260_models, 6006 alc260_cfg_tbl); 6007 if (board_config < 0) { 6008 snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, " 6009 "trying auto-probe from BIOS...\n"); 6010 board_config = ALC260_AUTO; 6011 } 6012 6013 if (board_config == ALC260_AUTO) { 6014 /* automatic parse from the BIOS config */ 6015 err = alc260_parse_auto_config(codec); 6016 if (err < 0) { 6017 alc_free(codec); 6018 return err; 6019 } else if (!err) { 6020 printk(KERN_INFO 6021 "hda_codec: Cannot set up configuration " 6022 "from BIOS. Using base mode...\n"); 6023 board_config = ALC260_BASIC; 6024 } 6025 } 6026 6027 err = snd_hda_attach_beep_device(codec, 0x1); 6028 if (err < 0) { 6029 alc_free(codec); 6030 return err; 6031 } 6032 6033 if (board_config != ALC260_AUTO) 6034 setup_preset(spec, &alc260_presets[board_config]); 6035 6036 spec->stream_name_analog = "ALC260 Analog"; 6037 spec->stream_analog_playback = &alc260_pcm_analog_playback; 6038 spec->stream_analog_capture = &alc260_pcm_analog_capture; 6039 6040 spec->stream_name_digital = "ALC260 Digital"; 6041 spec->stream_digital_playback = &alc260_pcm_digital_playback; 6042 spec->stream_digital_capture = &alc260_pcm_digital_capture; 6043 6044 if (!spec->adc_nids && spec->input_mux) { 6045 /* check whether NID 0x04 is valid */ 6046 unsigned int wcap = get_wcaps(codec, 0x04); 6047 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; 6048 /* get type */ 6049 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) { 6050 spec->adc_nids = alc260_adc_nids_alt; 6051 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt); 6052 } else { 6053 spec->adc_nids = alc260_adc_nids; 6054 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids); 6055 } 6056 } 6057 set_capture_mixer(spec); 6058 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT); 6059 6060 spec->vmaster_nid = 0x08; 6061 6062 codec->patch_ops = alc_patch_ops; 6063 if (board_config == ALC260_AUTO) 6064 spec->init_hook = alc260_auto_init; 6065#ifdef CONFIG_SND_HDA_POWER_SAVE 6066 if (!spec->loopback.amplist) 6067 spec->loopback.amplist = alc260_loopbacks; 6068#endif 6069 codec->proc_widget_hook = print_realtek_coef; 6070 6071 return 0; 6072} 6073 6074 6075/* 6076 * ALC882 support 6077 * 6078 * ALC882 is almost identical with ALC880 but has cleaner and more flexible 6079 * configuration. Each pin widget can choose any input DACs and a mixer. 6080 * Each ADC is connected from a mixer of all inputs. This makes possible 6081 * 6-channel independent captures. 6082 * 6083 * In addition, an independent DAC for the multi-playback (not used in this 6084 * driver yet). 6085 */ 6086#define ALC882_DIGOUT_NID 0x06 6087#define ALC882_DIGIN_NID 0x0a 6088 6089static struct hda_channel_mode alc882_ch_modes[1] = { 6090 { 8, NULL } 6091}; 6092 6093static hda_nid_t alc882_dac_nids[4] = { 6094 /* front, rear, clfe, rear_surr */ 6095 0x02, 0x03, 0x04, 0x05 6096}; 6097 6098/* identical with ALC880 */ 6099#define alc882_adc_nids alc880_adc_nids 6100#define alc882_adc_nids_alt alc880_adc_nids_alt 6101 6102static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 }; 6103static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 }; 6104 6105/* input MUX */ 6106/* FIXME: should be a matrix-type input source selection */ 6107 6108static struct hda_input_mux alc882_capture_source = { 6109 .num_items = 4, 6110 .items = { 6111 { "Mic", 0x0 }, 6112 { "Front Mic", 0x1 }, 6113 { "Line", 0x2 }, 6114 { "CD", 0x4 }, 6115 }, 6116}; 6117/* 6118 * 2ch mode 6119 */ 6120static struct hda_verb alc882_3ST_ch2_init[] = { 6121 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 6122 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 6123 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 6124 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 6125 { } /* end */ 6126}; 6127 6128/* 6129 * 6ch mode 6130 */ 6131static struct hda_verb alc882_3ST_ch6_init[] = { 6132 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 6133 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 6134 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, 6135 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 6136 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 6137 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 6138 { } /* end */ 6139}; 6140 6141static struct hda_channel_mode alc882_3ST_6ch_modes[2] = { 6142 { 2, alc882_3ST_ch2_init }, 6143 { 6, alc882_3ST_ch6_init }, 6144}; 6145 6146/* 6147 * 6ch mode 6148 */ 6149static struct hda_verb alc882_sixstack_ch6_init[] = { 6150 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 6151 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 6152 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 6153 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 6154 { } /* end */ 6155}; 6156 6157/* 6158 * 8ch mode 6159 */ 6160static struct hda_verb alc882_sixstack_ch8_init[] = { 6161 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 6162 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 6163 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 6164 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 6165 { } /* end */ 6166}; 6167 6168static struct hda_channel_mode alc882_sixstack_modes[2] = { 6169 { 6, alc882_sixstack_ch6_init }, 6170 { 8, alc882_sixstack_ch8_init }, 6171}; 6172 6173/* 6174 * macbook pro ALC885 can switch LineIn to LineOut without loosing Mic 6175 */ 6176 6177/* 6178 * 2ch mode 6179 */ 6180static struct hda_verb alc885_mbp_ch2_init[] = { 6181 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 6182 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6183 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6184 { } /* end */ 6185}; 6186 6187/* 6188 * 6ch mode 6189 */ 6190static struct hda_verb alc885_mbp_ch6_init[] = { 6191 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 6192 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6193 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 6194 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6195 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 6196 { } /* end */ 6197}; 6198 6199static struct hda_channel_mode alc885_mbp_6ch_modes[2] = { 6200 { 2, alc885_mbp_ch2_init }, 6201 { 6, alc885_mbp_ch6_init }, 6202}; 6203 6204 6205/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 6206 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b 6207 */ 6208static struct snd_kcontrol_new alc882_base_mixer[] = { 6209 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 6210 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 6211 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 6212 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 6213 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 6214 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 6215 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 6216 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 6217 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 6218 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 6219 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 6220 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 6221 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 6222 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 6223 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 6224 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 6225 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 6226 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 6227 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 6228 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 6229 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 6230 { } /* end */ 6231}; 6232 6233static struct snd_kcontrol_new alc885_mbp3_mixer[] = { 6234 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 6235 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT), 6236 HDA_CODEC_MUTE ("Speaker Playback Switch", 0x14, 0x00, HDA_OUTPUT), 6237 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0d, 0x00, HDA_OUTPUT), 6238 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 6239 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 6240 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT), 6241 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT), 6242 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT), 6243 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT), 6244 { } /* end */ 6245}; 6246static struct snd_kcontrol_new alc882_w2jc_mixer[] = { 6247 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 6248 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 6249 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 6250 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 6251 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 6252 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 6253 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 6254 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 6255 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 6256 { } /* end */ 6257}; 6258 6259static struct snd_kcontrol_new alc882_targa_mixer[] = { 6260 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 6261 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 6262 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 6263 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 6264 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 6265 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 6266 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 6267 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 6268 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 6269 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 6270 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 6271 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 6272 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 6273 { } /* end */ 6274}; 6275 6276/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ??? 6277 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c 6278 */ 6279static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = { 6280 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 6281 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 6282 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 6283 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT), 6284 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 6285 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 6286 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 6287 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 6288 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT), 6289 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT), 6290 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 6291 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 6292 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 6293 { } /* end */ 6294}; 6295 6296static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = { 6297 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 6298 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 6299 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 6300 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 6301 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 6302 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 6303 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 6304 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 6305 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 6306 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 6307 { } /* end */ 6308}; 6309 6310static struct snd_kcontrol_new alc882_chmode_mixer[] = { 6311 { 6312 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 6313 .name = "Channel Mode", 6314 .info = alc_ch_mode_info, 6315 .get = alc_ch_mode_get, 6316 .put = alc_ch_mode_put, 6317 }, 6318 { } /* end */ 6319}; 6320 6321static struct hda_verb alc882_init_verbs[] = { 6322 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 6323 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6324 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6325 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6326 /* Rear mixer */ 6327 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6328 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6329 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6330 /* CLFE mixer */ 6331 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6332 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6333 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6334 /* Side mixer */ 6335 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6336 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6337 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6338 6339 /* Front Pin: output 0 (0x0c) */ 6340 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6341 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6342 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 6343 /* Rear Pin: output 1 (0x0d) */ 6344 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6345 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6346 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 6347 /* CLFE Pin: output 2 (0x0e) */ 6348 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6349 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6350 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, 6351 /* Side Pin: output 3 (0x0f) */ 6352 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6353 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6354 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, 6355 /* Mic (rear) pin: input vref at 80% */ 6356 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 6357 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 6358 /* Front Mic pin: input vref at 80% */ 6359 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 6360 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 6361 /* Line In pin: input */ 6362 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 6363 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 6364 /* Line-2 In: Headphone output (output 0 - 0x0c) */ 6365 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6366 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6367 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 6368 /* CD pin widget for input */ 6369 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 6370 6371 /* FIXME: use matrix-type input source selection */ 6372 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 6373 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 6374 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6375 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 6376 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 6377 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 6378 /* Input mixer2 */ 6379 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6380 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 6381 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 6382 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 6383 /* Input mixer3 */ 6384 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6385 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 6386 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 6387 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 6388 /* ADC1: mute amp left and right */ 6389 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6390 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 6391 /* ADC2: mute amp left and right */ 6392 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6393 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 6394 /* ADC3: mute amp left and right */ 6395 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6396 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 6397 6398 { } 6399}; 6400 6401static struct hda_verb alc882_eapd_verbs[] = { 6402 /* change to EAPD mode */ 6403 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 6404 {0x20, AC_VERB_SET_PROC_COEF, 0x3060}, 6405 { } 6406}; 6407 6408/* Mac Pro test */ 6409static struct snd_kcontrol_new alc882_macpro_mixer[] = { 6410 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 6411 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 6412 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT), 6413 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT), 6414 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT), 6415 /* FIXME: this looks suspicious... 6416 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT), 6417 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT), 6418 */ 6419 { } /* end */ 6420}; 6421 6422static struct hda_verb alc882_macpro_init_verbs[] = { 6423 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 6424 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6425 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6426 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6427 /* Front Pin: output 0 (0x0c) */ 6428 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6429 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6430 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 6431 /* Front Mic pin: input vref at 80% */ 6432 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 6433 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 6434 /* Speaker: output */ 6435 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6436 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6437 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04}, 6438 /* Headphone output (output 0 - 0x0c) */ 6439 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6440 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6441 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00}, 6442 6443 /* FIXME: use matrix-type input source selection */ 6444 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 6445 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 6446 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6447 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 6448 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 6449 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 6450 /* Input mixer2 */ 6451 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6452 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 6453 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 6454 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 6455 /* Input mixer3 */ 6456 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6457 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 6458 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 6459 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 6460 /* ADC1: mute amp left and right */ 6461 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6462 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 6463 /* ADC2: mute amp left and right */ 6464 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6465 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 6466 /* ADC3: mute amp left and right */ 6467 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6468 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 6469 6470 { } 6471}; 6472 6473/* Macbook Pro rev3 */ 6474static struct hda_verb alc885_mbp3_init_verbs[] = { 6475 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 6476 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6477 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6478 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6479 /* Rear mixer */ 6480 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6481 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6482 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6483 /* Front Pin: output 0 (0x0c) */ 6484 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6485 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6486 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 6487 /* HP Pin: output 0 (0x0d) */ 6488 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, 6489 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 6490 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 6491 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 6492 /* Mic (rear) pin: input vref at 80% */ 6493 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 6494 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 6495 /* Front Mic pin: input vref at 80% */ 6496 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 6497 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 6498 /* Line In pin: use output 1 when in LineOut mode */ 6499 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 6500 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 6501 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, 6502 6503 /* FIXME: use matrix-type input source selection */ 6504 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 6505 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 6506 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6507 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 6508 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 6509 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 6510 /* Input mixer2 */ 6511 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6512 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 6513 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 6514 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 6515 /* Input mixer3 */ 6516 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6517 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 6518 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 6519 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 6520 /* ADC1: mute amp left and right */ 6521 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6522 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 6523 /* ADC2: mute amp left and right */ 6524 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6525 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 6526 /* ADC3: mute amp left and right */ 6527 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6528 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 6529 6530 { } 6531}; 6532 6533/* iMac 24 mixer. */ 6534static struct snd_kcontrol_new alc885_imac24_mixer[] = { 6535 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 6536 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT), 6537 { } /* end */ 6538}; 6539 6540/* iMac 24 init verbs. */ 6541static struct hda_verb alc885_imac24_init_verbs[] = { 6542 /* Internal speakers: output 0 (0x0c) */ 6543 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6544 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6545 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00}, 6546 /* Internal speakers: output 0 (0x0c) */ 6547 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6548 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6549 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00}, 6550 /* Headphone: output 0 (0x0c) */ 6551 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6552 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6553 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 6554 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 6555 /* Front Mic: input vref at 80% */ 6556 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 6557 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 6558 { } 6559}; 6560 6561/* Toggle speaker-output according to the hp-jack state */ 6562static void alc885_imac24_automute(struct hda_codec *codec) 6563{ 6564 unsigned int present; 6565 6566 present = snd_hda_codec_read(codec, 0x14, 0, 6567 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 6568 snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0, 6569 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 6570 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0, 6571 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 6572} 6573 6574/* Processes unsolicited events. */ 6575static void alc885_imac24_unsol_event(struct hda_codec *codec, 6576 unsigned int res) 6577{ 6578 /* Headphone insertion or removal. */ 6579 if ((res >> 26) == ALC880_HP_EVENT) 6580 alc885_imac24_automute(codec); 6581} 6582 6583static void alc885_mbp3_automute(struct hda_codec *codec) 6584{ 6585 unsigned int present; 6586 6587 present = snd_hda_codec_read(codec, 0x15, 0, 6588 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 6589 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 6590 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 6591 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 6592 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE); 6593 6594} 6595static void alc885_mbp3_unsol_event(struct hda_codec *codec, 6596 unsigned int res) 6597{ 6598 /* Headphone insertion or removal. */ 6599 if ((res >> 26) == ALC880_HP_EVENT) 6600 alc885_mbp3_automute(codec); 6601} 6602 6603 6604static struct hda_verb alc882_targa_verbs[] = { 6605 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6606 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 6607 6608 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6609 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6610 6611 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ 6612 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */ 6613 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 6614 6615 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 6616 {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, 6617 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03}, 6618 {0x01, AC_VERB_SET_GPIO_DATA, 0x03}, 6619 { } /* end */ 6620}; 6621 6622/* toggle speaker-output according to the hp-jack state */ 6623static void alc882_targa_automute(struct hda_codec *codec) 6624{ 6625 unsigned int present; 6626 6627 present = snd_hda_codec_read(codec, 0x14, 0, 6628 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 6629 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0, 6630 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 6631 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA, 6632 present ? 1 : 3); 6633} 6634 6635static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res) 6636{ 6637 /* Looks like the unsol event is incompatible with the standard 6638 * definition. 4bit tag is placed at 26 bit! 6639 */ 6640 if (((res >> 26) == ALC880_HP_EVENT)) { 6641 alc882_targa_automute(codec); 6642 } 6643} 6644 6645static struct hda_verb alc882_asus_a7j_verbs[] = { 6646 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6647 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 6648 6649 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6650 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6651 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6652 6653 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */ 6654 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 6655 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */ 6656 6657 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ 6658 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */ 6659 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 6660 { } /* end */ 6661}; 6662 6663static struct hda_verb alc882_asus_a7m_verbs[] = { 6664 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6665 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 6666 6667 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6668 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6669 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6670 6671 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */ 6672 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 6673 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */ 6674 6675 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ 6676 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */ 6677 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 6678 { } /* end */ 6679}; 6680 6681static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted) 6682{ 6683 unsigned int gpiostate, gpiomask, gpiodir; 6684 6685 gpiostate = snd_hda_codec_read(codec, codec->afg, 0, 6686 AC_VERB_GET_GPIO_DATA, 0); 6687 6688 if (!muted) 6689 gpiostate |= (1 << pin); 6690 else 6691 gpiostate &= ~(1 << pin); 6692 6693 gpiomask = snd_hda_codec_read(codec, codec->afg, 0, 6694 AC_VERB_GET_GPIO_MASK, 0); 6695 gpiomask |= (1 << pin); 6696 6697 gpiodir = snd_hda_codec_read(codec, codec->afg, 0, 6698 AC_VERB_GET_GPIO_DIRECTION, 0); 6699 gpiodir |= (1 << pin); 6700 6701 6702 snd_hda_codec_write(codec, codec->afg, 0, 6703 AC_VERB_SET_GPIO_MASK, gpiomask); 6704 snd_hda_codec_write(codec, codec->afg, 0, 6705 AC_VERB_SET_GPIO_DIRECTION, gpiodir); 6706 6707 msleep(1); 6708 6709 snd_hda_codec_write(codec, codec->afg, 0, 6710 AC_VERB_SET_GPIO_DATA, gpiostate); 6711} 6712 6713/* set up GPIO at initialization */ 6714static void alc885_macpro_init_hook(struct hda_codec *codec) 6715{ 6716 alc882_gpio_mute(codec, 0, 0); 6717 alc882_gpio_mute(codec, 1, 0); 6718} 6719 6720/* set up GPIO and update auto-muting at initialization */ 6721static void alc885_imac24_init_hook(struct hda_codec *codec) 6722{ 6723 alc885_macpro_init_hook(codec); 6724 alc885_imac24_automute(codec); 6725} 6726 6727/* 6728 * generic initialization of ADC, input mixers and output mixers 6729 */ 6730static struct hda_verb alc882_auto_init_verbs[] = { 6731 /* 6732 * Unmute ADC0-2 and set the default input to mic-in 6733 */ 6734 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 6735 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6736 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 6737 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6738 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 6739 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6740 6741 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 6742 * mixer widget 6743 * Note: PASD motherboards uses the Line In 2 as the input for 6744 * front panel mic (mic 2) 6745 */ 6746 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 6747 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6748 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6749 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 6750 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 6751 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 6752 6753 /* 6754 * Set up output mixers (0x0c - 0x0f) 6755 */ 6756 /* set vol=0 to output mixers */ 6757 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6758 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6759 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6760 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6761 /* set up input amps for analog loopback */ 6762 /* Amp Indices: DAC = 0, mixer = 1 */ 6763 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6764 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 6765 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6766 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 6767 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6768 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 6769 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6770 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 6771 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6772 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 6773 6774 /* FIXME: use matrix-type input source selection */ 6775 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 6776 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 6777 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 6778 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 6779 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 6780 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 6781 /* Input mixer2 */ 6782 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 6783 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 6784 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 6785 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 6786 /* Input mixer3 */ 6787 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 6788 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 6789 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 6790 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 6791 6792 { } 6793}; 6794 6795#ifdef CONFIG_SND_HDA_POWER_SAVE 6796#define alc882_loopbacks alc880_loopbacks 6797#endif 6798 6799/* pcm configuration: identiacal with ALC880 */ 6800#define alc882_pcm_analog_playback alc880_pcm_analog_playback 6801#define alc882_pcm_analog_capture alc880_pcm_analog_capture 6802#define alc882_pcm_digital_playback alc880_pcm_digital_playback 6803#define alc882_pcm_digital_capture alc880_pcm_digital_capture 6804 6805/* 6806 * configuration and preset 6807 */ 6808static const char *alc882_models[ALC882_MODEL_LAST] = { 6809 [ALC882_3ST_DIG] = "3stack-dig", 6810 [ALC882_6ST_DIG] = "6stack-dig", 6811 [ALC882_ARIMA] = "arima", 6812 [ALC882_W2JC] = "w2jc", 6813 [ALC882_TARGA] = "targa", 6814 [ALC882_ASUS_A7J] = "asus-a7j", 6815 [ALC882_ASUS_A7M] = "asus-a7m", 6816 [ALC885_MACPRO] = "macpro", 6817 [ALC885_MBP3] = "mbp3", 6818 [ALC885_IMAC24] = "imac24", 6819 [ALC882_AUTO] = "auto", 6820}; 6821 6822static struct snd_pci_quirk alc882_cfg_tbl[] = { 6823 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG), 6824 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J), 6825 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J), 6826 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M), 6827 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC), 6828 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG), 6829 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG), 6830 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG), 6831 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG), 6832 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */ 6833 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG), 6834 SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), 6835 {} 6836}; 6837 6838static struct alc_config_preset alc882_presets[] = { 6839 [ALC882_3ST_DIG] = { 6840 .mixers = { alc882_base_mixer }, 6841 .init_verbs = { alc882_init_verbs }, 6842 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 6843 .dac_nids = alc882_dac_nids, 6844 .dig_out_nid = ALC882_DIGOUT_NID, 6845 .dig_in_nid = ALC882_DIGIN_NID, 6846 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes), 6847 .channel_mode = alc882_ch_modes, 6848 .need_dac_fix = 1, 6849 .input_mux = &alc882_capture_source, 6850 }, 6851 [ALC882_6ST_DIG] = { 6852 .mixers = { alc882_base_mixer, alc882_chmode_mixer }, 6853 .init_verbs = { alc882_init_verbs }, 6854 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 6855 .dac_nids = alc882_dac_nids, 6856 .dig_out_nid = ALC882_DIGOUT_NID, 6857 .dig_in_nid = ALC882_DIGIN_NID, 6858 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes), 6859 .channel_mode = alc882_sixstack_modes, 6860 .input_mux = &alc882_capture_source, 6861 }, 6862 [ALC882_ARIMA] = { 6863 .mixers = { alc882_base_mixer, alc882_chmode_mixer }, 6864 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs }, 6865 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 6866 .dac_nids = alc882_dac_nids, 6867 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes), 6868 .channel_mode = alc882_sixstack_modes, 6869 .input_mux = &alc882_capture_source, 6870 }, 6871 [ALC882_W2JC] = { 6872 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer }, 6873 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs, 6874 alc880_gpio1_init_verbs }, 6875 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 6876 .dac_nids = alc882_dac_nids, 6877 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), 6878 .channel_mode = alc880_threestack_modes, 6879 .need_dac_fix = 1, 6880 .input_mux = &alc882_capture_source, 6881 .dig_out_nid = ALC882_DIGOUT_NID, 6882 }, 6883 [ALC885_MBP3] = { 6884 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer }, 6885 .init_verbs = { alc885_mbp3_init_verbs, 6886 alc880_gpio1_init_verbs }, 6887 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 6888 .dac_nids = alc882_dac_nids, 6889 .channel_mode = alc885_mbp_6ch_modes, 6890 .num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes), 6891 .input_mux = &alc882_capture_source, 6892 .dig_out_nid = ALC882_DIGOUT_NID, 6893 .dig_in_nid = ALC882_DIGIN_NID, 6894 .unsol_event = alc885_mbp3_unsol_event, 6895 .init_hook = alc885_mbp3_automute, 6896 }, 6897 [ALC885_MACPRO] = { 6898 .mixers = { alc882_macpro_mixer }, 6899 .init_verbs = { alc882_macpro_init_verbs }, 6900 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 6901 .dac_nids = alc882_dac_nids, 6902 .dig_out_nid = ALC882_DIGOUT_NID, 6903 .dig_in_nid = ALC882_DIGIN_NID, 6904 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes), 6905 .channel_mode = alc882_ch_modes, 6906 .input_mux = &alc882_capture_source, 6907 .init_hook = alc885_macpro_init_hook, 6908 }, 6909 [ALC885_IMAC24] = { 6910 .mixers = { alc885_imac24_mixer }, 6911 .init_verbs = { alc885_imac24_init_verbs }, 6912 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 6913 .dac_nids = alc882_dac_nids, 6914 .dig_out_nid = ALC882_DIGOUT_NID, 6915 .dig_in_nid = ALC882_DIGIN_NID, 6916 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes), 6917 .channel_mode = alc882_ch_modes, 6918 .input_mux = &alc882_capture_source, 6919 .unsol_event = alc885_imac24_unsol_event, 6920 .init_hook = alc885_imac24_init_hook, 6921 }, 6922 [ALC882_TARGA] = { 6923 .mixers = { alc882_targa_mixer, alc882_chmode_mixer }, 6924 .init_verbs = { alc882_init_verbs, alc882_targa_verbs}, 6925 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 6926 .dac_nids = alc882_dac_nids, 6927 .dig_out_nid = ALC882_DIGOUT_NID, 6928 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids), 6929 .adc_nids = alc882_adc_nids, 6930 .capsrc_nids = alc882_capsrc_nids, 6931 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes), 6932 .channel_mode = alc882_3ST_6ch_modes, 6933 .need_dac_fix = 1, 6934 .input_mux = &alc882_capture_source, 6935 .unsol_event = alc882_targa_unsol_event, 6936 .init_hook = alc882_targa_automute, 6937 }, 6938 [ALC882_ASUS_A7J] = { 6939 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer }, 6940 .init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs}, 6941 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 6942 .dac_nids = alc882_dac_nids, 6943 .dig_out_nid = ALC882_DIGOUT_NID, 6944 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids), 6945 .adc_nids = alc882_adc_nids, 6946 .capsrc_nids = alc882_capsrc_nids, 6947 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes), 6948 .channel_mode = alc882_3ST_6ch_modes, 6949 .need_dac_fix = 1, 6950 .input_mux = &alc882_capture_source, 6951 }, 6952 [ALC882_ASUS_A7M] = { 6953 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer }, 6954 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs, 6955 alc880_gpio1_init_verbs, 6956 alc882_asus_a7m_verbs }, 6957 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 6958 .dac_nids = alc882_dac_nids, 6959 .dig_out_nid = ALC882_DIGOUT_NID, 6960 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), 6961 .channel_mode = alc880_threestack_modes, 6962 .need_dac_fix = 1, 6963 .input_mux = &alc882_capture_source, 6964 }, 6965}; 6966 6967 6968/* 6969 * Pin config fixes 6970 */ 6971enum { 6972 PINFIX_ABIT_AW9D_MAX 6973}; 6974 6975static struct alc_pincfg alc882_abit_aw9d_pinfix[] = { 6976 { 0x15, 0x01080104 }, /* side */ 6977 { 0x16, 0x01011012 }, /* rear */ 6978 { 0x17, 0x01016011 }, /* clfe */ 6979 { } 6980}; 6981 6982static const struct alc_pincfg *alc882_pin_fixes[] = { 6983 [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix, 6984}; 6985 6986static struct snd_pci_quirk alc882_pinfix_tbl[] = { 6987 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX), 6988 {} 6989}; 6990 6991/* 6992 * BIOS auto configuration 6993 */ 6994static void alc882_auto_set_output_and_unmute(struct hda_codec *codec, 6995 hda_nid_t nid, int pin_type, 6996 int dac_idx) 6997{ 6998 /* set as output */ 6999 struct alc_spec *spec = codec->spec; 7000 int idx; 7001 7002 alc_set_pin_output(codec, nid, pin_type); 7003 if (spec->multiout.dac_nids[dac_idx] == 0x25) 7004 idx = 4; 7005 else 7006 idx = spec->multiout.dac_nids[dac_idx] - 2; 7007 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx); 7008 7009} 7010 7011static void alc882_auto_init_multi_out(struct hda_codec *codec) 7012{ 7013 struct alc_spec *spec = codec->spec; 7014 int i; 7015 7016 alc_subsystem_id(codec, 0x15, 0x1b, 0x14); 7017 for (i = 0; i <= HDA_SIDE; i++) { 7018 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 7019 int pin_type = get_pin_type(spec->autocfg.line_out_type); 7020 if (nid) 7021 alc882_auto_set_output_and_unmute(codec, nid, pin_type, 7022 i); 7023 } 7024} 7025 7026static void alc882_auto_init_hp_out(struct hda_codec *codec) 7027{ 7028 struct alc_spec *spec = codec->spec; 7029 hda_nid_t pin; 7030 7031 pin = spec->autocfg.hp_pins[0]; 7032 if (pin) /* connect to front */ 7033 /* use dac 0 */ 7034 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); 7035 pin = spec->autocfg.speaker_pins[0]; 7036 if (pin) 7037 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0); 7038} 7039 7040#define alc882_is_input_pin(nid) alc880_is_input_pin(nid) 7041#define ALC882_PIN_CD_NID ALC880_PIN_CD_NID 7042 7043static void alc882_auto_init_analog_input(struct hda_codec *codec) 7044{ 7045 struct alc_spec *spec = codec->spec; 7046 int i; 7047 7048 for (i = 0; i < AUTO_PIN_LAST; i++) { 7049 hda_nid_t nid = spec->autocfg.input_pins[i]; 7050 if (!nid) 7051 continue; 7052 alc_set_input_pin(codec, nid, AUTO_PIN_FRONT_MIC /*i*/); 7053 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP) 7054 snd_hda_codec_write(codec, nid, 0, 7055 AC_VERB_SET_AMP_GAIN_MUTE, 7056 AMP_OUT_MUTE); 7057 } 7058} 7059 7060static void alc882_auto_init_input_src(struct hda_codec *codec) 7061{ 7062 struct alc_spec *spec = codec->spec; 7063 int c; 7064 7065 for (c = 0; c < spec->num_adc_nids; c++) { 7066 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS]; 7067 hda_nid_t nid = spec->capsrc_nids[c]; 7068 unsigned int mux_idx; 7069 const struct hda_input_mux *imux; 7070 int conns, mute, idx, item; 7071 7072 conns = snd_hda_get_connections(codec, nid, conn_list, 7073 ARRAY_SIZE(conn_list)); 7074 if (conns < 0) 7075 continue; 7076 mux_idx = c >= spec->num_mux_defs ? 0 : c; 7077 imux = &spec->input_mux[mux_idx]; 7078 for (idx = 0; idx < conns; idx++) { 7079 /* if the current connection is the selected one, 7080 * unmute it as default - otherwise mute it 7081 */ 7082 mute = AMP_IN_MUTE(idx); 7083 for (item = 0; item < imux->num_items; item++) { 7084 if (imux->items[item].index == idx) { 7085 if (spec->cur_mux[c] == item) 7086 mute = AMP_IN_UNMUTE(idx); 7087 break; 7088 } 7089 } 7090 /* check if we have a selector or mixer 7091 * we could check for the widget type instead, but 7092 * just check for Amp-In presence (in case of mixer 7093 * without amp-in there is something wrong, this 7094 * function shouldn't be used or capsrc nid is wrong) 7095 */ 7096 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) 7097 snd_hda_codec_write(codec, nid, 0, 7098 AC_VERB_SET_AMP_GAIN_MUTE, 7099 mute); 7100 else if (mute != AMP_IN_MUTE(idx)) 7101 snd_hda_codec_write(codec, nid, 0, 7102 AC_VERB_SET_CONNECT_SEL, 7103 idx); 7104 } 7105 } 7106} 7107 7108/* add mic boosts if needed */ 7109static int alc_auto_add_mic_boost(struct hda_codec *codec) 7110{ 7111 struct alc_spec *spec = codec->spec; 7112 int err; 7113 hda_nid_t nid; 7114 7115 nid = spec->autocfg.input_pins[AUTO_PIN_MIC]; 7116 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) { 7117 err = add_control(spec, ALC_CTL_WIDGET_VOL, 7118 "Mic Boost", 7119 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT)); 7120 if (err < 0) 7121 return err; 7122 } 7123 nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC]; 7124 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) { 7125 err = add_control(spec, ALC_CTL_WIDGET_VOL, 7126 "Front Mic Boost", 7127 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT)); 7128 if (err < 0) 7129 return err; 7130 } 7131 return 0; 7132} 7133 7134/* almost identical with ALC880 parser... */ 7135static int alc882_parse_auto_config(struct hda_codec *codec) 7136{ 7137 struct alc_spec *spec = codec->spec; 7138 int err = alc880_parse_auto_config(codec); 7139 7140 if (err < 0) 7141 return err; 7142 else if (!err) 7143 return 0; /* no config found */ 7144 7145 err = alc_auto_add_mic_boost(codec); 7146 if (err < 0) 7147 return err; 7148 7149 /* hack - override the init verbs */ 7150 spec->init_verbs[0] = alc882_auto_init_verbs; 7151 7152 return 1; /* config found */ 7153} 7154 7155/* additional initialization for auto-configuration model */ 7156static void alc882_auto_init(struct hda_codec *codec) 7157{ 7158 struct alc_spec *spec = codec->spec; 7159 alc882_auto_init_multi_out(codec); 7160 alc882_auto_init_hp_out(codec); 7161 alc882_auto_init_analog_input(codec); 7162 alc882_auto_init_input_src(codec); 7163 if (spec->unsol_event) 7164 alc_inithook(codec); 7165} 7166 7167static int patch_alc883(struct hda_codec *codec); /* called in patch_alc882() */ 7168 7169static int patch_alc882(struct hda_codec *codec) 7170{ 7171 struct alc_spec *spec; 7172 int err, board_config; 7173 7174 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 7175 if (spec == NULL) 7176 return -ENOMEM; 7177 7178 codec->spec = spec; 7179 7180 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST, 7181 alc882_models, 7182 alc882_cfg_tbl); 7183 7184 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) { 7185 /* Pick up systems that don't supply PCI SSID */ 7186 switch (codec->subsystem_id) { 7187 case 0x106b0c00: /* Mac Pro */ 7188 board_config = ALC885_MACPRO; 7189 break; 7190 case 0x106b1000: /* iMac 24 */ 7191 case 0x106b2800: /* AppleTV */ 7192 case 0x106b3e00: /* iMac 24 Aluminium */ 7193 board_config = ALC885_IMAC24; 7194 break; 7195 case 0x106b00a0: /* MacBookPro3,1 - Another revision */ 7196 case 0x106b00a1: /* Macbook (might be wrong - PCI SSID?) */ 7197 case 0x106b00a4: /* MacbookPro4,1 */ 7198 case 0x106b2c00: /* Macbook Pro rev3 */ 7199 case 0x106b3600: /* Macbook 3.1 */ 7200 case 0x106b3800: /* MacbookPro4,1 - latter revision */ 7201 board_config = ALC885_MBP3; 7202 break; 7203 default: 7204 /* ALC889A is handled better as ALC888-compatible */ 7205 if (codec->revision_id == 0x100101 || 7206 codec->revision_id == 0x100103) { 7207 alc_free(codec); 7208 return patch_alc883(codec); 7209 } 7210 printk(KERN_INFO "hda_codec: Unknown model for ALC882, " 7211 "trying auto-probe from BIOS...\n"); 7212 board_config = ALC882_AUTO; 7213 } 7214 } 7215 7216 alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes); 7217 7218 if (board_config == ALC882_AUTO) { 7219 /* automatic parse from the BIOS config */ 7220 err = alc882_parse_auto_config(codec); 7221 if (err < 0) { 7222 alc_free(codec); 7223 return err; 7224 } else if (!err) { 7225 printk(KERN_INFO 7226 "hda_codec: Cannot set up configuration " 7227 "from BIOS. Using base mode...\n"); 7228 board_config = ALC882_3ST_DIG; 7229 } 7230 } 7231 7232 err = snd_hda_attach_beep_device(codec, 0x1); 7233 if (err < 0) { 7234 alc_free(codec); 7235 return err; 7236 } 7237 7238 if (board_config != ALC882_AUTO) 7239 setup_preset(spec, &alc882_presets[board_config]); 7240 7241 if (codec->vendor_id == 0x10ec0885) { 7242 spec->stream_name_analog = "ALC885 Analog"; 7243 spec->stream_name_digital = "ALC885 Digital"; 7244 } else { 7245 spec->stream_name_analog = "ALC882 Analog"; 7246 spec->stream_name_digital = "ALC882 Digital"; 7247 } 7248 7249 spec->stream_analog_playback = &alc882_pcm_analog_playback; 7250 spec->stream_analog_capture = &alc882_pcm_analog_capture; 7251 /* FIXME: setup DAC5 */ 7252 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/ 7253 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture; 7254 7255 spec->stream_digital_playback = &alc882_pcm_digital_playback; 7256 spec->stream_digital_capture = &alc882_pcm_digital_capture; 7257 7258 spec->capture_style = CAPT_MIX; /* matrix-style capture */ 7259 if (!spec->adc_nids && spec->input_mux) { 7260 /* check whether NID 0x07 is valid */ 7261 unsigned int wcap = get_wcaps(codec, 0x07); 7262 /* get type */ 7263 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; 7264 if (wcap != AC_WID_AUD_IN) { 7265 spec->adc_nids = alc882_adc_nids_alt; 7266 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt); 7267 spec->capsrc_nids = alc882_capsrc_nids_alt; 7268 } else { 7269 spec->adc_nids = alc882_adc_nids; 7270 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids); 7271 spec->capsrc_nids = alc882_capsrc_nids; 7272 } 7273 } 7274 set_capture_mixer(spec); 7275 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 7276 7277 spec->vmaster_nid = 0x0c; 7278 7279 codec->patch_ops = alc_patch_ops; 7280 if (board_config == ALC882_AUTO) 7281 spec->init_hook = alc882_auto_init; 7282#ifdef CONFIG_SND_HDA_POWER_SAVE 7283 if (!spec->loopback.amplist) 7284 spec->loopback.amplist = alc882_loopbacks; 7285#endif 7286 codec->proc_widget_hook = print_realtek_coef; 7287 7288 return 0; 7289} 7290 7291/* 7292 * ALC883 support 7293 * 7294 * ALC883 is almost identical with ALC880 but has cleaner and more flexible 7295 * configuration. Each pin widget can choose any input DACs and a mixer. 7296 * Each ADC is connected from a mixer of all inputs. This makes possible 7297 * 6-channel independent captures. 7298 * 7299 * In addition, an independent DAC for the multi-playback (not used in this 7300 * driver yet). 7301 */ 7302#define ALC883_DIGOUT_NID 0x06 7303#define ALC883_DIGIN_NID 0x0a 7304 7305#define ALC1200_DIGOUT_NID 0x10 7306 7307static hda_nid_t alc883_dac_nids[4] = { 7308 /* front, rear, clfe, rear_surr */ 7309 0x02, 0x03, 0x04, 0x05 7310}; 7311 7312static hda_nid_t alc883_adc_nids[2] = { 7313 /* ADC1-2 */ 7314 0x08, 0x09, 7315}; 7316 7317static hda_nid_t alc883_adc_nids_alt[1] = { 7318 /* ADC1 */ 7319 0x08, 7320}; 7321 7322static hda_nid_t alc883_adc_nids_rev[2] = { 7323 /* ADC2-1 */ 7324 0x09, 0x08 7325}; 7326 7327#define alc889_adc_nids alc880_adc_nids 7328 7329static hda_nid_t alc883_capsrc_nids[2] = { 0x23, 0x22 }; 7330 7331static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 }; 7332 7333#define alc889_capsrc_nids alc882_capsrc_nids 7334 7335/* input MUX */ 7336/* FIXME: should be a matrix-type input source selection */ 7337 7338static struct hda_input_mux alc883_capture_source = { 7339 .num_items = 4, 7340 .items = { 7341 { "Mic", 0x0 }, 7342 { "Front Mic", 0x1 }, 7343 { "Line", 0x2 }, 7344 { "CD", 0x4 }, 7345 }, 7346}; 7347 7348static struct hda_input_mux alc883_3stack_6ch_intel = { 7349 .num_items = 4, 7350 .items = { 7351 { "Mic", 0x1 }, 7352 { "Front Mic", 0x0 }, 7353 { "Line", 0x2 }, 7354 { "CD", 0x4 }, 7355 }, 7356}; 7357 7358static struct hda_input_mux alc883_lenovo_101e_capture_source = { 7359 .num_items = 2, 7360 .items = { 7361 { "Mic", 0x1 }, 7362 { "Line", 0x2 }, 7363 }, 7364}; 7365 7366static struct hda_input_mux alc883_lenovo_nb0763_capture_source = { 7367 .num_items = 4, 7368 .items = { 7369 { "Mic", 0x0 }, 7370 { "iMic", 0x1 }, 7371 { "Line", 0x2 }, 7372 { "CD", 0x4 }, 7373 }, 7374}; 7375 7376static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = { 7377 .num_items = 2, 7378 .items = { 7379 { "Mic", 0x0 }, 7380 { "Int Mic", 0x1 }, 7381 }, 7382}; 7383 7384static struct hda_input_mux alc883_lenovo_sky_capture_source = { 7385 .num_items = 3, 7386 .items = { 7387 { "Mic", 0x0 }, 7388 { "Front Mic", 0x1 }, 7389 { "Line", 0x4 }, 7390 }, 7391}; 7392 7393static struct hda_input_mux alc883_asus_eee1601_capture_source = { 7394 .num_items = 2, 7395 .items = { 7396 { "Mic", 0x0 }, 7397 { "Line", 0x2 }, 7398 }, 7399}; 7400 7401/* 7402 * 2ch mode 7403 */ 7404static struct hda_channel_mode alc883_3ST_2ch_modes[1] = { 7405 { 2, NULL } 7406}; 7407 7408/* 7409 * 2ch mode 7410 */ 7411static struct hda_verb alc883_3ST_ch2_init[] = { 7412 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 7413 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7414 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 7415 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7416 { } /* end */ 7417}; 7418 7419/* 7420 * 4ch mode 7421 */ 7422static struct hda_verb alc883_3ST_ch4_init[] = { 7423 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 7424 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7425 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7426 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7427 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7428 { } /* end */ 7429}; 7430 7431/* 7432 * 6ch mode 7433 */ 7434static struct hda_verb alc883_3ST_ch6_init[] = { 7435 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7436 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7437 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, 7438 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7439 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7440 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7441 { } /* end */ 7442}; 7443 7444static struct hda_channel_mode alc883_3ST_6ch_modes[3] = { 7445 { 2, alc883_3ST_ch2_init }, 7446 { 4, alc883_3ST_ch4_init }, 7447 { 6, alc883_3ST_ch6_init }, 7448}; 7449 7450/* 7451 * 2ch mode 7452 */ 7453static struct hda_verb alc883_3ST_ch2_intel_init[] = { 7454 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 7455 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7456 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 7457 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7458 { } /* end */ 7459}; 7460 7461/* 7462 * 4ch mode 7463 */ 7464static struct hda_verb alc883_3ST_ch4_intel_init[] = { 7465 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 7466 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7467 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7468 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7469 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7470 { } /* end */ 7471}; 7472 7473/* 7474 * 6ch mode 7475 */ 7476static struct hda_verb alc883_3ST_ch6_intel_init[] = { 7477 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7478 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7479 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 }, 7480 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7481 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7482 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7483 { } /* end */ 7484}; 7485 7486static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = { 7487 { 2, alc883_3ST_ch2_intel_init }, 7488 { 4, alc883_3ST_ch4_intel_init }, 7489 { 6, alc883_3ST_ch6_intel_init }, 7490}; 7491 7492/* 7493 * 6ch mode 7494 */ 7495static struct hda_verb alc883_sixstack_ch6_init[] = { 7496 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 7497 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7498 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7499 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7500 { } /* end */ 7501}; 7502 7503/* 7504 * 8ch mode 7505 */ 7506static struct hda_verb alc883_sixstack_ch8_init[] = { 7507 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7508 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7509 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7510 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7511 { } /* end */ 7512}; 7513 7514static struct hda_channel_mode alc883_sixstack_modes[2] = { 7515 { 6, alc883_sixstack_ch6_init }, 7516 { 8, alc883_sixstack_ch8_init }, 7517}; 7518 7519static struct hda_verb alc883_medion_eapd_verbs[] = { 7520 /* eanable EAPD on medion laptop */ 7521 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 7522 {0x20, AC_VERB_SET_PROC_COEF, 0x3070}, 7523 { } 7524}; 7525 7526/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 7527 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b 7528 */ 7529 7530static struct snd_kcontrol_new alc883_base_mixer[] = { 7531 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7532 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 7533 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 7534 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 7535 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 7536 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 7537 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 7538 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 7539 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 7540 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 7541 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 7542 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 7543 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 7544 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 7545 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 7546 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7547 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 7548 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7549 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 7550 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 7551 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 7552 { } /* end */ 7553}; 7554 7555static struct snd_kcontrol_new alc883_mitac_mixer[] = { 7556 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7557 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 7558 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 7559 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 7560 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 7561 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 7562 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 7563 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7564 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 7565 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7566 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 7567 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 7568 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 7569 { } /* end */ 7570}; 7571 7572static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = { 7573 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7574 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), 7575 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 7576 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 7577 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7578 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 7579 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7580 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 7581 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 7582 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 7583 { } /* end */ 7584}; 7585 7586static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = { 7587 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7588 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), 7589 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 7590 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 7591 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7592 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 7593 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7594 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 7595 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 7596 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 7597 { } /* end */ 7598}; 7599 7600static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = { 7601 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7602 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 7603 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 7604 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 7605 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 7606 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 7607 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 7608 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7609 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 7610 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7611 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 7612 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 7613 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 7614 { } /* end */ 7615}; 7616 7617static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = { 7618 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7619 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 7620 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 7621 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 7622 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 7623 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 7624 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 7625 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 7626 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 7627 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 7628 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 7629 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 7630 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 7631 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7632 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 7633 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7634 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 7635 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 7636 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 7637 { } /* end */ 7638}; 7639 7640static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = { 7641 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7642 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 7643 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 7644 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 7645 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, 7646 HDA_OUTPUT), 7647 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 7648 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 7649 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 7650 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 7651 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 7652 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 7653 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 7654 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 7655 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 7656 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT), 7657 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 7658 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7659 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT), 7660 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7661 { } /* end */ 7662}; 7663 7664static struct snd_kcontrol_new alc883_fivestack_mixer[] = { 7665 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7666 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 7667 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 7668 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 7669 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 7670 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 7671 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 7672 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 7673 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 7674 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 7675 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 7676 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 7677 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 7678 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7679 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 7680 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7681 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 7682 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 7683 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 7684 { } /* end */ 7685}; 7686 7687static struct snd_kcontrol_new alc883_tagra_mixer[] = { 7688 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7689 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 7690 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 7691 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 7692 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 7693 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 7694 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 7695 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 7696 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 7697 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 7698 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 7699 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 7700 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 7701 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7702 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 7703 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7704 { } /* end */ 7705}; 7706 7707static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = { 7708 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7709 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 7710 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 7711 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 7712 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 7713 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7714 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 7715 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7716 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 7717 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 7718 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 7719 { } /* end */ 7720}; 7721 7722static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = { 7723 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7724 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 7725 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 7726 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 7727 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 7728 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 7729 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 7730 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 7731 { } /* end */ 7732}; 7733 7734static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = { 7735 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7736 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT), 7737 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 7738 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 7739 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 7740 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7741 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7742 HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT), 7743 HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT), 7744 { } /* end */ 7745}; 7746 7747static struct snd_kcontrol_new alc883_medion_md2_mixer[] = { 7748 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7749 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 7750 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT), 7751 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 7752 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 7753 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7754 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7755 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 7756 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 7757 { } /* end */ 7758}; 7759 7760static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = { 7761 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7762 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 7763 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 7764 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 7765 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 7766 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7767 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 7768 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7769 { } /* end */ 7770}; 7771 7772static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = { 7773 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7774 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 7775 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT), 7776 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT), 7777 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 7778 0x0d, 1, 0x0, HDA_OUTPUT), 7779 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT), 7780 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT), 7781 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT), 7782 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 7783 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 7784 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 7785 HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x1a, 0x0, HDA_OUTPUT), 7786 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 7787 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 7788 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 7789 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 7790 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7791 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 7792 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7793 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 7794 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 7795 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 7796 { } /* end */ 7797}; 7798 7799static struct hda_bind_ctls alc883_bind_cap_vol = { 7800 .ops = &snd_hda_bind_vol, 7801 .values = { 7802 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT), 7803 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT), 7804 0 7805 }, 7806}; 7807 7808static struct hda_bind_ctls alc883_bind_cap_switch = { 7809 .ops = &snd_hda_bind_sw, 7810 .values = { 7811 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT), 7812 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT), 7813 0 7814 }, 7815}; 7816 7817static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = { 7818 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7819 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 7820 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 7821 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 7822 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 7823 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7824 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 7825 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7826 { } /* end */ 7827}; 7828 7829static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = { 7830 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol), 7831 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch), 7832 { 7833 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 7834 /* .name = "Capture Source", */ 7835 .name = "Input Source", 7836 .count = 1, 7837 .info = alc_mux_enum_info, 7838 .get = alc_mux_enum_get, 7839 .put = alc_mux_enum_put, 7840 }, 7841 { } /* end */ 7842}; 7843 7844static struct snd_kcontrol_new alc883_chmode_mixer[] = { 7845 { 7846 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 7847 .name = "Channel Mode", 7848 .info = alc_ch_mode_info, 7849 .get = alc_ch_mode_get, 7850 .put = alc_ch_mode_put, 7851 }, 7852 { } /* end */ 7853}; 7854 7855static struct hda_verb alc883_init_verbs[] = { 7856 /* ADC1: mute amp left and right */ 7857 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7858 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 7859 /* ADC2: mute amp left and right */ 7860 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7861 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 7862 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 7863 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 7864 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7865 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7866 /* Rear mixer */ 7867 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 7868 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7869 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7870 /* CLFE mixer */ 7871 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 7872 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7873 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7874 /* Side mixer */ 7875 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 7876 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7877 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7878 7879 /* mute analog input loopbacks */ 7880 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7881 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7882 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 7883 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 7884 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 7885 7886 /* Front Pin: output 0 (0x0c) */ 7887 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 7888 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7889 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 7890 /* Rear Pin: output 1 (0x0d) */ 7891 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 7892 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7893 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 7894 /* CLFE Pin: output 2 (0x0e) */ 7895 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 7896 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7897 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, 7898 /* Side Pin: output 3 (0x0f) */ 7899 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 7900 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7901 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, 7902 /* Mic (rear) pin: input vref at 80% */ 7903 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 7904 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 7905 /* Front Mic pin: input vref at 80% */ 7906 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 7907 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 7908 /* Line In pin: input */ 7909 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 7910 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 7911 /* Line-2 In: Headphone output (output 0 - 0x0c) */ 7912 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 7913 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7914 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 7915 /* CD pin widget for input */ 7916 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 7917 7918 /* FIXME: use matrix-type input source selection */ 7919 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 7920 /* Input mixer2 */ 7921 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7922 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7923 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 7924 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 7925 /* Input mixer3 */ 7926 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7927 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7928 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 7929 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 7930 { } 7931}; 7932 7933/* toggle speaker-output according to the hp-jack state */ 7934static void alc883_mitac_hp_automute(struct hda_codec *codec) 7935{ 7936 unsigned int present; 7937 7938 present = snd_hda_codec_read(codec, 0x15, 0, 7939 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 7940 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 7941 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 7942 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0, 7943 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 7944} 7945 7946/* auto-toggle front mic */ 7947/* 7948static void alc883_mitac_mic_automute(struct hda_codec *codec) 7949{ 7950 unsigned int present; 7951 unsigned char bits; 7952 7953 present = snd_hda_codec_read(codec, 0x18, 0, 7954 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 7955 bits = present ? HDA_AMP_MUTE : 0; 7956 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits); 7957} 7958*/ 7959 7960static void alc883_mitac_automute(struct hda_codec *codec) 7961{ 7962 alc883_mitac_hp_automute(codec); 7963 /* alc883_mitac_mic_automute(codec); */ 7964} 7965 7966static void alc883_mitac_unsol_event(struct hda_codec *codec, 7967 unsigned int res) 7968{ 7969 switch (res >> 26) { 7970 case ALC880_HP_EVENT: 7971 alc883_mitac_hp_automute(codec); 7972 break; 7973 case ALC880_MIC_EVENT: 7974 /* alc883_mitac_mic_automute(codec); */ 7975 break; 7976 } 7977} 7978 7979static struct hda_verb alc883_mitac_verbs[] = { 7980 /* HP */ 7981 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 7982 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 7983 /* Subwoofer */ 7984 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02}, 7985 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 7986 7987 /* enable unsolicited event */ 7988 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 7989 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */ 7990 7991 { } /* end */ 7992}; 7993 7994static struct hda_verb alc883_clevo_m720_verbs[] = { 7995 /* HP */ 7996 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 7997 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 7998 /* Int speaker */ 7999 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01}, 8000 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8001 8002 /* enable unsolicited event */ 8003 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 8004 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, 8005 8006 { } /* end */ 8007}; 8008 8009static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = { 8010 /* HP */ 8011 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 8012 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8013 /* Subwoofer */ 8014 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 8015 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8016 8017 /* enable unsolicited event */ 8018 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 8019 8020 { } /* end */ 8021}; 8022 8023static struct hda_verb alc883_tagra_verbs[] = { 8024 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8025 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8026 8027 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8028 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8029 8030 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ 8031 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */ 8032 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 8033 8034 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 8035 {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, 8036 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03}, 8037 {0x01, AC_VERB_SET_GPIO_DATA, 0x03}, 8038 8039 { } /* end */ 8040}; 8041 8042static struct hda_verb alc883_lenovo_101e_verbs[] = { 8043 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 8044 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN}, 8045 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN}, 8046 { } /* end */ 8047}; 8048 8049static struct hda_verb alc883_lenovo_nb0763_verbs[] = { 8050 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 8051 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8052 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 8053 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8054 { } /* end */ 8055}; 8056 8057static struct hda_verb alc888_lenovo_ms7195_verbs[] = { 8058 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8059 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8060 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 8061 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN}, 8062 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 8063 { } /* end */ 8064}; 8065 8066static struct hda_verb alc883_haier_w66_verbs[] = { 8067 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8068 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8069 8070 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8071 8072 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 8073 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8074 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 8075 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8076 { } /* end */ 8077}; 8078 8079static struct hda_verb alc888_lenovo_sky_verbs[] = { 8080 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8081 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8082 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8083 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8084 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8085 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8086 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00}, 8087 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 8088 { } /* end */ 8089}; 8090 8091static struct hda_verb alc888_6st_dell_verbs[] = { 8092 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 8093 { } 8094}; 8095 8096static void alc888_3st_hp_front_automute(struct hda_codec *codec) 8097{ 8098 unsigned int present, bits; 8099 8100 present = snd_hda_codec_read(codec, 0x1b, 0, 8101 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 8102 bits = present ? HDA_AMP_MUTE : 0; 8103 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 8104 HDA_AMP_MUTE, bits); 8105 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0, 8106 HDA_AMP_MUTE, bits); 8107 snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0, 8108 HDA_AMP_MUTE, bits); 8109} 8110 8111static void alc888_3st_hp_unsol_event(struct hda_codec *codec, 8112 unsigned int res) 8113{ 8114 switch (res >> 26) { 8115 case ALC880_HP_EVENT: 8116 alc888_3st_hp_front_automute(codec); 8117 break; 8118 } 8119} 8120 8121static struct hda_verb alc888_3st_hp_verbs[] = { 8122 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */ 8123 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */ 8124 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */ 8125 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 8126 { } /* end */ 8127}; 8128 8129/* 8130 * 2ch mode 8131 */ 8132static struct hda_verb alc888_3st_hp_2ch_init[] = { 8133 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 8134 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 8135 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 8136 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 8137 { } /* end */ 8138}; 8139 8140/* 8141 * 4ch mode 8142 */ 8143static struct hda_verb alc888_3st_hp_4ch_init[] = { 8144 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 8145 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 8146 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 8147 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 8148 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 }, 8149 { } /* end */ 8150}; 8151 8152/* 8153 * 6ch mode 8154 */ 8155static struct hda_verb alc888_3st_hp_6ch_init[] = { 8156 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 8157 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 8158 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, 8159 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 8160 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 8161 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 }, 8162 { } /* end */ 8163}; 8164 8165static struct hda_channel_mode alc888_3st_hp_modes[3] = { 8166 { 2, alc888_3st_hp_2ch_init }, 8167 { 4, alc888_3st_hp_4ch_init }, 8168 { 6, alc888_3st_hp_6ch_init }, 8169}; 8170 8171/* toggle front-jack and RCA according to the hp-jack state */ 8172static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec) 8173{ 8174 unsigned int present; 8175 8176 present = snd_hda_codec_read(codec, 0x1b, 0, 8177 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 8178 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 8179 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 8180 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 8181 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 8182} 8183 8184/* toggle RCA according to the front-jack state */ 8185static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec) 8186{ 8187 unsigned int present; 8188 8189 present = snd_hda_codec_read(codec, 0x14, 0, 8190 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 8191 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 8192 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 8193} 8194 8195static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec, 8196 unsigned int res) 8197{ 8198 if ((res >> 26) == ALC880_HP_EVENT) 8199 alc888_lenovo_ms7195_front_automute(codec); 8200 if ((res >> 26) == ALC880_FRONT_EVENT) 8201 alc888_lenovo_ms7195_rca_automute(codec); 8202} 8203 8204static struct hda_verb alc883_medion_md2_verbs[] = { 8205 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8206 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8207 8208 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8209 8210 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 8211 { } /* end */ 8212}; 8213 8214/* toggle speaker-output according to the hp-jack state */ 8215static void alc883_medion_md2_automute(struct hda_codec *codec) 8216{ 8217 unsigned int present; 8218 8219 present = snd_hda_codec_read(codec, 0x14, 0, 8220 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 8221 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 8222 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 8223} 8224 8225static void alc883_medion_md2_unsol_event(struct hda_codec *codec, 8226 unsigned int res) 8227{ 8228 if ((res >> 26) == ALC880_HP_EVENT) 8229 alc883_medion_md2_automute(codec); 8230} 8231 8232/* toggle speaker-output according to the hp-jack state */ 8233static void alc883_tagra_automute(struct hda_codec *codec) 8234{ 8235 unsigned int present; 8236 unsigned char bits; 8237 8238 present = snd_hda_codec_read(codec, 0x14, 0, 8239 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 8240 bits = present ? HDA_AMP_MUTE : 0; 8241 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0, 8242 HDA_AMP_MUTE, bits); 8243 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA, 8244 present ? 1 : 3); 8245} 8246 8247static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res) 8248{ 8249 if ((res >> 26) == ALC880_HP_EVENT) 8250 alc883_tagra_automute(codec); 8251} 8252 8253/* toggle speaker-output according to the hp-jack state */ 8254static void alc883_clevo_m720_hp_automute(struct hda_codec *codec) 8255{ 8256 unsigned int present; 8257 unsigned char bits; 8258 8259 present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0) 8260 & AC_PINSENSE_PRESENCE; 8261 bits = present ? HDA_AMP_MUTE : 0; 8262 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 8263 HDA_AMP_MUTE, bits); 8264} 8265 8266static void alc883_clevo_m720_mic_automute(struct hda_codec *codec) 8267{ 8268 unsigned int present; 8269 8270 present = snd_hda_codec_read(codec, 0x18, 0, 8271 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 8272 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, 8273 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 8274} 8275 8276static void alc883_clevo_m720_automute(struct hda_codec *codec) 8277{ 8278 alc883_clevo_m720_hp_automute(codec); 8279 alc883_clevo_m720_mic_automute(codec); 8280} 8281 8282static void alc883_clevo_m720_unsol_event(struct hda_codec *codec, 8283 unsigned int res) 8284{ 8285 switch (res >> 26) { 8286 case ALC880_HP_EVENT: 8287 alc883_clevo_m720_hp_automute(codec); 8288 break; 8289 case ALC880_MIC_EVENT: 8290 alc883_clevo_m720_mic_automute(codec); 8291 break; 8292 } 8293} 8294 8295/* toggle speaker-output according to the hp-jack state */ 8296static void alc883_2ch_fujitsu_pi2515_automute(struct hda_codec *codec) 8297{ 8298 unsigned int present; 8299 unsigned char bits; 8300 8301 present = snd_hda_codec_read(codec, 0x14, 0, AC_VERB_GET_PIN_SENSE, 0) 8302 & AC_PINSENSE_PRESENCE; 8303 bits = present ? HDA_AMP_MUTE : 0; 8304 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 8305 HDA_AMP_MUTE, bits); 8306} 8307 8308static void alc883_2ch_fujitsu_pi2515_unsol_event(struct hda_codec *codec, 8309 unsigned int res) 8310{ 8311 if ((res >> 26) == ALC880_HP_EVENT) 8312 alc883_2ch_fujitsu_pi2515_automute(codec); 8313} 8314 8315static void alc883_haier_w66_automute(struct hda_codec *codec) 8316{ 8317 unsigned int present; 8318 unsigned char bits; 8319 8320 present = snd_hda_codec_read(codec, 0x1b, 0, 8321 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 8322 bits = present ? 0x80 : 0; 8323 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 8324 0x80, bits); 8325} 8326 8327static void alc883_haier_w66_unsol_event(struct hda_codec *codec, 8328 unsigned int res) 8329{ 8330 if ((res >> 26) == ALC880_HP_EVENT) 8331 alc883_haier_w66_automute(codec); 8332} 8333 8334static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec) 8335{ 8336 unsigned int present; 8337 unsigned char bits; 8338 8339 present = snd_hda_codec_read(codec, 0x14, 0, 8340 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 8341 bits = present ? HDA_AMP_MUTE : 0; 8342 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 8343 HDA_AMP_MUTE, bits); 8344} 8345 8346static void alc883_lenovo_101e_all_automute(struct hda_codec *codec) 8347{ 8348 unsigned int present; 8349 unsigned char bits; 8350 8351 present = snd_hda_codec_read(codec, 0x1b, 0, 8352 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 8353 bits = present ? HDA_AMP_MUTE : 0; 8354 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 8355 HDA_AMP_MUTE, bits); 8356 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 8357 HDA_AMP_MUTE, bits); 8358} 8359 8360static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec, 8361 unsigned int res) 8362{ 8363 if ((res >> 26) == ALC880_HP_EVENT) 8364 alc883_lenovo_101e_all_automute(codec); 8365 if ((res >> 26) == ALC880_FRONT_EVENT) 8366 alc883_lenovo_101e_ispeaker_automute(codec); 8367} 8368 8369/* toggle speaker-output according to the hp-jack state */ 8370static void alc883_acer_aspire_automute(struct hda_codec *codec) 8371{ 8372 unsigned int present; 8373 8374 present = snd_hda_codec_read(codec, 0x14, 0, 8375 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 8376 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 8377 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 8378 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0, 8379 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 8380} 8381 8382static void alc883_acer_aspire_unsol_event(struct hda_codec *codec, 8383 unsigned int res) 8384{ 8385 if ((res >> 26) == ALC880_HP_EVENT) 8386 alc883_acer_aspire_automute(codec); 8387} 8388 8389static struct hda_verb alc883_acer_eapd_verbs[] = { 8390 /* HP Pin: output 0 (0x0c) */ 8391 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8392 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8393 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 8394 /* Front Pin: output 0 (0x0c) */ 8395 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8396 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 8397 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8398 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, 8399 /* eanable EAPD on medion laptop */ 8400 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 8401 {0x20, AC_VERB_SET_PROC_COEF, 0x3050}, 8402 /* enable unsolicited event */ 8403 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 8404 { } 8405}; 8406 8407static void alc888_6st_dell_front_automute(struct hda_codec *codec) 8408{ 8409 unsigned int present; 8410 8411 present = snd_hda_codec_read(codec, 0x1b, 0, 8412 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 8413 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 8414 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 8415 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 8416 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 8417 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0, 8418 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 8419 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0, 8420 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 8421} 8422 8423static void alc888_6st_dell_unsol_event(struct hda_codec *codec, 8424 unsigned int res) 8425{ 8426 switch (res >> 26) { 8427 case ALC880_HP_EVENT: 8428 /* printk(KERN_DEBUG "hp_event\n"); */ 8429 alc888_6st_dell_front_automute(codec); 8430 break; 8431 } 8432} 8433 8434static void alc888_lenovo_sky_front_automute(struct hda_codec *codec) 8435{ 8436 unsigned int mute; 8437 unsigned int present; 8438 8439 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0); 8440 present = snd_hda_codec_read(codec, 0x1b, 0, 8441 AC_VERB_GET_PIN_SENSE, 0); 8442 present = (present & 0x80000000) != 0; 8443 if (present) { 8444 /* mute internal speaker */ 8445 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 8446 HDA_AMP_MUTE, HDA_AMP_MUTE); 8447 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 8448 HDA_AMP_MUTE, HDA_AMP_MUTE); 8449 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0, 8450 HDA_AMP_MUTE, HDA_AMP_MUTE); 8451 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0, 8452 HDA_AMP_MUTE, HDA_AMP_MUTE); 8453 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0, 8454 HDA_AMP_MUTE, HDA_AMP_MUTE); 8455 } else { 8456 /* unmute internal speaker if necessary */ 8457 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0); 8458 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 8459 HDA_AMP_MUTE, mute); 8460 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 8461 HDA_AMP_MUTE, mute); 8462 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0, 8463 HDA_AMP_MUTE, mute); 8464 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0, 8465 HDA_AMP_MUTE, mute); 8466 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0, 8467 HDA_AMP_MUTE, mute); 8468 } 8469} 8470 8471static void alc883_lenovo_sky_unsol_event(struct hda_codec *codec, 8472 unsigned int res) 8473{ 8474 if ((res >> 26) == ALC880_HP_EVENT) 8475 alc888_lenovo_sky_front_automute(codec); 8476} 8477 8478/* 8479 * generic initialization of ADC, input mixers and output mixers 8480 */ 8481static struct hda_verb alc883_auto_init_verbs[] = { 8482 /* 8483 * Unmute ADC0-2 and set the default input to mic-in 8484 */ 8485 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 8486 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8487 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 8488 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8489 8490 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 8491 * mixer widget 8492 * Note: PASD motherboards uses the Line In 2 as the input for 8493 * front panel mic (mic 2) 8494 */ 8495 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 8496 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8497 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8498 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 8499 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8500 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8501 8502 /* 8503 * Set up output mixers (0x0c - 0x0f) 8504 */ 8505 /* set vol=0 to output mixers */ 8506 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8507 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8508 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8509 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8510 /* set up input amps for analog loopback */ 8511 /* Amp Indices: DAC = 0, mixer = 1 */ 8512 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8513 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8514 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8515 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8516 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8517 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8518 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8519 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8520 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8521 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8522 8523 /* FIXME: use matrix-type input source selection */ 8524 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 8525 /* Input mixer1 */ 8526 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8527 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8528 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 8529 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */ 8530 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, 8531 /* Input mixer2 */ 8532 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8533 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8534 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 8535 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */ 8536 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, 8537 8538 { } 8539}; 8540 8541static struct hda_verb alc888_asus_m90v_verbs[] = { 8542 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8543 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8544 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8545 /* enable unsolicited event */ 8546 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 8547 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, 8548 { } /* end */ 8549}; 8550 8551static void alc883_nb_mic_automute(struct hda_codec *codec) 8552{ 8553 unsigned int present; 8554 8555 present = snd_hda_codec_read(codec, 0x18, 0, 8556 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 8557 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE, 8558 0x7000 | (0x00 << 8) | (present ? 0 : 0x80)); 8559 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE, 8560 0x7000 | (0x01 << 8) | (present ? 0x80 : 0)); 8561} 8562 8563static void alc883_M90V_speaker_automute(struct hda_codec *codec) 8564{ 8565 unsigned int present; 8566 unsigned char bits; 8567 8568 present = snd_hda_codec_read(codec, 0x1b, 0, 8569 AC_VERB_GET_PIN_SENSE, 0) 8570 & AC_PINSENSE_PRESENCE; 8571 bits = present ? 0 : PIN_OUT; 8572 snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 8573 bits); 8574 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 8575 bits); 8576 snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 8577 bits); 8578} 8579 8580static void alc883_mode2_unsol_event(struct hda_codec *codec, 8581 unsigned int res) 8582{ 8583 switch (res >> 26) { 8584 case ALC880_HP_EVENT: 8585 alc883_M90V_speaker_automute(codec); 8586 break; 8587 case ALC880_MIC_EVENT: 8588 alc883_nb_mic_automute(codec); 8589 break; 8590 } 8591} 8592 8593static void alc883_mode2_inithook(struct hda_codec *codec) 8594{ 8595 alc883_M90V_speaker_automute(codec); 8596 alc883_nb_mic_automute(codec); 8597} 8598 8599static struct hda_verb alc888_asus_eee1601_verbs[] = { 8600 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8601 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8602 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8603 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8604 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8605 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b}, 8606 {0x20, AC_VERB_SET_PROC_COEF, 0x0838}, 8607 /* enable unsolicited event */ 8608 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 8609 { } /* end */ 8610}; 8611 8612static void alc883_eee1601_speaker_automute(struct hda_codec *codec) 8613{ 8614 unsigned int present; 8615 unsigned char bits; 8616 8617 present = snd_hda_codec_read(codec, 0x14, 0, 8618 AC_VERB_GET_PIN_SENSE, 0) 8619 & AC_PINSENSE_PRESENCE; 8620 bits = present ? 0 : PIN_OUT; 8621 snd_hda_codec_write(codec, 0x1b, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 8622 bits); 8623} 8624 8625static void alc883_eee1601_unsol_event(struct hda_codec *codec, 8626 unsigned int res) 8627{ 8628 switch (res >> 26) { 8629 case ALC880_HP_EVENT: 8630 alc883_eee1601_speaker_automute(codec); 8631 break; 8632 } 8633} 8634 8635static void alc883_eee1601_inithook(struct hda_codec *codec) 8636{ 8637 alc883_eee1601_speaker_automute(codec); 8638} 8639 8640#ifdef CONFIG_SND_HDA_POWER_SAVE 8641#define alc883_loopbacks alc880_loopbacks 8642#endif 8643 8644/* pcm configuration: identiacal with ALC880 */ 8645#define alc883_pcm_analog_playback alc880_pcm_analog_playback 8646#define alc883_pcm_analog_capture alc880_pcm_analog_capture 8647#define alc883_pcm_analog_alt_capture alc880_pcm_analog_alt_capture 8648#define alc883_pcm_digital_playback alc880_pcm_digital_playback 8649#define alc883_pcm_digital_capture alc880_pcm_digital_capture 8650 8651/* 8652 * configuration and preset 8653 */ 8654static const char *alc883_models[ALC883_MODEL_LAST] = { 8655 [ALC883_3ST_2ch_DIG] = "3stack-dig", 8656 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig", 8657 [ALC883_3ST_6ch] = "3stack-6ch", 8658 [ALC883_6ST_DIG] = "6stack-dig", 8659 [ALC883_TARGA_DIG] = "targa-dig", 8660 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig", 8661 [ALC883_ACER] = "acer", 8662 [ALC883_ACER_ASPIRE] = "acer-aspire", 8663 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g", 8664 [ALC883_MEDION] = "medion", 8665 [ALC883_MEDION_MD2] = "medion-md2", 8666 [ALC883_LAPTOP_EAPD] = "laptop-eapd", 8667 [ALC883_LENOVO_101E_2ch] = "lenovo-101e", 8668 [ALC883_LENOVO_NB0763] = "lenovo-nb0763", 8669 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig", 8670 [ALC888_LENOVO_SKY] = "lenovo-sky", 8671 [ALC883_HAIER_W66] = "haier-w66", 8672 [ALC888_3ST_HP] = "3stack-hp", 8673 [ALC888_6ST_DELL] = "6stack-dell", 8674 [ALC883_MITAC] = "mitac", 8675 [ALC883_CLEVO_M720] = "clevo-m720", 8676 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515", 8677 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530", 8678 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel", 8679 [ALC1200_ASUS_P5Q] = "asus-p5q", 8680 [ALC883_AUTO] = "auto", 8681}; 8682 8683static struct snd_pci_quirk alc883_cfg_tbl[] = { 8684 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG), 8685 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE), 8686 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE), 8687 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE), 8688 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE), 8689 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE), 8690 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE), 8691 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G", 8692 ALC888_ACER_ASPIRE_4930G), 8693 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G", 8694 ALC888_ACER_ASPIRE_4930G), 8695 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC883_AUTO), 8696 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC883_AUTO), 8697 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G", 8698 ALC888_ACER_ASPIRE_4930G), 8699 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G", 8700 ALC888_ACER_ASPIRE_4930G), 8701 /* default Acer */ 8702 SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), 8703 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL), 8704 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG), 8705 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP), 8706 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP), 8707 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG), 8708 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP), 8709 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP), 8710 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V), 8711 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG), 8712 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG), 8713 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q), 8714 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601), 8715 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG), 8716 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG), 8717 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC), 8718 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC), 8719 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD), 8720 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL), 8721 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch), 8722 SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG), 8723 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG), 8724 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG), 8725 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG), 8726 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC883_TARGA_2ch_DIG), 8727 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG), 8728 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG), 8729 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG), 8730 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG), 8731 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG), 8732 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG), 8733 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG), 8734 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG), 8735 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG), 8736 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG), 8737 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG), 8738 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG), 8739 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG), 8740 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG), 8741 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG), 8742 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG), 8743 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG), 8744 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG), 8745 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG), 8746 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG), 8747 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720), 8748 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720), 8749 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD), 8750 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch), 8751 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION), 8752 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx", 8753 ALC883_FUJITSU_PI2515), 8754 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx", 8755 ALC888_FUJITSU_XA3530), 8756 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch), 8757 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763), 8758 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763), 8759 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763), 8760 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY), 8761 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2), 8762 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG), 8763 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG), 8764 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66), 8765 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL), 8766 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL), 8767 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC), 8768 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC883_3ST_6ch_INTEL), 8769 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch), 8770 {} 8771}; 8772 8773static hda_nid_t alc883_slave_dig_outs[] = { 8774 ALC1200_DIGOUT_NID, 0, 8775}; 8776 8777static hda_nid_t alc1200_slave_dig_outs[] = { 8778 ALC883_DIGOUT_NID, 0, 8779}; 8780 8781static struct alc_config_preset alc883_presets[] = { 8782 [ALC883_3ST_2ch_DIG] = { 8783 .mixers = { alc883_3ST_2ch_mixer }, 8784 .init_verbs = { alc883_init_verbs }, 8785 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 8786 .dac_nids = alc883_dac_nids, 8787 .dig_out_nid = ALC883_DIGOUT_NID, 8788 .dig_in_nid = ALC883_DIGIN_NID, 8789 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 8790 .channel_mode = alc883_3ST_2ch_modes, 8791 .input_mux = &alc883_capture_source, 8792 }, 8793 [ALC883_3ST_6ch_DIG] = { 8794 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, 8795 .init_verbs = { alc883_init_verbs }, 8796 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 8797 .dac_nids = alc883_dac_nids, 8798 .dig_out_nid = ALC883_DIGOUT_NID, 8799 .dig_in_nid = ALC883_DIGIN_NID, 8800 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 8801 .channel_mode = alc883_3ST_6ch_modes, 8802 .need_dac_fix = 1, 8803 .input_mux = &alc883_capture_source, 8804 }, 8805 [ALC883_3ST_6ch] = { 8806 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, 8807 .init_verbs = { alc883_init_verbs }, 8808 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 8809 .dac_nids = alc883_dac_nids, 8810 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 8811 .channel_mode = alc883_3ST_6ch_modes, 8812 .need_dac_fix = 1, 8813 .input_mux = &alc883_capture_source, 8814 }, 8815 [ALC883_3ST_6ch_INTEL] = { 8816 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer }, 8817 .init_verbs = { alc883_init_verbs }, 8818 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 8819 .dac_nids = alc883_dac_nids, 8820 .dig_out_nid = ALC883_DIGOUT_NID, 8821 .dig_in_nid = ALC883_DIGIN_NID, 8822 .slave_dig_outs = alc883_slave_dig_outs, 8823 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes), 8824 .channel_mode = alc883_3ST_6ch_intel_modes, 8825 .need_dac_fix = 1, 8826 .input_mux = &alc883_3stack_6ch_intel, 8827 }, 8828 [ALC883_6ST_DIG] = { 8829 .mixers = { alc883_base_mixer, alc883_chmode_mixer }, 8830 .init_verbs = { alc883_init_verbs }, 8831 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 8832 .dac_nids = alc883_dac_nids, 8833 .dig_out_nid = ALC883_DIGOUT_NID, 8834 .dig_in_nid = ALC883_DIGIN_NID, 8835 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), 8836 .channel_mode = alc883_sixstack_modes, 8837 .input_mux = &alc883_capture_source, 8838 }, 8839 [ALC883_TARGA_DIG] = { 8840 .mixers = { alc883_tagra_mixer, alc883_chmode_mixer }, 8841 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs}, 8842 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 8843 .dac_nids = alc883_dac_nids, 8844 .dig_out_nid = ALC883_DIGOUT_NID, 8845 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 8846 .channel_mode = alc883_3ST_6ch_modes, 8847 .need_dac_fix = 1, 8848 .input_mux = &alc883_capture_source, 8849 .unsol_event = alc883_tagra_unsol_event, 8850 .init_hook = alc883_tagra_automute, 8851 }, 8852 [ALC883_TARGA_2ch_DIG] = { 8853 .mixers = { alc883_tagra_2ch_mixer}, 8854 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs}, 8855 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 8856 .dac_nids = alc883_dac_nids, 8857 .adc_nids = alc883_adc_nids_alt, 8858 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt), 8859 .dig_out_nid = ALC883_DIGOUT_NID, 8860 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 8861 .channel_mode = alc883_3ST_2ch_modes, 8862 .input_mux = &alc883_capture_source, 8863 .unsol_event = alc883_tagra_unsol_event, 8864 .init_hook = alc883_tagra_automute, 8865 }, 8866 [ALC883_ACER] = { 8867 .mixers = { alc883_base_mixer }, 8868 /* On TravelMate laptops, GPIO 0 enables the internal speaker 8869 * and the headphone jack. Turn this on and rely on the 8870 * standard mute methods whenever the user wants to turn 8871 * these outputs off. 8872 */ 8873 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs }, 8874 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 8875 .dac_nids = alc883_dac_nids, 8876 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 8877 .channel_mode = alc883_3ST_2ch_modes, 8878 .input_mux = &alc883_capture_source, 8879 }, 8880 [ALC883_ACER_ASPIRE] = { 8881 .mixers = { alc883_acer_aspire_mixer }, 8882 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs }, 8883 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 8884 .dac_nids = alc883_dac_nids, 8885 .dig_out_nid = ALC883_DIGOUT_NID, 8886 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 8887 .channel_mode = alc883_3ST_2ch_modes, 8888 .input_mux = &alc883_capture_source, 8889 .unsol_event = alc883_acer_aspire_unsol_event, 8890 .init_hook = alc883_acer_aspire_automute, 8891 }, 8892 [ALC888_ACER_ASPIRE_4930G] = { 8893 .mixers = { alc888_base_mixer, 8894 alc883_chmode_mixer }, 8895 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs, 8896 alc888_acer_aspire_4930g_verbs }, 8897 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 8898 .dac_nids = alc883_dac_nids, 8899 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev), 8900 .adc_nids = alc883_adc_nids_rev, 8901 .capsrc_nids = alc883_capsrc_nids_rev, 8902 .dig_out_nid = ALC883_DIGOUT_NID, 8903 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 8904 .channel_mode = alc883_3ST_6ch_modes, 8905 .need_dac_fix = 1, 8906 .num_mux_defs = 8907 ARRAY_SIZE(alc888_2_capture_sources), 8908 .input_mux = alc888_2_capture_sources, 8909 .unsol_event = alc888_acer_aspire_4930g_unsol_event, 8910 .init_hook = alc888_acer_aspire_4930g_automute, 8911 }, 8912 [ALC883_MEDION] = { 8913 .mixers = { alc883_fivestack_mixer, 8914 alc883_chmode_mixer }, 8915 .init_verbs = { alc883_init_verbs, 8916 alc883_medion_eapd_verbs }, 8917 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 8918 .dac_nids = alc883_dac_nids, 8919 .adc_nids = alc883_adc_nids_alt, 8920 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt), 8921 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), 8922 .channel_mode = alc883_sixstack_modes, 8923 .input_mux = &alc883_capture_source, 8924 }, 8925 [ALC883_MEDION_MD2] = { 8926 .mixers = { alc883_medion_md2_mixer}, 8927 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs}, 8928 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 8929 .dac_nids = alc883_dac_nids, 8930 .dig_out_nid = ALC883_DIGOUT_NID, 8931 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 8932 .channel_mode = alc883_3ST_2ch_modes, 8933 .input_mux = &alc883_capture_source, 8934 .unsol_event = alc883_medion_md2_unsol_event, 8935 .init_hook = alc883_medion_md2_automute, 8936 }, 8937 [ALC883_LAPTOP_EAPD] = { 8938 .mixers = { alc883_base_mixer }, 8939 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs }, 8940 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 8941 .dac_nids = alc883_dac_nids, 8942 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 8943 .channel_mode = alc883_3ST_2ch_modes, 8944 .input_mux = &alc883_capture_source, 8945 }, 8946 [ALC883_CLEVO_M720] = { 8947 .mixers = { alc883_clevo_m720_mixer }, 8948 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs }, 8949 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 8950 .dac_nids = alc883_dac_nids, 8951 .dig_out_nid = ALC883_DIGOUT_NID, 8952 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 8953 .channel_mode = alc883_3ST_2ch_modes, 8954 .input_mux = &alc883_capture_source, 8955 .unsol_event = alc883_clevo_m720_unsol_event, 8956 .init_hook = alc883_clevo_m720_automute, 8957 }, 8958 [ALC883_LENOVO_101E_2ch] = { 8959 .mixers = { alc883_lenovo_101e_2ch_mixer}, 8960 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs}, 8961 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 8962 .dac_nids = alc883_dac_nids, 8963 .adc_nids = alc883_adc_nids_alt, 8964 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt), 8965 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 8966 .channel_mode = alc883_3ST_2ch_modes, 8967 .input_mux = &alc883_lenovo_101e_capture_source, 8968 .unsol_event = alc883_lenovo_101e_unsol_event, 8969 .init_hook = alc883_lenovo_101e_all_automute, 8970 }, 8971 [ALC883_LENOVO_NB0763] = { 8972 .mixers = { alc883_lenovo_nb0763_mixer }, 8973 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs}, 8974 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 8975 .dac_nids = alc883_dac_nids, 8976 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 8977 .channel_mode = alc883_3ST_2ch_modes, 8978 .need_dac_fix = 1, 8979 .input_mux = &alc883_lenovo_nb0763_capture_source, 8980 .unsol_event = alc883_medion_md2_unsol_event, 8981 .init_hook = alc883_medion_md2_automute, 8982 }, 8983 [ALC888_LENOVO_MS7195_DIG] = { 8984 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, 8985 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs}, 8986 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 8987 .dac_nids = alc883_dac_nids, 8988 .dig_out_nid = ALC883_DIGOUT_NID, 8989 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 8990 .channel_mode = alc883_3ST_6ch_modes, 8991 .need_dac_fix = 1, 8992 .input_mux = &alc883_capture_source, 8993 .unsol_event = alc883_lenovo_ms7195_unsol_event, 8994 .init_hook = alc888_lenovo_ms7195_front_automute, 8995 }, 8996 [ALC883_HAIER_W66] = { 8997 .mixers = { alc883_tagra_2ch_mixer}, 8998 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs}, 8999 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 9000 .dac_nids = alc883_dac_nids, 9001 .dig_out_nid = ALC883_DIGOUT_NID, 9002 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 9003 .channel_mode = alc883_3ST_2ch_modes, 9004 .input_mux = &alc883_capture_source, 9005 .unsol_event = alc883_haier_w66_unsol_event, 9006 .init_hook = alc883_haier_w66_automute, 9007 }, 9008 [ALC888_3ST_HP] = { 9009 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, 9010 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs }, 9011 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 9012 .dac_nids = alc883_dac_nids, 9013 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes), 9014 .channel_mode = alc888_3st_hp_modes, 9015 .need_dac_fix = 1, 9016 .input_mux = &alc883_capture_source, 9017 .unsol_event = alc888_3st_hp_unsol_event, 9018 .init_hook = alc888_3st_hp_front_automute, 9019 }, 9020 [ALC888_6ST_DELL] = { 9021 .mixers = { alc883_base_mixer, alc883_chmode_mixer }, 9022 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs }, 9023 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 9024 .dac_nids = alc883_dac_nids, 9025 .dig_out_nid = ALC883_DIGOUT_NID, 9026 .dig_in_nid = ALC883_DIGIN_NID, 9027 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), 9028 .channel_mode = alc883_sixstack_modes, 9029 .input_mux = &alc883_capture_source, 9030 .unsol_event = alc888_6st_dell_unsol_event, 9031 .init_hook = alc888_6st_dell_front_automute, 9032 }, 9033 [ALC883_MITAC] = { 9034 .mixers = { alc883_mitac_mixer }, 9035 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs }, 9036 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 9037 .dac_nids = alc883_dac_nids, 9038 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 9039 .channel_mode = alc883_3ST_2ch_modes, 9040 .input_mux = &alc883_capture_source, 9041 .unsol_event = alc883_mitac_unsol_event, 9042 .init_hook = alc883_mitac_automute, 9043 }, 9044 [ALC883_FUJITSU_PI2515] = { 9045 .mixers = { alc883_2ch_fujitsu_pi2515_mixer }, 9046 .init_verbs = { alc883_init_verbs, 9047 alc883_2ch_fujitsu_pi2515_verbs}, 9048 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 9049 .dac_nids = alc883_dac_nids, 9050 .dig_out_nid = ALC883_DIGOUT_NID, 9051 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 9052 .channel_mode = alc883_3ST_2ch_modes, 9053 .input_mux = &alc883_fujitsu_pi2515_capture_source, 9054 .unsol_event = alc883_2ch_fujitsu_pi2515_unsol_event, 9055 .init_hook = alc883_2ch_fujitsu_pi2515_automute, 9056 }, 9057 [ALC888_FUJITSU_XA3530] = { 9058 .mixers = { alc888_base_mixer, alc883_chmode_mixer }, 9059 .init_verbs = { alc883_init_verbs, 9060 alc888_fujitsu_xa3530_verbs }, 9061 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 9062 .dac_nids = alc883_dac_nids, 9063 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev), 9064 .adc_nids = alc883_adc_nids_rev, 9065 .capsrc_nids = alc883_capsrc_nids_rev, 9066 .dig_out_nid = ALC883_DIGOUT_NID, 9067 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes), 9068 .channel_mode = alc888_4ST_8ch_intel_modes, 9069 .num_mux_defs = 9070 ARRAY_SIZE(alc888_2_capture_sources), 9071 .input_mux = alc888_2_capture_sources, 9072 .unsol_event = alc888_fujitsu_xa3530_unsol_event, 9073 .init_hook = alc888_fujitsu_xa3530_automute, 9074 }, 9075 [ALC888_LENOVO_SKY] = { 9076 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer }, 9077 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs}, 9078 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 9079 .dac_nids = alc883_dac_nids, 9080 .dig_out_nid = ALC883_DIGOUT_NID, 9081 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), 9082 .channel_mode = alc883_sixstack_modes, 9083 .need_dac_fix = 1, 9084 .input_mux = &alc883_lenovo_sky_capture_source, 9085 .unsol_event = alc883_lenovo_sky_unsol_event, 9086 .init_hook = alc888_lenovo_sky_front_automute, 9087 }, 9088 [ALC888_ASUS_M90V] = { 9089 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, 9090 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs }, 9091 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 9092 .dac_nids = alc883_dac_nids, 9093 .dig_out_nid = ALC883_DIGOUT_NID, 9094 .dig_in_nid = ALC883_DIGIN_NID, 9095 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 9096 .channel_mode = alc883_3ST_6ch_modes, 9097 .need_dac_fix = 1, 9098 .input_mux = &alc883_fujitsu_pi2515_capture_source, 9099 .unsol_event = alc883_mode2_unsol_event, 9100 .init_hook = alc883_mode2_inithook, 9101 }, 9102 [ALC888_ASUS_EEE1601] = { 9103 .mixers = { alc883_asus_eee1601_mixer }, 9104 .cap_mixer = alc883_asus_eee1601_cap_mixer, 9105 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs }, 9106 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 9107 .dac_nids = alc883_dac_nids, 9108 .dig_out_nid = ALC883_DIGOUT_NID, 9109 .dig_in_nid = ALC883_DIGIN_NID, 9110 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 9111 .channel_mode = alc883_3ST_2ch_modes, 9112 .need_dac_fix = 1, 9113 .input_mux = &alc883_asus_eee1601_capture_source, 9114 .unsol_event = alc883_eee1601_unsol_event, 9115 .init_hook = alc883_eee1601_inithook, 9116 }, 9117 [ALC1200_ASUS_P5Q] = { 9118 .mixers = { alc883_base_mixer, alc883_chmode_mixer }, 9119 .init_verbs = { alc883_init_verbs }, 9120 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 9121 .dac_nids = alc883_dac_nids, 9122 .dig_out_nid = ALC1200_DIGOUT_NID, 9123 .dig_in_nid = ALC883_DIGIN_NID, 9124 .slave_dig_outs = alc1200_slave_dig_outs, 9125 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), 9126 .channel_mode = alc883_sixstack_modes, 9127 .input_mux = &alc883_capture_source, 9128 }, 9129}; 9130 9131 9132/* 9133 * BIOS auto configuration 9134 */ 9135static void alc883_auto_set_output_and_unmute(struct hda_codec *codec, 9136 hda_nid_t nid, int pin_type, 9137 int dac_idx) 9138{ 9139 /* set as output */ 9140 struct alc_spec *spec = codec->spec; 9141 int idx; 9142 9143 alc_set_pin_output(codec, nid, pin_type); 9144 if (spec->multiout.dac_nids[dac_idx] == 0x25) 9145 idx = 4; 9146 else 9147 idx = spec->multiout.dac_nids[dac_idx] - 2; 9148 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx); 9149 9150} 9151 9152static void alc883_auto_init_multi_out(struct hda_codec *codec) 9153{ 9154 struct alc_spec *spec = codec->spec; 9155 int i; 9156 9157 alc_subsystem_id(codec, 0x15, 0x1b, 0x14); 9158 for (i = 0; i <= HDA_SIDE; i++) { 9159 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 9160 int pin_type = get_pin_type(spec->autocfg.line_out_type); 9161 if (nid) 9162 alc883_auto_set_output_and_unmute(codec, nid, pin_type, 9163 i); 9164 } 9165} 9166 9167static void alc883_auto_init_hp_out(struct hda_codec *codec) 9168{ 9169 struct alc_spec *spec = codec->spec; 9170 hda_nid_t pin; 9171 9172 pin = spec->autocfg.hp_pins[0]; 9173 if (pin) /* connect to front */ 9174 /* use dac 0 */ 9175 alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); 9176 pin = spec->autocfg.speaker_pins[0]; 9177 if (pin) 9178 alc883_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0); 9179} 9180 9181#define alc883_is_input_pin(nid) alc880_is_input_pin(nid) 9182#define ALC883_PIN_CD_NID ALC880_PIN_CD_NID 9183 9184static void alc883_auto_init_analog_input(struct hda_codec *codec) 9185{ 9186 struct alc_spec *spec = codec->spec; 9187 int i; 9188 9189 for (i = 0; i < AUTO_PIN_LAST; i++) { 9190 hda_nid_t nid = spec->autocfg.input_pins[i]; 9191 if (alc883_is_input_pin(nid)) { 9192 alc_set_input_pin(codec, nid, i); 9193 if (nid != ALC883_PIN_CD_NID && 9194 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)) 9195 snd_hda_codec_write(codec, nid, 0, 9196 AC_VERB_SET_AMP_GAIN_MUTE, 9197 AMP_OUT_MUTE); 9198 } 9199 } 9200} 9201 9202#define alc883_auto_init_input_src alc882_auto_init_input_src 9203 9204/* almost identical with ALC880 parser... */ 9205static int alc883_parse_auto_config(struct hda_codec *codec) 9206{ 9207 struct alc_spec *spec = codec->spec; 9208 int err = alc880_parse_auto_config(codec); 9209 struct auto_pin_cfg *cfg = &spec->autocfg; 9210 int i; 9211 9212 if (err < 0) 9213 return err; 9214 else if (!err) 9215 return 0; /* no config found */ 9216 9217 err = alc_auto_add_mic_boost(codec); 9218 if (err < 0) 9219 return err; 9220 9221 /* hack - override the init verbs */ 9222 spec->init_verbs[0] = alc883_auto_init_verbs; 9223 9224 /* setup input_mux for ALC889 */ 9225 if (codec->vendor_id == 0x10ec0889) { 9226 /* digital-mic input pin is excluded in alc880_auto_create..() 9227 * because it's under 0x18 9228 */ 9229 if (cfg->input_pins[AUTO_PIN_MIC] == 0x12 || 9230 cfg->input_pins[AUTO_PIN_FRONT_MIC] == 0x12) { 9231 struct hda_input_mux *imux = &spec->private_imux[0]; 9232 for (i = 1; i < 3; i++) 9233 memcpy(&spec->private_imux[i], 9234 &spec->private_imux[0], 9235 sizeof(spec->private_imux[0])); 9236 imux->items[imux->num_items].label = "Int DMic"; 9237 imux->items[imux->num_items].index = 0x0b; 9238 imux->num_items++; 9239 spec->num_mux_defs = 3; 9240 spec->input_mux = spec->private_imux; 9241 } 9242 } 9243 9244 return 1; /* config found */ 9245} 9246 9247/* additional initialization for auto-configuration model */ 9248static void alc883_auto_init(struct hda_codec *codec) 9249{ 9250 struct alc_spec *spec = codec->spec; 9251 alc883_auto_init_multi_out(codec); 9252 alc883_auto_init_hp_out(codec); 9253 alc883_auto_init_analog_input(codec); 9254 alc883_auto_init_input_src(codec); 9255 if (spec->unsol_event) 9256 alc_inithook(codec); 9257} 9258 9259static int patch_alc883(struct hda_codec *codec) 9260{ 9261 struct alc_spec *spec; 9262 int err, board_config; 9263 9264 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 9265 if (spec == NULL) 9266 return -ENOMEM; 9267 9268 codec->spec = spec; 9269 9270 alc_fix_pll_init(codec, 0x20, 0x0a, 10); 9271 9272 board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST, 9273 alc883_models, 9274 alc883_cfg_tbl); 9275 if (board_config < 0) { 9276 printk(KERN_INFO "hda_codec: Unknown model for ALC883, " 9277 "trying auto-probe from BIOS...\n"); 9278 board_config = ALC883_AUTO; 9279 } 9280 9281 if (board_config == ALC883_AUTO) { 9282 /* automatic parse from the BIOS config */ 9283 err = alc883_parse_auto_config(codec); 9284 if (err < 0) { 9285 alc_free(codec); 9286 return err; 9287 } else if (!err) { 9288 printk(KERN_INFO 9289 "hda_codec: Cannot set up configuration " 9290 "from BIOS. Using base mode...\n"); 9291 board_config = ALC883_3ST_2ch_DIG; 9292 } 9293 } 9294 9295 err = snd_hda_attach_beep_device(codec, 0x1); 9296 if (err < 0) { 9297 alc_free(codec); 9298 return err; 9299 } 9300 9301 if (board_config != ALC883_AUTO) 9302 setup_preset(spec, &alc883_presets[board_config]); 9303 9304 switch (codec->vendor_id) { 9305 case 0x10ec0888: 9306 if (codec->revision_id == 0x100101) { 9307 spec->stream_name_analog = "ALC1200 Analog"; 9308 spec->stream_name_digital = "ALC1200 Digital"; 9309 } else { 9310 spec->stream_name_analog = "ALC888 Analog"; 9311 spec->stream_name_digital = "ALC888 Digital"; 9312 } 9313 if (!spec->num_adc_nids) { 9314 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids); 9315 spec->adc_nids = alc883_adc_nids; 9316 } 9317 if (!spec->capsrc_nids) 9318 spec->capsrc_nids = alc883_capsrc_nids; 9319 spec->capture_style = CAPT_MIX; /* matrix-style capture */ 9320 break; 9321 case 0x10ec0889: 9322 spec->stream_name_analog = "ALC889 Analog"; 9323 spec->stream_name_digital = "ALC889 Digital"; 9324 if (!spec->num_adc_nids) { 9325 spec->num_adc_nids = ARRAY_SIZE(alc889_adc_nids); 9326 spec->adc_nids = alc889_adc_nids; 9327 } 9328 if (!spec->capsrc_nids) 9329 spec->capsrc_nids = alc889_capsrc_nids; 9330 spec->capture_style = CAPT_1MUX_MIX; /* 1mux/Nmix-style 9331 capture */ 9332 break; 9333 default: 9334 spec->stream_name_analog = "ALC883 Analog"; 9335 spec->stream_name_digital = "ALC883 Digital"; 9336 if (!spec->num_adc_nids) { 9337 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids); 9338 spec->adc_nids = alc883_adc_nids; 9339 } 9340 if (!spec->capsrc_nids) 9341 spec->capsrc_nids = alc883_capsrc_nids; 9342 spec->capture_style = CAPT_MIX; /* matrix-style capture */ 9343 break; 9344 } 9345 9346 spec->stream_analog_playback = &alc883_pcm_analog_playback; 9347 spec->stream_analog_capture = &alc883_pcm_analog_capture; 9348 spec->stream_analog_alt_capture = &alc883_pcm_analog_alt_capture; 9349 9350 spec->stream_digital_playback = &alc883_pcm_digital_playback; 9351 spec->stream_digital_capture = &alc883_pcm_digital_capture; 9352 9353 if (!spec->cap_mixer) 9354 set_capture_mixer(spec); 9355 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 9356 9357 spec->vmaster_nid = 0x0c; 9358 9359 codec->patch_ops = alc_patch_ops; 9360 if (board_config == ALC883_AUTO) 9361 spec->init_hook = alc883_auto_init; 9362 9363#ifdef CONFIG_SND_HDA_POWER_SAVE 9364 if (!spec->loopback.amplist) 9365 spec->loopback.amplist = alc883_loopbacks; 9366#endif 9367 codec->proc_widget_hook = print_realtek_coef; 9368 9369 return 0; 9370} 9371 9372/* 9373 * ALC262 support 9374 */ 9375 9376#define ALC262_DIGOUT_NID ALC880_DIGOUT_NID 9377#define ALC262_DIGIN_NID ALC880_DIGIN_NID 9378 9379#define alc262_dac_nids alc260_dac_nids 9380#define alc262_adc_nids alc882_adc_nids 9381#define alc262_adc_nids_alt alc882_adc_nids_alt 9382#define alc262_capsrc_nids alc882_capsrc_nids 9383#define alc262_capsrc_nids_alt alc882_capsrc_nids_alt 9384 9385#define alc262_modes alc260_modes 9386#define alc262_capture_source alc882_capture_source 9387 9388static hda_nid_t alc262_dmic_adc_nids[1] = { 9389 /* ADC0 */ 9390 0x09 9391}; 9392 9393static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 }; 9394 9395static struct snd_kcontrol_new alc262_base_mixer[] = { 9396 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9397 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 9398 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 9399 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 9400 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 9401 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 9402 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9403 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9404 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 9405 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 9406 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 9407 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 9408 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT), 9409 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 9410 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 9411 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT), 9412 { } /* end */ 9413}; 9414 9415static struct snd_kcontrol_new alc262_hippo1_mixer[] = { 9416 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9417 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 9418 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 9419 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 9420 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 9421 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 9422 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9423 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9424 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 9425 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 9426 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 9427 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 9428 /*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/ 9429 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 9430 { } /* end */ 9431}; 9432 9433/* update HP, line and mono-out pins according to the master switch */ 9434static void alc262_hp_master_update(struct hda_codec *codec) 9435{ 9436 struct alc_spec *spec = codec->spec; 9437 int val = spec->master_sw; 9438 9439 /* HP & line-out */ 9440 snd_hda_codec_write_cache(codec, 0x1b, 0, 9441 AC_VERB_SET_PIN_WIDGET_CONTROL, 9442 val ? PIN_HP : 0); 9443 snd_hda_codec_write_cache(codec, 0x15, 0, 9444 AC_VERB_SET_PIN_WIDGET_CONTROL, 9445 val ? PIN_HP : 0); 9446 /* mono (speaker) depending on the HP jack sense */ 9447 val = val && !spec->jack_present; 9448 snd_hda_codec_write_cache(codec, 0x16, 0, 9449 AC_VERB_SET_PIN_WIDGET_CONTROL, 9450 val ? PIN_OUT : 0); 9451} 9452 9453static void alc262_hp_bpc_automute(struct hda_codec *codec) 9454{ 9455 struct alc_spec *spec = codec->spec; 9456 unsigned int presence; 9457 presence = snd_hda_codec_read(codec, 0x1b, 0, 9458 AC_VERB_GET_PIN_SENSE, 0); 9459 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE); 9460 alc262_hp_master_update(codec); 9461} 9462 9463static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res) 9464{ 9465 if ((res >> 26) != ALC880_HP_EVENT) 9466 return; 9467 alc262_hp_bpc_automute(codec); 9468} 9469 9470static void alc262_hp_wildwest_automute(struct hda_codec *codec) 9471{ 9472 struct alc_spec *spec = codec->spec; 9473 unsigned int presence; 9474 presence = snd_hda_codec_read(codec, 0x15, 0, 9475 AC_VERB_GET_PIN_SENSE, 0); 9476 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE); 9477 alc262_hp_master_update(codec); 9478} 9479 9480static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec, 9481 unsigned int res) 9482{ 9483 if ((res >> 26) != ALC880_HP_EVENT) 9484 return; 9485 alc262_hp_wildwest_automute(codec); 9486} 9487 9488static int alc262_hp_master_sw_get(struct snd_kcontrol *kcontrol, 9489 struct snd_ctl_elem_value *ucontrol) 9490{ 9491 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 9492 struct alc_spec *spec = codec->spec; 9493 *ucontrol->value.integer.value = spec->master_sw; 9494 return 0; 9495} 9496 9497static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol, 9498 struct snd_ctl_elem_value *ucontrol) 9499{ 9500 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 9501 struct alc_spec *spec = codec->spec; 9502 int val = !!*ucontrol->value.integer.value; 9503 9504 if (val == spec->master_sw) 9505 return 0; 9506 spec->master_sw = val; 9507 alc262_hp_master_update(codec); 9508 return 1; 9509} 9510 9511static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = { 9512 { 9513 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 9514 .name = "Master Playback Switch", 9515 .info = snd_ctl_boolean_mono_info, 9516 .get = alc262_hp_master_sw_get, 9517 .put = alc262_hp_master_sw_put, 9518 }, 9519 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9520 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT), 9521 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 9522 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0, 9523 HDA_OUTPUT), 9524 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0, 9525 HDA_OUTPUT), 9526 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9527 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9528 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 9529 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 9530 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 9531 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 9532 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 9533 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 9534 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 9535 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 9536 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT), 9537 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT), 9538 { } /* end */ 9539}; 9540 9541static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = { 9542 { 9543 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 9544 .name = "Master Playback Switch", 9545 .info = snd_ctl_boolean_mono_info, 9546 .get = alc262_hp_master_sw_get, 9547 .put = alc262_hp_master_sw_put, 9548 }, 9549 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9550 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 9551 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 9552 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 9553 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0, 9554 HDA_OUTPUT), 9555 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0, 9556 HDA_OUTPUT), 9557 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT), 9558 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT), 9559 HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT), 9560 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT), 9561 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT), 9562 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 9563 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 9564 { } /* end */ 9565}; 9566 9567static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = { 9568 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9569 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9570 HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT), 9571 { } /* end */ 9572}; 9573 9574/* mute/unmute internal speaker according to the hp jack and mute state */ 9575static void alc262_hp_t5735_automute(struct hda_codec *codec, int force) 9576{ 9577 struct alc_spec *spec = codec->spec; 9578 9579 if (force || !spec->sense_updated) { 9580 unsigned int present; 9581 present = snd_hda_codec_read(codec, 0x15, 0, 9582 AC_VERB_GET_PIN_SENSE, 0); 9583 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0; 9584 spec->sense_updated = 1; 9585 } 9586 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0, HDA_AMP_MUTE, 9587 spec->jack_present ? HDA_AMP_MUTE : 0); 9588} 9589 9590static void alc262_hp_t5735_unsol_event(struct hda_codec *codec, 9591 unsigned int res) 9592{ 9593 if ((res >> 26) != ALC880_HP_EVENT) 9594 return; 9595 alc262_hp_t5735_automute(codec, 1); 9596} 9597 9598static void alc262_hp_t5735_init_hook(struct hda_codec *codec) 9599{ 9600 alc262_hp_t5735_automute(codec, 1); 9601} 9602 9603static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = { 9604 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9605 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 9606 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 9607 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 9608 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9609 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9610 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 9611 { } /* end */ 9612}; 9613 9614static struct hda_verb alc262_hp_t5735_verbs[] = { 9615 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9616 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9617 9618 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9619 { } 9620}; 9621 9622static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = { 9623 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9624 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 9625 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT), 9626 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT), 9627 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT), 9628 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT), 9629 { } /* end */ 9630}; 9631 9632static struct hda_verb alc262_hp_rp5700_verbs[] = { 9633 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9634 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9635 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9636 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9637 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 9638 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 9639 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 9640 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 9641 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))}, 9642 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))}, 9643 {} 9644}; 9645 9646static struct hda_input_mux alc262_hp_rp5700_capture_source = { 9647 .num_items = 1, 9648 .items = { 9649 { "Line", 0x1 }, 9650 }, 9651}; 9652 9653/* bind hp and internal speaker mute (with plug check) */ 9654static int alc262_sony_master_sw_put(struct snd_kcontrol *kcontrol, 9655 struct snd_ctl_elem_value *ucontrol) 9656{ 9657 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 9658 long *valp = ucontrol->value.integer.value; 9659 int change; 9660 9661 /* change hp mute */ 9662 change = snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0, 9663 HDA_AMP_MUTE, 9664 valp[0] ? 0 : HDA_AMP_MUTE); 9665 change |= snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0, 9666 HDA_AMP_MUTE, 9667 valp[1] ? 0 : HDA_AMP_MUTE); 9668 if (change) { 9669 /* change speaker according to HP jack state */ 9670 struct alc_spec *spec = codec->spec; 9671 unsigned int mute; 9672 if (spec->jack_present) 9673 mute = HDA_AMP_MUTE; 9674 else 9675 mute = snd_hda_codec_amp_read(codec, 0x15, 0, 9676 HDA_OUTPUT, 0); 9677 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 9678 HDA_AMP_MUTE, mute); 9679 } 9680 return change; 9681} 9682 9683static struct snd_kcontrol_new alc262_sony_mixer[] = { 9684 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9685 { 9686 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 9687 .name = "Master Playback Switch", 9688 .info = snd_hda_mixer_amp_switch_info, 9689 .get = snd_hda_mixer_amp_switch_get, 9690 .put = alc262_sony_master_sw_put, 9691 .private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT), 9692 }, 9693 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9694 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9695 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 9696 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 9697 { } /* end */ 9698}; 9699 9700static struct snd_kcontrol_new alc262_benq_t31_mixer[] = { 9701 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9702 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 9703 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 9704 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9705 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9706 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 9707 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 9708 { } /* end */ 9709}; 9710 9711static struct snd_kcontrol_new alc262_tyan_mixer[] = { 9712 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9713 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT), 9714 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT), 9715 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT), 9716 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 9717 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 9718 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9719 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9720 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 9721 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 9722 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 9723 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 9724 { } /* end */ 9725}; 9726 9727static struct hda_verb alc262_tyan_verbs[] = { 9728 /* Headphone automute */ 9729 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 9730 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9731 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9732 9733 /* P11 AUX_IN, white 4-pin connector */ 9734 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 9735 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1}, 9736 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93}, 9737 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19}, 9738 9739 {} 9740}; 9741 9742/* unsolicited event for HP jack sensing */ 9743static void alc262_tyan_automute(struct hda_codec *codec) 9744{ 9745 unsigned int mute; 9746 unsigned int present; 9747 9748 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0); 9749 present = snd_hda_codec_read(codec, 0x1b, 0, 9750 AC_VERB_GET_PIN_SENSE, 0); 9751 present = (present & 0x80000000) != 0; 9752 if (present) { 9753 /* mute line output on ATX panel */ 9754 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 9755 HDA_AMP_MUTE, HDA_AMP_MUTE); 9756 } else { 9757 /* unmute line output if necessary */ 9758 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0); 9759 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 9760 HDA_AMP_MUTE, mute); 9761 } 9762} 9763 9764static void alc262_tyan_unsol_event(struct hda_codec *codec, 9765 unsigned int res) 9766{ 9767 if ((res >> 26) != ALC880_HP_EVENT) 9768 return; 9769 alc262_tyan_automute(codec); 9770} 9771 9772#define alc262_capture_mixer alc882_capture_mixer 9773#define alc262_capture_alt_mixer alc882_capture_alt_mixer 9774 9775/* 9776 * generic initialization of ADC, input mixers and output mixers 9777 */ 9778static struct hda_verb alc262_init_verbs[] = { 9779 /* 9780 * Unmute ADC0-2 and set the default input to mic-in 9781 */ 9782 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 9783 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9784 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 9785 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9786 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 9787 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9788 9789 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 9790 * mixer widget 9791 * Note: PASD motherboards uses the Line In 2 as the input for 9792 * front panel mic (mic 2) 9793 */ 9794 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 9795 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 9796 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 9797 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 9798 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 9799 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 9800 9801 /* 9802 * Set up output mixers (0x0c - 0x0e) 9803 */ 9804 /* set vol=0 to output mixers */ 9805 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 9806 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 9807 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 9808 /* set up input amps for analog loopback */ 9809 /* Amp Indices: DAC = 0, mixer = 1 */ 9810 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9811 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9812 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9813 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9814 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9815 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9816 9817 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 9818 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 9819 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 9820 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 9821 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 9822 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 9823 9824 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 9825 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 9826 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 9827 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 9828 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 9829 9830 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 9831 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 9832 9833 /* FIXME: use matrix-type input source selection */ 9834 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 9835 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 9836 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 9837 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 9838 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 9839 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 9840 /* Input mixer2 */ 9841 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 9842 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 9843 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 9844 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 9845 /* Input mixer3 */ 9846 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 9847 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 9848 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 9849 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 9850 9851 { } 9852}; 9853 9854static struct hda_verb alc262_eapd_verbs[] = { 9855 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 9856 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, 9857 { } 9858}; 9859 9860static struct hda_verb alc262_hippo_unsol_verbs[] = { 9861 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 9862 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9863 {} 9864}; 9865 9866static struct hda_verb alc262_hippo1_unsol_verbs[] = { 9867 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 9868 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 9869 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 9870 9871 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 9872 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9873 {} 9874}; 9875 9876static struct hda_verb alc262_sony_unsol_verbs[] = { 9877 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 9878 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9879 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic 9880 9881 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 9882 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9883 {} 9884}; 9885 9886static struct hda_input_mux alc262_dmic_capture_source = { 9887 .num_items = 2, 9888 .items = { 9889 { "Int DMic", 0x9 }, 9890 { "Mic", 0x0 }, 9891 }, 9892}; 9893 9894static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = { 9895 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9896 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 9897 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 9898 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9899 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9900 { } /* end */ 9901}; 9902 9903static struct hda_verb alc262_toshiba_s06_verbs[] = { 9904 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 9905 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9906 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9907 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9908 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09}, 9909 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 9910 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 9911 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 9912 {} 9913}; 9914 9915static void alc262_dmic_automute(struct hda_codec *codec) 9916{ 9917 unsigned int present; 9918 9919 present = snd_hda_codec_read(codec, 0x18, 0, 9920 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 9921 snd_hda_codec_write(codec, 0x22, 0, 9922 AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x09); 9923} 9924 9925/* toggle speaker-output according to the hp-jack state */ 9926static void alc262_toshiba_s06_speaker_automute(struct hda_codec *codec) 9927{ 9928 unsigned int present; 9929 unsigned char bits; 9930 9931 present = snd_hda_codec_read(codec, 0x15, 0, 9932 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 9933 bits = present ? 0 : PIN_OUT; 9934 snd_hda_codec_write(codec, 0x14, 0, 9935 AC_VERB_SET_PIN_WIDGET_CONTROL, bits); 9936} 9937 9938 9939 9940/* unsolicited event for HP jack sensing */ 9941static void alc262_toshiba_s06_unsol_event(struct hda_codec *codec, 9942 unsigned int res) 9943{ 9944 if ((res >> 26) == ALC880_HP_EVENT) 9945 alc262_toshiba_s06_speaker_automute(codec); 9946 if ((res >> 26) == ALC880_MIC_EVENT) 9947 alc262_dmic_automute(codec); 9948 9949} 9950 9951static void alc262_toshiba_s06_init_hook(struct hda_codec *codec) 9952{ 9953 alc262_toshiba_s06_speaker_automute(codec); 9954 alc262_dmic_automute(codec); 9955} 9956 9957/* mute/unmute internal speaker according to the hp jack and mute state */ 9958static void alc262_hippo_automute(struct hda_codec *codec) 9959{ 9960 struct alc_spec *spec = codec->spec; 9961 unsigned int mute; 9962 unsigned int present; 9963 9964 /* need to execute and sync at first */ 9965 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0); 9966 present = snd_hda_codec_read(codec, 0x15, 0, 9967 AC_VERB_GET_PIN_SENSE, 0); 9968 spec->jack_present = (present & 0x80000000) != 0; 9969 if (spec->jack_present) { 9970 /* mute internal speaker */ 9971 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 9972 HDA_AMP_MUTE, HDA_AMP_MUTE); 9973 } else { 9974 /* unmute internal speaker if necessary */ 9975 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0); 9976 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 9977 HDA_AMP_MUTE, mute); 9978 } 9979} 9980 9981/* unsolicited event for HP jack sensing */ 9982static void alc262_hippo_unsol_event(struct hda_codec *codec, 9983 unsigned int res) 9984{ 9985 if ((res >> 26) != ALC880_HP_EVENT) 9986 return; 9987 alc262_hippo_automute(codec); 9988} 9989 9990static void alc262_hippo1_automute(struct hda_codec *codec) 9991{ 9992 unsigned int mute; 9993 unsigned int present; 9994 9995 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0); 9996 present = snd_hda_codec_read(codec, 0x1b, 0, 9997 AC_VERB_GET_PIN_SENSE, 0); 9998 present = (present & 0x80000000) != 0; 9999 if (present) { 10000 /* mute internal speaker */ 10001 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 10002 HDA_AMP_MUTE, HDA_AMP_MUTE); 10003 } else { 10004 /* unmute internal speaker if necessary */ 10005 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0); 10006 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 10007 HDA_AMP_MUTE, mute); 10008 } 10009} 10010 10011/* unsolicited event for HP jack sensing */ 10012static void alc262_hippo1_unsol_event(struct hda_codec *codec, 10013 unsigned int res) 10014{ 10015 if ((res >> 26) != ALC880_HP_EVENT) 10016 return; 10017 alc262_hippo1_automute(codec); 10018} 10019 10020/* 10021 * nec model 10022 * 0x15 = headphone 10023 * 0x16 = internal speaker 10024 * 0x18 = external mic 10025 */ 10026 10027static struct snd_kcontrol_new alc262_nec_mixer[] = { 10028 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 10029 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT), 10030 10031 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 10032 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 10033 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 10034 10035 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 10036 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 10037 { } /* end */ 10038}; 10039 10040static struct hda_verb alc262_nec_verbs[] = { 10041 /* Unmute Speaker */ 10042 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 10043 10044 /* Headphone */ 10045 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 10046 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 10047 10048 /* External mic to headphone */ 10049 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 10050 /* External mic to speaker */ 10051 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 10052 {} 10053}; 10054 10055/* 10056 * fujitsu model 10057 * 0x14 = headphone/spdif-out, 0x15 = internal speaker, 10058 * 0x1b = port replicator headphone out 10059 */ 10060 10061#define ALC_HP_EVENT 0x37 10062 10063static struct hda_verb alc262_fujitsu_unsol_verbs[] = { 10064 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, 10065 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 10066 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, 10067 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 10068 {} 10069}; 10070 10071static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = { 10072 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, 10073 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 10074 {} 10075}; 10076 10077static struct hda_input_mux alc262_fujitsu_capture_source = { 10078 .num_items = 3, 10079 .items = { 10080 { "Mic", 0x0 }, 10081 { "Int Mic", 0x1 }, 10082 { "CD", 0x4 }, 10083 }, 10084}; 10085 10086static struct hda_input_mux alc262_HP_capture_source = { 10087 .num_items = 5, 10088 .items = { 10089 { "Mic", 0x0 }, 10090 { "Front Mic", 0x1 }, 10091 { "Line", 0x2 }, 10092 { "CD", 0x4 }, 10093 { "AUX IN", 0x6 }, 10094 }, 10095}; 10096 10097static struct hda_input_mux alc262_HP_D7000_capture_source = { 10098 .num_items = 4, 10099 .items = { 10100 { "Mic", 0x0 }, 10101 { "Front Mic", 0x2 }, 10102 { "Line", 0x1 }, 10103 { "CD", 0x4 }, 10104 }, 10105}; 10106 10107/* mute/unmute internal speaker according to the hp jacks and mute state */ 10108static void alc262_fujitsu_automute(struct hda_codec *codec, int force) 10109{ 10110 struct alc_spec *spec = codec->spec; 10111 unsigned int mute; 10112 10113 if (force || !spec->sense_updated) { 10114 unsigned int present; 10115 /* need to execute and sync at first */ 10116 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0); 10117 /* check laptop HP jack */ 10118 present = snd_hda_codec_read(codec, 0x14, 0, 10119 AC_VERB_GET_PIN_SENSE, 0); 10120 /* need to execute and sync at first */ 10121 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0); 10122 /* check docking HP jack */ 10123 present |= snd_hda_codec_read(codec, 0x1b, 0, 10124 AC_VERB_GET_PIN_SENSE, 0); 10125 if (present & AC_PINSENSE_PRESENCE) 10126 spec->jack_present = 1; 10127 else 10128 spec->jack_present = 0; 10129 spec->sense_updated = 1; 10130 } 10131 /* unmute internal speaker only if both HPs are unplugged and 10132 * master switch is on 10133 */ 10134 if (spec->jack_present) 10135 mute = HDA_AMP_MUTE; 10136 else 10137 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0); 10138 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 10139 HDA_AMP_MUTE, mute); 10140} 10141 10142/* unsolicited event for HP jack sensing */ 10143static void alc262_fujitsu_unsol_event(struct hda_codec *codec, 10144 unsigned int res) 10145{ 10146 if ((res >> 26) != ALC_HP_EVENT) 10147 return; 10148 alc262_fujitsu_automute(codec, 1); 10149} 10150 10151static void alc262_fujitsu_init_hook(struct hda_codec *codec) 10152{ 10153 alc262_fujitsu_automute(codec, 1); 10154} 10155 10156/* bind volumes of both NID 0x0c and 0x0d */ 10157static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = { 10158 .ops = &snd_hda_bind_vol, 10159 .values = { 10160 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT), 10161 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT), 10162 0 10163 }, 10164}; 10165 10166/* mute/unmute internal speaker according to the hp jack and mute state */ 10167static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force) 10168{ 10169 struct alc_spec *spec = codec->spec; 10170 unsigned int mute; 10171 10172 if (force || !spec->sense_updated) { 10173 unsigned int present_int_hp; 10174 /* need to execute and sync at first */ 10175 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0); 10176 present_int_hp = snd_hda_codec_read(codec, 0x1b, 0, 10177 AC_VERB_GET_PIN_SENSE, 0); 10178 spec->jack_present = (present_int_hp & 0x80000000) != 0; 10179 spec->sense_updated = 1; 10180 } 10181 if (spec->jack_present) { 10182 /* mute internal speaker */ 10183 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 10184 HDA_AMP_MUTE, HDA_AMP_MUTE); 10185 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0, 10186 HDA_AMP_MUTE, HDA_AMP_MUTE); 10187 } else { 10188 /* unmute internal speaker if necessary */ 10189 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0); 10190 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 10191 HDA_AMP_MUTE, mute); 10192 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0, 10193 HDA_AMP_MUTE, mute); 10194 } 10195} 10196 10197/* unsolicited event for HP jack sensing */ 10198static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec, 10199 unsigned int res) 10200{ 10201 if ((res >> 26) != ALC_HP_EVENT) 10202 return; 10203 alc262_lenovo_3000_automute(codec, 1); 10204} 10205 10206/* bind hp and internal speaker mute (with plug check) */ 10207static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol, 10208 struct snd_ctl_elem_value *ucontrol) 10209{ 10210 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 10211 long *valp = ucontrol->value.integer.value; 10212 int change; 10213 10214 change = snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 10215 HDA_AMP_MUTE, 10216 valp ? 0 : HDA_AMP_MUTE); 10217 change |= snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0, 10218 HDA_AMP_MUTE, 10219 valp ? 0 : HDA_AMP_MUTE); 10220 10221 if (change) 10222 alc262_fujitsu_automute(codec, 0); 10223 return change; 10224} 10225 10226static struct snd_kcontrol_new alc262_fujitsu_mixer[] = { 10227 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol), 10228 { 10229 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 10230 .name = "Master Playback Switch", 10231 .info = snd_hda_mixer_amp_switch_info, 10232 .get = snd_hda_mixer_amp_switch_get, 10233 .put = alc262_fujitsu_master_sw_put, 10234 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 10235 }, 10236 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 10237 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 10238 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 10239 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 10240 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 10241 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 10242 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 10243 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 10244 { } /* end */ 10245}; 10246 10247/* bind hp and internal speaker mute (with plug check) */ 10248static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol, 10249 struct snd_ctl_elem_value *ucontrol) 10250{ 10251 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 10252 long *valp = ucontrol->value.integer.value; 10253 int change; 10254 10255 change = snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0, 10256 HDA_AMP_MUTE, 10257 valp ? 0 : HDA_AMP_MUTE); 10258 10259 if (change) 10260 alc262_lenovo_3000_automute(codec, 0); 10261 return change; 10262} 10263 10264static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = { 10265 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol), 10266 { 10267 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 10268 .name = "Master Playback Switch", 10269 .info = snd_hda_mixer_amp_switch_info, 10270 .get = snd_hda_mixer_amp_switch_get, 10271 .put = alc262_lenovo_3000_master_sw_put, 10272 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT), 10273 }, 10274 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 10275 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 10276 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 10277 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 10278 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 10279 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 10280 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 10281 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 10282 { } /* end */ 10283}; 10284 10285static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = { 10286 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol), 10287 { 10288 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 10289 .name = "Master Playback Switch", 10290 .info = snd_hda_mixer_amp_switch_info, 10291 .get = snd_hda_mixer_amp_switch_get, 10292 .put = alc262_sony_master_sw_put, 10293 .private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT), 10294 }, 10295 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 10296 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 10297 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 10298 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 10299 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 10300 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 10301 { } /* end */ 10302}; 10303 10304/* additional init verbs for Benq laptops */ 10305static struct hda_verb alc262_EAPD_verbs[] = { 10306 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 10307 {0x20, AC_VERB_SET_PROC_COEF, 0x3070}, 10308 {} 10309}; 10310 10311static struct hda_verb alc262_benq_t31_EAPD_verbs[] = { 10312 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 10313 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 10314 10315 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 10316 {0x20, AC_VERB_SET_PROC_COEF, 0x3050}, 10317 {} 10318}; 10319 10320/* Samsung Q1 Ultra Vista model setup */ 10321static struct snd_kcontrol_new alc262_ultra_mixer[] = { 10322 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 10323 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT), 10324 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 10325 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 10326 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT), 10327 HDA_CODEC_VOLUME("Headphone Mic Boost", 0x15, 0, HDA_INPUT), 10328 { } /* end */ 10329}; 10330 10331static struct hda_verb alc262_ultra_verbs[] = { 10332 /* output mixer */ 10333 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 10334 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 10335 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 10336 /* speaker */ 10337 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 10338 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 10339 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 10340 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 10341 /* HP */ 10342 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 10343 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 10344 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 10345 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 10346 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 10347 /* internal mic */ 10348 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 10349 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 10350 /* ADC, choose mic */ 10351 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 10352 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 10353 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 10354 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 10355 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 10356 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 10357 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, 10358 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, 10359 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, 10360 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)}, 10361 {} 10362}; 10363 10364/* mute/unmute internal speaker according to the hp jack and mute state */ 10365static void alc262_ultra_automute(struct hda_codec *codec) 10366{ 10367 struct alc_spec *spec = codec->spec; 10368 unsigned int mute; 10369 10370 mute = 0; 10371 /* auto-mute only when HP is used as HP */ 10372 if (!spec->cur_mux[0]) { 10373 unsigned int present; 10374 /* need to execute and sync at first */ 10375 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0); 10376 present = snd_hda_codec_read(codec, 0x15, 0, 10377 AC_VERB_GET_PIN_SENSE, 0); 10378 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0; 10379 if (spec->jack_present) 10380 mute = HDA_AMP_MUTE; 10381 } 10382 /* mute/unmute internal speaker */ 10383 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 10384 HDA_AMP_MUTE, mute); 10385 /* mute/unmute HP */ 10386 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 10387 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE); 10388} 10389 10390/* unsolicited event for HP jack sensing */ 10391static void alc262_ultra_unsol_event(struct hda_codec *codec, 10392 unsigned int res) 10393{ 10394 if ((res >> 26) != ALC880_HP_EVENT) 10395 return; 10396 alc262_ultra_automute(codec); 10397} 10398 10399static struct hda_input_mux alc262_ultra_capture_source = { 10400 .num_items = 2, 10401 .items = { 10402 { "Mic", 0x1 }, 10403 { "Headphone", 0x7 }, 10404 }, 10405}; 10406 10407static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol, 10408 struct snd_ctl_elem_value *ucontrol) 10409{ 10410 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 10411 struct alc_spec *spec = codec->spec; 10412 int ret; 10413 10414 ret = alc_mux_enum_put(kcontrol, ucontrol); 10415 if (!ret) 10416 return 0; 10417 /* reprogram the HP pin as mic or HP according to the input source */ 10418 snd_hda_codec_write_cache(codec, 0x15, 0, 10419 AC_VERB_SET_PIN_WIDGET_CONTROL, 10420 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP); 10421 alc262_ultra_automute(codec); /* mute/unmute HP */ 10422 return ret; 10423} 10424 10425static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = { 10426 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT), 10427 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT), 10428 { 10429 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 10430 .name = "Capture Source", 10431 .info = alc_mux_enum_info, 10432 .get = alc_mux_enum_get, 10433 .put = alc262_ultra_mux_enum_put, 10434 }, 10435 { } /* end */ 10436}; 10437 10438/* add playback controls from the parsed DAC table */ 10439static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, 10440 const struct auto_pin_cfg *cfg) 10441{ 10442 hda_nid_t nid; 10443 int err; 10444 10445 spec->multiout.num_dacs = 1; /* only use one dac */ 10446 spec->multiout.dac_nids = spec->private_dac_nids; 10447 spec->multiout.dac_nids[0] = 2; 10448 10449 nid = cfg->line_out_pins[0]; 10450 if (nid) { 10451 err = add_control(spec, ALC_CTL_WIDGET_VOL, 10452 "Front Playback Volume", 10453 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT)); 10454 if (err < 0) 10455 return err; 10456 err = add_control(spec, ALC_CTL_WIDGET_MUTE, 10457 "Front Playback Switch", 10458 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); 10459 if (err < 0) 10460 return err; 10461 } 10462 10463 nid = cfg->speaker_pins[0]; 10464 if (nid) { 10465 if (nid == 0x16) { 10466 err = add_control(spec, ALC_CTL_WIDGET_VOL, 10467 "Speaker Playback Volume", 10468 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, 10469 HDA_OUTPUT)); 10470 if (err < 0) 10471 return err; 10472 err = add_control(spec, ALC_CTL_WIDGET_MUTE, 10473 "Speaker Playback Switch", 10474 HDA_COMPOSE_AMP_VAL(nid, 2, 0, 10475 HDA_OUTPUT)); 10476 if (err < 0) 10477 return err; 10478 } else { 10479 err = add_control(spec, ALC_CTL_WIDGET_MUTE, 10480 "Speaker Playback Switch", 10481 HDA_COMPOSE_AMP_VAL(nid, 3, 0, 10482 HDA_OUTPUT)); 10483 if (err < 0) 10484 return err; 10485 } 10486 } 10487 nid = cfg->hp_pins[0]; 10488 if (nid) { 10489 /* spec->multiout.hp_nid = 2; */ 10490 if (nid == 0x16) { 10491 err = add_control(spec, ALC_CTL_WIDGET_VOL, 10492 "Headphone Playback Volume", 10493 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, 10494 HDA_OUTPUT)); 10495 if (err < 0) 10496 return err; 10497 err = add_control(spec, ALC_CTL_WIDGET_MUTE, 10498 "Headphone Playback Switch", 10499 HDA_COMPOSE_AMP_VAL(nid, 2, 0, 10500 HDA_OUTPUT)); 10501 if (err < 0) 10502 return err; 10503 } else { 10504 err = add_control(spec, ALC_CTL_WIDGET_MUTE, 10505 "Headphone Playback Switch", 10506 HDA_COMPOSE_AMP_VAL(nid, 3, 0, 10507 HDA_OUTPUT)); 10508 if (err < 0) 10509 return err; 10510 } 10511 } 10512 return 0; 10513} 10514 10515/* identical with ALC880 */ 10516#define alc262_auto_create_analog_input_ctls \ 10517 alc880_auto_create_analog_input_ctls 10518 10519/* 10520 * generic initialization of ADC, input mixers and output mixers 10521 */ 10522static struct hda_verb alc262_volume_init_verbs[] = { 10523 /* 10524 * Unmute ADC0-2 and set the default input to mic-in 10525 */ 10526 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 10527 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 10528 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 10529 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 10530 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 10531 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 10532 10533 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 10534 * mixer widget 10535 * Note: PASD motherboards uses the Line In 2 as the input for 10536 * front panel mic (mic 2) 10537 */ 10538 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 10539 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 10540 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 10541 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 10542 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 10543 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 10544 10545 /* 10546 * Set up output mixers (0x0c - 0x0f) 10547 */ 10548 /* set vol=0 to output mixers */ 10549 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 10550 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 10551 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 10552 10553 /* set up input amps for analog loopback */ 10554 /* Amp Indices: DAC = 0, mixer = 1 */ 10555 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 10556 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 10557 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 10558 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 10559 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 10560 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 10561 10562 /* FIXME: use matrix-type input source selection */ 10563 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 10564 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 10565 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 10566 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 10567 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 10568 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 10569 /* Input mixer2 */ 10570 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 10571 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 10572 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 10573 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 10574 /* Input mixer3 */ 10575 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 10576 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 10577 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 10578 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 10579 10580 { } 10581}; 10582 10583static struct hda_verb alc262_HP_BPC_init_verbs[] = { 10584 /* 10585 * Unmute ADC0-2 and set the default input to mic-in 10586 */ 10587 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 10588 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 10589 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 10590 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 10591 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 10592 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 10593 10594 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 10595 * mixer widget 10596 * Note: PASD motherboards uses the Line In 2 as the input for 10597 * front panel mic (mic 2) 10598 */ 10599 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 10600 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 10601 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 10602 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 10603 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 10604 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 10605 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, 10606 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, 10607 10608 /* 10609 * Set up output mixers (0x0c - 0x0e) 10610 */ 10611 /* set vol=0 to output mixers */ 10612 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 10613 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 10614 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 10615 10616 /* set up input amps for analog loopback */ 10617 /* Amp Indices: DAC = 0, mixer = 1 */ 10618 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 10619 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 10620 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 10621 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 10622 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 10623 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 10624 10625 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 10626 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 10627 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 10628 10629 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 10630 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 10631 10632 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 10633 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 10634 10635 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 10636 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 10637 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 10638 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 10639 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 10640 10641 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, 10642 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 10643 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 10644 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, 10645 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 10646 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 10647 10648 10649 /* FIXME: use matrix-type input source selection */ 10650 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 10651 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 10652 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 10653 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, 10654 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, 10655 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, 10656 /* Input mixer2 */ 10657 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 10658 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, 10659 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, 10660 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, 10661 /* Input mixer3 */ 10662 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 10663 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, 10664 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, 10665 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, 10666 10667 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 10668 10669 { } 10670}; 10671 10672static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = { 10673 /* 10674 * Unmute ADC0-2 and set the default input to mic-in 10675 */ 10676 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 10677 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 10678 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 10679 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 10680 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 10681 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 10682 10683 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 10684 * mixer widget 10685 * Note: PASD motherboards uses the Line In 2 as the input for front 10686 * panel mic (mic 2) 10687 */ 10688 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 10689 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 10690 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 10691 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 10692 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 10693 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 10694 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, 10695 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, 10696 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, 10697 /* 10698 * Set up output mixers (0x0c - 0x0e) 10699 */ 10700 /* set vol=0 to output mixers */ 10701 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 10702 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 10703 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 10704 10705 /* set up input amps for analog loopback */ 10706 /* Amp Indices: DAC = 0, mixer = 1 */ 10707 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 10708 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 10709 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 10710 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 10711 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 10712 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 10713 10714 10715 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */ 10716 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */ 10717 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */ 10718 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */ 10719 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */ 10720 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */ 10721 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */ 10722 10723 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 10724 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 10725 10726 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 10727 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 10728 10729 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */ 10730 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 10731 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 10732 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, 10733 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 10734 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 10735 10736 /* FIXME: use matrix-type input source selection */ 10737 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 10738 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 10739 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/ 10740 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/ 10741 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/ 10742 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/ 10743 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/ 10744 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */ 10745 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/ 10746 /* Input mixer2 */ 10747 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 10748 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 10749 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, 10750 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, 10751 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, 10752 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */ 10753 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, 10754 /* Input mixer3 */ 10755 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 10756 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 10757 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, 10758 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, 10759 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, 10760 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */ 10761 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, 10762 10763 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 10764 10765 { } 10766}; 10767 10768static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = { 10769 10770 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */ 10771 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 10772 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01}, 10773 10774 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */ 10775 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */ 10776 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) }, 10777 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) }, 10778 10779 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */ 10780 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 10781 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 10782 {} 10783}; 10784 10785 10786#ifdef CONFIG_SND_HDA_POWER_SAVE 10787#define alc262_loopbacks alc880_loopbacks 10788#endif 10789 10790/* pcm configuration: identiacal with ALC880 */ 10791#define alc262_pcm_analog_playback alc880_pcm_analog_playback 10792#define alc262_pcm_analog_capture alc880_pcm_analog_capture 10793#define alc262_pcm_digital_playback alc880_pcm_digital_playback 10794#define alc262_pcm_digital_capture alc880_pcm_digital_capture 10795 10796/* 10797 * BIOS auto configuration 10798 */ 10799static int alc262_parse_auto_config(struct hda_codec *codec) 10800{ 10801 struct alc_spec *spec = codec->spec; 10802 int err; 10803 static hda_nid_t alc262_ignore[] = { 0x1d, 0 }; 10804 10805 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 10806 alc262_ignore); 10807 if (err < 0) 10808 return err; 10809 if (!spec->autocfg.line_outs) { 10810 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) { 10811 spec->multiout.max_channels = 2; 10812 spec->no_analog = 1; 10813 goto dig_only; 10814 } 10815 return 0; /* can't find valid BIOS pin config */ 10816 } 10817 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg); 10818 if (err < 0) 10819 return err; 10820 err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg); 10821 if (err < 0) 10822 return err; 10823 10824 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 10825 10826 dig_only: 10827 if (spec->autocfg.dig_outs) { 10828 spec->multiout.dig_out_nid = ALC262_DIGOUT_NID; 10829 spec->dig_out_type = spec->autocfg.dig_out_type[0]; 10830 } 10831 if (spec->autocfg.dig_in_pin) 10832 spec->dig_in_nid = ALC262_DIGIN_NID; 10833 10834 if (spec->kctls.list) 10835 add_mixer(spec, spec->kctls.list); 10836 10837 add_verb(spec, alc262_volume_init_verbs); 10838 spec->num_mux_defs = 1; 10839 spec->input_mux = &spec->private_imux[0]; 10840 10841 err = alc_auto_add_mic_boost(codec); 10842 if (err < 0) 10843 return err; 10844 10845 return 1; 10846} 10847 10848#define alc262_auto_init_multi_out alc882_auto_init_multi_out 10849#define alc262_auto_init_hp_out alc882_auto_init_hp_out 10850#define alc262_auto_init_analog_input alc882_auto_init_analog_input 10851#define alc262_auto_init_input_src alc882_auto_init_input_src 10852 10853 10854/* init callback for auto-configuration model -- overriding the default init */ 10855static void alc262_auto_init(struct hda_codec *codec) 10856{ 10857 struct alc_spec *spec = codec->spec; 10858 alc262_auto_init_multi_out(codec); 10859 alc262_auto_init_hp_out(codec); 10860 alc262_auto_init_analog_input(codec); 10861 alc262_auto_init_input_src(codec); 10862 if (spec->unsol_event) 10863 alc_inithook(codec); 10864} 10865 10866/* 10867 * configuration and preset 10868 */ 10869static const char *alc262_models[ALC262_MODEL_LAST] = { 10870 [ALC262_BASIC] = "basic", 10871 [ALC262_HIPPO] = "hippo", 10872 [ALC262_HIPPO_1] = "hippo_1", 10873 [ALC262_FUJITSU] = "fujitsu", 10874 [ALC262_HP_BPC] = "hp-bpc", 10875 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000", 10876 [ALC262_HP_TC_T5735] = "hp-tc-t5735", 10877 [ALC262_HP_RP5700] = "hp-rp5700", 10878 [ALC262_BENQ_ED8] = "benq", 10879 [ALC262_BENQ_T31] = "benq-t31", 10880 [ALC262_SONY_ASSAMD] = "sony-assamd", 10881 [ALC262_TOSHIBA_S06] = "toshiba-s06", 10882 [ALC262_TOSHIBA_RX1] = "toshiba-rx1", 10883 [ALC262_ULTRA] = "ultra", 10884 [ALC262_LENOVO_3000] = "lenovo-3000", 10885 [ALC262_NEC] = "nec", 10886 [ALC262_TYAN] = "tyan", 10887 [ALC262_AUTO] = "auto", 10888}; 10889 10890static struct snd_pci_quirk alc262_cfg_tbl[] = { 10891 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO), 10892 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC), 10893 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series", 10894 ALC262_HP_BPC), 10895 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series", 10896 ALC262_HP_BPC), 10897 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series", 10898 ALC262_HP_BPC), 10899 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL), 10900 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF), 10901 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL), 10902 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF), 10903 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL), 10904 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF), 10905 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL), 10906 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF), 10907 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC), 10908 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC), 10909 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC), 10910 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735", 10911 ALC262_HP_TC_T5735), 10912 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700), 10913 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD), 10914 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO), 10915 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD), 10916 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */ 10917 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO", 10918 ALC262_SONY_ASSAMD), 10919 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1", 10920 ALC262_TOSHIBA_RX1), 10921 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06), 10922 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU), 10923 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU), 10924 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN), 10925 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1", 10926 ALC262_ULTRA), 10927 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO), 10928 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000), 10929 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8), 10930 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31), 10931 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1), 10932 {} 10933}; 10934 10935static struct alc_config_preset alc262_presets[] = { 10936 [ALC262_BASIC] = { 10937 .mixers = { alc262_base_mixer }, 10938 .init_verbs = { alc262_init_verbs }, 10939 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 10940 .dac_nids = alc262_dac_nids, 10941 .hp_nid = 0x03, 10942 .num_channel_mode = ARRAY_SIZE(alc262_modes), 10943 .channel_mode = alc262_modes, 10944 .input_mux = &alc262_capture_source, 10945 }, 10946 [ALC262_HIPPO] = { 10947 .mixers = { alc262_base_mixer }, 10948 .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs}, 10949 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 10950 .dac_nids = alc262_dac_nids, 10951 .hp_nid = 0x03, 10952 .dig_out_nid = ALC262_DIGOUT_NID, 10953 .num_channel_mode = ARRAY_SIZE(alc262_modes), 10954 .channel_mode = alc262_modes, 10955 .input_mux = &alc262_capture_source, 10956 .unsol_event = alc262_hippo_unsol_event, 10957 .init_hook = alc262_hippo_automute, 10958 }, 10959 [ALC262_HIPPO_1] = { 10960 .mixers = { alc262_hippo1_mixer }, 10961 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs}, 10962 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 10963 .dac_nids = alc262_dac_nids, 10964 .hp_nid = 0x02, 10965 .dig_out_nid = ALC262_DIGOUT_NID, 10966 .num_channel_mode = ARRAY_SIZE(alc262_modes), 10967 .channel_mode = alc262_modes, 10968 .input_mux = &alc262_capture_source, 10969 .unsol_event = alc262_hippo1_unsol_event, 10970 .init_hook = alc262_hippo1_automute, 10971 }, 10972 [ALC262_FUJITSU] = { 10973 .mixers = { alc262_fujitsu_mixer }, 10974 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs, 10975 alc262_fujitsu_unsol_verbs }, 10976 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 10977 .dac_nids = alc262_dac_nids, 10978 .hp_nid = 0x03, 10979 .dig_out_nid = ALC262_DIGOUT_NID, 10980 .num_channel_mode = ARRAY_SIZE(alc262_modes), 10981 .channel_mode = alc262_modes, 10982 .input_mux = &alc262_fujitsu_capture_source, 10983 .unsol_event = alc262_fujitsu_unsol_event, 10984 .init_hook = alc262_fujitsu_init_hook, 10985 }, 10986 [ALC262_HP_BPC] = { 10987 .mixers = { alc262_HP_BPC_mixer }, 10988 .init_verbs = { alc262_HP_BPC_init_verbs }, 10989 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 10990 .dac_nids = alc262_dac_nids, 10991 .hp_nid = 0x03, 10992 .num_channel_mode = ARRAY_SIZE(alc262_modes), 10993 .channel_mode = alc262_modes, 10994 .input_mux = &alc262_HP_capture_source, 10995 .unsol_event = alc262_hp_bpc_unsol_event, 10996 .init_hook = alc262_hp_bpc_automute, 10997 }, 10998 [ALC262_HP_BPC_D7000_WF] = { 10999 .mixers = { alc262_HP_BPC_WildWest_mixer }, 11000 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs }, 11001 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 11002 .dac_nids = alc262_dac_nids, 11003 .hp_nid = 0x03, 11004 .num_channel_mode = ARRAY_SIZE(alc262_modes), 11005 .channel_mode = alc262_modes, 11006 .input_mux = &alc262_HP_D7000_capture_source, 11007 .unsol_event = alc262_hp_wildwest_unsol_event, 11008 .init_hook = alc262_hp_wildwest_automute, 11009 }, 11010 [ALC262_HP_BPC_D7000_WL] = { 11011 .mixers = { alc262_HP_BPC_WildWest_mixer, 11012 alc262_HP_BPC_WildWest_option_mixer }, 11013 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs }, 11014 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 11015 .dac_nids = alc262_dac_nids, 11016 .hp_nid = 0x03, 11017 .num_channel_mode = ARRAY_SIZE(alc262_modes), 11018 .channel_mode = alc262_modes, 11019 .input_mux = &alc262_HP_D7000_capture_source, 11020 .unsol_event = alc262_hp_wildwest_unsol_event, 11021 .init_hook = alc262_hp_wildwest_automute, 11022 }, 11023 [ALC262_HP_TC_T5735] = { 11024 .mixers = { alc262_hp_t5735_mixer }, 11025 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs }, 11026 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 11027 .dac_nids = alc262_dac_nids, 11028 .hp_nid = 0x03, 11029 .num_channel_mode = ARRAY_SIZE(alc262_modes), 11030 .channel_mode = alc262_modes, 11031 .input_mux = &alc262_capture_source, 11032 .unsol_event = alc262_hp_t5735_unsol_event, 11033 .init_hook = alc262_hp_t5735_init_hook, 11034 }, 11035 [ALC262_HP_RP5700] = { 11036 .mixers = { alc262_hp_rp5700_mixer }, 11037 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs }, 11038 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 11039 .dac_nids = alc262_dac_nids, 11040 .num_channel_mode = ARRAY_SIZE(alc262_modes), 11041 .channel_mode = alc262_modes, 11042 .input_mux = &alc262_hp_rp5700_capture_source, 11043 }, 11044 [ALC262_BENQ_ED8] = { 11045 .mixers = { alc262_base_mixer }, 11046 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs }, 11047 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 11048 .dac_nids = alc262_dac_nids, 11049 .hp_nid = 0x03, 11050 .num_channel_mode = ARRAY_SIZE(alc262_modes), 11051 .channel_mode = alc262_modes, 11052 .input_mux = &alc262_capture_source, 11053 }, 11054 [ALC262_SONY_ASSAMD] = { 11055 .mixers = { alc262_sony_mixer }, 11056 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs}, 11057 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 11058 .dac_nids = alc262_dac_nids, 11059 .hp_nid = 0x02, 11060 .num_channel_mode = ARRAY_SIZE(alc262_modes), 11061 .channel_mode = alc262_modes, 11062 .input_mux = &alc262_capture_source, 11063 .unsol_event = alc262_hippo_unsol_event, 11064 .init_hook = alc262_hippo_automute, 11065 }, 11066 [ALC262_BENQ_T31] = { 11067 .mixers = { alc262_benq_t31_mixer }, 11068 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs }, 11069 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 11070 .dac_nids = alc262_dac_nids, 11071 .hp_nid = 0x03, 11072 .num_channel_mode = ARRAY_SIZE(alc262_modes), 11073 .channel_mode = alc262_modes, 11074 .input_mux = &alc262_capture_source, 11075 .unsol_event = alc262_hippo_unsol_event, 11076 .init_hook = alc262_hippo_automute, 11077 }, 11078 [ALC262_ULTRA] = { 11079 .mixers = { alc262_ultra_mixer }, 11080 .cap_mixer = alc262_ultra_capture_mixer, 11081 .init_verbs = { alc262_ultra_verbs }, 11082 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 11083 .dac_nids = alc262_dac_nids, 11084 .num_channel_mode = ARRAY_SIZE(alc262_modes), 11085 .channel_mode = alc262_modes, 11086 .input_mux = &alc262_ultra_capture_source, 11087 .adc_nids = alc262_adc_nids, /* ADC0 */ 11088 .capsrc_nids = alc262_capsrc_nids, 11089 .num_adc_nids = 1, /* single ADC */ 11090 .unsol_event = alc262_ultra_unsol_event, 11091 .init_hook = alc262_ultra_automute, 11092 }, 11093 [ALC262_LENOVO_3000] = { 11094 .mixers = { alc262_lenovo_3000_mixer }, 11095 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs, 11096 alc262_lenovo_3000_unsol_verbs }, 11097 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 11098 .dac_nids = alc262_dac_nids, 11099 .hp_nid = 0x03, 11100 .dig_out_nid = ALC262_DIGOUT_NID, 11101 .num_channel_mode = ARRAY_SIZE(alc262_modes), 11102 .channel_mode = alc262_modes, 11103 .input_mux = &alc262_fujitsu_capture_source, 11104 .unsol_event = alc262_lenovo_3000_unsol_event, 11105 }, 11106 [ALC262_NEC] = { 11107 .mixers = { alc262_nec_mixer }, 11108 .init_verbs = { alc262_nec_verbs }, 11109 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 11110 .dac_nids = alc262_dac_nids, 11111 .hp_nid = 0x03, 11112 .num_channel_mode = ARRAY_SIZE(alc262_modes), 11113 .channel_mode = alc262_modes, 11114 .input_mux = &alc262_capture_source, 11115 }, 11116 [ALC262_TOSHIBA_S06] = { 11117 .mixers = { alc262_toshiba_s06_mixer }, 11118 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs, 11119 alc262_eapd_verbs }, 11120 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 11121 .capsrc_nids = alc262_dmic_capsrc_nids, 11122 .dac_nids = alc262_dac_nids, 11123 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */ 11124 .dig_out_nid = ALC262_DIGOUT_NID, 11125 .num_channel_mode = ARRAY_SIZE(alc262_modes), 11126 .channel_mode = alc262_modes, 11127 .input_mux = &alc262_dmic_capture_source, 11128 .unsol_event = alc262_toshiba_s06_unsol_event, 11129 .init_hook = alc262_toshiba_s06_init_hook, 11130 }, 11131 [ALC262_TOSHIBA_RX1] = { 11132 .mixers = { alc262_toshiba_rx1_mixer }, 11133 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs }, 11134 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 11135 .dac_nids = alc262_dac_nids, 11136 .hp_nid = 0x03, 11137 .num_channel_mode = ARRAY_SIZE(alc262_modes), 11138 .channel_mode = alc262_modes, 11139 .input_mux = &alc262_capture_source, 11140 .unsol_event = alc262_hippo_unsol_event, 11141 .init_hook = alc262_hippo_automute, 11142 }, 11143 [ALC262_TYAN] = { 11144 .mixers = { alc262_tyan_mixer }, 11145 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs}, 11146 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 11147 .dac_nids = alc262_dac_nids, 11148 .hp_nid = 0x02, 11149 .dig_out_nid = ALC262_DIGOUT_NID, 11150 .num_channel_mode = ARRAY_SIZE(alc262_modes), 11151 .channel_mode = alc262_modes, 11152 .input_mux = &alc262_capture_source, 11153 .unsol_event = alc262_tyan_unsol_event, 11154 .init_hook = alc262_tyan_automute, 11155 }, 11156}; 11157 11158static int patch_alc262(struct hda_codec *codec) 11159{ 11160 struct alc_spec *spec; 11161 int board_config; 11162 int err; 11163 11164 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 11165 if (spec == NULL) 11166 return -ENOMEM; 11167 11168 codec->spec = spec; 11169#if 0 11170 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is 11171 * under-run 11172 */ 11173 { 11174 int tmp; 11175 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7); 11176 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0); 11177 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7); 11178 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80); 11179 } 11180#endif 11181 11182 alc_fix_pll_init(codec, 0x20, 0x0a, 10); 11183 11184 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST, 11185 alc262_models, 11186 alc262_cfg_tbl); 11187 11188 if (board_config < 0) { 11189 printk(KERN_INFO "hda_codec: Unknown model for ALC262, " 11190 "trying auto-probe from BIOS...\n"); 11191 board_config = ALC262_AUTO; 11192 } 11193 11194 if (board_config == ALC262_AUTO) { 11195 /* automatic parse from the BIOS config */ 11196 err = alc262_parse_auto_config(codec); 11197 if (err < 0) { 11198 alc_free(codec); 11199 return err; 11200 } else if (!err) { 11201 printk(KERN_INFO 11202 "hda_codec: Cannot set up configuration " 11203 "from BIOS. Using base mode...\n"); 11204 board_config = ALC262_BASIC; 11205 } 11206 } 11207 11208 if (!spec->no_analog) { 11209 err = snd_hda_attach_beep_device(codec, 0x1); 11210 if (err < 0) { 11211 alc_free(codec); 11212 return err; 11213 } 11214 } 11215 11216 if (board_config != ALC262_AUTO) 11217 setup_preset(spec, &alc262_presets[board_config]); 11218 11219 spec->stream_name_analog = "ALC262 Analog"; 11220 spec->stream_analog_playback = &alc262_pcm_analog_playback; 11221 spec->stream_analog_capture = &alc262_pcm_analog_capture; 11222 11223 spec->stream_name_digital = "ALC262 Digital"; 11224 spec->stream_digital_playback = &alc262_pcm_digital_playback; 11225 spec->stream_digital_capture = &alc262_pcm_digital_capture; 11226 11227 spec->capture_style = CAPT_MIX; 11228 if (!spec->adc_nids && spec->input_mux) { 11229 /* check whether NID 0x07 is valid */ 11230 unsigned int wcap = get_wcaps(codec, 0x07); 11231 11232 /* get type */ 11233 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; 11234 if (wcap != AC_WID_AUD_IN) { 11235 spec->adc_nids = alc262_adc_nids_alt; 11236 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt); 11237 spec->capsrc_nids = alc262_capsrc_nids_alt; 11238 } else { 11239 spec->adc_nids = alc262_adc_nids; 11240 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids); 11241 spec->capsrc_nids = alc262_capsrc_nids; 11242 } 11243 } 11244 if (!spec->cap_mixer && !spec->no_analog) 11245 set_capture_mixer(spec); 11246 if (!spec->no_analog) 11247 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 11248 11249 spec->vmaster_nid = 0x0c; 11250 11251 codec->patch_ops = alc_patch_ops; 11252 if (board_config == ALC262_AUTO) 11253 spec->init_hook = alc262_auto_init; 11254#ifdef CONFIG_SND_HDA_POWER_SAVE 11255 if (!spec->loopback.amplist) 11256 spec->loopback.amplist = alc262_loopbacks; 11257#endif 11258 codec->proc_widget_hook = print_realtek_coef; 11259 11260 return 0; 11261} 11262 11263/* 11264 * ALC268 channel source setting (2 channel) 11265 */ 11266#define ALC268_DIGOUT_NID ALC880_DIGOUT_NID 11267#define alc268_modes alc260_modes 11268 11269static hda_nid_t alc268_dac_nids[2] = { 11270 /* front, hp */ 11271 0x02, 0x03 11272}; 11273 11274static hda_nid_t alc268_adc_nids[2] = { 11275 /* ADC0-1 */ 11276 0x08, 0x07 11277}; 11278 11279static hda_nid_t alc268_adc_nids_alt[1] = { 11280 /* ADC0 */ 11281 0x08 11282}; 11283 11284static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 }; 11285 11286static struct snd_kcontrol_new alc268_base_mixer[] = { 11287 /* output mixer control */ 11288 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), 11289 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 11290 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT), 11291 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 11292 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 11293 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 11294 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT), 11295 { } 11296}; 11297 11298/* bind Beep switches of both NID 0x0f and 0x10 */ 11299static struct hda_bind_ctls alc268_bind_beep_sw = { 11300 .ops = &snd_hda_bind_sw, 11301 .values = { 11302 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT), 11303 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT), 11304 0 11305 }, 11306}; 11307 11308static struct snd_kcontrol_new alc268_beep_mixer[] = { 11309 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT), 11310 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw), 11311 { } 11312}; 11313 11314static struct hda_verb alc268_eapd_verbs[] = { 11315 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 11316 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, 11317 { } 11318}; 11319 11320/* Toshiba specific */ 11321#define alc268_toshiba_automute alc262_hippo_automute 11322 11323static struct hda_verb alc268_toshiba_verbs[] = { 11324 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 11325 { } /* end */ 11326}; 11327 11328static struct hda_input_mux alc268_acer_lc_capture_source = { 11329 .num_items = 2, 11330 .items = { 11331 { "i-Mic", 0x6 }, 11332 { "E-Mic", 0x0 }, 11333 }, 11334}; 11335 11336/* Acer specific */ 11337/* bind volumes of both NID 0x02 and 0x03 */ 11338static struct hda_bind_ctls alc268_acer_bind_master_vol = { 11339 .ops = &snd_hda_bind_vol, 11340 .values = { 11341 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), 11342 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT), 11343 0 11344 }, 11345}; 11346 11347/* mute/unmute internal speaker according to the hp jack and mute state */ 11348static void alc268_acer_automute(struct hda_codec *codec, int force) 11349{ 11350 struct alc_spec *spec = codec->spec; 11351 unsigned int mute; 11352 11353 if (force || !spec->sense_updated) { 11354 unsigned int present; 11355 present = snd_hda_codec_read(codec, 0x14, 0, 11356 AC_VERB_GET_PIN_SENSE, 0); 11357 spec->jack_present = (present & 0x80000000) != 0; 11358 spec->sense_updated = 1; 11359 } 11360 if (spec->jack_present) 11361 mute = HDA_AMP_MUTE; /* mute internal speaker */ 11362 else /* unmute internal speaker if necessary */ 11363 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0); 11364 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 11365 HDA_AMP_MUTE, mute); 11366} 11367 11368 11369/* bind hp and internal speaker mute (with plug check) */ 11370static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol, 11371 struct snd_ctl_elem_value *ucontrol) 11372{ 11373 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 11374 long *valp = ucontrol->value.integer.value; 11375 int change; 11376 11377 change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0, 11378 HDA_AMP_MUTE, 11379 valp[0] ? 0 : HDA_AMP_MUTE); 11380 change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0, 11381 HDA_AMP_MUTE, 11382 valp[1] ? 0 : HDA_AMP_MUTE); 11383 if (change) 11384 alc268_acer_automute(codec, 0); 11385 return change; 11386} 11387 11388static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = { 11389 /* output mixer control */ 11390 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), 11391 { 11392 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 11393 .name = "Master Playback Switch", 11394 .info = snd_hda_mixer_amp_switch_info, 11395 .get = snd_hda_mixer_amp_switch_get, 11396 .put = alc268_acer_master_sw_put, 11397 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 11398 }, 11399 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT), 11400 { } 11401}; 11402 11403static struct snd_kcontrol_new alc268_acer_mixer[] = { 11404 /* output mixer control */ 11405 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), 11406 { 11407 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 11408 .name = "Master Playback Switch", 11409 .info = snd_hda_mixer_amp_switch_info, 11410 .get = snd_hda_mixer_amp_switch_get, 11411 .put = alc268_acer_master_sw_put, 11412 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 11413 }, 11414 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 11415 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), 11416 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT), 11417 { } 11418}; 11419 11420static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = { 11421 /* output mixer control */ 11422 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), 11423 { 11424 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 11425 .name = "Master Playback Switch", 11426 .info = snd_hda_mixer_amp_switch_info, 11427 .get = snd_hda_mixer_amp_switch_get, 11428 .put = alc268_acer_master_sw_put, 11429 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 11430 }, 11431 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 11432 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT), 11433 { } 11434}; 11435 11436static struct hda_verb alc268_acer_aspire_one_verbs[] = { 11437 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 11438 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11439 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 11440 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 11441 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06}, 11442 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017}, 11443 { } 11444}; 11445 11446static struct hda_verb alc268_acer_verbs[] = { 11447 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */ 11448 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 11449 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11450 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 11451 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 11452 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 11453 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 11454 { } 11455}; 11456 11457/* unsolicited event for HP jack sensing */ 11458static void alc268_toshiba_unsol_event(struct hda_codec *codec, 11459 unsigned int res) 11460{ 11461 if ((res >> 26) != ALC880_HP_EVENT) 11462 return; 11463 alc268_toshiba_automute(codec); 11464} 11465 11466static void alc268_acer_unsol_event(struct hda_codec *codec, 11467 unsigned int res) 11468{ 11469 if ((res >> 26) != ALC880_HP_EVENT) 11470 return; 11471 alc268_acer_automute(codec, 1); 11472} 11473 11474static void alc268_acer_init_hook(struct hda_codec *codec) 11475{ 11476 alc268_acer_automute(codec, 1); 11477} 11478 11479/* toggle speaker-output according to the hp-jack state */ 11480static void alc268_aspire_one_speaker_automute(struct hda_codec *codec) 11481{ 11482 unsigned int present; 11483 unsigned char bits; 11484 11485 present = snd_hda_codec_read(codec, 0x15, 0, 11486 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 11487 bits = present ? AMP_IN_MUTE(0) : 0; 11488 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0, 11489 AMP_IN_MUTE(0), bits); 11490 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1, 11491 AMP_IN_MUTE(0), bits); 11492} 11493 11494 11495static void alc268_acer_mic_automute(struct hda_codec *codec) 11496{ 11497 unsigned int present; 11498 11499 present = snd_hda_codec_read(codec, 0x18, 0, 11500 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 11501 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_CONNECT_SEL, 11502 present ? 0x0 : 0x6); 11503} 11504 11505static void alc268_acer_lc_unsol_event(struct hda_codec *codec, 11506 unsigned int res) 11507{ 11508 if ((res >> 26) == ALC880_HP_EVENT) 11509 alc268_aspire_one_speaker_automute(codec); 11510 if ((res >> 26) == ALC880_MIC_EVENT) 11511 alc268_acer_mic_automute(codec); 11512} 11513 11514static void alc268_acer_lc_init_hook(struct hda_codec *codec) 11515{ 11516 alc268_aspire_one_speaker_automute(codec); 11517 alc268_acer_mic_automute(codec); 11518} 11519 11520static struct snd_kcontrol_new alc268_dell_mixer[] = { 11521 /* output mixer control */ 11522 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 11523 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 11524 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 11525 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 11526 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 11527 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), 11528 { } 11529}; 11530 11531static struct hda_verb alc268_dell_verbs[] = { 11532 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11533 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11534 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 11535 { } 11536}; 11537 11538/* mute/unmute internal speaker according to the hp jack and mute state */ 11539static void alc268_dell_automute(struct hda_codec *codec) 11540{ 11541 unsigned int present; 11542 unsigned int mute; 11543 11544 present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0); 11545 if (present & 0x80000000) 11546 mute = HDA_AMP_MUTE; 11547 else 11548 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0); 11549 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 11550 HDA_AMP_MUTE, mute); 11551} 11552 11553static void alc268_dell_unsol_event(struct hda_codec *codec, 11554 unsigned int res) 11555{ 11556 if ((res >> 26) != ALC880_HP_EVENT) 11557 return; 11558 alc268_dell_automute(codec); 11559} 11560 11561#define alc268_dell_init_hook alc268_dell_automute 11562 11563static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = { 11564 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT), 11565 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 11566 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT), 11567 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 11568 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT), 11569 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT), 11570 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT), 11571 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 11572 { } 11573}; 11574 11575static struct hda_verb alc267_quanta_il1_verbs[] = { 11576 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 11577 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, 11578 { } 11579}; 11580 11581static void alc267_quanta_il1_hp_automute(struct hda_codec *codec) 11582{ 11583 unsigned int present; 11584 11585 present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0) 11586 & AC_PINSENSE_PRESENCE; 11587 snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 11588 present ? 0 : PIN_OUT); 11589} 11590 11591static void alc267_quanta_il1_mic_automute(struct hda_codec *codec) 11592{ 11593 unsigned int present; 11594 11595 present = snd_hda_codec_read(codec, 0x18, 0, 11596 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 11597 snd_hda_codec_write(codec, 0x23, 0, 11598 AC_VERB_SET_CONNECT_SEL, 11599 present ? 0x00 : 0x01); 11600} 11601 11602static void alc267_quanta_il1_automute(struct hda_codec *codec) 11603{ 11604 alc267_quanta_il1_hp_automute(codec); 11605 alc267_quanta_il1_mic_automute(codec); 11606} 11607 11608static void alc267_quanta_il1_unsol_event(struct hda_codec *codec, 11609 unsigned int res) 11610{ 11611 switch (res >> 26) { 11612 case ALC880_HP_EVENT: 11613 alc267_quanta_il1_hp_automute(codec); 11614 break; 11615 case ALC880_MIC_EVENT: 11616 alc267_quanta_il1_mic_automute(codec); 11617 break; 11618 } 11619} 11620 11621/* 11622 * generic initialization of ADC, input mixers and output mixers 11623 */ 11624static struct hda_verb alc268_base_init_verbs[] = { 11625 /* Unmute DAC0-1 and set vol = 0 */ 11626 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 11627 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 11628 11629 /* 11630 * Set up output mixers (0x0c - 0x0e) 11631 */ 11632 /* set vol=0 to output mixers */ 11633 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11634 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00}, 11635 11636 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11637 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11638 11639 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 11640 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 11641 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 11642 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 11643 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 11644 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 11645 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 11646 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 11647 11648 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 11649 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 11650 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 11651 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 11652 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 11653 11654 /* set PCBEEP vol = 0, mute connections */ 11655 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11656 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 11657 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 11658 11659 /* Unmute Selector 23h,24h and set the default input to mic-in */ 11660 11661 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00}, 11662 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 11663 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00}, 11664 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 11665 11666 { } 11667}; 11668 11669/* 11670 * generic initialization of ADC, input mixers and output mixers 11671 */ 11672static struct hda_verb alc268_volume_init_verbs[] = { 11673 /* set output DAC */ 11674 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 11675 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 11676 11677 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 11678 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 11679 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 11680 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 11681 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 11682 11683 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11684 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11685 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11686 11687 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 11688 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 11689 11690 /* set PCBEEP vol = 0, mute connections */ 11691 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11692 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 11693 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 11694 11695 { } 11696}; 11697 11698static struct snd_kcontrol_new alc268_capture_alt_mixer[] = { 11699 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT), 11700 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT), 11701 { 11702 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 11703 /* The multiple "Capture Source" controls confuse alsamixer 11704 * So call somewhat different.. 11705 */ 11706 /* .name = "Capture Source", */ 11707 .name = "Input Source", 11708 .count = 1, 11709 .info = alc_mux_enum_info, 11710 .get = alc_mux_enum_get, 11711 .put = alc_mux_enum_put, 11712 }, 11713 { } /* end */ 11714}; 11715 11716static struct snd_kcontrol_new alc268_capture_mixer[] = { 11717 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT), 11718 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT), 11719 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT), 11720 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT), 11721 { 11722 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 11723 /* The multiple "Capture Source" controls confuse alsamixer 11724 * So call somewhat different.. 11725 */ 11726 /* .name = "Capture Source", */ 11727 .name = "Input Source", 11728 .count = 2, 11729 .info = alc_mux_enum_info, 11730 .get = alc_mux_enum_get, 11731 .put = alc_mux_enum_put, 11732 }, 11733 { } /* end */ 11734}; 11735 11736static struct hda_input_mux alc268_capture_source = { 11737 .num_items = 4, 11738 .items = { 11739 { "Mic", 0x0 }, 11740 { "Front Mic", 0x1 }, 11741 { "Line", 0x2 }, 11742 { "CD", 0x3 }, 11743 }, 11744}; 11745 11746static struct hda_input_mux alc268_acer_capture_source = { 11747 .num_items = 3, 11748 .items = { 11749 { "Mic", 0x0 }, 11750 { "Internal Mic", 0x1 }, 11751 { "Line", 0x2 }, 11752 }, 11753}; 11754 11755static struct hda_input_mux alc268_acer_dmic_capture_source = { 11756 .num_items = 3, 11757 .items = { 11758 { "Mic", 0x0 }, 11759 { "Internal Mic", 0x6 }, 11760 { "Line", 0x2 }, 11761 }, 11762}; 11763 11764#ifdef CONFIG_SND_DEBUG 11765static struct snd_kcontrol_new alc268_test_mixer[] = { 11766 /* Volume widgets */ 11767 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT), 11768 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT), 11769 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT), 11770 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT), 11771 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT), 11772 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT), 11773 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT), 11774 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT), 11775 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT), 11776 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT), 11777 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT), 11778 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT), 11779 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT), 11780 /* The below appears problematic on some hardwares */ 11781 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/ 11782 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT), 11783 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT), 11784 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT), 11785 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT), 11786 11787 /* Modes for retasking pin widgets */ 11788 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT), 11789 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT), 11790 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT), 11791 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT), 11792 11793 /* Controls for GPIO pins, assuming they are configured as outputs */ 11794 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01), 11795 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02), 11796 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04), 11797 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08), 11798 11799 /* Switches to allow the digital SPDIF output pin to be enabled. 11800 * The ALC268 does not have an SPDIF input. 11801 */ 11802 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01), 11803 11804 /* A switch allowing EAPD to be enabled. Some laptops seem to use 11805 * this output to turn on an external amplifier. 11806 */ 11807 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02), 11808 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02), 11809 11810 { } /* end */ 11811}; 11812#endif 11813 11814/* create input playback/capture controls for the given pin */ 11815static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid, 11816 const char *ctlname, int idx) 11817{ 11818 char name[32]; 11819 int err; 11820 11821 sprintf(name, "%s Playback Volume", ctlname); 11822 if (nid == 0x14) { 11823 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, 11824 HDA_COMPOSE_AMP_VAL(0x02, 3, idx, 11825 HDA_OUTPUT)); 11826 if (err < 0) 11827 return err; 11828 } else if (nid == 0x15) { 11829 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, 11830 HDA_COMPOSE_AMP_VAL(0x03, 3, idx, 11831 HDA_OUTPUT)); 11832 if (err < 0) 11833 return err; 11834 } else 11835 return -1; 11836 sprintf(name, "%s Playback Switch", ctlname); 11837 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, 11838 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT)); 11839 if (err < 0) 11840 return err; 11841 return 0; 11842} 11843 11844/* add playback controls from the parsed DAC table */ 11845static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec, 11846 const struct auto_pin_cfg *cfg) 11847{ 11848 hda_nid_t nid; 11849 int err; 11850 11851 spec->multiout.num_dacs = 2; /* only use one dac */ 11852 spec->multiout.dac_nids = spec->private_dac_nids; 11853 spec->multiout.dac_nids[0] = 2; 11854 spec->multiout.dac_nids[1] = 3; 11855 11856 nid = cfg->line_out_pins[0]; 11857 if (nid) 11858 alc268_new_analog_output(spec, nid, "Front", 0); 11859 11860 nid = cfg->speaker_pins[0]; 11861 if (nid == 0x1d) { 11862 err = add_control(spec, ALC_CTL_WIDGET_VOL, 11863 "Speaker Playback Volume", 11864 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT)); 11865 if (err < 0) 11866 return err; 11867 } 11868 nid = cfg->hp_pins[0]; 11869 if (nid) 11870 alc268_new_analog_output(spec, nid, "Headphone", 0); 11871 11872 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2]; 11873 if (nid == 0x16) { 11874 err = add_control(spec, ALC_CTL_WIDGET_MUTE, 11875 "Mono Playback Switch", 11876 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT)); 11877 if (err < 0) 11878 return err; 11879 } 11880 return 0; 11881} 11882 11883/* create playback/capture controls for input pins */ 11884static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec, 11885 const struct auto_pin_cfg *cfg) 11886{ 11887 struct hda_input_mux *imux = &spec->private_imux[0]; 11888 int i, idx1; 11889 11890 for (i = 0; i < AUTO_PIN_LAST; i++) { 11891 switch(cfg->input_pins[i]) { 11892 case 0x18: 11893 idx1 = 0; /* Mic 1 */ 11894 break; 11895 case 0x19: 11896 idx1 = 1; /* Mic 2 */ 11897 break; 11898 case 0x1a: 11899 idx1 = 2; /* Line In */ 11900 break; 11901 case 0x1c: 11902 idx1 = 3; /* CD */ 11903 break; 11904 case 0x12: 11905 case 0x13: 11906 idx1 = 6; /* digital mics */ 11907 break; 11908 default: 11909 continue; 11910 } 11911 imux->items[imux->num_items].label = auto_pin_cfg_labels[i]; 11912 imux->items[imux->num_items].index = idx1; 11913 imux->num_items++; 11914 } 11915 return 0; 11916} 11917 11918static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec) 11919{ 11920 struct alc_spec *spec = codec->spec; 11921 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0]; 11922 hda_nid_t hp_nid = spec->autocfg.hp_pins[0]; 11923 hda_nid_t line_nid = spec->autocfg.line_out_pins[0]; 11924 unsigned int dac_vol1, dac_vol2; 11925 11926 if (speaker_nid) { 11927 snd_hda_codec_write(codec, speaker_nid, 0, 11928 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); 11929 snd_hda_codec_write(codec, 0x0f, 0, 11930 AC_VERB_SET_AMP_GAIN_MUTE, 11931 AMP_IN_UNMUTE(1)); 11932 snd_hda_codec_write(codec, 0x10, 0, 11933 AC_VERB_SET_AMP_GAIN_MUTE, 11934 AMP_IN_UNMUTE(1)); 11935 } else { 11936 snd_hda_codec_write(codec, 0x0f, 0, 11937 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)); 11938 snd_hda_codec_write(codec, 0x10, 0, 11939 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)); 11940 } 11941 11942 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */ 11943 if (line_nid == 0x14) 11944 dac_vol2 = AMP_OUT_ZERO; 11945 else if (line_nid == 0x15) 11946 dac_vol1 = AMP_OUT_ZERO; 11947 if (hp_nid == 0x14) 11948 dac_vol2 = AMP_OUT_ZERO; 11949 else if (hp_nid == 0x15) 11950 dac_vol1 = AMP_OUT_ZERO; 11951 if (line_nid != 0x16 || hp_nid != 0x16 || 11952 spec->autocfg.line_out_pins[1] != 0x16 || 11953 spec->autocfg.line_out_pins[2] != 0x16) 11954 dac_vol1 = dac_vol2 = AMP_OUT_ZERO; 11955 11956 snd_hda_codec_write(codec, 0x02, 0, 11957 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1); 11958 snd_hda_codec_write(codec, 0x03, 0, 11959 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2); 11960} 11961 11962/* pcm configuration: identiacal with ALC880 */ 11963#define alc268_pcm_analog_playback alc880_pcm_analog_playback 11964#define alc268_pcm_analog_capture alc880_pcm_analog_capture 11965#define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture 11966#define alc268_pcm_digital_playback alc880_pcm_digital_playback 11967 11968/* 11969 * BIOS auto configuration 11970 */ 11971static int alc268_parse_auto_config(struct hda_codec *codec) 11972{ 11973 struct alc_spec *spec = codec->spec; 11974 int err; 11975 static hda_nid_t alc268_ignore[] = { 0 }; 11976 11977 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 11978 alc268_ignore); 11979 if (err < 0) 11980 return err; 11981 if (!spec->autocfg.line_outs) { 11982 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) { 11983 spec->multiout.max_channels = 2; 11984 spec->no_analog = 1; 11985 goto dig_only; 11986 } 11987 return 0; /* can't find valid BIOS pin config */ 11988 } 11989 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg); 11990 if (err < 0) 11991 return err; 11992 err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg); 11993 if (err < 0) 11994 return err; 11995 11996 spec->multiout.max_channels = 2; 11997 11998 dig_only: 11999 /* digital only support output */ 12000 if (spec->autocfg.dig_outs) { 12001 spec->multiout.dig_out_nid = ALC268_DIGOUT_NID; 12002 spec->dig_out_type = spec->autocfg.dig_out_type[0]; 12003 } 12004 if (spec->kctls.list) 12005 add_mixer(spec, spec->kctls.list); 12006 12007 if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d) 12008 add_mixer(spec, alc268_beep_mixer); 12009 12010 add_verb(spec, alc268_volume_init_verbs); 12011 spec->num_mux_defs = 1; 12012 spec->input_mux = &spec->private_imux[0]; 12013 12014 err = alc_auto_add_mic_boost(codec); 12015 if (err < 0) 12016 return err; 12017 12018 return 1; 12019} 12020 12021#define alc268_auto_init_multi_out alc882_auto_init_multi_out 12022#define alc268_auto_init_hp_out alc882_auto_init_hp_out 12023#define alc268_auto_init_analog_input alc882_auto_init_analog_input 12024 12025/* init callback for auto-configuration model -- overriding the default init */ 12026static void alc268_auto_init(struct hda_codec *codec) 12027{ 12028 struct alc_spec *spec = codec->spec; 12029 alc268_auto_init_multi_out(codec); 12030 alc268_auto_init_hp_out(codec); 12031 alc268_auto_init_mono_speaker_out(codec); 12032 alc268_auto_init_analog_input(codec); 12033 if (spec->unsol_event) 12034 alc_inithook(codec); 12035} 12036 12037/* 12038 * configuration and preset 12039 */ 12040static const char *alc268_models[ALC268_MODEL_LAST] = { 12041 [ALC267_QUANTA_IL1] = "quanta-il1", 12042 [ALC268_3ST] = "3stack", 12043 [ALC268_TOSHIBA] = "toshiba", 12044 [ALC268_ACER] = "acer", 12045 [ALC268_ACER_DMIC] = "acer-dmic", 12046 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire", 12047 [ALC268_DELL] = "dell", 12048 [ALC268_ZEPTO] = "zepto", 12049#ifdef CONFIG_SND_DEBUG 12050 [ALC268_TEST] = "test", 12051#endif 12052 [ALC268_AUTO] = "auto", 12053}; 12054 12055static struct snd_pci_quirk alc268_cfg_tbl[] = { 12056 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER), 12057 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER), 12058 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER), 12059 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER), 12060 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER), 12061 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One", 12062 ALC268_ACER_ASPIRE_ONE), 12063 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL), 12064 SND_PCI_QUIRK(0x1028, 0x02b0, "Dell Inspiron Mini9", ALC268_DELL), 12065 SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA), 12066 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST), 12067 SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA), 12068 SND_PCI_QUIRK(0x1179, 0xff50, "TOSHIBA A305", ALC268_TOSHIBA), 12069 SND_PCI_QUIRK(0x1179, 0xff64, "TOSHIBA L305", ALC268_TOSHIBA), 12070 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA), 12071 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER), 12072 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1), 12073 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO), 12074 {} 12075}; 12076 12077static struct alc_config_preset alc268_presets[] = { 12078 [ALC267_QUANTA_IL1] = { 12079 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer }, 12080 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 12081 alc267_quanta_il1_verbs }, 12082 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 12083 .dac_nids = alc268_dac_nids, 12084 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 12085 .adc_nids = alc268_adc_nids_alt, 12086 .hp_nid = 0x03, 12087 .num_channel_mode = ARRAY_SIZE(alc268_modes), 12088 .channel_mode = alc268_modes, 12089 .input_mux = &alc268_capture_source, 12090 .unsol_event = alc267_quanta_il1_unsol_event, 12091 .init_hook = alc267_quanta_il1_automute, 12092 }, 12093 [ALC268_3ST] = { 12094 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer, 12095 alc268_beep_mixer }, 12096 .init_verbs = { alc268_base_init_verbs }, 12097 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 12098 .dac_nids = alc268_dac_nids, 12099 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 12100 .adc_nids = alc268_adc_nids_alt, 12101 .capsrc_nids = alc268_capsrc_nids, 12102 .hp_nid = 0x03, 12103 .dig_out_nid = ALC268_DIGOUT_NID, 12104 .num_channel_mode = ARRAY_SIZE(alc268_modes), 12105 .channel_mode = alc268_modes, 12106 .input_mux = &alc268_capture_source, 12107 }, 12108 [ALC268_TOSHIBA] = { 12109 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer, 12110 alc268_beep_mixer }, 12111 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 12112 alc268_toshiba_verbs }, 12113 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 12114 .dac_nids = alc268_dac_nids, 12115 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 12116 .adc_nids = alc268_adc_nids_alt, 12117 .capsrc_nids = alc268_capsrc_nids, 12118 .hp_nid = 0x03, 12119 .num_channel_mode = ARRAY_SIZE(alc268_modes), 12120 .channel_mode = alc268_modes, 12121 .input_mux = &alc268_capture_source, 12122 .unsol_event = alc268_toshiba_unsol_event, 12123 .init_hook = alc268_toshiba_automute, 12124 }, 12125 [ALC268_ACER] = { 12126 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer, 12127 alc268_beep_mixer }, 12128 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 12129 alc268_acer_verbs }, 12130 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 12131 .dac_nids = alc268_dac_nids, 12132 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 12133 .adc_nids = alc268_adc_nids_alt, 12134 .capsrc_nids = alc268_capsrc_nids, 12135 .hp_nid = 0x02, 12136 .num_channel_mode = ARRAY_SIZE(alc268_modes), 12137 .channel_mode = alc268_modes, 12138 .input_mux = &alc268_acer_capture_source, 12139 .unsol_event = alc268_acer_unsol_event, 12140 .init_hook = alc268_acer_init_hook, 12141 }, 12142 [ALC268_ACER_DMIC] = { 12143 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer, 12144 alc268_beep_mixer }, 12145 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 12146 alc268_acer_verbs }, 12147 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 12148 .dac_nids = alc268_dac_nids, 12149 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 12150 .adc_nids = alc268_adc_nids_alt, 12151 .capsrc_nids = alc268_capsrc_nids, 12152 .hp_nid = 0x02, 12153 .num_channel_mode = ARRAY_SIZE(alc268_modes), 12154 .channel_mode = alc268_modes, 12155 .input_mux = &alc268_acer_dmic_capture_source, 12156 .unsol_event = alc268_acer_unsol_event, 12157 .init_hook = alc268_acer_init_hook, 12158 }, 12159 [ALC268_ACER_ASPIRE_ONE] = { 12160 .mixers = { alc268_acer_aspire_one_mixer, 12161 alc268_beep_mixer, 12162 alc268_capture_alt_mixer }, 12163 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 12164 alc268_acer_aspire_one_verbs }, 12165 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 12166 .dac_nids = alc268_dac_nids, 12167 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 12168 .adc_nids = alc268_adc_nids_alt, 12169 .capsrc_nids = alc268_capsrc_nids, 12170 .hp_nid = 0x03, 12171 .num_channel_mode = ARRAY_SIZE(alc268_modes), 12172 .channel_mode = alc268_modes, 12173 .input_mux = &alc268_acer_lc_capture_source, 12174 .unsol_event = alc268_acer_lc_unsol_event, 12175 .init_hook = alc268_acer_lc_init_hook, 12176 }, 12177 [ALC268_DELL] = { 12178 .mixers = { alc268_dell_mixer, alc268_beep_mixer }, 12179 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 12180 alc268_dell_verbs }, 12181 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 12182 .dac_nids = alc268_dac_nids, 12183 .hp_nid = 0x02, 12184 .num_channel_mode = ARRAY_SIZE(alc268_modes), 12185 .channel_mode = alc268_modes, 12186 .unsol_event = alc268_dell_unsol_event, 12187 .init_hook = alc268_dell_init_hook, 12188 .input_mux = &alc268_capture_source, 12189 }, 12190 [ALC268_ZEPTO] = { 12191 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer, 12192 alc268_beep_mixer }, 12193 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 12194 alc268_toshiba_verbs }, 12195 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 12196 .dac_nids = alc268_dac_nids, 12197 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 12198 .adc_nids = alc268_adc_nids_alt, 12199 .capsrc_nids = alc268_capsrc_nids, 12200 .hp_nid = 0x03, 12201 .dig_out_nid = ALC268_DIGOUT_NID, 12202 .num_channel_mode = ARRAY_SIZE(alc268_modes), 12203 .channel_mode = alc268_modes, 12204 .input_mux = &alc268_capture_source, 12205 .unsol_event = alc268_toshiba_unsol_event, 12206 .init_hook = alc268_toshiba_automute 12207 }, 12208#ifdef CONFIG_SND_DEBUG 12209 [ALC268_TEST] = { 12210 .mixers = { alc268_test_mixer, alc268_capture_mixer }, 12211 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 12212 alc268_volume_init_verbs }, 12213 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 12214 .dac_nids = alc268_dac_nids, 12215 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 12216 .adc_nids = alc268_adc_nids_alt, 12217 .capsrc_nids = alc268_capsrc_nids, 12218 .hp_nid = 0x03, 12219 .dig_out_nid = ALC268_DIGOUT_NID, 12220 .num_channel_mode = ARRAY_SIZE(alc268_modes), 12221 .channel_mode = alc268_modes, 12222 .input_mux = &alc268_capture_source, 12223 }, 12224#endif 12225}; 12226 12227static int patch_alc268(struct hda_codec *codec) 12228{ 12229 struct alc_spec *spec; 12230 int board_config; 12231 int i, has_beep, err; 12232 12233 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); 12234 if (spec == NULL) 12235 return -ENOMEM; 12236 12237 codec->spec = spec; 12238 12239 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST, 12240 alc268_models, 12241 alc268_cfg_tbl); 12242 12243 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) { 12244 printk(KERN_INFO "hda_codec: Unknown model for ALC268, " 12245 "trying auto-probe from BIOS...\n"); 12246 board_config = ALC268_AUTO; 12247 } 12248 12249 if (board_config == ALC268_AUTO) { 12250 /* automatic parse from the BIOS config */ 12251 err = alc268_parse_auto_config(codec); 12252 if (err < 0) { 12253 alc_free(codec); 12254 return err; 12255 } else if (!err) { 12256 printk(KERN_INFO 12257 "hda_codec: Cannot set up configuration " 12258 "from BIOS. Using base mode...\n"); 12259 board_config = ALC268_3ST; 12260 } 12261 } 12262 12263 if (board_config != ALC268_AUTO) 12264 setup_preset(spec, &alc268_presets[board_config]); 12265 12266 if (codec->vendor_id == 0x10ec0267) { 12267 spec->stream_name_analog = "ALC267 Analog"; 12268 spec->stream_name_digital = "ALC267 Digital"; 12269 } else { 12270 spec->stream_name_analog = "ALC268 Analog"; 12271 spec->stream_name_digital = "ALC268 Digital"; 12272 } 12273 12274 spec->stream_analog_playback = &alc268_pcm_analog_playback; 12275 spec->stream_analog_capture = &alc268_pcm_analog_capture; 12276 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture; 12277 12278 spec->stream_digital_playback = &alc268_pcm_digital_playback; 12279 12280 has_beep = 0; 12281 for (i = 0; i < spec->num_mixers; i++) { 12282 if (spec->mixers[i] == alc268_beep_mixer) { 12283 has_beep = 1; 12284 break; 12285 } 12286 } 12287 12288 if (has_beep) { 12289 err = snd_hda_attach_beep_device(codec, 0x1); 12290 if (err < 0) { 12291 alc_free(codec); 12292 return err; 12293 } 12294 if (!query_amp_caps(codec, 0x1d, HDA_INPUT)) 12295 /* override the amp caps for beep generator */ 12296 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT, 12297 (0x0c << AC_AMPCAP_OFFSET_SHIFT) | 12298 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) | 12299 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) | 12300 (0 << AC_AMPCAP_MUTE_SHIFT)); 12301 } 12302 12303 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) { 12304 /* check whether NID 0x07 is valid */ 12305 unsigned int wcap = get_wcaps(codec, 0x07); 12306 int i; 12307 12308 /* get type */ 12309 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; 12310 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) { 12311 spec->adc_nids = alc268_adc_nids_alt; 12312 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt); 12313 add_mixer(spec, alc268_capture_alt_mixer); 12314 } else { 12315 spec->adc_nids = alc268_adc_nids; 12316 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids); 12317 add_mixer(spec, alc268_capture_mixer); 12318 } 12319 spec->capsrc_nids = alc268_capsrc_nids; 12320 /* set default input source */ 12321 for (i = 0; i < spec->num_adc_nids; i++) 12322 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i], 12323 0, AC_VERB_SET_CONNECT_SEL, 12324 spec->input_mux->items[0].index); 12325 } 12326 12327 spec->vmaster_nid = 0x02; 12328 12329 codec->patch_ops = alc_patch_ops; 12330 if (board_config == ALC268_AUTO) 12331 spec->init_hook = alc268_auto_init; 12332 12333 codec->proc_widget_hook = print_realtek_coef; 12334 12335 return 0; 12336} 12337 12338/* 12339 * ALC269 channel source setting (2 channel) 12340 */ 12341#define ALC269_DIGOUT_NID ALC880_DIGOUT_NID 12342 12343#define alc269_dac_nids alc260_dac_nids 12344 12345static hda_nid_t alc269_adc_nids[1] = { 12346 /* ADC1 */ 12347 0x08, 12348}; 12349 12350static hda_nid_t alc269_capsrc_nids[1] = { 12351 0x23, 12352}; 12353 12354/* NOTE: ADC2 (0x07) is connected from a recording *MIXER* (0x24), 12355 * not a mux! 12356 */ 12357 12358static struct hda_input_mux alc269_eeepc_dmic_capture_source = { 12359 .num_items = 2, 12360 .items = { 12361 { "i-Mic", 0x5 }, 12362 { "e-Mic", 0x0 }, 12363 }, 12364}; 12365 12366static struct hda_input_mux alc269_eeepc_amic_capture_source = { 12367 .num_items = 2, 12368 .items = { 12369 { "i-Mic", 0x1 }, 12370 { "e-Mic", 0x0 }, 12371 }, 12372}; 12373 12374#define alc269_modes alc260_modes 12375#define alc269_capture_source alc880_lg_lw_capture_source 12376 12377static struct snd_kcontrol_new alc269_base_mixer[] = { 12378 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 12379 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 12380 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 12381 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 12382 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 12383 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 12384 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 12385 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 12386 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 12387 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 12388 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 12389 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT), 12390 { } /* end */ 12391}; 12392 12393static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = { 12394 /* output mixer control */ 12395 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), 12396 { 12397 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 12398 .name = "Master Playback Switch", 12399 .info = snd_hda_mixer_amp_switch_info, 12400 .get = snd_hda_mixer_amp_switch_get, 12401 .put = alc268_acer_master_sw_put, 12402 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 12403 }, 12404 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 12405 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 12406 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 12407 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 12408 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 12409 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), 12410 { } 12411}; 12412 12413static struct snd_kcontrol_new alc269_lifebook_mixer[] = { 12414 /* output mixer control */ 12415 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), 12416 { 12417 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 12418 .name = "Master Playback Switch", 12419 .info = snd_hda_mixer_amp_switch_info, 12420 .get = snd_hda_mixer_amp_switch_get, 12421 .put = alc268_acer_master_sw_put, 12422 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 12423 }, 12424 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 12425 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 12426 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 12427 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 12428 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 12429 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), 12430 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT), 12431 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT), 12432 HDA_CODEC_VOLUME("Dock Mic Boost", 0x1b, 0, HDA_INPUT), 12433 { } 12434}; 12435 12436/* bind volumes of both NID 0x0c and 0x0d */ 12437static struct hda_bind_ctls alc269_epc_bind_vol = { 12438 .ops = &snd_hda_bind_vol, 12439 .values = { 12440 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), 12441 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT), 12442 0 12443 }, 12444}; 12445 12446static struct snd_kcontrol_new alc269_eeepc_mixer[] = { 12447 HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 12448 HDA_BIND_VOL("LineOut Playback Volume", &alc269_epc_bind_vol), 12449 HDA_CODEC_MUTE("LineOut Playback Switch", 0x15, 0x0, HDA_OUTPUT), 12450 { } /* end */ 12451}; 12452 12453/* capture mixer elements */ 12454static struct snd_kcontrol_new alc269_epc_capture_mixer[] = { 12455 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 12456 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 12457 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 12458 { } /* end */ 12459}; 12460 12461/* FSC amilo */ 12462static struct snd_kcontrol_new alc269_fujitsu_mixer[] = { 12463 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 12464 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 12465 HDA_BIND_VOL("PCM Playback Volume", &alc269_epc_bind_vol), 12466 { } /* end */ 12467}; 12468 12469static struct hda_verb alc269_quanta_fl1_verbs[] = { 12470 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 12471 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 12472 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 12473 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 12474 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 12475 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 12476 { } 12477}; 12478 12479static struct hda_verb alc269_lifebook_verbs[] = { 12480 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 12481 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, 12482 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 12483 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 12484 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 12485 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 12486 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 12487 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 12488 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 12489 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 12490 { } 12491}; 12492 12493/* toggle speaker-output according to the hp-jack state */ 12494static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec) 12495{ 12496 unsigned int present; 12497 unsigned char bits; 12498 12499 present = snd_hda_codec_read(codec, 0x15, 0, 12500 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 12501 bits = present ? AMP_IN_MUTE(0) : 0; 12502 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 12503 AMP_IN_MUTE(0), bits); 12504 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 12505 AMP_IN_MUTE(0), bits); 12506 12507 snd_hda_codec_write(codec, 0x20, 0, 12508 AC_VERB_SET_COEF_INDEX, 0x0c); 12509 snd_hda_codec_write(codec, 0x20, 0, 12510 AC_VERB_SET_PROC_COEF, 0x680); 12511 12512 snd_hda_codec_write(codec, 0x20, 0, 12513 AC_VERB_SET_COEF_INDEX, 0x0c); 12514 snd_hda_codec_write(codec, 0x20, 0, 12515 AC_VERB_SET_PROC_COEF, 0x480); 12516} 12517 12518/* toggle speaker-output according to the hp-jacks state */ 12519static void alc269_lifebook_speaker_automute(struct hda_codec *codec) 12520{ 12521 unsigned int present; 12522 unsigned char bits; 12523 12524 /* Check laptop headphone socket */ 12525 present = snd_hda_codec_read(codec, 0x15, 0, 12526 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 12527 12528 /* Check port replicator headphone socket */ 12529 present |= snd_hda_codec_read(codec, 0x1a, 0, 12530 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 12531 12532 bits = present ? AMP_IN_MUTE(0) : 0; 12533 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 12534 AMP_IN_MUTE(0), bits); 12535 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 12536 AMP_IN_MUTE(0), bits); 12537 12538 snd_hda_codec_write(codec, 0x20, 0, 12539 AC_VERB_SET_COEF_INDEX, 0x0c); 12540 snd_hda_codec_write(codec, 0x20, 0, 12541 AC_VERB_SET_PROC_COEF, 0x680); 12542 12543 snd_hda_codec_write(codec, 0x20, 0, 12544 AC_VERB_SET_COEF_INDEX, 0x0c); 12545 snd_hda_codec_write(codec, 0x20, 0, 12546 AC_VERB_SET_PROC_COEF, 0x480); 12547} 12548 12549static void alc269_quanta_fl1_mic_automute(struct hda_codec *codec) 12550{ 12551 unsigned int present; 12552 12553 present = snd_hda_codec_read(codec, 0x18, 0, 12554 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 12555 snd_hda_codec_write(codec, 0x23, 0, 12556 AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x1); 12557} 12558 12559static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec) 12560{ 12561 unsigned int present_laptop; 12562 unsigned int present_dock; 12563 12564 present_laptop = snd_hda_codec_read(codec, 0x18, 0, 12565 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 12566 12567 present_dock = snd_hda_codec_read(codec, 0x1b, 0, 12568 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 12569 12570 /* Laptop mic port overrides dock mic port, design decision */ 12571 if (present_dock) 12572 snd_hda_codec_write(codec, 0x23, 0, 12573 AC_VERB_SET_CONNECT_SEL, 0x3); 12574 if (present_laptop) 12575 snd_hda_codec_write(codec, 0x23, 0, 12576 AC_VERB_SET_CONNECT_SEL, 0x0); 12577 if (!present_dock && !present_laptop) 12578 snd_hda_codec_write(codec, 0x23, 0, 12579 AC_VERB_SET_CONNECT_SEL, 0x1); 12580} 12581 12582static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec, 12583 unsigned int res) 12584{ 12585 if ((res >> 26) == ALC880_HP_EVENT) 12586 alc269_quanta_fl1_speaker_automute(codec); 12587 if ((res >> 26) == ALC880_MIC_EVENT) 12588 alc269_quanta_fl1_mic_automute(codec); 12589} 12590 12591static void alc269_lifebook_unsol_event(struct hda_codec *codec, 12592 unsigned int res) 12593{ 12594 if ((res >> 26) == ALC880_HP_EVENT) 12595 alc269_lifebook_speaker_automute(codec); 12596 if ((res >> 26) == ALC880_MIC_EVENT) 12597 alc269_lifebook_mic_autoswitch(codec); 12598} 12599 12600static void alc269_quanta_fl1_init_hook(struct hda_codec *codec) 12601{ 12602 alc269_quanta_fl1_speaker_automute(codec); 12603 alc269_quanta_fl1_mic_automute(codec); 12604} 12605 12606static void alc269_lifebook_init_hook(struct hda_codec *codec) 12607{ 12608 alc269_lifebook_speaker_automute(codec); 12609 alc269_lifebook_mic_autoswitch(codec); 12610} 12611 12612static struct hda_verb alc269_eeepc_dmic_init_verbs[] = { 12613 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 12614 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05}, 12615 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 }, 12616 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))}, 12617 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 12618 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 12619 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 12620 {} 12621}; 12622 12623static struct hda_verb alc269_eeepc_amic_init_verbs[] = { 12624 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 12625 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01}, 12626 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 }, 12627 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))}, 12628 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 12629 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 12630 {} 12631}; 12632 12633/* toggle speaker-output according to the hp-jack state */ 12634static void alc269_speaker_automute(struct hda_codec *codec) 12635{ 12636 unsigned int present; 12637 unsigned char bits; 12638 12639 present = snd_hda_codec_read(codec, 0x15, 0, 12640 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 12641 bits = present ? AMP_IN_MUTE(0) : 0; 12642 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 12643 AMP_IN_MUTE(0), bits); 12644 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 12645 AMP_IN_MUTE(0), bits); 12646} 12647 12648static void alc269_eeepc_dmic_automute(struct hda_codec *codec) 12649{ 12650 unsigned int present; 12651 12652 present = snd_hda_codec_read(codec, 0x18, 0, 12653 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 12654 snd_hda_codec_write(codec, 0x23, 0, 12655 AC_VERB_SET_CONNECT_SEL, (present ? 0 : 5)); 12656} 12657 12658static void alc269_eeepc_amic_automute(struct hda_codec *codec) 12659{ 12660 unsigned int present; 12661 12662 present = snd_hda_codec_read(codec, 0x18, 0, 12663 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 12664 snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE, 12665 0x7000 | (0x00 << 8) | (present ? 0 : 0x80)); 12666 snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE, 12667 0x7000 | (0x01 << 8) | (present ? 0x80 : 0)); 12668} 12669 12670/* unsolicited event for HP jack sensing */ 12671static void alc269_eeepc_dmic_unsol_event(struct hda_codec *codec, 12672 unsigned int res) 12673{ 12674 if ((res >> 26) == ALC880_HP_EVENT) 12675 alc269_speaker_automute(codec); 12676 12677 if ((res >> 26) == ALC880_MIC_EVENT) 12678 alc269_eeepc_dmic_automute(codec); 12679} 12680 12681static void alc269_eeepc_dmic_inithook(struct hda_codec *codec) 12682{ 12683 alc269_speaker_automute(codec); 12684 alc269_eeepc_dmic_automute(codec); 12685} 12686 12687/* unsolicited event for HP jack sensing */ 12688static void alc269_eeepc_amic_unsol_event(struct hda_codec *codec, 12689 unsigned int res) 12690{ 12691 if ((res >> 26) == ALC880_HP_EVENT) 12692 alc269_speaker_automute(codec); 12693 12694 if ((res >> 26) == ALC880_MIC_EVENT) 12695 alc269_eeepc_amic_automute(codec); 12696} 12697 12698static void alc269_eeepc_amic_inithook(struct hda_codec *codec) 12699{ 12700 alc269_speaker_automute(codec); 12701 alc269_eeepc_amic_automute(codec); 12702} 12703 12704/* 12705 * generic initialization of ADC, input mixers and output mixers 12706 */ 12707static struct hda_verb alc269_init_verbs[] = { 12708 /* 12709 * Unmute ADC0 and set the default input to mic-in 12710 */ 12711 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12712 12713 /* Mute input amps (PCBeep, Line In, Mic 1 & Mic 2) of the 12714 * analog-loopback mixer widget 12715 * Note: PASD motherboards uses the Line In 2 as the input for 12716 * front panel mic (mic 2) 12717 */ 12718 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 12719 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 12720 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 12721 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 12722 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 12723 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 12724 12725 /* 12726 * Set up output mixers (0x0c - 0x0e) 12727 */ 12728 /* set vol=0 to output mixers */ 12729 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 12730 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 12731 12732 /* set up input amps for analog loopback */ 12733 /* Amp Indices: DAC = 0, mixer = 1 */ 12734 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12735 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12736 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12737 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12738 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12739 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12740 12741 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 12742 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 12743 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 12744 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 12745 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 12746 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 12747 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 12748 12749 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 12750 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 12751 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 12752 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 12753 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 12754 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 12755 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 12756 12757 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 12758 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 12759 12760 /* FIXME: use matrix-type input source selection */ 12761 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */ 12762 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 12763 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 12764 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12765 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 12766 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 12767 12768 /* set EAPD */ 12769 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 12770 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, 12771 { } 12772}; 12773 12774/* add playback controls from the parsed DAC table */ 12775static int alc269_auto_create_multi_out_ctls(struct alc_spec *spec, 12776 const struct auto_pin_cfg *cfg) 12777{ 12778 hda_nid_t nid; 12779 int err; 12780 12781 spec->multiout.num_dacs = 1; /* only use one dac */ 12782 spec->multiout.dac_nids = spec->private_dac_nids; 12783 spec->multiout.dac_nids[0] = 2; 12784 12785 nid = cfg->line_out_pins[0]; 12786 if (nid) { 12787 err = add_control(spec, ALC_CTL_WIDGET_VOL, 12788 "Front Playback Volume", 12789 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT)); 12790 if (err < 0) 12791 return err; 12792 err = add_control(spec, ALC_CTL_WIDGET_MUTE, 12793 "Front Playback Switch", 12794 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); 12795 if (err < 0) 12796 return err; 12797 } 12798 12799 nid = cfg->speaker_pins[0]; 12800 if (nid) { 12801 if (!cfg->line_out_pins[0]) { 12802 err = add_control(spec, ALC_CTL_WIDGET_VOL, 12803 "Speaker Playback Volume", 12804 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, 12805 HDA_OUTPUT)); 12806 if (err < 0) 12807 return err; 12808 } 12809 if (nid == 0x16) { 12810 err = add_control(spec, ALC_CTL_WIDGET_MUTE, 12811 "Speaker Playback Switch", 12812 HDA_COMPOSE_AMP_VAL(nid, 2, 0, 12813 HDA_OUTPUT)); 12814 if (err < 0) 12815 return err; 12816 } else { 12817 err = add_control(spec, ALC_CTL_WIDGET_MUTE, 12818 "Speaker Playback Switch", 12819 HDA_COMPOSE_AMP_VAL(nid, 3, 0, 12820 HDA_OUTPUT)); 12821 if (err < 0) 12822 return err; 12823 } 12824 } 12825 nid = cfg->hp_pins[0]; 12826 if (nid) { 12827 /* spec->multiout.hp_nid = 2; */ 12828 if (!cfg->line_out_pins[0] && !cfg->speaker_pins[0]) { 12829 err = add_control(spec, ALC_CTL_WIDGET_VOL, 12830 "Headphone Playback Volume", 12831 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, 12832 HDA_OUTPUT)); 12833 if (err < 0) 12834 return err; 12835 } 12836 if (nid == 0x16) { 12837 err = add_control(spec, ALC_CTL_WIDGET_MUTE, 12838 "Headphone Playback Switch", 12839 HDA_COMPOSE_AMP_VAL(nid, 2, 0, 12840 HDA_OUTPUT)); 12841 if (err < 0) 12842 return err; 12843 } else { 12844 err = add_control(spec, ALC_CTL_WIDGET_MUTE, 12845 "Headphone Playback Switch", 12846 HDA_COMPOSE_AMP_VAL(nid, 3, 0, 12847 HDA_OUTPUT)); 12848 if (err < 0) 12849 return err; 12850 } 12851 } 12852 return 0; 12853} 12854 12855static int alc269_auto_create_analog_input_ctls(struct alc_spec *spec, 12856 const struct auto_pin_cfg *cfg) 12857{ 12858 int err; 12859 12860 err = alc880_auto_create_analog_input_ctls(spec, cfg); 12861 if (err < 0) 12862 return err; 12863 /* digital-mic input pin is excluded in alc880_auto_create..() 12864 * because it's under 0x18 12865 */ 12866 if (cfg->input_pins[AUTO_PIN_MIC] == 0x12 || 12867 cfg->input_pins[AUTO_PIN_FRONT_MIC] == 0x12) { 12868 struct hda_input_mux *imux = &spec->private_imux[0]; 12869 imux->items[imux->num_items].label = "Int Mic"; 12870 imux->items[imux->num_items].index = 0x05; 12871 imux->num_items++; 12872 } 12873 return 0; 12874} 12875 12876#ifdef CONFIG_SND_HDA_POWER_SAVE 12877#define alc269_loopbacks alc880_loopbacks 12878#endif 12879 12880/* pcm configuration: identiacal with ALC880 */ 12881#define alc269_pcm_analog_playback alc880_pcm_analog_playback 12882#define alc269_pcm_analog_capture alc880_pcm_analog_capture 12883#define alc269_pcm_digital_playback alc880_pcm_digital_playback 12884#define alc269_pcm_digital_capture alc880_pcm_digital_capture 12885 12886static struct hda_pcm_stream alc269_44k_pcm_analog_playback = { 12887 .substreams = 1, 12888 .channels_min = 2, 12889 .channels_max = 8, 12890 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */ 12891 /* NID is set in alc_build_pcms */ 12892 .ops = { 12893 .open = alc880_playback_pcm_open, 12894 .prepare = alc880_playback_pcm_prepare, 12895 .cleanup = alc880_playback_pcm_cleanup 12896 }, 12897}; 12898 12899static struct hda_pcm_stream alc269_44k_pcm_analog_capture = { 12900 .substreams = 1, 12901 .channels_min = 2, 12902 .channels_max = 2, 12903 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */ 12904 /* NID is set in alc_build_pcms */ 12905}; 12906 12907/* 12908 * BIOS auto configuration 12909 */ 12910static int alc269_parse_auto_config(struct hda_codec *codec) 12911{ 12912 struct alc_spec *spec = codec->spec; 12913 int err; 12914 static hda_nid_t alc269_ignore[] = { 0x1d, 0 }; 12915 12916 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 12917 alc269_ignore); 12918 if (err < 0) 12919 return err; 12920 12921 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg); 12922 if (err < 0) 12923 return err; 12924 err = alc269_auto_create_analog_input_ctls(spec, &spec->autocfg); 12925 if (err < 0) 12926 return err; 12927 12928 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 12929 12930 if (spec->autocfg.dig_outs) 12931 spec->multiout.dig_out_nid = ALC269_DIGOUT_NID; 12932 12933 if (spec->kctls.list) 12934 add_mixer(spec, spec->kctls.list); 12935 12936 add_verb(spec, alc269_init_verbs); 12937 spec->num_mux_defs = 1; 12938 spec->input_mux = &spec->private_imux[0]; 12939 /* set default input source */ 12940 snd_hda_codec_write_cache(codec, alc269_capsrc_nids[0], 12941 0, AC_VERB_SET_CONNECT_SEL, 12942 spec->input_mux->items[0].index); 12943 12944 err = alc_auto_add_mic_boost(codec); 12945 if (err < 0) 12946 return err; 12947 12948 if (!spec->cap_mixer && !spec->no_analog) 12949 set_capture_mixer(spec); 12950 12951 return 1; 12952} 12953 12954#define alc269_auto_init_multi_out alc882_auto_init_multi_out 12955#define alc269_auto_init_hp_out alc882_auto_init_hp_out 12956#define alc269_auto_init_analog_input alc882_auto_init_analog_input 12957 12958 12959/* init callback for auto-configuration model -- overriding the default init */ 12960static void alc269_auto_init(struct hda_codec *codec) 12961{ 12962 struct alc_spec *spec = codec->spec; 12963 alc269_auto_init_multi_out(codec); 12964 alc269_auto_init_hp_out(codec); 12965 alc269_auto_init_analog_input(codec); 12966 if (spec->unsol_event) 12967 alc_inithook(codec); 12968} 12969 12970/* 12971 * configuration and preset 12972 */ 12973static const char *alc269_models[ALC269_MODEL_LAST] = { 12974 [ALC269_BASIC] = "basic", 12975 [ALC269_QUANTA_FL1] = "quanta", 12976 [ALC269_ASUS_EEEPC_P703] = "eeepc-p703", 12977 [ALC269_ASUS_EEEPC_P901] = "eeepc-p901", 12978 [ALC269_FUJITSU] = "fujitsu", 12979 [ALC269_LIFEBOOK] = "lifebook" 12980}; 12981 12982static struct snd_pci_quirk alc269_cfg_tbl[] = { 12983 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1), 12984 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A", 12985 ALC269_ASUS_EEEPC_P703), 12986 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_ASUS_EEEPC_P703), 12987 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_ASUS_EEEPC_P703), 12988 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_ASUS_EEEPC_P703), 12989 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_ASUS_EEEPC_P703), 12990 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_ASUS_EEEPC_P703), 12991 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_ASUS_EEEPC_P703), 12992 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901", 12993 ALC269_ASUS_EEEPC_P901), 12994 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101", 12995 ALC269_ASUS_EEEPC_P901), 12996 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_ASUS_EEEPC_P901), 12997 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU), 12998 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK), 12999 {} 13000}; 13001 13002static struct alc_config_preset alc269_presets[] = { 13003 [ALC269_BASIC] = { 13004 .mixers = { alc269_base_mixer }, 13005 .init_verbs = { alc269_init_verbs }, 13006 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 13007 .dac_nids = alc269_dac_nids, 13008 .hp_nid = 0x03, 13009 .num_channel_mode = ARRAY_SIZE(alc269_modes), 13010 .channel_mode = alc269_modes, 13011 .input_mux = &alc269_capture_source, 13012 }, 13013 [ALC269_QUANTA_FL1] = { 13014 .mixers = { alc269_quanta_fl1_mixer }, 13015 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs }, 13016 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 13017 .dac_nids = alc269_dac_nids, 13018 .hp_nid = 0x03, 13019 .num_channel_mode = ARRAY_SIZE(alc269_modes), 13020 .channel_mode = alc269_modes, 13021 .input_mux = &alc269_capture_source, 13022 .unsol_event = alc269_quanta_fl1_unsol_event, 13023 .init_hook = alc269_quanta_fl1_init_hook, 13024 }, 13025 [ALC269_ASUS_EEEPC_P703] = { 13026 .mixers = { alc269_eeepc_mixer }, 13027 .cap_mixer = alc269_epc_capture_mixer, 13028 .init_verbs = { alc269_init_verbs, 13029 alc269_eeepc_amic_init_verbs }, 13030 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 13031 .dac_nids = alc269_dac_nids, 13032 .hp_nid = 0x03, 13033 .num_channel_mode = ARRAY_SIZE(alc269_modes), 13034 .channel_mode = alc269_modes, 13035 .input_mux = &alc269_eeepc_amic_capture_source, 13036 .unsol_event = alc269_eeepc_amic_unsol_event, 13037 .init_hook = alc269_eeepc_amic_inithook, 13038 }, 13039 [ALC269_ASUS_EEEPC_P901] = { 13040 .mixers = { alc269_eeepc_mixer }, 13041 .cap_mixer = alc269_epc_capture_mixer, 13042 .init_verbs = { alc269_init_verbs, 13043 alc269_eeepc_dmic_init_verbs }, 13044 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 13045 .dac_nids = alc269_dac_nids, 13046 .hp_nid = 0x03, 13047 .num_channel_mode = ARRAY_SIZE(alc269_modes), 13048 .channel_mode = alc269_modes, 13049 .input_mux = &alc269_eeepc_dmic_capture_source, 13050 .unsol_event = alc269_eeepc_dmic_unsol_event, 13051 .init_hook = alc269_eeepc_dmic_inithook, 13052 }, 13053 [ALC269_FUJITSU] = { 13054 .mixers = { alc269_fujitsu_mixer }, 13055 .cap_mixer = alc269_epc_capture_mixer, 13056 .init_verbs = { alc269_init_verbs, 13057 alc269_eeepc_dmic_init_verbs }, 13058 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 13059 .dac_nids = alc269_dac_nids, 13060 .hp_nid = 0x03, 13061 .num_channel_mode = ARRAY_SIZE(alc269_modes), 13062 .channel_mode = alc269_modes, 13063 .input_mux = &alc269_eeepc_dmic_capture_source, 13064 .unsol_event = alc269_eeepc_dmic_unsol_event, 13065 .init_hook = alc269_eeepc_dmic_inithook, 13066 }, 13067 [ALC269_LIFEBOOK] = { 13068 .mixers = { alc269_lifebook_mixer }, 13069 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs }, 13070 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 13071 .dac_nids = alc269_dac_nids, 13072 .hp_nid = 0x03, 13073 .num_channel_mode = ARRAY_SIZE(alc269_modes), 13074 .channel_mode = alc269_modes, 13075 .input_mux = &alc269_capture_source, 13076 .unsol_event = alc269_lifebook_unsol_event, 13077 .init_hook = alc269_lifebook_init_hook, 13078 }, 13079}; 13080 13081static int patch_alc269(struct hda_codec *codec) 13082{ 13083 struct alc_spec *spec; 13084 int board_config; 13085 int err; 13086 13087 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 13088 if (spec == NULL) 13089 return -ENOMEM; 13090 13091 codec->spec = spec; 13092 13093 alc_fix_pll_init(codec, 0x20, 0x04, 15); 13094 13095 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST, 13096 alc269_models, 13097 alc269_cfg_tbl); 13098 13099 if (board_config < 0) { 13100 printk(KERN_INFO "hda_codec: Unknown model for ALC269, " 13101 "trying auto-probe from BIOS...\n"); 13102 board_config = ALC269_AUTO; 13103 } 13104 13105 if (board_config == ALC269_AUTO) { 13106 /* automatic parse from the BIOS config */ 13107 err = alc269_parse_auto_config(codec); 13108 if (err < 0) { 13109 alc_free(codec); 13110 return err; 13111 } else if (!err) { 13112 printk(KERN_INFO 13113 "hda_codec: Cannot set up configuration " 13114 "from BIOS. Using base mode...\n"); 13115 board_config = ALC269_BASIC; 13116 } 13117 } 13118 13119 err = snd_hda_attach_beep_device(codec, 0x1); 13120 if (err < 0) { 13121 alc_free(codec); 13122 return err; 13123 } 13124 13125 if (board_config != ALC269_AUTO) 13126 setup_preset(spec, &alc269_presets[board_config]); 13127 13128 spec->stream_name_analog = "ALC269 Analog"; 13129 if (codec->subsystem_id == 0x17aa3bf8) { 13130 /* Due to a hardware problem on Lenovo Ideadpad, we need to 13131 * fix the sample rate of analog I/O to 44.1kHz 13132 */ 13133 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback; 13134 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture; 13135 } else { 13136 spec->stream_analog_playback = &alc269_pcm_analog_playback; 13137 spec->stream_analog_capture = &alc269_pcm_analog_capture; 13138 } 13139 spec->stream_name_digital = "ALC269 Digital"; 13140 spec->stream_digital_playback = &alc269_pcm_digital_playback; 13141 spec->stream_digital_capture = &alc269_pcm_digital_capture; 13142 13143 spec->adc_nids = alc269_adc_nids; 13144 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids); 13145 spec->capsrc_nids = alc269_capsrc_nids; 13146 if (!spec->cap_mixer) 13147 set_capture_mixer(spec); 13148 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); 13149 13150 codec->patch_ops = alc_patch_ops; 13151 if (board_config == ALC269_AUTO) 13152 spec->init_hook = alc269_auto_init; 13153#ifdef CONFIG_SND_HDA_POWER_SAVE 13154 if (!spec->loopback.amplist) 13155 spec->loopback.amplist = alc269_loopbacks; 13156#endif 13157 codec->proc_widget_hook = print_realtek_coef; 13158 13159 return 0; 13160} 13161 13162/* 13163 * ALC861 channel source setting (2/6 channel selection for 3-stack) 13164 */ 13165 13166/* 13167 * set the path ways for 2 channel output 13168 * need to set the codec line out and mic 1 pin widgets to inputs 13169 */ 13170static struct hda_verb alc861_threestack_ch2_init[] = { 13171 /* set pin widget 1Ah (line in) for input */ 13172 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 13173 /* set pin widget 18h (mic1/2) for input, for mic also enable 13174 * the vref 13175 */ 13176 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 13177 13178 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, 13179#if 0 13180 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/ 13181 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/ 13182#endif 13183 { } /* end */ 13184}; 13185/* 13186 * 6ch mode 13187 * need to set the codec line out and mic 1 pin widgets to outputs 13188 */ 13189static struct hda_verb alc861_threestack_ch6_init[] = { 13190 /* set pin widget 1Ah (line in) for output (Back Surround)*/ 13191 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 13192 /* set pin widget 18h (mic1) for output (CLFE)*/ 13193 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 13194 13195 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 }, 13196 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 }, 13197 13198 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 }, 13199#if 0 13200 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/ 13201 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/ 13202#endif 13203 { } /* end */ 13204}; 13205 13206static struct hda_channel_mode alc861_threestack_modes[2] = { 13207 { 2, alc861_threestack_ch2_init }, 13208 { 6, alc861_threestack_ch6_init }, 13209}; 13210/* Set mic1 as input and unmute the mixer */ 13211static struct hda_verb alc861_uniwill_m31_ch2_init[] = { 13212 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 13213 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/ 13214 { } /* end */ 13215}; 13216/* Set mic1 as output and mute mixer */ 13217static struct hda_verb alc861_uniwill_m31_ch4_init[] = { 13218 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 13219 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/ 13220 { } /* end */ 13221}; 13222 13223static struct hda_channel_mode alc861_uniwill_m31_modes[2] = { 13224 { 2, alc861_uniwill_m31_ch2_init }, 13225 { 4, alc861_uniwill_m31_ch4_init }, 13226}; 13227 13228/* Set mic1 and line-in as input and unmute the mixer */ 13229static struct hda_verb alc861_asus_ch2_init[] = { 13230 /* set pin widget 1Ah (line in) for input */ 13231 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 13232 /* set pin widget 18h (mic1/2) for input, for mic also enable 13233 * the vref 13234 */ 13235 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 13236 13237 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, 13238#if 0 13239 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/ 13240 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/ 13241#endif 13242 { } /* end */ 13243}; 13244/* Set mic1 nad line-in as output and mute mixer */ 13245static struct hda_verb alc861_asus_ch6_init[] = { 13246 /* set pin widget 1Ah (line in) for output (Back Surround)*/ 13247 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 13248 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */ 13249 /* set pin widget 18h (mic1) for output (CLFE)*/ 13250 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 13251 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */ 13252 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 }, 13253 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 }, 13254 13255 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 }, 13256#if 0 13257 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/ 13258 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/ 13259#endif 13260 { } /* end */ 13261}; 13262 13263static struct hda_channel_mode alc861_asus_modes[2] = { 13264 { 2, alc861_asus_ch2_init }, 13265 { 6, alc861_asus_ch6_init }, 13266}; 13267 13268/* patch-ALC861 */ 13269 13270static struct snd_kcontrol_new alc861_base_mixer[] = { 13271 /* output mixer control */ 13272 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), 13273 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), 13274 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT), 13275 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT), 13276 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), 13277 13278 /*Input mixer control */ 13279 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT), 13280 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */ 13281 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), 13282 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), 13283 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT), 13284 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT), 13285 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), 13286 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), 13287 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), 13288 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT), 13289 13290 { } /* end */ 13291}; 13292 13293static struct snd_kcontrol_new alc861_3ST_mixer[] = { 13294 /* output mixer control */ 13295 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), 13296 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), 13297 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT), 13298 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT), 13299 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */ 13300 13301 /* Input mixer control */ 13302 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT), 13303 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */ 13304 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), 13305 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), 13306 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT), 13307 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT), 13308 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), 13309 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), 13310 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), 13311 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT), 13312 13313 { 13314 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 13315 .name = "Channel Mode", 13316 .info = alc_ch_mode_info, 13317 .get = alc_ch_mode_get, 13318 .put = alc_ch_mode_put, 13319 .private_value = ARRAY_SIZE(alc861_threestack_modes), 13320 }, 13321 { } /* end */ 13322}; 13323 13324static struct snd_kcontrol_new alc861_toshiba_mixer[] = { 13325 /* output mixer control */ 13326 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT), 13327 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), 13328 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), 13329 13330 { } /* end */ 13331}; 13332 13333static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = { 13334 /* output mixer control */ 13335 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), 13336 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), 13337 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT), 13338 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT), 13339 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */ 13340 13341 /* Input mixer control */ 13342 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT), 13343 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */ 13344 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), 13345 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), 13346 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT), 13347 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT), 13348 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), 13349 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), 13350 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), 13351 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT), 13352 13353 { 13354 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 13355 .name = "Channel Mode", 13356 .info = alc_ch_mode_info, 13357 .get = alc_ch_mode_get, 13358 .put = alc_ch_mode_put, 13359 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes), 13360 }, 13361 { } /* end */ 13362}; 13363 13364static struct snd_kcontrol_new alc861_asus_mixer[] = { 13365 /* output mixer control */ 13366 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), 13367 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), 13368 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT), 13369 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT), 13370 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), 13371 13372 /* Input mixer control */ 13373 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT), 13374 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), 13375 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), 13376 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), 13377 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT), 13378 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT), 13379 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), 13380 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), 13381 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), 13382 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT), 13383 13384 { 13385 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 13386 .name = "Channel Mode", 13387 .info = alc_ch_mode_info, 13388 .get = alc_ch_mode_get, 13389 .put = alc_ch_mode_put, 13390 .private_value = ARRAY_SIZE(alc861_asus_modes), 13391 }, 13392 { } 13393}; 13394 13395/* additional mixer */ 13396static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = { 13397 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), 13398 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), 13399 { } 13400}; 13401 13402/* 13403 * generic initialization of ADC, input mixers and output mixers 13404 */ 13405static struct hda_verb alc861_base_init_verbs[] = { 13406 /* 13407 * Unmute ADC0 and set the default input to mic-in 13408 */ 13409 /* port-A for surround (rear panel) */ 13410 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 13411 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 }, 13412 /* port-B for mic-in (rear panel) with vref */ 13413 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 13414 /* port-C for line-in (rear panel) */ 13415 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 13416 /* port-D for Front */ 13417 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 13418 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 }, 13419 /* port-E for HP out (front panel) */ 13420 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, 13421 /* route front PCM to HP */ 13422 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, 13423 /* port-F for mic-in (front panel) with vref */ 13424 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 13425 /* port-G for CLFE (rear panel) */ 13426 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 13427 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 }, 13428 /* port-H for side (rear panel) */ 13429 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 13430 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 }, 13431 /* CD-in */ 13432 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 13433 /* route front mic to ADC1*/ 13434 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 13435 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13436 13437 /* Unmute DAC0~3 & spdif out*/ 13438 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 13439 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 13440 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 13441 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 13442 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 13443 13444 /* Unmute Mixer 14 (mic) 1c (Line in)*/ 13445 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13446 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 13447 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13448 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 13449 13450 /* Unmute Stereo Mixer 15 */ 13451 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13452 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 13453 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 13454 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */ 13455 13456 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13457 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 13458 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13459 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 13460 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13461 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 13462 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13463 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 13464 /* hp used DAC 3 (Front) */ 13465 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 13466 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 13467 13468 { } 13469}; 13470 13471static struct hda_verb alc861_threestack_init_verbs[] = { 13472 /* 13473 * Unmute ADC0 and set the default input to mic-in 13474 */ 13475 /* port-A for surround (rear panel) */ 13476 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 13477 /* port-B for mic-in (rear panel) with vref */ 13478 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 13479 /* port-C for line-in (rear panel) */ 13480 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 13481 /* port-D for Front */ 13482 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 13483 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 }, 13484 /* port-E for HP out (front panel) */ 13485 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, 13486 /* route front PCM to HP */ 13487 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, 13488 /* port-F for mic-in (front panel) with vref */ 13489 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 13490 /* port-G for CLFE (rear panel) */ 13491 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 13492 /* port-H for side (rear panel) */ 13493 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 13494 /* CD-in */ 13495 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 13496 /* route front mic to ADC1*/ 13497 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 13498 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13499 /* Unmute DAC0~3 & spdif out*/ 13500 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 13501 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 13502 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 13503 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 13504 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 13505 13506 /* Unmute Mixer 14 (mic) 1c (Line in)*/ 13507 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13508 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 13509 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13510 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 13511 13512 /* Unmute Stereo Mixer 15 */ 13513 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13514 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 13515 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 13516 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */ 13517 13518 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13519 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 13520 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13521 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 13522 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13523 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 13524 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13525 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 13526 /* hp used DAC 3 (Front) */ 13527 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 13528 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 13529 { } 13530}; 13531 13532static struct hda_verb alc861_uniwill_m31_init_verbs[] = { 13533 /* 13534 * Unmute ADC0 and set the default input to mic-in 13535 */ 13536 /* port-A for surround (rear panel) */ 13537 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 13538 /* port-B for mic-in (rear panel) with vref */ 13539 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 13540 /* port-C for line-in (rear panel) */ 13541 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 13542 /* port-D for Front */ 13543 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 13544 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 }, 13545 /* port-E for HP out (front panel) */ 13546 /* this has to be set to VREF80 */ 13547 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 13548 /* route front PCM to HP */ 13549 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, 13550 /* port-F for mic-in (front panel) with vref */ 13551 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 13552 /* port-G for CLFE (rear panel) */ 13553 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 13554 /* port-H for side (rear panel) */ 13555 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 13556 /* CD-in */ 13557 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 13558 /* route front mic to ADC1*/ 13559 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 13560 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13561 /* Unmute DAC0~3 & spdif out*/ 13562 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 13563 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 13564 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 13565 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 13566 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 13567 13568 /* Unmute Mixer 14 (mic) 1c (Line in)*/ 13569 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13570 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 13571 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13572 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 13573 13574 /* Unmute Stereo Mixer 15 */ 13575 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13576 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 13577 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 13578 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */ 13579 13580 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13581 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 13582 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13583 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 13584 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13585 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 13586 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13587 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 13588 /* hp used DAC 3 (Front) */ 13589 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 13590 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 13591 { } 13592}; 13593 13594static struct hda_verb alc861_asus_init_verbs[] = { 13595 /* 13596 * Unmute ADC0 and set the default input to mic-in 13597 */ 13598 /* port-A for surround (rear panel) 13599 * according to codec#0 this is the HP jack 13600 */ 13601 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */ 13602 /* route front PCM to HP */ 13603 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 }, 13604 /* port-B for mic-in (rear panel) with vref */ 13605 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 13606 /* port-C for line-in (rear panel) */ 13607 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 13608 /* port-D for Front */ 13609 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 13610 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 }, 13611 /* port-E for HP out (front panel) */ 13612 /* this has to be set to VREF80 */ 13613 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 13614 /* route front PCM to HP */ 13615 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, 13616 /* port-F for mic-in (front panel) with vref */ 13617 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 13618 /* port-G for CLFE (rear panel) */ 13619 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 13620 /* port-H for side (rear panel) */ 13621 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 13622 /* CD-in */ 13623 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 13624 /* route front mic to ADC1*/ 13625 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 13626 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13627 /* Unmute DAC0~3 & spdif out*/ 13628 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 13629 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 13630 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 13631 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 13632 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 13633 /* Unmute Mixer 14 (mic) 1c (Line in)*/ 13634 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13635 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 13636 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13637 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 13638 13639 /* Unmute Stereo Mixer 15 */ 13640 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13641 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 13642 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 13643 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */ 13644 13645 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13646 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 13647 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13648 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 13649 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13650 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 13651 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13652 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 13653 /* hp used DAC 3 (Front) */ 13654 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 13655 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 13656 { } 13657}; 13658 13659/* additional init verbs for ASUS laptops */ 13660static struct hda_verb alc861_asus_laptop_init_verbs[] = { 13661 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */ 13662 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */ 13663 { } 13664}; 13665 13666/* 13667 * generic initialization of ADC, input mixers and output mixers 13668 */ 13669static struct hda_verb alc861_auto_init_verbs[] = { 13670 /* 13671 * Unmute ADC0 and set the default input to mic-in 13672 */ 13673 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */ 13674 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13675 13676 /* Unmute DAC0~3 & spdif out*/ 13677 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 13678 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 13679 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 13680 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 13681 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 13682 13683 /* Unmute Mixer 14 (mic) 1c (Line in)*/ 13684 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13685 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 13686 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13687 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 13688 13689 /* Unmute Stereo Mixer 15 */ 13690 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13691 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 13692 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 13693 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, 13694 13695 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13696 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 13697 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13698 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 13699 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13700 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 13701 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13702 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 13703 13704 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 13705 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 13706 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 13707 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 13708 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 13709 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 13710 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 13711 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 13712 13713 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */ 13714 13715 { } 13716}; 13717 13718static struct hda_verb alc861_toshiba_init_verbs[] = { 13719 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 13720 13721 { } 13722}; 13723 13724/* toggle speaker-output according to the hp-jack state */ 13725static void alc861_toshiba_automute(struct hda_codec *codec) 13726{ 13727 unsigned int present; 13728 13729 present = snd_hda_codec_read(codec, 0x0f, 0, 13730 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 13731 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0, 13732 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 13733 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3, 13734 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE); 13735} 13736 13737static void alc861_toshiba_unsol_event(struct hda_codec *codec, 13738 unsigned int res) 13739{ 13740 if ((res >> 26) == ALC880_HP_EVENT) 13741 alc861_toshiba_automute(codec); 13742} 13743 13744/* pcm configuration: identiacal with ALC880 */ 13745#define alc861_pcm_analog_playback alc880_pcm_analog_playback 13746#define alc861_pcm_analog_capture alc880_pcm_analog_capture 13747#define alc861_pcm_digital_playback alc880_pcm_digital_playback 13748#define alc861_pcm_digital_capture alc880_pcm_digital_capture 13749 13750 13751#define ALC861_DIGOUT_NID 0x07 13752 13753static struct hda_channel_mode alc861_8ch_modes[1] = { 13754 { 8, NULL } 13755}; 13756 13757static hda_nid_t alc861_dac_nids[4] = { 13758 /* front, surround, clfe, side */ 13759 0x03, 0x06, 0x05, 0x04 13760}; 13761 13762static hda_nid_t alc660_dac_nids[3] = { 13763 /* front, clfe, surround */ 13764 0x03, 0x05, 0x06 13765}; 13766 13767static hda_nid_t alc861_adc_nids[1] = { 13768 /* ADC0-2 */ 13769 0x08, 13770}; 13771 13772static struct hda_input_mux alc861_capture_source = { 13773 .num_items = 5, 13774 .items = { 13775 { "Mic", 0x0 }, 13776 { "Front Mic", 0x3 }, 13777 { "Line", 0x1 }, 13778 { "CD", 0x4 }, 13779 { "Mixer", 0x5 }, 13780 }, 13781}; 13782 13783/* fill in the dac_nids table from the parsed pin configuration */ 13784static int alc861_auto_fill_dac_nids(struct alc_spec *spec, 13785 const struct auto_pin_cfg *cfg) 13786{ 13787 int i; 13788 hda_nid_t nid; 13789 13790 spec->multiout.dac_nids = spec->private_dac_nids; 13791 for (i = 0; i < cfg->line_outs; i++) { 13792 nid = cfg->line_out_pins[i]; 13793 if (nid) { 13794 if (i >= ARRAY_SIZE(alc861_dac_nids)) 13795 continue; 13796 spec->multiout.dac_nids[i] = alc861_dac_nids[i]; 13797 } 13798 } 13799 spec->multiout.num_dacs = cfg->line_outs; 13800 return 0; 13801} 13802 13803/* add playback controls from the parsed DAC table */ 13804static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec, 13805 const struct auto_pin_cfg *cfg) 13806{ 13807 char name[32]; 13808 static const char *chname[4] = { 13809 "Front", "Surround", NULL /*CLFE*/, "Side" 13810 }; 13811 hda_nid_t nid; 13812 int i, idx, err; 13813 13814 for (i = 0; i < cfg->line_outs; i++) { 13815 nid = spec->multiout.dac_nids[i]; 13816 if (!nid) 13817 continue; 13818 if (nid == 0x05) { 13819 /* Center/LFE */ 13820 err = add_control(spec, ALC_CTL_BIND_MUTE, 13821 "Center Playback Switch", 13822 HDA_COMPOSE_AMP_VAL(nid, 1, 0, 13823 HDA_OUTPUT)); 13824 if (err < 0) 13825 return err; 13826 err = add_control(spec, ALC_CTL_BIND_MUTE, 13827 "LFE Playback Switch", 13828 HDA_COMPOSE_AMP_VAL(nid, 2, 0, 13829 HDA_OUTPUT)); 13830 if (err < 0) 13831 return err; 13832 } else { 13833 for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1; 13834 idx++) 13835 if (nid == alc861_dac_nids[idx]) 13836 break; 13837 sprintf(name, "%s Playback Switch", chname[idx]); 13838 err = add_control(spec, ALC_CTL_BIND_MUTE, name, 13839 HDA_COMPOSE_AMP_VAL(nid, 3, 0, 13840 HDA_OUTPUT)); 13841 if (err < 0) 13842 return err; 13843 } 13844 } 13845 return 0; 13846} 13847 13848static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin) 13849{ 13850 int err; 13851 hda_nid_t nid; 13852 13853 if (!pin) 13854 return 0; 13855 13856 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) { 13857 nid = 0x03; 13858 err = add_control(spec, ALC_CTL_WIDGET_MUTE, 13859 "Headphone Playback Switch", 13860 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); 13861 if (err < 0) 13862 return err; 13863 spec->multiout.hp_nid = nid; 13864 } 13865 return 0; 13866} 13867 13868/* create playback/capture controls for input pins */ 13869static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec, 13870 const struct auto_pin_cfg *cfg) 13871{ 13872 struct hda_input_mux *imux = &spec->private_imux[0]; 13873 int i, err, idx, idx1; 13874 13875 for (i = 0; i < AUTO_PIN_LAST; i++) { 13876 switch (cfg->input_pins[i]) { 13877 case 0x0c: 13878 idx1 = 1; 13879 idx = 2; /* Line In */ 13880 break; 13881 case 0x0f: 13882 idx1 = 2; 13883 idx = 2; /* Line In */ 13884 break; 13885 case 0x0d: 13886 idx1 = 0; 13887 idx = 1; /* Mic In */ 13888 break; 13889 case 0x10: 13890 idx1 = 3; 13891 idx = 1; /* Mic In */ 13892 break; 13893 case 0x11: 13894 idx1 = 4; 13895 idx = 0; /* CD */ 13896 break; 13897 default: 13898 continue; 13899 } 13900 13901 err = new_analog_input(spec, cfg->input_pins[i], 13902 auto_pin_cfg_labels[i], idx, 0x15); 13903 if (err < 0) 13904 return err; 13905 13906 imux->items[imux->num_items].label = auto_pin_cfg_labels[i]; 13907 imux->items[imux->num_items].index = idx1; 13908 imux->num_items++; 13909 } 13910 return 0; 13911} 13912 13913static void alc861_auto_set_output_and_unmute(struct hda_codec *codec, 13914 hda_nid_t nid, 13915 int pin_type, int dac_idx) 13916{ 13917 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 13918 pin_type); 13919 snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE, 13920 AMP_OUT_UNMUTE); 13921} 13922 13923static void alc861_auto_init_multi_out(struct hda_codec *codec) 13924{ 13925 struct alc_spec *spec = codec->spec; 13926 int i; 13927 13928 alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b); 13929 for (i = 0; i < spec->autocfg.line_outs; i++) { 13930 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 13931 int pin_type = get_pin_type(spec->autocfg.line_out_type); 13932 if (nid) 13933 alc861_auto_set_output_and_unmute(codec, nid, pin_type, 13934 spec->multiout.dac_nids[i]); 13935 } 13936} 13937 13938static void alc861_auto_init_hp_out(struct hda_codec *codec) 13939{ 13940 struct alc_spec *spec = codec->spec; 13941 hda_nid_t pin; 13942 13943 pin = spec->autocfg.hp_pins[0]; 13944 if (pin) /* connect to front */ 13945 alc861_auto_set_output_and_unmute(codec, pin, PIN_HP, 13946 spec->multiout.dac_nids[0]); 13947 pin = spec->autocfg.speaker_pins[0]; 13948 if (pin) 13949 alc861_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0); 13950} 13951 13952static void alc861_auto_init_analog_input(struct hda_codec *codec) 13953{ 13954 struct alc_spec *spec = codec->spec; 13955 int i; 13956 13957 for (i = 0; i < AUTO_PIN_LAST; i++) { 13958 hda_nid_t nid = spec->autocfg.input_pins[i]; 13959 if (nid >= 0x0c && nid <= 0x11) 13960 alc_set_input_pin(codec, nid, i); 13961 } 13962} 13963 13964/* parse the BIOS configuration and set up the alc_spec */ 13965/* return 1 if successful, 0 if the proper config is not found, 13966 * or a negative error code 13967 */ 13968static int alc861_parse_auto_config(struct hda_codec *codec) 13969{ 13970 struct alc_spec *spec = codec->spec; 13971 int err; 13972 static hda_nid_t alc861_ignore[] = { 0x1d, 0 }; 13973 13974 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 13975 alc861_ignore); 13976 if (err < 0) 13977 return err; 13978 if (!spec->autocfg.line_outs) 13979 return 0; /* can't find valid BIOS pin config */ 13980 13981 err = alc861_auto_fill_dac_nids(spec, &spec->autocfg); 13982 if (err < 0) 13983 return err; 13984 err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg); 13985 if (err < 0) 13986 return err; 13987 err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]); 13988 if (err < 0) 13989 return err; 13990 err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg); 13991 if (err < 0) 13992 return err; 13993 13994 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 13995 13996 if (spec->autocfg.dig_outs) 13997 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID; 13998 13999 if (spec->kctls.list) 14000 add_mixer(spec, spec->kctls.list); 14001 14002 add_verb(spec, alc861_auto_init_verbs); 14003 14004 spec->num_mux_defs = 1; 14005 spec->input_mux = &spec->private_imux[0]; 14006 14007 spec->adc_nids = alc861_adc_nids; 14008 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids); 14009 set_capture_mixer(spec); 14010 14011 return 1; 14012} 14013 14014/* additional initialization for auto-configuration model */ 14015static void alc861_auto_init(struct hda_codec *codec) 14016{ 14017 struct alc_spec *spec = codec->spec; 14018 alc861_auto_init_multi_out(codec); 14019 alc861_auto_init_hp_out(codec); 14020 alc861_auto_init_analog_input(codec); 14021 if (spec->unsol_event) 14022 alc_inithook(codec); 14023} 14024 14025#ifdef CONFIG_SND_HDA_POWER_SAVE 14026static struct hda_amp_list alc861_loopbacks[] = { 14027 { 0x15, HDA_INPUT, 0 }, 14028 { 0x15, HDA_INPUT, 1 }, 14029 { 0x15, HDA_INPUT, 2 }, 14030 { 0x15, HDA_INPUT, 3 }, 14031 { } /* end */ 14032}; 14033#endif 14034 14035 14036/* 14037 * configuration and preset 14038 */ 14039static const char *alc861_models[ALC861_MODEL_LAST] = { 14040 [ALC861_3ST] = "3stack", 14041 [ALC660_3ST] = "3stack-660", 14042 [ALC861_3ST_DIG] = "3stack-dig", 14043 [ALC861_6ST_DIG] = "6stack-dig", 14044 [ALC861_UNIWILL_M31] = "uniwill-m31", 14045 [ALC861_TOSHIBA] = "toshiba", 14046 [ALC861_ASUS] = "asus", 14047 [ALC861_ASUS_LAPTOP] = "asus-laptop", 14048 [ALC861_AUTO] = "auto", 14049}; 14050 14051static struct snd_pci_quirk alc861_cfg_tbl[] = { 14052 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST), 14053 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP), 14054 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP), 14055 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS), 14056 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP), 14057 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG), 14058 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA), 14059 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!) 14060 * Any other models that need this preset? 14061 */ 14062 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */ 14063 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST), 14064 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST), 14065 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31), 14066 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31), 14067 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP), 14068 /* FIXME: the below seems conflict */ 14069 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */ 14070 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST), 14071 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST), 14072 {} 14073}; 14074 14075static struct alc_config_preset alc861_presets[] = { 14076 [ALC861_3ST] = { 14077 .mixers = { alc861_3ST_mixer }, 14078 .init_verbs = { alc861_threestack_init_verbs }, 14079 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 14080 .dac_nids = alc861_dac_nids, 14081 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes), 14082 .channel_mode = alc861_threestack_modes, 14083 .need_dac_fix = 1, 14084 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 14085 .adc_nids = alc861_adc_nids, 14086 .input_mux = &alc861_capture_source, 14087 }, 14088 [ALC861_3ST_DIG] = { 14089 .mixers = { alc861_base_mixer }, 14090 .init_verbs = { alc861_threestack_init_verbs }, 14091 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 14092 .dac_nids = alc861_dac_nids, 14093 .dig_out_nid = ALC861_DIGOUT_NID, 14094 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes), 14095 .channel_mode = alc861_threestack_modes, 14096 .need_dac_fix = 1, 14097 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 14098 .adc_nids = alc861_adc_nids, 14099 .input_mux = &alc861_capture_source, 14100 }, 14101 [ALC861_6ST_DIG] = { 14102 .mixers = { alc861_base_mixer }, 14103 .init_verbs = { alc861_base_init_verbs }, 14104 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 14105 .dac_nids = alc861_dac_nids, 14106 .dig_out_nid = ALC861_DIGOUT_NID, 14107 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes), 14108 .channel_mode = alc861_8ch_modes, 14109 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 14110 .adc_nids = alc861_adc_nids, 14111 .input_mux = &alc861_capture_source, 14112 }, 14113 [ALC660_3ST] = { 14114 .mixers = { alc861_3ST_mixer }, 14115 .init_verbs = { alc861_threestack_init_verbs }, 14116 .num_dacs = ARRAY_SIZE(alc660_dac_nids), 14117 .dac_nids = alc660_dac_nids, 14118 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes), 14119 .channel_mode = alc861_threestack_modes, 14120 .need_dac_fix = 1, 14121 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 14122 .adc_nids = alc861_adc_nids, 14123 .input_mux = &alc861_capture_source, 14124 }, 14125 [ALC861_UNIWILL_M31] = { 14126 .mixers = { alc861_uniwill_m31_mixer }, 14127 .init_verbs = { alc861_uniwill_m31_init_verbs }, 14128 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 14129 .dac_nids = alc861_dac_nids, 14130 .dig_out_nid = ALC861_DIGOUT_NID, 14131 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes), 14132 .channel_mode = alc861_uniwill_m31_modes, 14133 .need_dac_fix = 1, 14134 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 14135 .adc_nids = alc861_adc_nids, 14136 .input_mux = &alc861_capture_source, 14137 }, 14138 [ALC861_TOSHIBA] = { 14139 .mixers = { alc861_toshiba_mixer }, 14140 .init_verbs = { alc861_base_init_verbs, 14141 alc861_toshiba_init_verbs }, 14142 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 14143 .dac_nids = alc861_dac_nids, 14144 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 14145 .channel_mode = alc883_3ST_2ch_modes, 14146 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 14147 .adc_nids = alc861_adc_nids, 14148 .input_mux = &alc861_capture_source, 14149 .unsol_event = alc861_toshiba_unsol_event, 14150 .init_hook = alc861_toshiba_automute, 14151 }, 14152 [ALC861_ASUS] = { 14153 .mixers = { alc861_asus_mixer }, 14154 .init_verbs = { alc861_asus_init_verbs }, 14155 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 14156 .dac_nids = alc861_dac_nids, 14157 .dig_out_nid = ALC861_DIGOUT_NID, 14158 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes), 14159 .channel_mode = alc861_asus_modes, 14160 .need_dac_fix = 1, 14161 .hp_nid = 0x06, 14162 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 14163 .adc_nids = alc861_adc_nids, 14164 .input_mux = &alc861_capture_source, 14165 }, 14166 [ALC861_ASUS_LAPTOP] = { 14167 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer }, 14168 .init_verbs = { alc861_asus_init_verbs, 14169 alc861_asus_laptop_init_verbs }, 14170 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 14171 .dac_nids = alc861_dac_nids, 14172 .dig_out_nid = ALC861_DIGOUT_NID, 14173 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 14174 .channel_mode = alc883_3ST_2ch_modes, 14175 .need_dac_fix = 1, 14176 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 14177 .adc_nids = alc861_adc_nids, 14178 .input_mux = &alc861_capture_source, 14179 }, 14180}; 14181 14182 14183static int patch_alc861(struct hda_codec *codec) 14184{ 14185 struct alc_spec *spec; 14186 int board_config; 14187 int err; 14188 14189 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 14190 if (spec == NULL) 14191 return -ENOMEM; 14192 14193 codec->spec = spec; 14194 14195 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST, 14196 alc861_models, 14197 alc861_cfg_tbl); 14198 14199 if (board_config < 0) { 14200 printk(KERN_INFO "hda_codec: Unknown model for ALC861, " 14201 "trying auto-probe from BIOS...\n"); 14202 board_config = ALC861_AUTO; 14203 } 14204 14205 if (board_config == ALC861_AUTO) { 14206 /* automatic parse from the BIOS config */ 14207 err = alc861_parse_auto_config(codec); 14208 if (err < 0) { 14209 alc_free(codec); 14210 return err; 14211 } else if (!err) { 14212 printk(KERN_INFO 14213 "hda_codec: Cannot set up configuration " 14214 "from BIOS. Using base mode...\n"); 14215 board_config = ALC861_3ST_DIG; 14216 } 14217 } 14218 14219 err = snd_hda_attach_beep_device(codec, 0x23); 14220 if (err < 0) { 14221 alc_free(codec); 14222 return err; 14223 } 14224 14225 if (board_config != ALC861_AUTO) 14226 setup_preset(spec, &alc861_presets[board_config]); 14227 14228 spec->stream_name_analog = "ALC861 Analog"; 14229 spec->stream_analog_playback = &alc861_pcm_analog_playback; 14230 spec->stream_analog_capture = &alc861_pcm_analog_capture; 14231 14232 spec->stream_name_digital = "ALC861 Digital"; 14233 spec->stream_digital_playback = &alc861_pcm_digital_playback; 14234 spec->stream_digital_capture = &alc861_pcm_digital_capture; 14235 14236 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT); 14237 14238 spec->vmaster_nid = 0x03; 14239 14240 codec->patch_ops = alc_patch_ops; 14241 if (board_config == ALC861_AUTO) 14242 spec->init_hook = alc861_auto_init; 14243#ifdef CONFIG_SND_HDA_POWER_SAVE 14244 if (!spec->loopback.amplist) 14245 spec->loopback.amplist = alc861_loopbacks; 14246#endif 14247 codec->proc_widget_hook = print_realtek_coef; 14248 14249 return 0; 14250} 14251 14252/* 14253 * ALC861-VD support 14254 * 14255 * Based on ALC882 14256 * 14257 * In addition, an independent DAC 14258 */ 14259#define ALC861VD_DIGOUT_NID 0x06 14260 14261static hda_nid_t alc861vd_dac_nids[4] = { 14262 /* front, surr, clfe, side surr */ 14263 0x02, 0x03, 0x04, 0x05 14264}; 14265 14266/* dac_nids for ALC660vd are in a different order - according to 14267 * Realtek's driver. 14268 * This should probably tesult in a different mixer for 6stack models 14269 * of ALC660vd codecs, but for now there is only 3stack mixer 14270 * - and it is the same as in 861vd. 14271 * adc_nids in ALC660vd are (is) the same as in 861vd 14272 */ 14273static hda_nid_t alc660vd_dac_nids[3] = { 14274 /* front, rear, clfe, rear_surr */ 14275 0x02, 0x04, 0x03 14276}; 14277 14278static hda_nid_t alc861vd_adc_nids[1] = { 14279 /* ADC0 */ 14280 0x09, 14281}; 14282 14283static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 }; 14284 14285/* input MUX */ 14286/* FIXME: should be a matrix-type input source selection */ 14287static struct hda_input_mux alc861vd_capture_source = { 14288 .num_items = 4, 14289 .items = { 14290 { "Mic", 0x0 }, 14291 { "Front Mic", 0x1 }, 14292 { "Line", 0x2 }, 14293 { "CD", 0x4 }, 14294 }, 14295}; 14296 14297static struct hda_input_mux alc861vd_dallas_capture_source = { 14298 .num_items = 2, 14299 .items = { 14300 { "Ext Mic", 0x0 }, 14301 { "Int Mic", 0x1 }, 14302 }, 14303}; 14304 14305static struct hda_input_mux alc861vd_hp_capture_source = { 14306 .num_items = 2, 14307 .items = { 14308 { "Front Mic", 0x0 }, 14309 { "ATAPI Mic", 0x1 }, 14310 }, 14311}; 14312 14313/* 14314 * 2ch mode 14315 */ 14316static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = { 14317 { 2, NULL } 14318}; 14319 14320/* 14321 * 6ch mode 14322 */ 14323static struct hda_verb alc861vd_6stack_ch6_init[] = { 14324 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 14325 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 14326 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 14327 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 14328 { } /* end */ 14329}; 14330 14331/* 14332 * 8ch mode 14333 */ 14334static struct hda_verb alc861vd_6stack_ch8_init[] = { 14335 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 14336 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 14337 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 14338 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 14339 { } /* end */ 14340}; 14341 14342static struct hda_channel_mode alc861vd_6stack_modes[2] = { 14343 { 6, alc861vd_6stack_ch6_init }, 14344 { 8, alc861vd_6stack_ch8_init }, 14345}; 14346 14347static struct snd_kcontrol_new alc861vd_chmode_mixer[] = { 14348 { 14349 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 14350 .name = "Channel Mode", 14351 .info = alc_ch_mode_info, 14352 .get = alc_ch_mode_get, 14353 .put = alc_ch_mode_put, 14354 }, 14355 { } /* end */ 14356}; 14357 14358/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 14359 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b 14360 */ 14361static struct snd_kcontrol_new alc861vd_6st_mixer[] = { 14362 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 14363 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 14364 14365 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT), 14366 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 14367 14368 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, 14369 HDA_OUTPUT), 14370 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, 14371 HDA_OUTPUT), 14372 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 14373 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 14374 14375 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT), 14376 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 14377 14378 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 14379 14380 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 14381 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 14382 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 14383 14384 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 14385 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 14386 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 14387 14388 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 14389 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 14390 14391 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 14392 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 14393 14394 { } /* end */ 14395}; 14396 14397static struct snd_kcontrol_new alc861vd_3st_mixer[] = { 14398 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 14399 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 14400 14401 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 14402 14403 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 14404 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 14405 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 14406 14407 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 14408 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 14409 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 14410 14411 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 14412 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 14413 14414 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 14415 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 14416 14417 { } /* end */ 14418}; 14419 14420static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = { 14421 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 14422 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/ 14423 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 14424 14425 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 14426 14427 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 14428 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 14429 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 14430 14431 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 14432 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 14433 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 14434 14435 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 14436 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 14437 14438 { } /* end */ 14439}; 14440 14441/* Pin assignment: Speaker=0x14, HP = 0x15, 14442 * Ext Mic=0x18, Int Mic = 0x19, CD = 0x1c, PC Beep = 0x1d 14443 */ 14444static struct snd_kcontrol_new alc861vd_dallas_mixer[] = { 14445 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 14446 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT), 14447 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 14448 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT), 14449 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT), 14450 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 14451 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 14452 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 14453 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 14454 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 14455 { } /* end */ 14456}; 14457 14458/* Pin assignment: Speaker=0x14, Line-out = 0x15, 14459 * Front Mic=0x18, ATAPI Mic = 0x19, 14460 */ 14461static struct snd_kcontrol_new alc861vd_hp_mixer[] = { 14462 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 14463 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 14464 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 14465 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT), 14466 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 14467 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 14468 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 14469 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 14470 14471 { } /* end */ 14472}; 14473 14474/* 14475 * generic initialization of ADC, input mixers and output mixers 14476 */ 14477static struct hda_verb alc861vd_volume_init_verbs[] = { 14478 /* 14479 * Unmute ADC0 and set the default input to mic-in 14480 */ 14481 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 14482 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14483 14484 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of 14485 * the analog-loopback mixer widget 14486 */ 14487 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 14488 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 14489 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 14490 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 14491 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 14492 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 14493 14494 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */ 14495 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14496 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 14497 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 14498 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, 14499 14500 /* 14501 * Set up output mixers (0x02 - 0x05) 14502 */ 14503 /* set vol=0 to output mixers */ 14504 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 14505 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 14506 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 14507 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 14508 14509 /* set up input amps for analog loopback */ 14510 /* Amp Indices: DAC = 0, mixer = 1 */ 14511 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 14512 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 14513 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 14514 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 14515 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 14516 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 14517 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 14518 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 14519 14520 { } 14521}; 14522 14523/* 14524 * 3-stack pin configuration: 14525 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b 14526 */ 14527static struct hda_verb alc861vd_3stack_init_verbs[] = { 14528 /* 14529 * Set pin mode and muting 14530 */ 14531 /* set front pin widgets 0x14 for output */ 14532 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 14533 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 14534 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 14535 14536 /* Mic (rear) pin: input vref at 80% */ 14537 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 14538 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 14539 /* Front Mic pin: input vref at 80% */ 14540 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 14541 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 14542 /* Line In pin: input */ 14543 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14544 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 14545 /* Line-2 In: Headphone output (output 0 - 0x0c) */ 14546 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 14547 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 14548 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 14549 /* CD pin widget for input */ 14550 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14551 14552 { } 14553}; 14554 14555/* 14556 * 6-stack pin configuration: 14557 */ 14558static struct hda_verb alc861vd_6stack_init_verbs[] = { 14559 /* 14560 * Set pin mode and muting 14561 */ 14562 /* set front pin widgets 0x14 for output */ 14563 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 14564 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 14565 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 14566 14567 /* Rear Pin: output 1 (0x0d) */ 14568 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 14569 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 14570 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 14571 /* CLFE Pin: output 2 (0x0e) */ 14572 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 14573 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 14574 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, 14575 /* Side Pin: output 3 (0x0f) */ 14576 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 14577 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 14578 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, 14579 14580 /* Mic (rear) pin: input vref at 80% */ 14581 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 14582 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 14583 /* Front Mic pin: input vref at 80% */ 14584 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 14585 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 14586 /* Line In pin: input */ 14587 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14588 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 14589 /* Line-2 In: Headphone output (output 0 - 0x0c) */ 14590 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 14591 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 14592 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 14593 /* CD pin widget for input */ 14594 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14595 14596 { } 14597}; 14598 14599static struct hda_verb alc861vd_eapd_verbs[] = { 14600 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 14601 { } 14602}; 14603 14604static struct hda_verb alc660vd_eapd_verbs[] = { 14605 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 14606 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, 14607 { } 14608}; 14609 14610static struct hda_verb alc861vd_lenovo_unsol_verbs[] = { 14611 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14612 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 14613 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, 14614 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 14615 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 14616 {} 14617}; 14618 14619/* toggle speaker-output according to the hp-jack state */ 14620static void alc861vd_lenovo_hp_automute(struct hda_codec *codec) 14621{ 14622 unsigned int present; 14623 unsigned char bits; 14624 14625 present = snd_hda_codec_read(codec, 0x1b, 0, 14626 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 14627 bits = present ? HDA_AMP_MUTE : 0; 14628 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 14629 HDA_AMP_MUTE, bits); 14630} 14631 14632static void alc861vd_lenovo_mic_automute(struct hda_codec *codec) 14633{ 14634 unsigned int present; 14635 unsigned char bits; 14636 14637 present = snd_hda_codec_read(codec, 0x18, 0, 14638 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 14639 bits = present ? HDA_AMP_MUTE : 0; 14640 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, 14641 HDA_AMP_MUTE, bits); 14642} 14643 14644static void alc861vd_lenovo_automute(struct hda_codec *codec) 14645{ 14646 alc861vd_lenovo_hp_automute(codec); 14647 alc861vd_lenovo_mic_automute(codec); 14648} 14649 14650static void alc861vd_lenovo_unsol_event(struct hda_codec *codec, 14651 unsigned int res) 14652{ 14653 switch (res >> 26) { 14654 case ALC880_HP_EVENT: 14655 alc861vd_lenovo_hp_automute(codec); 14656 break; 14657 case ALC880_MIC_EVENT: 14658 alc861vd_lenovo_mic_automute(codec); 14659 break; 14660 } 14661} 14662 14663static struct hda_verb alc861vd_dallas_verbs[] = { 14664 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 14665 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 14666 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 14667 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 14668 14669 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14670 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 14671 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 14672 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 14673 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 14674 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 14675 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 14676 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 14677 14678 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 14679 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 14680 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 14681 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 14682 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 14683 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 14684 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 14685 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 14686 14687 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, 14688 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 14689 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, 14690 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 14691 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14692 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14693 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14694 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14695 14696 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14697 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 14698 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 14699 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 14700 14701 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 14702 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 14703 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 14704 14705 { } /* end */ 14706}; 14707 14708/* toggle speaker-output according to the hp-jack state */ 14709static void alc861vd_dallas_automute(struct hda_codec *codec) 14710{ 14711 unsigned int present; 14712 14713 present = snd_hda_codec_read(codec, 0x15, 0, 14714 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 14715 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 14716 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 14717} 14718 14719static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int res) 14720{ 14721 if ((res >> 26) == ALC880_HP_EVENT) 14722 alc861vd_dallas_automute(codec); 14723} 14724 14725#ifdef CONFIG_SND_HDA_POWER_SAVE 14726#define alc861vd_loopbacks alc880_loopbacks 14727#endif 14728 14729/* pcm configuration: identiacal with ALC880 */ 14730#define alc861vd_pcm_analog_playback alc880_pcm_analog_playback 14731#define alc861vd_pcm_analog_capture alc880_pcm_analog_capture 14732#define alc861vd_pcm_digital_playback alc880_pcm_digital_playback 14733#define alc861vd_pcm_digital_capture alc880_pcm_digital_capture 14734 14735/* 14736 * configuration and preset 14737 */ 14738static const char *alc861vd_models[ALC861VD_MODEL_LAST] = { 14739 [ALC660VD_3ST] = "3stack-660", 14740 [ALC660VD_3ST_DIG] = "3stack-660-digout", 14741 [ALC660VD_ASUS_V1S] = "asus-v1s", 14742 [ALC861VD_3ST] = "3stack", 14743 [ALC861VD_3ST_DIG] = "3stack-digout", 14744 [ALC861VD_6ST_DIG] = "6stack-digout", 14745 [ALC861VD_LENOVO] = "lenovo", 14746 [ALC861VD_DALLAS] = "dallas", 14747 [ALC861VD_HP] = "hp", 14748 [ALC861VD_AUTO] = "auto", 14749}; 14750 14751static struct snd_pci_quirk alc861vd_cfg_tbl[] = { 14752 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST), 14753 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP), 14754 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST), 14755 SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST), 14756 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S), 14757 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG), 14758 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST), 14759 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO), 14760 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/ 14761 SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS), 14762 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO), 14763 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS), 14764 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG), 14765 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO), 14766 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG), 14767 {} 14768}; 14769 14770static struct alc_config_preset alc861vd_presets[] = { 14771 [ALC660VD_3ST] = { 14772 .mixers = { alc861vd_3st_mixer }, 14773 .init_verbs = { alc861vd_volume_init_verbs, 14774 alc861vd_3stack_init_verbs }, 14775 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids), 14776 .dac_nids = alc660vd_dac_nids, 14777 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 14778 .channel_mode = alc861vd_3stack_2ch_modes, 14779 .input_mux = &alc861vd_capture_source, 14780 }, 14781 [ALC660VD_3ST_DIG] = { 14782 .mixers = { alc861vd_3st_mixer }, 14783 .init_verbs = { alc861vd_volume_init_verbs, 14784 alc861vd_3stack_init_verbs }, 14785 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids), 14786 .dac_nids = alc660vd_dac_nids, 14787 .dig_out_nid = ALC861VD_DIGOUT_NID, 14788 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 14789 .channel_mode = alc861vd_3stack_2ch_modes, 14790 .input_mux = &alc861vd_capture_source, 14791 }, 14792 [ALC861VD_3ST] = { 14793 .mixers = { alc861vd_3st_mixer }, 14794 .init_verbs = { alc861vd_volume_init_verbs, 14795 alc861vd_3stack_init_verbs }, 14796 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids), 14797 .dac_nids = alc861vd_dac_nids, 14798 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 14799 .channel_mode = alc861vd_3stack_2ch_modes, 14800 .input_mux = &alc861vd_capture_source, 14801 }, 14802 [ALC861VD_3ST_DIG] = { 14803 .mixers = { alc861vd_3st_mixer }, 14804 .init_verbs = { alc861vd_volume_init_verbs, 14805 alc861vd_3stack_init_verbs }, 14806 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids), 14807 .dac_nids = alc861vd_dac_nids, 14808 .dig_out_nid = ALC861VD_DIGOUT_NID, 14809 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 14810 .channel_mode = alc861vd_3stack_2ch_modes, 14811 .input_mux = &alc861vd_capture_source, 14812 }, 14813 [ALC861VD_6ST_DIG] = { 14814 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer }, 14815 .init_verbs = { alc861vd_volume_init_verbs, 14816 alc861vd_6stack_init_verbs }, 14817 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids), 14818 .dac_nids = alc861vd_dac_nids, 14819 .dig_out_nid = ALC861VD_DIGOUT_NID, 14820 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes), 14821 .channel_mode = alc861vd_6stack_modes, 14822 .input_mux = &alc861vd_capture_source, 14823 }, 14824 [ALC861VD_LENOVO] = { 14825 .mixers = { alc861vd_lenovo_mixer }, 14826 .init_verbs = { alc861vd_volume_init_verbs, 14827 alc861vd_3stack_init_verbs, 14828 alc861vd_eapd_verbs, 14829 alc861vd_lenovo_unsol_verbs }, 14830 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids), 14831 .dac_nids = alc660vd_dac_nids, 14832 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 14833 .channel_mode = alc861vd_3stack_2ch_modes, 14834 .input_mux = &alc861vd_capture_source, 14835 .unsol_event = alc861vd_lenovo_unsol_event, 14836 .init_hook = alc861vd_lenovo_automute, 14837 }, 14838 [ALC861VD_DALLAS] = { 14839 .mixers = { alc861vd_dallas_mixer }, 14840 .init_verbs = { alc861vd_dallas_verbs }, 14841 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids), 14842 .dac_nids = alc861vd_dac_nids, 14843 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 14844 .channel_mode = alc861vd_3stack_2ch_modes, 14845 .input_mux = &alc861vd_dallas_capture_source, 14846 .unsol_event = alc861vd_dallas_unsol_event, 14847 .init_hook = alc861vd_dallas_automute, 14848 }, 14849 [ALC861VD_HP] = { 14850 .mixers = { alc861vd_hp_mixer }, 14851 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs }, 14852 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids), 14853 .dac_nids = alc861vd_dac_nids, 14854 .dig_out_nid = ALC861VD_DIGOUT_NID, 14855 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 14856 .channel_mode = alc861vd_3stack_2ch_modes, 14857 .input_mux = &alc861vd_hp_capture_source, 14858 .unsol_event = alc861vd_dallas_unsol_event, 14859 .init_hook = alc861vd_dallas_automute, 14860 }, 14861 [ALC660VD_ASUS_V1S] = { 14862 .mixers = { alc861vd_lenovo_mixer }, 14863 .init_verbs = { alc861vd_volume_init_verbs, 14864 alc861vd_3stack_init_verbs, 14865 alc861vd_eapd_verbs, 14866 alc861vd_lenovo_unsol_verbs }, 14867 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids), 14868 .dac_nids = alc660vd_dac_nids, 14869 .dig_out_nid = ALC861VD_DIGOUT_NID, 14870 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 14871 .channel_mode = alc861vd_3stack_2ch_modes, 14872 .input_mux = &alc861vd_capture_source, 14873 .unsol_event = alc861vd_lenovo_unsol_event, 14874 .init_hook = alc861vd_lenovo_automute, 14875 }, 14876}; 14877 14878/* 14879 * BIOS auto configuration 14880 */ 14881static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec, 14882 hda_nid_t nid, int pin_type, int dac_idx) 14883{ 14884 alc_set_pin_output(codec, nid, pin_type); 14885} 14886 14887static void alc861vd_auto_init_multi_out(struct hda_codec *codec) 14888{ 14889 struct alc_spec *spec = codec->spec; 14890 int i; 14891 14892 alc_subsystem_id(codec, 0x15, 0x1b, 0x14); 14893 for (i = 0; i <= HDA_SIDE; i++) { 14894 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 14895 int pin_type = get_pin_type(spec->autocfg.line_out_type); 14896 if (nid) 14897 alc861vd_auto_set_output_and_unmute(codec, nid, 14898 pin_type, i); 14899 } 14900} 14901 14902 14903static void alc861vd_auto_init_hp_out(struct hda_codec *codec) 14904{ 14905 struct alc_spec *spec = codec->spec; 14906 hda_nid_t pin; 14907 14908 pin = spec->autocfg.hp_pins[0]; 14909 if (pin) /* connect to front and use dac 0 */ 14910 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); 14911 pin = spec->autocfg.speaker_pins[0]; 14912 if (pin) 14913 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0); 14914} 14915 14916#define alc861vd_is_input_pin(nid) alc880_is_input_pin(nid) 14917#define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID 14918 14919static void alc861vd_auto_init_analog_input(struct hda_codec *codec) 14920{ 14921 struct alc_spec *spec = codec->spec; 14922 int i; 14923 14924 for (i = 0; i < AUTO_PIN_LAST; i++) { 14925 hda_nid_t nid = spec->autocfg.input_pins[i]; 14926 if (alc861vd_is_input_pin(nid)) { 14927 alc_set_input_pin(codec, nid, i); 14928 if (nid != ALC861VD_PIN_CD_NID && 14929 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)) 14930 snd_hda_codec_write(codec, nid, 0, 14931 AC_VERB_SET_AMP_GAIN_MUTE, 14932 AMP_OUT_MUTE); 14933 } 14934 } 14935} 14936 14937#define alc861vd_auto_init_input_src alc882_auto_init_input_src 14938 14939#define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02) 14940#define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c) 14941 14942/* add playback controls from the parsed DAC table */ 14943/* Based on ALC880 version. But ALC861VD has separate, 14944 * different NIDs for mute/unmute switch and volume control */ 14945static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec, 14946 const struct auto_pin_cfg *cfg) 14947{ 14948 char name[32]; 14949 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"}; 14950 hda_nid_t nid_v, nid_s; 14951 int i, err; 14952 14953 for (i = 0; i < cfg->line_outs; i++) { 14954 if (!spec->multiout.dac_nids[i]) 14955 continue; 14956 nid_v = alc861vd_idx_to_mixer_vol( 14957 alc880_dac_to_idx( 14958 spec->multiout.dac_nids[i])); 14959 nid_s = alc861vd_idx_to_mixer_switch( 14960 alc880_dac_to_idx( 14961 spec->multiout.dac_nids[i])); 14962 14963 if (i == 2) { 14964 /* Center/LFE */ 14965 err = add_control(spec, ALC_CTL_WIDGET_VOL, 14966 "Center Playback Volume", 14967 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0, 14968 HDA_OUTPUT)); 14969 if (err < 0) 14970 return err; 14971 err = add_control(spec, ALC_CTL_WIDGET_VOL, 14972 "LFE Playback Volume", 14973 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0, 14974 HDA_OUTPUT)); 14975 if (err < 0) 14976 return err; 14977 err = add_control(spec, ALC_CTL_BIND_MUTE, 14978 "Center Playback Switch", 14979 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2, 14980 HDA_INPUT)); 14981 if (err < 0) 14982 return err; 14983 err = add_control(spec, ALC_CTL_BIND_MUTE, 14984 "LFE Playback Switch", 14985 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2, 14986 HDA_INPUT)); 14987 if (err < 0) 14988 return err; 14989 } else { 14990 sprintf(name, "%s Playback Volume", chname[i]); 14991 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, 14992 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, 14993 HDA_OUTPUT)); 14994 if (err < 0) 14995 return err; 14996 sprintf(name, "%s Playback Switch", chname[i]); 14997 err = add_control(spec, ALC_CTL_BIND_MUTE, name, 14998 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, 14999 HDA_INPUT)); 15000 if (err < 0) 15001 return err; 15002 } 15003 } 15004 return 0; 15005} 15006 15007/* add playback controls for speaker and HP outputs */ 15008/* Based on ALC880 version. But ALC861VD has separate, 15009 * different NIDs for mute/unmute switch and volume control */ 15010static int alc861vd_auto_create_extra_out(struct alc_spec *spec, 15011 hda_nid_t pin, const char *pfx) 15012{ 15013 hda_nid_t nid_v, nid_s; 15014 int err; 15015 char name[32]; 15016 15017 if (!pin) 15018 return 0; 15019 15020 if (alc880_is_fixed_pin(pin)) { 15021 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); 15022 /* specify the DAC as the extra output */ 15023 if (!spec->multiout.hp_nid) 15024 spec->multiout.hp_nid = nid_v; 15025 else 15026 spec->multiout.extra_out_nid[0] = nid_v; 15027 /* control HP volume/switch on the output mixer amp */ 15028 nid_v = alc861vd_idx_to_mixer_vol( 15029 alc880_fixed_pin_idx(pin)); 15030 nid_s = alc861vd_idx_to_mixer_switch( 15031 alc880_fixed_pin_idx(pin)); 15032 15033 sprintf(name, "%s Playback Volume", pfx); 15034 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, 15035 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT)); 15036 if (err < 0) 15037 return err; 15038 sprintf(name, "%s Playback Switch", pfx); 15039 err = add_control(spec, ALC_CTL_BIND_MUTE, name, 15040 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT)); 15041 if (err < 0) 15042 return err; 15043 } else if (alc880_is_multi_pin(pin)) { 15044 /* set manual connection */ 15045 /* we have only a switch on HP-out PIN */ 15046 sprintf(name, "%s Playback Switch", pfx); 15047 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, 15048 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); 15049 if (err < 0) 15050 return err; 15051 } 15052 return 0; 15053} 15054 15055/* parse the BIOS configuration and set up the alc_spec 15056 * return 1 if successful, 0 if the proper config is not found, 15057 * or a negative error code 15058 * Based on ALC880 version - had to change it to override 15059 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */ 15060static int alc861vd_parse_auto_config(struct hda_codec *codec) 15061{ 15062 struct alc_spec *spec = codec->spec; 15063 int err; 15064 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 }; 15065 15066 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 15067 alc861vd_ignore); 15068 if (err < 0) 15069 return err; 15070 if (!spec->autocfg.line_outs) 15071 return 0; /* can't find valid BIOS pin config */ 15072 15073 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); 15074 if (err < 0) 15075 return err; 15076 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg); 15077 if (err < 0) 15078 return err; 15079 err = alc861vd_auto_create_extra_out(spec, 15080 spec->autocfg.speaker_pins[0], 15081 "Speaker"); 15082 if (err < 0) 15083 return err; 15084 err = alc861vd_auto_create_extra_out(spec, 15085 spec->autocfg.hp_pins[0], 15086 "Headphone"); 15087 if (err < 0) 15088 return err; 15089 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg); 15090 if (err < 0) 15091 return err; 15092 15093 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 15094 15095 if (spec->autocfg.dig_outs) 15096 spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID; 15097 15098 if (spec->kctls.list) 15099 add_mixer(spec, spec->kctls.list); 15100 15101 add_verb(spec, alc861vd_volume_init_verbs); 15102 15103 spec->num_mux_defs = 1; 15104 spec->input_mux = &spec->private_imux[0]; 15105 15106 err = alc_auto_add_mic_boost(codec); 15107 if (err < 0) 15108 return err; 15109 15110 return 1; 15111} 15112 15113/* additional initialization for auto-configuration model */ 15114static void alc861vd_auto_init(struct hda_codec *codec) 15115{ 15116 struct alc_spec *spec = codec->spec; 15117 alc861vd_auto_init_multi_out(codec); 15118 alc861vd_auto_init_hp_out(codec); 15119 alc861vd_auto_init_analog_input(codec); 15120 alc861vd_auto_init_input_src(codec); 15121 if (spec->unsol_event) 15122 alc_inithook(codec); 15123} 15124 15125static int patch_alc861vd(struct hda_codec *codec) 15126{ 15127 struct alc_spec *spec; 15128 int err, board_config; 15129 15130 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 15131 if (spec == NULL) 15132 return -ENOMEM; 15133 15134 codec->spec = spec; 15135 15136 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST, 15137 alc861vd_models, 15138 alc861vd_cfg_tbl); 15139 15140 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) { 15141 printk(KERN_INFO "hda_codec: Unknown model for ALC660VD/" 15142 "ALC861VD, trying auto-probe from BIOS...\n"); 15143 board_config = ALC861VD_AUTO; 15144 } 15145 15146 if (board_config == ALC861VD_AUTO) { 15147 /* automatic parse from the BIOS config */ 15148 err = alc861vd_parse_auto_config(codec); 15149 if (err < 0) { 15150 alc_free(codec); 15151 return err; 15152 } else if (!err) { 15153 printk(KERN_INFO 15154 "hda_codec: Cannot set up configuration " 15155 "from BIOS. Using base mode...\n"); 15156 board_config = ALC861VD_3ST; 15157 } 15158 } 15159 15160 err = snd_hda_attach_beep_device(codec, 0x23); 15161 if (err < 0) { 15162 alc_free(codec); 15163 return err; 15164 } 15165 15166 if (board_config != ALC861VD_AUTO) 15167 setup_preset(spec, &alc861vd_presets[board_config]); 15168 15169 if (codec->vendor_id == 0x10ec0660) { 15170 spec->stream_name_analog = "ALC660-VD Analog"; 15171 spec->stream_name_digital = "ALC660-VD Digital"; 15172 /* always turn on EAPD */ 15173 add_verb(spec, alc660vd_eapd_verbs); 15174 } else { 15175 spec->stream_name_analog = "ALC861VD Analog"; 15176 spec->stream_name_digital = "ALC861VD Digital"; 15177 } 15178 15179 spec->stream_analog_playback = &alc861vd_pcm_analog_playback; 15180 spec->stream_analog_capture = &alc861vd_pcm_analog_capture; 15181 15182 spec->stream_digital_playback = &alc861vd_pcm_digital_playback; 15183 spec->stream_digital_capture = &alc861vd_pcm_digital_capture; 15184 15185 spec->adc_nids = alc861vd_adc_nids; 15186 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids); 15187 spec->capsrc_nids = alc861vd_capsrc_nids; 15188 spec->capture_style = CAPT_MIX; 15189 15190 set_capture_mixer(spec); 15191 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 15192 15193 spec->vmaster_nid = 0x02; 15194 15195 codec->patch_ops = alc_patch_ops; 15196 15197 if (board_config == ALC861VD_AUTO) 15198 spec->init_hook = alc861vd_auto_init; 15199#ifdef CONFIG_SND_HDA_POWER_SAVE 15200 if (!spec->loopback.amplist) 15201 spec->loopback.amplist = alc861vd_loopbacks; 15202#endif 15203 codec->proc_widget_hook = print_realtek_coef; 15204 15205 return 0; 15206} 15207 15208/* 15209 * ALC662 support 15210 * 15211 * ALC662 is almost identical with ALC880 but has cleaner and more flexible 15212 * configuration. Each pin widget can choose any input DACs and a mixer. 15213 * Each ADC is connected from a mixer of all inputs. This makes possible 15214 * 6-channel independent captures. 15215 * 15216 * In addition, an independent DAC for the multi-playback (not used in this 15217 * driver yet). 15218 */ 15219#define ALC662_DIGOUT_NID 0x06 15220#define ALC662_DIGIN_NID 0x0a 15221 15222static hda_nid_t alc662_dac_nids[4] = { 15223 /* front, rear, clfe, rear_surr */ 15224 0x02, 0x03, 0x04 15225}; 15226 15227static hda_nid_t alc272_dac_nids[2] = { 15228 0x02, 0x03 15229}; 15230 15231static hda_nid_t alc662_adc_nids[1] = { 15232 /* ADC1-2 */ 15233 0x09, 15234}; 15235 15236static hda_nid_t alc272_adc_nids[1] = { 15237 /* ADC1-2 */ 15238 0x08, 15239}; 15240 15241static hda_nid_t alc662_capsrc_nids[1] = { 0x22 }; 15242static hda_nid_t alc272_capsrc_nids[1] = { 0x23 }; 15243 15244 15245/* input MUX */ 15246/* FIXME: should be a matrix-type input source selection */ 15247static struct hda_input_mux alc662_capture_source = { 15248 .num_items = 4, 15249 .items = { 15250 { "Mic", 0x0 }, 15251 { "Front Mic", 0x1 }, 15252 { "Line", 0x2 }, 15253 { "CD", 0x4 }, 15254 }, 15255}; 15256 15257static struct hda_input_mux alc662_lenovo_101e_capture_source = { 15258 .num_items = 2, 15259 .items = { 15260 { "Mic", 0x1 }, 15261 { "Line", 0x2 }, 15262 }, 15263}; 15264 15265static struct hda_input_mux alc662_eeepc_capture_source = { 15266 .num_items = 2, 15267 .items = { 15268 { "i-Mic", 0x1 }, 15269 { "e-Mic", 0x0 }, 15270 }, 15271}; 15272 15273static struct hda_input_mux alc663_capture_source = { 15274 .num_items = 3, 15275 .items = { 15276 { "Mic", 0x0 }, 15277 { "Front Mic", 0x1 }, 15278 { "Line", 0x2 }, 15279 }, 15280}; 15281 15282static struct hda_input_mux alc663_m51va_capture_source = { 15283 .num_items = 2, 15284 .items = { 15285 { "Ext-Mic", 0x0 }, 15286 { "D-Mic", 0x9 }, 15287 }, 15288}; 15289 15290/* 15291 * 2ch mode 15292 */ 15293static struct hda_channel_mode alc662_3ST_2ch_modes[1] = { 15294 { 2, NULL } 15295}; 15296 15297/* 15298 * 2ch mode 15299 */ 15300static struct hda_verb alc662_3ST_ch2_init[] = { 15301 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 15302 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 15303 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 15304 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 15305 { } /* end */ 15306}; 15307 15308/* 15309 * 6ch mode 15310 */ 15311static struct hda_verb alc662_3ST_ch6_init[] = { 15312 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 15313 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 15314 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, 15315 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 15316 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 15317 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 15318 { } /* end */ 15319}; 15320 15321static struct hda_channel_mode alc662_3ST_6ch_modes[2] = { 15322 { 2, alc662_3ST_ch2_init }, 15323 { 6, alc662_3ST_ch6_init }, 15324}; 15325 15326/* 15327 * 2ch mode 15328 */ 15329static struct hda_verb alc662_sixstack_ch6_init[] = { 15330 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 15331 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 15332 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 15333 { } /* end */ 15334}; 15335 15336/* 15337 * 6ch mode 15338 */ 15339static struct hda_verb alc662_sixstack_ch8_init[] = { 15340 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 15341 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 15342 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 15343 { } /* end */ 15344}; 15345 15346static struct hda_channel_mode alc662_5stack_modes[2] = { 15347 { 2, alc662_sixstack_ch6_init }, 15348 { 6, alc662_sixstack_ch8_init }, 15349}; 15350 15351/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 15352 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b 15353 */ 15354 15355static struct snd_kcontrol_new alc662_base_mixer[] = { 15356 /* output mixer control */ 15357 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), 15358 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT), 15359 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT), 15360 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT), 15361 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT), 15362 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT), 15363 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT), 15364 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT), 15365 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 15366 15367 /*Input mixer control */ 15368 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT), 15369 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT), 15370 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT), 15371 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT), 15372 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT), 15373 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT), 15374 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT), 15375 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT), 15376 { } /* end */ 15377}; 15378 15379static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = { 15380 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 15381 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT), 15382 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 15383 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 15384 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 15385 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 15386 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 15387 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 15388 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 15389 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 15390 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 15391 { } /* end */ 15392}; 15393 15394static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = { 15395 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 15396 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT), 15397 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT), 15398 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT), 15399 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT), 15400 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT), 15401 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT), 15402 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT), 15403 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 15404 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 15405 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 15406 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 15407 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 15408 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 15409 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 15410 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 15411 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 15412 { } /* end */ 15413}; 15414 15415static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = { 15416 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 15417 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT), 15418 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT), 15419 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT), 15420 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 15421 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 15422 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 15423 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 15424 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 15425 { } /* end */ 15426}; 15427 15428static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = { 15429 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 15430 15431 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT), 15432 HDA_CODEC_MUTE("Line-Out Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 15433 15434 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT), 15435 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 15436 HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 15437 15438 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT), 15439 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 15440 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 15441 { } /* end */ 15442}; 15443 15444static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = { 15445 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT), 15446 HDA_CODEC_MUTE("Line-Out Playback Switch", 0x14, 0x0, HDA_OUTPUT), 15447 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT), 15448 HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT), 15449 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT), 15450 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT), 15451 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT), 15452 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT), 15453 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 15454 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT), 15455 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 15456 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 15457 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 15458 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 15459 { } /* end */ 15460}; 15461 15462static struct hda_bind_ctls alc663_asus_bind_master_vol = { 15463 .ops = &snd_hda_bind_vol, 15464 .values = { 15465 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), 15466 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT), 15467 0 15468 }, 15469}; 15470 15471static struct hda_bind_ctls alc663_asus_one_bind_switch = { 15472 .ops = &snd_hda_bind_sw, 15473 .values = { 15474 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 15475 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT), 15476 0 15477 }, 15478}; 15479 15480static struct snd_kcontrol_new alc663_m51va_mixer[] = { 15481 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol), 15482 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch), 15483 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 15484 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 15485 { } /* end */ 15486}; 15487 15488static struct hda_bind_ctls alc663_asus_tree_bind_switch = { 15489 .ops = &snd_hda_bind_sw, 15490 .values = { 15491 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 15492 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT), 15493 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT), 15494 0 15495 }, 15496}; 15497 15498static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = { 15499 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol), 15500 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch), 15501 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 15502 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 15503 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 15504 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 15505 15506 { } /* end */ 15507}; 15508 15509static struct hda_bind_ctls alc663_asus_four_bind_switch = { 15510 .ops = &snd_hda_bind_sw, 15511 .values = { 15512 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 15513 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT), 15514 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT), 15515 0 15516 }, 15517}; 15518 15519static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = { 15520 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol), 15521 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch), 15522 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 15523 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 15524 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 15525 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 15526 { } /* end */ 15527}; 15528 15529static struct snd_kcontrol_new alc662_1bjd_mixer[] = { 15530 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 15531 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 15532 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 15533 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 15534 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 15535 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 15536 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 15537 { } /* end */ 15538}; 15539 15540static struct hda_bind_ctls alc663_asus_two_bind_master_vol = { 15541 .ops = &snd_hda_bind_vol, 15542 .values = { 15543 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), 15544 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT), 15545 0 15546 }, 15547}; 15548 15549static struct hda_bind_ctls alc663_asus_two_bind_switch = { 15550 .ops = &snd_hda_bind_sw, 15551 .values = { 15552 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 15553 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT), 15554 0 15555 }, 15556}; 15557 15558static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = { 15559 HDA_BIND_VOL("Master Playback Volume", 15560 &alc663_asus_two_bind_master_vol), 15561 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch), 15562 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 15563 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT), 15564 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 15565 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 15566 { } /* end */ 15567}; 15568 15569static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = { 15570 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol), 15571 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch), 15572 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 15573 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 15574 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 15575 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 15576 { } /* end */ 15577}; 15578 15579static struct snd_kcontrol_new alc663_g71v_mixer[] = { 15580 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 15581 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 15582 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT), 15583 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT), 15584 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT), 15585 15586 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 15587 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 15588 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 15589 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 15590 { } /* end */ 15591}; 15592 15593static struct snd_kcontrol_new alc663_g50v_mixer[] = { 15594 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 15595 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 15596 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT), 15597 15598 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 15599 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 15600 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 15601 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 15602 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 15603 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 15604 { } /* end */ 15605}; 15606 15607static struct snd_kcontrol_new alc662_chmode_mixer[] = { 15608 { 15609 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 15610 .name = "Channel Mode", 15611 .info = alc_ch_mode_info, 15612 .get = alc_ch_mode_get, 15613 .put = alc_ch_mode_put, 15614 }, 15615 { } /* end */ 15616}; 15617 15618static struct hda_verb alc662_init_verbs[] = { 15619 /* ADC: mute amp left and right */ 15620 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 15621 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 15622 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 15623 15624 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 15625 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 15626 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 15627 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 15628 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 15629 15630 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15631 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15632 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15633 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15634 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15635 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15636 15637 /* Front Pin: output 0 (0x0c) */ 15638 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 15639 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15640 15641 /* Rear Pin: output 1 (0x0d) */ 15642 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 15643 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15644 15645 /* CLFE Pin: output 2 (0x0e) */ 15646 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 15647 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15648 15649 /* Mic (rear) pin: input vref at 80% */ 15650 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 15651 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 15652 /* Front Mic pin: input vref at 80% */ 15653 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 15654 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 15655 /* Line In pin: input */ 15656 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 15657 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 15658 /* Line-2 In: Headphone output (output 0 - 0x0c) */ 15659 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 15660 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15661 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 15662 /* CD pin widget for input */ 15663 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 15664 15665 /* FIXME: use matrix-type input source selection */ 15666 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 15667 /* Input mixer */ 15668 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15669 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15670 15671 /* always trun on EAPD */ 15672 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 15673 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, 15674 15675 { } 15676}; 15677 15678static struct hda_verb alc662_sue_init_verbs[] = { 15679 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT}, 15680 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT}, 15681 {} 15682}; 15683 15684static struct hda_verb alc662_eeepc_sue_init_verbs[] = { 15685 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 15686 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 15687 {} 15688}; 15689 15690/* Set Unsolicited Event*/ 15691static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = { 15692 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 15693 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 15694 {} 15695}; 15696 15697/* 15698 * generic initialization of ADC, input mixers and output mixers 15699 */ 15700static struct hda_verb alc662_auto_init_verbs[] = { 15701 /* 15702 * Unmute ADC and set the default input to mic-in 15703 */ 15704 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 15705 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15706 15707 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 15708 * mixer widget 15709 * Note: PASD motherboards uses the Line In 2 as the input for front 15710 * panel mic (mic 2) 15711 */ 15712 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 15713 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 15714 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 15715 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 15716 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 15717 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 15718 15719 /* 15720 * Set up output mixers (0x0c - 0x0f) 15721 */ 15722 /* set vol=0 to output mixers */ 15723 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 15724 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 15725 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 15726 15727 /* set up input amps for analog loopback */ 15728 /* Amp Indices: DAC = 0, mixer = 1 */ 15729 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15730 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15731 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15732 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15733 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15734 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15735 15736 15737 /* FIXME: use matrix-type input source selection */ 15738 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 15739 /* Input mixer */ 15740 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15741 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15742 { } 15743}; 15744 15745/* additional verbs for ALC663 */ 15746static struct hda_verb alc663_auto_init_verbs[] = { 15747 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15748 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15749 { } 15750}; 15751 15752static struct hda_verb alc663_m51va_init_verbs[] = { 15753 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 15754 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 15755 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 15756 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15757 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ 15758 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 15759 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)}, 15760 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 15761 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 15762 {} 15763}; 15764 15765static struct hda_verb alc663_21jd_amic_init_verbs[] = { 15766 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 15767 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15768 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ 15769 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 15770 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15771 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 15772 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 15773 {} 15774}; 15775 15776static struct hda_verb alc662_1bjd_amic_init_verbs[] = { 15777 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 15778 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 15779 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15780 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */ 15781 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 15782 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15783 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 15784 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 15785 {} 15786}; 15787 15788static struct hda_verb alc663_15jd_amic_init_verbs[] = { 15789 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 15790 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15791 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ 15792 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 15793 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15794 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 15795 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 15796 {} 15797}; 15798 15799static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = { 15800 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 15801 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 15802 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15803 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */ 15804 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 15805 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15806 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */ 15807 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 15808 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15809 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 15810 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 15811 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 15812 {} 15813}; 15814 15815static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = { 15816 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 15817 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 15818 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15819 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ 15820 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 15821 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15822 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ 15823 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 15824 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15825 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 15826 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 15827 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 15828 {} 15829}; 15830 15831static struct hda_verb alc663_g71v_init_verbs[] = { 15832 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 15833 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */ 15834 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */ 15835 15836 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 15837 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15838 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */ 15839 15840 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT}, 15841 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT}, 15842 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT}, 15843 {} 15844}; 15845 15846static struct hda_verb alc663_g50v_init_verbs[] = { 15847 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 15848 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15849 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */ 15850 15851 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 15852 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 15853 {} 15854}; 15855 15856static struct hda_verb alc662_ecs_init_verbs[] = { 15857 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f}, 15858 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 15859 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 15860 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 15861 {} 15862}; 15863 15864static struct hda_verb alc272_dell_zm1_init_verbs[] = { 15865 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 15866 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 15867 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 15868 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 15869 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 15870 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15871 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ 15872 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 15873 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)}, 15874 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 15875 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 15876 {} 15877}; 15878 15879static struct hda_verb alc272_dell_init_verbs[] = { 15880 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 15881 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 15882 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 15883 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 15884 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 15885 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15886 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ 15887 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 15888 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)}, 15889 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 15890 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 15891 {} 15892}; 15893 15894static struct snd_kcontrol_new alc662_auto_capture_mixer[] = { 15895 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), 15896 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), 15897 { } /* end */ 15898}; 15899 15900static struct snd_kcontrol_new alc272_auto_capture_mixer[] = { 15901 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 15902 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 15903 { } /* end */ 15904}; 15905 15906static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec) 15907{ 15908 unsigned int present; 15909 unsigned char bits; 15910 15911 present = snd_hda_codec_read(codec, 0x14, 0, 15912 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 15913 bits = present ? HDA_AMP_MUTE : 0; 15914 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 15915 HDA_AMP_MUTE, bits); 15916} 15917 15918static void alc662_lenovo_101e_all_automute(struct hda_codec *codec) 15919{ 15920 unsigned int present; 15921 unsigned char bits; 15922 15923 present = snd_hda_codec_read(codec, 0x1b, 0, 15924 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 15925 bits = present ? HDA_AMP_MUTE : 0; 15926 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 15927 HDA_AMP_MUTE, bits); 15928 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 15929 HDA_AMP_MUTE, bits); 15930} 15931 15932static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec, 15933 unsigned int res) 15934{ 15935 if ((res >> 26) == ALC880_HP_EVENT) 15936 alc662_lenovo_101e_all_automute(codec); 15937 if ((res >> 26) == ALC880_FRONT_EVENT) 15938 alc662_lenovo_101e_ispeaker_automute(codec); 15939} 15940 15941static void alc662_eeepc_mic_automute(struct hda_codec *codec) 15942{ 15943 unsigned int present; 15944 15945 present = snd_hda_codec_read(codec, 0x18, 0, 15946 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 15947 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE, 15948 0x7000 | (0x00 << 8) | (present ? 0 : 0x80)); 15949 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE, 15950 0x7000 | (0x00 << 8) | (present ? 0 : 0x80)); 15951 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE, 15952 0x7000 | (0x01 << 8) | (present ? 0x80 : 0)); 15953 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE, 15954 0x7000 | (0x01 << 8) | (present ? 0x80 : 0)); 15955} 15956 15957/* unsolicited event for HP jack sensing */ 15958static void alc662_eeepc_unsol_event(struct hda_codec *codec, 15959 unsigned int res) 15960{ 15961 if ((res >> 26) == ALC880_HP_EVENT) 15962 alc262_hippo1_automute( codec ); 15963 15964 if ((res >> 26) == ALC880_MIC_EVENT) 15965 alc662_eeepc_mic_automute(codec); 15966} 15967 15968static void alc662_eeepc_inithook(struct hda_codec *codec) 15969{ 15970 alc262_hippo1_automute( codec ); 15971 alc662_eeepc_mic_automute(codec); 15972} 15973 15974static void alc662_eeepc_ep20_automute(struct hda_codec *codec) 15975{ 15976 unsigned int mute; 15977 unsigned int present; 15978 15979 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0); 15980 present = snd_hda_codec_read(codec, 0x14, 0, 15981 AC_VERB_GET_PIN_SENSE, 0); 15982 present = (present & 0x80000000) != 0; 15983 if (present) { 15984 /* mute internal speaker */ 15985 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0, 15986 HDA_AMP_MUTE, HDA_AMP_MUTE); 15987 } else { 15988 /* unmute internal speaker if necessary */ 15989 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0); 15990 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0, 15991 HDA_AMP_MUTE, mute); 15992 } 15993} 15994 15995/* unsolicited event for HP jack sensing */ 15996static void alc662_eeepc_ep20_unsol_event(struct hda_codec *codec, 15997 unsigned int res) 15998{ 15999 if ((res >> 26) == ALC880_HP_EVENT) 16000 alc662_eeepc_ep20_automute(codec); 16001} 16002 16003static void alc662_eeepc_ep20_inithook(struct hda_codec *codec) 16004{ 16005 alc662_eeepc_ep20_automute(codec); 16006} 16007 16008static void alc663_m51va_speaker_automute(struct hda_codec *codec) 16009{ 16010 unsigned int present; 16011 unsigned char bits; 16012 16013 present = snd_hda_codec_read(codec, 0x21, 0, 16014 AC_VERB_GET_PIN_SENSE, 0) 16015 & AC_PINSENSE_PRESENCE; 16016 bits = present ? HDA_AMP_MUTE : 0; 16017 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 16018 AMP_IN_MUTE(0), bits); 16019 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 16020 AMP_IN_MUTE(0), bits); 16021} 16022 16023static void alc663_21jd_two_speaker_automute(struct hda_codec *codec) 16024{ 16025 unsigned int present; 16026 unsigned char bits; 16027 16028 present = snd_hda_codec_read(codec, 0x21, 0, 16029 AC_VERB_GET_PIN_SENSE, 0) 16030 & AC_PINSENSE_PRESENCE; 16031 bits = present ? HDA_AMP_MUTE : 0; 16032 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 16033 AMP_IN_MUTE(0), bits); 16034 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 16035 AMP_IN_MUTE(0), bits); 16036 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0, 16037 AMP_IN_MUTE(0), bits); 16038 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1, 16039 AMP_IN_MUTE(0), bits); 16040} 16041 16042static void alc663_15jd_two_speaker_automute(struct hda_codec *codec) 16043{ 16044 unsigned int present; 16045 unsigned char bits; 16046 16047 present = snd_hda_codec_read(codec, 0x15, 0, 16048 AC_VERB_GET_PIN_SENSE, 0) 16049 & AC_PINSENSE_PRESENCE; 16050 bits = present ? HDA_AMP_MUTE : 0; 16051 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 16052 AMP_IN_MUTE(0), bits); 16053 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 16054 AMP_IN_MUTE(0), bits); 16055 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0, 16056 AMP_IN_MUTE(0), bits); 16057 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1, 16058 AMP_IN_MUTE(0), bits); 16059} 16060 16061static void alc662_f5z_speaker_automute(struct hda_codec *codec) 16062{ 16063 unsigned int present; 16064 unsigned char bits; 16065 16066 present = snd_hda_codec_read(codec, 0x1b, 0, 16067 AC_VERB_GET_PIN_SENSE, 0) 16068 & AC_PINSENSE_PRESENCE; 16069 bits = present ? 0 : PIN_OUT; 16070 snd_hda_codec_write(codec, 0x14, 0, 16071 AC_VERB_SET_PIN_WIDGET_CONTROL, bits); 16072} 16073 16074static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec) 16075{ 16076 unsigned int present1, present2; 16077 16078 present1 = snd_hda_codec_read(codec, 0x21, 0, 16079 AC_VERB_GET_PIN_SENSE, 0) 16080 & AC_PINSENSE_PRESENCE; 16081 present2 = snd_hda_codec_read(codec, 0x15, 0, 16082 AC_VERB_GET_PIN_SENSE, 0) 16083 & AC_PINSENSE_PRESENCE; 16084 16085 if (present1 || present2) { 16086 snd_hda_codec_write_cache(codec, 0x14, 0, 16087 AC_VERB_SET_PIN_WIDGET_CONTROL, 0); 16088 } else { 16089 snd_hda_codec_write_cache(codec, 0x14, 0, 16090 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); 16091 } 16092} 16093 16094static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec) 16095{ 16096 unsigned int present1, present2; 16097 16098 present1 = snd_hda_codec_read(codec, 0x1b, 0, 16099 AC_VERB_GET_PIN_SENSE, 0) 16100 & AC_PINSENSE_PRESENCE; 16101 present2 = snd_hda_codec_read(codec, 0x15, 0, 16102 AC_VERB_GET_PIN_SENSE, 0) 16103 & AC_PINSENSE_PRESENCE; 16104 16105 if (present1 || present2) { 16106 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 16107 AMP_IN_MUTE(0), AMP_IN_MUTE(0)); 16108 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 16109 AMP_IN_MUTE(0), AMP_IN_MUTE(0)); 16110 } else { 16111 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 16112 AMP_IN_MUTE(0), 0); 16113 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 16114 AMP_IN_MUTE(0), 0); 16115 } 16116} 16117 16118static void alc663_m51va_mic_automute(struct hda_codec *codec) 16119{ 16120 unsigned int present; 16121 16122 present = snd_hda_codec_read(codec, 0x18, 0, 16123 AC_VERB_GET_PIN_SENSE, 0) 16124 & AC_PINSENSE_PRESENCE; 16125 snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE, 16126 0x7000 | (0x00 << 8) | (present ? 0 : 0x80)); 16127 snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE, 16128 0x7000 | (0x00 << 8) | (present ? 0 : 0x80)); 16129 snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE, 16130 0x7000 | (0x09 << 8) | (present ? 0x80 : 0)); 16131 snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE, 16132 0x7000 | (0x09 << 8) | (present ? 0x80 : 0)); 16133} 16134 16135static void alc663_m51va_unsol_event(struct hda_codec *codec, 16136 unsigned int res) 16137{ 16138 switch (res >> 26) { 16139 case ALC880_HP_EVENT: 16140 alc663_m51va_speaker_automute(codec); 16141 break; 16142 case ALC880_MIC_EVENT: 16143 alc663_m51va_mic_automute(codec); 16144 break; 16145 } 16146} 16147 16148static void alc663_m51va_inithook(struct hda_codec *codec) 16149{ 16150 alc663_m51va_speaker_automute(codec); 16151 alc663_m51va_mic_automute(codec); 16152} 16153 16154/* ***************** Mode1 ******************************/ 16155static void alc663_mode1_unsol_event(struct hda_codec *codec, 16156 unsigned int res) 16157{ 16158 switch (res >> 26) { 16159 case ALC880_HP_EVENT: 16160 alc663_m51va_speaker_automute(codec); 16161 break; 16162 case ALC880_MIC_EVENT: 16163 alc662_eeepc_mic_automute(codec); 16164 break; 16165 } 16166} 16167 16168static void alc663_mode1_inithook(struct hda_codec *codec) 16169{ 16170 alc663_m51va_speaker_automute(codec); 16171 alc662_eeepc_mic_automute(codec); 16172} 16173/* ***************** Mode2 ******************************/ 16174static void alc662_mode2_unsol_event(struct hda_codec *codec, 16175 unsigned int res) 16176{ 16177 switch (res >> 26) { 16178 case ALC880_HP_EVENT: 16179 alc662_f5z_speaker_automute(codec); 16180 break; 16181 case ALC880_MIC_EVENT: 16182 alc662_eeepc_mic_automute(codec); 16183 break; 16184 } 16185} 16186 16187static void alc662_mode2_inithook(struct hda_codec *codec) 16188{ 16189 alc662_f5z_speaker_automute(codec); 16190 alc662_eeepc_mic_automute(codec); 16191} 16192/* ***************** Mode3 ******************************/ 16193static void alc663_mode3_unsol_event(struct hda_codec *codec, 16194 unsigned int res) 16195{ 16196 switch (res >> 26) { 16197 case ALC880_HP_EVENT: 16198 alc663_two_hp_m1_speaker_automute(codec); 16199 break; 16200 case ALC880_MIC_EVENT: 16201 alc662_eeepc_mic_automute(codec); 16202 break; 16203 } 16204} 16205 16206static void alc663_mode3_inithook(struct hda_codec *codec) 16207{ 16208 alc663_two_hp_m1_speaker_automute(codec); 16209 alc662_eeepc_mic_automute(codec); 16210} 16211/* ***************** Mode4 ******************************/ 16212static void alc663_mode4_unsol_event(struct hda_codec *codec, 16213 unsigned int res) 16214{ 16215 switch (res >> 26) { 16216 case ALC880_HP_EVENT: 16217 alc663_21jd_two_speaker_automute(codec); 16218 break; 16219 case ALC880_MIC_EVENT: 16220 alc662_eeepc_mic_automute(codec); 16221 break; 16222 } 16223} 16224 16225static void alc663_mode4_inithook(struct hda_codec *codec) 16226{ 16227 alc663_21jd_two_speaker_automute(codec); 16228 alc662_eeepc_mic_automute(codec); 16229} 16230/* ***************** Mode5 ******************************/ 16231static void alc663_mode5_unsol_event(struct hda_codec *codec, 16232 unsigned int res) 16233{ 16234 switch (res >> 26) { 16235 case ALC880_HP_EVENT: 16236 alc663_15jd_two_speaker_automute(codec); 16237 break; 16238 case ALC880_MIC_EVENT: 16239 alc662_eeepc_mic_automute(codec); 16240 break; 16241 } 16242} 16243 16244static void alc663_mode5_inithook(struct hda_codec *codec) 16245{ 16246 alc663_15jd_two_speaker_automute(codec); 16247 alc662_eeepc_mic_automute(codec); 16248} 16249/* ***************** Mode6 ******************************/ 16250static void alc663_mode6_unsol_event(struct hda_codec *codec, 16251 unsigned int res) 16252{ 16253 switch (res >> 26) { 16254 case ALC880_HP_EVENT: 16255 alc663_two_hp_m2_speaker_automute(codec); 16256 break; 16257 case ALC880_MIC_EVENT: 16258 alc662_eeepc_mic_automute(codec); 16259 break; 16260 } 16261} 16262 16263static void alc663_mode6_inithook(struct hda_codec *codec) 16264{ 16265 alc663_two_hp_m2_speaker_automute(codec); 16266 alc662_eeepc_mic_automute(codec); 16267} 16268 16269static void alc663_g71v_hp_automute(struct hda_codec *codec) 16270{ 16271 unsigned int present; 16272 unsigned char bits; 16273 16274 present = snd_hda_codec_read(codec, 0x21, 0, 16275 AC_VERB_GET_PIN_SENSE, 0) 16276 & AC_PINSENSE_PRESENCE; 16277 bits = present ? HDA_AMP_MUTE : 0; 16278 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 16279 HDA_AMP_MUTE, bits); 16280 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 16281 HDA_AMP_MUTE, bits); 16282} 16283 16284static void alc663_g71v_front_automute(struct hda_codec *codec) 16285{ 16286 unsigned int present; 16287 unsigned char bits; 16288 16289 present = snd_hda_codec_read(codec, 0x15, 0, 16290 AC_VERB_GET_PIN_SENSE, 0) 16291 & AC_PINSENSE_PRESENCE; 16292 bits = present ? HDA_AMP_MUTE : 0; 16293 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 16294 HDA_AMP_MUTE, bits); 16295} 16296 16297static void alc663_g71v_unsol_event(struct hda_codec *codec, 16298 unsigned int res) 16299{ 16300 switch (res >> 26) { 16301 case ALC880_HP_EVENT: 16302 alc663_g71v_hp_automute(codec); 16303 break; 16304 case ALC880_FRONT_EVENT: 16305 alc663_g71v_front_automute(codec); 16306 break; 16307 case ALC880_MIC_EVENT: 16308 alc662_eeepc_mic_automute(codec); 16309 break; 16310 } 16311} 16312 16313static void alc663_g71v_inithook(struct hda_codec *codec) 16314{ 16315 alc663_g71v_front_automute(codec); 16316 alc663_g71v_hp_automute(codec); 16317 alc662_eeepc_mic_automute(codec); 16318} 16319 16320static void alc663_g50v_unsol_event(struct hda_codec *codec, 16321 unsigned int res) 16322{ 16323 switch (res >> 26) { 16324 case ALC880_HP_EVENT: 16325 alc663_m51va_speaker_automute(codec); 16326 break; 16327 case ALC880_MIC_EVENT: 16328 alc662_eeepc_mic_automute(codec); 16329 break; 16330 } 16331} 16332 16333static void alc663_g50v_inithook(struct hda_codec *codec) 16334{ 16335 alc663_m51va_speaker_automute(codec); 16336 alc662_eeepc_mic_automute(codec); 16337} 16338 16339/* bind hp and internal speaker mute (with plug check) */ 16340static int alc662_ecs_master_sw_put(struct snd_kcontrol *kcontrol, 16341 struct snd_ctl_elem_value *ucontrol) 16342{ 16343 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 16344 long *valp = ucontrol->value.integer.value; 16345 int change; 16346 16347 change = snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0, 16348 HDA_AMP_MUTE, 16349 valp[0] ? 0 : HDA_AMP_MUTE); 16350 change |= snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0, 16351 HDA_AMP_MUTE, 16352 valp[1] ? 0 : HDA_AMP_MUTE); 16353 if (change) 16354 alc262_hippo1_automute(codec); 16355 return change; 16356} 16357 16358static struct snd_kcontrol_new alc662_ecs_mixer[] = { 16359 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT), 16360 { 16361 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 16362 .name = "Master Playback Switch", 16363 .info = snd_hda_mixer_amp_switch_info, 16364 .get = snd_hda_mixer_amp_switch_get, 16365 .put = alc662_ecs_master_sw_put, 16366 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT), 16367 }, 16368 16369 HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT), 16370 HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT), 16371 HDA_CODEC_MUTE("e-Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT), 16372 16373 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT), 16374 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 16375 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 16376 { } /* end */ 16377}; 16378 16379#ifdef CONFIG_SND_HDA_POWER_SAVE 16380#define alc662_loopbacks alc880_loopbacks 16381#endif 16382 16383 16384/* pcm configuration: identiacal with ALC880 */ 16385#define alc662_pcm_analog_playback alc880_pcm_analog_playback 16386#define alc662_pcm_analog_capture alc880_pcm_analog_capture 16387#define alc662_pcm_digital_playback alc880_pcm_digital_playback 16388#define alc662_pcm_digital_capture alc880_pcm_digital_capture 16389 16390/* 16391 * configuration and preset 16392 */ 16393static const char *alc662_models[ALC662_MODEL_LAST] = { 16394 [ALC662_3ST_2ch_DIG] = "3stack-dig", 16395 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig", 16396 [ALC662_3ST_6ch] = "3stack-6ch", 16397 [ALC662_5ST_DIG] = "6stack-dig", 16398 [ALC662_LENOVO_101E] = "lenovo-101e", 16399 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701", 16400 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20", 16401 [ALC662_ECS] = "ecs", 16402 [ALC663_ASUS_M51VA] = "m51va", 16403 [ALC663_ASUS_G71V] = "g71v", 16404 [ALC663_ASUS_H13] = "h13", 16405 [ALC663_ASUS_G50V] = "g50v", 16406 [ALC663_ASUS_MODE1] = "asus-mode1", 16407 [ALC662_ASUS_MODE2] = "asus-mode2", 16408 [ALC663_ASUS_MODE3] = "asus-mode3", 16409 [ALC663_ASUS_MODE4] = "asus-mode4", 16410 [ALC663_ASUS_MODE5] = "asus-mode5", 16411 [ALC663_ASUS_MODE6] = "asus-mode6", 16412 [ALC662_AUTO] = "auto", 16413}; 16414 16415static struct snd_pci_quirk alc662_cfg_tbl[] = { 16416 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS), 16417 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL), 16418 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1), 16419 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1), 16420 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3), 16421 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3), 16422 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1), 16423 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2), 16424 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1), 16425 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2), 16426 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2), 16427 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2), 16428 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6), 16429 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6), 16430 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2), 16431 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3), 16432 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA), 16433 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2), 16434 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2), 16435 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5), 16436 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6), 16437 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2), 16438 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1), 16439 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2), 16440 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2), 16441 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA), 16442 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/ 16443 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3), 16444 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3), 16445 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1), 16446 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1), 16447 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1), 16448 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1), 16449 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2), 16450 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2), 16451 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1), 16452 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1), 16453 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3), 16454 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1), 16455 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1), 16456 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V), 16457 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/ 16458 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1), 16459 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2), 16460 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA), 16461 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1), 16462 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4), 16463 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG), 16464 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701), 16465 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20), 16466 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS), 16467 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K", 16468 ALC662_3ST_6ch_DIG), 16469 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L", 16470 ALC662_3ST_6ch_DIG), 16471 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG), 16472 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E), 16473 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0", 16474 ALC662_3ST_6ch_DIG), 16475 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x", 16476 ALC663_ASUS_H13), 16477 {} 16478}; 16479 16480static struct alc_config_preset alc662_presets[] = { 16481 [ALC662_3ST_2ch_DIG] = { 16482 .mixers = { alc662_3ST_2ch_mixer }, 16483 .init_verbs = { alc662_init_verbs }, 16484 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 16485 .dac_nids = alc662_dac_nids, 16486 .dig_out_nid = ALC662_DIGOUT_NID, 16487 .dig_in_nid = ALC662_DIGIN_NID, 16488 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 16489 .channel_mode = alc662_3ST_2ch_modes, 16490 .input_mux = &alc662_capture_source, 16491 }, 16492 [ALC662_3ST_6ch_DIG] = { 16493 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer }, 16494 .init_verbs = { alc662_init_verbs }, 16495 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 16496 .dac_nids = alc662_dac_nids, 16497 .dig_out_nid = ALC662_DIGOUT_NID, 16498 .dig_in_nid = ALC662_DIGIN_NID, 16499 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), 16500 .channel_mode = alc662_3ST_6ch_modes, 16501 .need_dac_fix = 1, 16502 .input_mux = &alc662_capture_source, 16503 }, 16504 [ALC662_3ST_6ch] = { 16505 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer }, 16506 .init_verbs = { alc662_init_verbs }, 16507 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 16508 .dac_nids = alc662_dac_nids, 16509 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), 16510 .channel_mode = alc662_3ST_6ch_modes, 16511 .need_dac_fix = 1, 16512 .input_mux = &alc662_capture_source, 16513 }, 16514 [ALC662_5ST_DIG] = { 16515 .mixers = { alc662_base_mixer, alc662_chmode_mixer }, 16516 .init_verbs = { alc662_init_verbs }, 16517 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 16518 .dac_nids = alc662_dac_nids, 16519 .dig_out_nid = ALC662_DIGOUT_NID, 16520 .dig_in_nid = ALC662_DIGIN_NID, 16521 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes), 16522 .channel_mode = alc662_5stack_modes, 16523 .input_mux = &alc662_capture_source, 16524 }, 16525 [ALC662_LENOVO_101E] = { 16526 .mixers = { alc662_lenovo_101e_mixer }, 16527 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs }, 16528 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 16529 .dac_nids = alc662_dac_nids, 16530 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 16531 .channel_mode = alc662_3ST_2ch_modes, 16532 .input_mux = &alc662_lenovo_101e_capture_source, 16533 .unsol_event = alc662_lenovo_101e_unsol_event, 16534 .init_hook = alc662_lenovo_101e_all_automute, 16535 }, 16536 [ALC662_ASUS_EEEPC_P701] = { 16537 .mixers = { alc662_eeepc_p701_mixer }, 16538 .init_verbs = { alc662_init_verbs, 16539 alc662_eeepc_sue_init_verbs }, 16540 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 16541 .dac_nids = alc662_dac_nids, 16542 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 16543 .channel_mode = alc662_3ST_2ch_modes, 16544 .input_mux = &alc662_eeepc_capture_source, 16545 .unsol_event = alc662_eeepc_unsol_event, 16546 .init_hook = alc662_eeepc_inithook, 16547 }, 16548 [ALC662_ASUS_EEEPC_EP20] = { 16549 .mixers = { alc662_eeepc_ep20_mixer, 16550 alc662_chmode_mixer }, 16551 .init_verbs = { alc662_init_verbs, 16552 alc662_eeepc_ep20_sue_init_verbs }, 16553 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 16554 .dac_nids = alc662_dac_nids, 16555 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), 16556 .channel_mode = alc662_3ST_6ch_modes, 16557 .input_mux = &alc662_lenovo_101e_capture_source, 16558 .unsol_event = alc662_eeepc_ep20_unsol_event, 16559 .init_hook = alc662_eeepc_ep20_inithook, 16560 }, 16561 [ALC662_ECS] = { 16562 .mixers = { alc662_ecs_mixer }, 16563 .init_verbs = { alc662_init_verbs, 16564 alc662_ecs_init_verbs }, 16565 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 16566 .dac_nids = alc662_dac_nids, 16567 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 16568 .channel_mode = alc662_3ST_2ch_modes, 16569 .input_mux = &alc662_eeepc_capture_source, 16570 .unsol_event = alc662_eeepc_unsol_event, 16571 .init_hook = alc662_eeepc_inithook, 16572 }, 16573 [ALC663_ASUS_M51VA] = { 16574 .mixers = { alc663_m51va_mixer }, 16575 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs }, 16576 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 16577 .dac_nids = alc662_dac_nids, 16578 .dig_out_nid = ALC662_DIGOUT_NID, 16579 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 16580 .channel_mode = alc662_3ST_2ch_modes, 16581 .input_mux = &alc663_m51va_capture_source, 16582 .unsol_event = alc663_m51va_unsol_event, 16583 .init_hook = alc663_m51va_inithook, 16584 }, 16585 [ALC663_ASUS_G71V] = { 16586 .mixers = { alc663_g71v_mixer }, 16587 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs }, 16588 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 16589 .dac_nids = alc662_dac_nids, 16590 .dig_out_nid = ALC662_DIGOUT_NID, 16591 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 16592 .channel_mode = alc662_3ST_2ch_modes, 16593 .input_mux = &alc662_eeepc_capture_source, 16594 .unsol_event = alc663_g71v_unsol_event, 16595 .init_hook = alc663_g71v_inithook, 16596 }, 16597 [ALC663_ASUS_H13] = { 16598 .mixers = { alc663_m51va_mixer }, 16599 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs }, 16600 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 16601 .dac_nids = alc662_dac_nids, 16602 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 16603 .channel_mode = alc662_3ST_2ch_modes, 16604 .input_mux = &alc663_m51va_capture_source, 16605 .unsol_event = alc663_m51va_unsol_event, 16606 .init_hook = alc663_m51va_inithook, 16607 }, 16608 [ALC663_ASUS_G50V] = { 16609 .mixers = { alc663_g50v_mixer }, 16610 .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs }, 16611 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 16612 .dac_nids = alc662_dac_nids, 16613 .dig_out_nid = ALC662_DIGOUT_NID, 16614 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), 16615 .channel_mode = alc662_3ST_6ch_modes, 16616 .input_mux = &alc663_capture_source, 16617 .unsol_event = alc663_g50v_unsol_event, 16618 .init_hook = alc663_g50v_inithook, 16619 }, 16620 [ALC663_ASUS_MODE1] = { 16621 .mixers = { alc663_m51va_mixer }, 16622 .cap_mixer = alc662_auto_capture_mixer, 16623 .init_verbs = { alc662_init_verbs, 16624 alc663_21jd_amic_init_verbs }, 16625 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 16626 .hp_nid = 0x03, 16627 .dac_nids = alc662_dac_nids, 16628 .dig_out_nid = ALC662_DIGOUT_NID, 16629 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 16630 .channel_mode = alc662_3ST_2ch_modes, 16631 .input_mux = &alc662_eeepc_capture_source, 16632 .unsol_event = alc663_mode1_unsol_event, 16633 .init_hook = alc663_mode1_inithook, 16634 }, 16635 [ALC662_ASUS_MODE2] = { 16636 .mixers = { alc662_1bjd_mixer }, 16637 .cap_mixer = alc662_auto_capture_mixer, 16638 .init_verbs = { alc662_init_verbs, 16639 alc662_1bjd_amic_init_verbs }, 16640 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 16641 .dac_nids = alc662_dac_nids, 16642 .dig_out_nid = ALC662_DIGOUT_NID, 16643 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 16644 .channel_mode = alc662_3ST_2ch_modes, 16645 .input_mux = &alc662_eeepc_capture_source, 16646 .unsol_event = alc662_mode2_unsol_event, 16647 .init_hook = alc662_mode2_inithook, 16648 }, 16649 [ALC663_ASUS_MODE3] = { 16650 .mixers = { alc663_two_hp_m1_mixer }, 16651 .cap_mixer = alc662_auto_capture_mixer, 16652 .init_verbs = { alc662_init_verbs, 16653 alc663_two_hp_amic_m1_init_verbs }, 16654 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 16655 .hp_nid = 0x03, 16656 .dac_nids = alc662_dac_nids, 16657 .dig_out_nid = ALC662_DIGOUT_NID, 16658 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 16659 .channel_mode = alc662_3ST_2ch_modes, 16660 .input_mux = &alc662_eeepc_capture_source, 16661 .unsol_event = alc663_mode3_unsol_event, 16662 .init_hook = alc663_mode3_inithook, 16663 }, 16664 [ALC663_ASUS_MODE4] = { 16665 .mixers = { alc663_asus_21jd_clfe_mixer }, 16666 .cap_mixer = alc662_auto_capture_mixer, 16667 .init_verbs = { alc662_init_verbs, 16668 alc663_21jd_amic_init_verbs}, 16669 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 16670 .hp_nid = 0x03, 16671 .dac_nids = alc662_dac_nids, 16672 .dig_out_nid = ALC662_DIGOUT_NID, 16673 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 16674 .channel_mode = alc662_3ST_2ch_modes, 16675 .input_mux = &alc662_eeepc_capture_source, 16676 .unsol_event = alc663_mode4_unsol_event, 16677 .init_hook = alc663_mode4_inithook, 16678 }, 16679 [ALC663_ASUS_MODE5] = { 16680 .mixers = { alc663_asus_15jd_clfe_mixer }, 16681 .cap_mixer = alc662_auto_capture_mixer, 16682 .init_verbs = { alc662_init_verbs, 16683 alc663_15jd_amic_init_verbs }, 16684 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 16685 .hp_nid = 0x03, 16686 .dac_nids = alc662_dac_nids, 16687 .dig_out_nid = ALC662_DIGOUT_NID, 16688 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 16689 .channel_mode = alc662_3ST_2ch_modes, 16690 .input_mux = &alc662_eeepc_capture_source, 16691 .unsol_event = alc663_mode5_unsol_event, 16692 .init_hook = alc663_mode5_inithook, 16693 }, 16694 [ALC663_ASUS_MODE6] = { 16695 .mixers = { alc663_two_hp_m2_mixer }, 16696 .cap_mixer = alc662_auto_capture_mixer, 16697 .init_verbs = { alc662_init_verbs, 16698 alc663_two_hp_amic_m2_init_verbs }, 16699 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 16700 .hp_nid = 0x03, 16701 .dac_nids = alc662_dac_nids, 16702 .dig_out_nid = ALC662_DIGOUT_NID, 16703 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 16704 .channel_mode = alc662_3ST_2ch_modes, 16705 .input_mux = &alc662_eeepc_capture_source, 16706 .unsol_event = alc663_mode6_unsol_event, 16707 .init_hook = alc663_mode6_inithook, 16708 }, 16709 [ALC272_DELL] = { 16710 .mixers = { alc663_m51va_mixer }, 16711 .cap_mixer = alc272_auto_capture_mixer, 16712 .init_verbs = { alc662_init_verbs, alc272_dell_init_verbs }, 16713 .num_dacs = ARRAY_SIZE(alc272_dac_nids), 16714 .dac_nids = alc662_dac_nids, 16715 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 16716 .adc_nids = alc272_adc_nids, 16717 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids), 16718 .capsrc_nids = alc272_capsrc_nids, 16719 .channel_mode = alc662_3ST_2ch_modes, 16720 .input_mux = &alc663_m51va_capture_source, 16721 .unsol_event = alc663_m51va_unsol_event, 16722 .init_hook = alc663_m51va_inithook, 16723 }, 16724 [ALC272_DELL_ZM1] = { 16725 .mixers = { alc663_m51va_mixer }, 16726 .cap_mixer = alc662_auto_capture_mixer, 16727 .init_verbs = { alc662_init_verbs, alc272_dell_zm1_init_verbs }, 16728 .num_dacs = ARRAY_SIZE(alc272_dac_nids), 16729 .dac_nids = alc662_dac_nids, 16730 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 16731 .adc_nids = alc662_adc_nids, 16732 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids), 16733 .capsrc_nids = alc662_capsrc_nids, 16734 .channel_mode = alc662_3ST_2ch_modes, 16735 .input_mux = &alc663_m51va_capture_source, 16736 .unsol_event = alc663_m51va_unsol_event, 16737 .init_hook = alc663_m51va_inithook, 16738 }, 16739}; 16740 16741 16742/* 16743 * BIOS auto configuration 16744 */ 16745 16746/* add playback controls from the parsed DAC table */ 16747static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec, 16748 const struct auto_pin_cfg *cfg) 16749{ 16750 char name[32]; 16751 static const char *chname[4] = { 16752 "Front", "Surround", NULL /*CLFE*/, "Side" 16753 }; 16754 hda_nid_t nid; 16755 int i, err; 16756 16757 for (i = 0; i < cfg->line_outs; i++) { 16758 if (!spec->multiout.dac_nids[i]) 16759 continue; 16760 nid = alc880_idx_to_dac(i); 16761 if (i == 2) { 16762 /* Center/LFE */ 16763 err = add_control(spec, ALC_CTL_WIDGET_VOL, 16764 "Center Playback Volume", 16765 HDA_COMPOSE_AMP_VAL(nid, 1, 0, 16766 HDA_OUTPUT)); 16767 if (err < 0) 16768 return err; 16769 err = add_control(spec, ALC_CTL_WIDGET_VOL, 16770 "LFE Playback Volume", 16771 HDA_COMPOSE_AMP_VAL(nid, 2, 0, 16772 HDA_OUTPUT)); 16773 if (err < 0) 16774 return err; 16775 err = add_control(spec, ALC_CTL_WIDGET_MUTE, 16776 "Center Playback Switch", 16777 HDA_COMPOSE_AMP_VAL(0x0e, 1, 0, 16778 HDA_INPUT)); 16779 if (err < 0) 16780 return err; 16781 err = add_control(spec, ALC_CTL_WIDGET_MUTE, 16782 "LFE Playback Switch", 16783 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, 16784 HDA_INPUT)); 16785 if (err < 0) 16786 return err; 16787 } else { 16788 sprintf(name, "%s Playback Volume", chname[i]); 16789 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, 16790 HDA_COMPOSE_AMP_VAL(nid, 3, 0, 16791 HDA_OUTPUT)); 16792 if (err < 0) 16793 return err; 16794 sprintf(name, "%s Playback Switch", chname[i]); 16795 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, 16796 HDA_COMPOSE_AMP_VAL(alc880_idx_to_mixer(i), 16797 3, 0, HDA_INPUT)); 16798 if (err < 0) 16799 return err; 16800 } 16801 } 16802 return 0; 16803} 16804 16805/* add playback controls for speaker and HP outputs */ 16806static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin, 16807 const char *pfx) 16808{ 16809 hda_nid_t nid; 16810 int err; 16811 char name[32]; 16812 16813 if (!pin) 16814 return 0; 16815 16816 if (pin == 0x17) { 16817 /* ALC663 has a mono output pin on 0x17 */ 16818 sprintf(name, "%s Playback Switch", pfx); 16819 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, 16820 HDA_COMPOSE_AMP_VAL(pin, 2, 0, HDA_OUTPUT)); 16821 return err; 16822 } 16823 16824 if (alc880_is_fixed_pin(pin)) { 16825 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); 16826 /* printk(KERN_DEBUG "DAC nid=%x\n",nid); */ 16827 /* specify the DAC as the extra output */ 16828 if (!spec->multiout.hp_nid) 16829 spec->multiout.hp_nid = nid; 16830 else 16831 spec->multiout.extra_out_nid[0] = nid; 16832 /* control HP volume/switch on the output mixer amp */ 16833 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); 16834 sprintf(name, "%s Playback Volume", pfx); 16835 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, 16836 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); 16837 if (err < 0) 16838 return err; 16839 sprintf(name, "%s Playback Switch", pfx); 16840 err = add_control(spec, ALC_CTL_BIND_MUTE, name, 16841 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT)); 16842 if (err < 0) 16843 return err; 16844 } else if (alc880_is_multi_pin(pin)) { 16845 /* set manual connection */ 16846 /* we have only a switch on HP-out PIN */ 16847 sprintf(name, "%s Playback Switch", pfx); 16848 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, 16849 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); 16850 if (err < 0) 16851 return err; 16852 } 16853 return 0; 16854} 16855 16856/* return the index of the src widget from the connection list of the nid. 16857 * return -1 if not found 16858 */ 16859static int alc662_input_pin_idx(struct hda_codec *codec, hda_nid_t nid, 16860 hda_nid_t src) 16861{ 16862 hda_nid_t conn_list[HDA_MAX_CONNECTIONS]; 16863 int i, conns; 16864 16865 conns = snd_hda_get_connections(codec, nid, conn_list, 16866 ARRAY_SIZE(conn_list)); 16867 if (conns < 0) 16868 return -1; 16869 for (i = 0; i < conns; i++) 16870 if (conn_list[i] == src) 16871 return i; 16872 return -1; 16873} 16874 16875static int alc662_is_input_pin(struct hda_codec *codec, hda_nid_t nid) 16876{ 16877 unsigned int pincap = snd_hda_query_pin_caps(codec, nid); 16878 return (pincap & AC_PINCAP_IN) != 0; 16879} 16880 16881/* create playback/capture controls for input pins */ 16882static int alc662_auto_create_analog_input_ctls(struct hda_codec *codec, 16883 const struct auto_pin_cfg *cfg) 16884{ 16885 struct alc_spec *spec = codec->spec; 16886 struct hda_input_mux *imux = &spec->private_imux[0]; 16887 int i, err, idx; 16888 16889 for (i = 0; i < AUTO_PIN_LAST; i++) { 16890 if (alc662_is_input_pin(codec, cfg->input_pins[i])) { 16891 idx = alc662_input_pin_idx(codec, 0x0b, 16892 cfg->input_pins[i]); 16893 if (idx >= 0) { 16894 err = new_analog_input(spec, cfg->input_pins[i], 16895 auto_pin_cfg_labels[i], 16896 idx, 0x0b); 16897 if (err < 0) 16898 return err; 16899 } 16900 idx = alc662_input_pin_idx(codec, 0x22, 16901 cfg->input_pins[i]); 16902 if (idx >= 0) { 16903 imux->items[imux->num_items].label = 16904 auto_pin_cfg_labels[i]; 16905 imux->items[imux->num_items].index = idx; 16906 imux->num_items++; 16907 } 16908 } 16909 } 16910 return 0; 16911} 16912 16913static void alc662_auto_set_output_and_unmute(struct hda_codec *codec, 16914 hda_nid_t nid, int pin_type, 16915 int dac_idx) 16916{ 16917 alc_set_pin_output(codec, nid, pin_type); 16918 /* need the manual connection? */ 16919 if (alc880_is_multi_pin(nid)) { 16920 struct alc_spec *spec = codec->spec; 16921 int idx = alc880_multi_pin_idx(nid); 16922 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0, 16923 AC_VERB_SET_CONNECT_SEL, 16924 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx])); 16925 } 16926} 16927 16928static void alc662_auto_init_multi_out(struct hda_codec *codec) 16929{ 16930 struct alc_spec *spec = codec->spec; 16931 int i; 16932 16933 alc_subsystem_id(codec, 0x15, 0x1b, 0x14); 16934 for (i = 0; i <= HDA_SIDE; i++) { 16935 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 16936 int pin_type = get_pin_type(spec->autocfg.line_out_type); 16937 if (nid) 16938 alc662_auto_set_output_and_unmute(codec, nid, pin_type, 16939 i); 16940 } 16941} 16942 16943static void alc662_auto_init_hp_out(struct hda_codec *codec) 16944{ 16945 struct alc_spec *spec = codec->spec; 16946 hda_nid_t pin; 16947 16948 pin = spec->autocfg.hp_pins[0]; 16949 if (pin) /* connect to front */ 16950 /* use dac 0 */ 16951 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); 16952 pin = spec->autocfg.speaker_pins[0]; 16953 if (pin) 16954 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0); 16955} 16956 16957#define ALC662_PIN_CD_NID ALC880_PIN_CD_NID 16958 16959static void alc662_auto_init_analog_input(struct hda_codec *codec) 16960{ 16961 struct alc_spec *spec = codec->spec; 16962 int i; 16963 16964 for (i = 0; i < AUTO_PIN_LAST; i++) { 16965 hda_nid_t nid = spec->autocfg.input_pins[i]; 16966 if (alc662_is_input_pin(codec, nid)) { 16967 alc_set_input_pin(codec, nid, i); 16968 if (nid != ALC662_PIN_CD_NID && 16969 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)) 16970 snd_hda_codec_write(codec, nid, 0, 16971 AC_VERB_SET_AMP_GAIN_MUTE, 16972 AMP_OUT_MUTE); 16973 } 16974 } 16975} 16976 16977#define alc662_auto_init_input_src alc882_auto_init_input_src 16978 16979static int alc662_parse_auto_config(struct hda_codec *codec) 16980{ 16981 struct alc_spec *spec = codec->spec; 16982 int err; 16983 static hda_nid_t alc662_ignore[] = { 0x1d, 0 }; 16984 16985 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 16986 alc662_ignore); 16987 if (err < 0) 16988 return err; 16989 if (!spec->autocfg.line_outs) 16990 return 0; /* can't find valid BIOS pin config */ 16991 16992 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); 16993 if (err < 0) 16994 return err; 16995 err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg); 16996 if (err < 0) 16997 return err; 16998 err = alc662_auto_create_extra_out(spec, 16999 spec->autocfg.speaker_pins[0], 17000 "Speaker"); 17001 if (err < 0) 17002 return err; 17003 err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0], 17004 "Headphone"); 17005 if (err < 0) 17006 return err; 17007 err = alc662_auto_create_analog_input_ctls(codec, &spec->autocfg); 17008 if (err < 0) 17009 return err; 17010 17011 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 17012 17013 if (spec->autocfg.dig_outs) 17014 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID; 17015 17016 if (spec->kctls.list) 17017 add_mixer(spec, spec->kctls.list); 17018 17019 spec->num_mux_defs = 1; 17020 spec->input_mux = &spec->private_imux[0]; 17021 17022 add_verb(spec, alc662_auto_init_verbs); 17023 if (codec->vendor_id == 0x10ec0663) 17024 add_verb(spec, alc663_auto_init_verbs); 17025 17026 err = alc_auto_add_mic_boost(codec); 17027 if (err < 0) 17028 return err; 17029 17030 return 1; 17031} 17032 17033/* additional initialization for auto-configuration model */ 17034static void alc662_auto_init(struct hda_codec *codec) 17035{ 17036 struct alc_spec *spec = codec->spec; 17037 alc662_auto_init_multi_out(codec); 17038 alc662_auto_init_hp_out(codec); 17039 alc662_auto_init_analog_input(codec); 17040 alc662_auto_init_input_src(codec); 17041 if (spec->unsol_event) 17042 alc_inithook(codec); 17043} 17044 17045static int patch_alc662(struct hda_codec *codec) 17046{ 17047 struct alc_spec *spec; 17048 int err, board_config; 17049 17050 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 17051 if (!spec) 17052 return -ENOMEM; 17053 17054 codec->spec = spec; 17055 17056 alc_fix_pll_init(codec, 0x20, 0x04, 15); 17057 17058 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST, 17059 alc662_models, 17060 alc662_cfg_tbl); 17061 if (board_config < 0) { 17062 printk(KERN_INFO "hda_codec: Unknown model for ALC662, " 17063 "trying auto-probe from BIOS...\n"); 17064 board_config = ALC662_AUTO; 17065 } 17066 17067 if (board_config == ALC662_AUTO) { 17068 /* automatic parse from the BIOS config */ 17069 err = alc662_parse_auto_config(codec); 17070 if (err < 0) { 17071 alc_free(codec); 17072 return err; 17073 } else if (!err) { 17074 printk(KERN_INFO 17075 "hda_codec: Cannot set up configuration " 17076 "from BIOS. Using base mode...\n"); 17077 board_config = ALC662_3ST_2ch_DIG; 17078 } 17079 } 17080 17081 err = snd_hda_attach_beep_device(codec, 0x1); 17082 if (err < 0) { 17083 alc_free(codec); 17084 return err; 17085 } 17086 17087 if (board_config != ALC662_AUTO) 17088 setup_preset(spec, &alc662_presets[board_config]); 17089 17090 if (codec->vendor_id == 0x10ec0663) { 17091 spec->stream_name_analog = "ALC663 Analog"; 17092 spec->stream_name_digital = "ALC663 Digital"; 17093 } else if (codec->vendor_id == 0x10ec0272) { 17094 spec->stream_name_analog = "ALC272 Analog"; 17095 spec->stream_name_digital = "ALC272 Digital"; 17096 } else { 17097 spec->stream_name_analog = "ALC662 Analog"; 17098 spec->stream_name_digital = "ALC662 Digital"; 17099 } 17100 17101 spec->stream_analog_playback = &alc662_pcm_analog_playback; 17102 spec->stream_analog_capture = &alc662_pcm_analog_capture; 17103 17104 spec->stream_digital_playback = &alc662_pcm_digital_playback; 17105 spec->stream_digital_capture = &alc662_pcm_digital_capture; 17106 17107 spec->adc_nids = alc662_adc_nids; 17108 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids); 17109 spec->capsrc_nids = alc662_capsrc_nids; 17110 spec->capture_style = CAPT_MIX; 17111 17112 if (!spec->cap_mixer) 17113 set_capture_mixer(spec); 17114 if (codec->vendor_id == 0x10ec0662) 17115 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 17116 else 17117 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); 17118 17119 spec->vmaster_nid = 0x02; 17120 17121 codec->patch_ops = alc_patch_ops; 17122 if (board_config == ALC662_AUTO) 17123 spec->init_hook = alc662_auto_init; 17124#ifdef CONFIG_SND_HDA_POWER_SAVE 17125 if (!spec->loopback.amplist) 17126 spec->loopback.amplist = alc662_loopbacks; 17127#endif 17128 codec->proc_widget_hook = print_realtek_coef; 17129 17130 return 0; 17131} 17132 17133/* 17134 * patch entries 17135 */ 17136static struct hda_codec_preset snd_hda_preset_realtek[] = { 17137 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 }, 17138 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 }, 17139 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 }, 17140 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 }, 17141 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 }, 17142 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 }, 17143 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660", 17144 .patch = patch_alc861 }, 17145 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd }, 17146 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 }, 17147 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd }, 17148 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2", 17149 .patch = patch_alc883 }, 17150 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1", 17151 .patch = patch_alc662 }, 17152 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 }, 17153 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 }, 17154 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 }, 17155 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 }, 17156 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A", 17157 .patch = patch_alc882 }, /* should be patch_alc883() in future */ 17158 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A", 17159 .patch = patch_alc882 }, /* should be patch_alc883() in future */ 17160 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 }, 17161 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc883 }, 17162 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200", 17163 .patch = patch_alc883 }, 17164 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 }, 17165 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc883 }, 17166 {} /* terminator */ 17167}; 17168 17169MODULE_ALIAS("snd-hda-codec-id:10ec*"); 17170 17171MODULE_LICENSE("GPL"); 17172MODULE_DESCRIPTION("Realtek HD-audio codec"); 17173 17174static struct hda_codec_preset_list realtek_list = { 17175 .preset = snd_hda_preset_realtek, 17176 .owner = THIS_MODULE, 17177}; 17178 17179static int __init patch_realtek_init(void) 17180{ 17181 return snd_hda_add_codec_preset(&realtek_list); 17182} 17183 17184static void __exit patch_realtek_exit(void) 17185{ 17186 snd_hda_delete_codec_preset(&realtek_list); 17187} 17188 17189module_init(patch_realtek_init) 17190module_exit(patch_realtek_exit) 17191