patch_realtek.c revision 26f5df265f06b8c8fe9f5d0942b7d8df00e5edec
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_patch.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#ifdef CONFIG_SND_DEBUG 82 ALC260_TEST, 83#endif 84 ALC260_AUTO, 85 ALC260_MODEL_LAST /* last tag */ 86}; 87 88/* ALC262 models */ 89enum { 90 ALC262_BASIC, 91 ALC262_HIPPO, 92 ALC262_HIPPO_1, 93 ALC262_FUJITSU, 94 ALC262_HP_BPC, 95 ALC262_HP_BPC_D7000_WL, 96 ALC262_HP_BPC_D7000_WF, 97 ALC262_HP_TC_T5735, 98 ALC262_HP_RP5700, 99 ALC262_BENQ_ED8, 100 ALC262_SONY_ASSAMD, 101 ALC262_BENQ_T31, 102 ALC262_ULTRA, 103 ALC262_LENOVO_3000, 104 ALC262_NEC, 105 ALC262_TOSHIBA_S06, 106 ALC262_TOSHIBA_RX1, 107 ALC262_AUTO, 108 ALC262_MODEL_LAST /* last tag */ 109}; 110 111/* ALC268 models */ 112enum { 113 ALC267_QUANTA_IL1, 114 ALC268_3ST, 115 ALC268_TOSHIBA, 116 ALC268_ACER, 117 ALC268_ACER_ASPIRE_ONE, 118 ALC268_DELL, 119 ALC268_ZEPTO, 120#ifdef CONFIG_SND_DEBUG 121 ALC268_TEST, 122#endif 123 ALC268_AUTO, 124 ALC268_MODEL_LAST /* last tag */ 125}; 126 127/* ALC269 models */ 128enum { 129 ALC269_BASIC, 130 ALC269_QUANTA_FL1, 131 ALC269_ASUS_EEEPC_P703, 132 ALC269_ASUS_EEEPC_P901, 133 ALC269_FUJITSU, 134 ALC269_AUTO, 135 ALC269_MODEL_LAST /* last tag */ 136}; 137 138/* ALC861 models */ 139enum { 140 ALC861_3ST, 141 ALC660_3ST, 142 ALC861_3ST_DIG, 143 ALC861_6ST_DIG, 144 ALC861_UNIWILL_M31, 145 ALC861_TOSHIBA, 146 ALC861_ASUS, 147 ALC861_ASUS_LAPTOP, 148 ALC861_AUTO, 149 ALC861_MODEL_LAST, 150}; 151 152/* ALC861-VD models */ 153enum { 154 ALC660VD_3ST, 155 ALC660VD_3ST_DIG, 156 ALC861VD_3ST, 157 ALC861VD_3ST_DIG, 158 ALC861VD_6ST_DIG, 159 ALC861VD_LENOVO, 160 ALC861VD_DALLAS, 161 ALC861VD_HP, 162 ALC861VD_AUTO, 163 ALC861VD_MODEL_LAST, 164}; 165 166/* ALC662 models */ 167enum { 168 ALC662_3ST_2ch_DIG, 169 ALC662_3ST_6ch_DIG, 170 ALC662_3ST_6ch, 171 ALC662_5ST_DIG, 172 ALC662_LENOVO_101E, 173 ALC662_ASUS_EEEPC_P701, 174 ALC662_ASUS_EEEPC_EP20, 175 ALC663_ASUS_M51VA, 176 ALC663_ASUS_G71V, 177 ALC663_ASUS_H13, 178 ALC663_ASUS_G50V, 179 ALC662_ECS, 180 ALC663_ASUS_MODE1, 181 ALC662_ASUS_MODE2, 182 ALC663_ASUS_MODE3, 183 ALC663_ASUS_MODE4, 184 ALC663_ASUS_MODE5, 185 ALC663_ASUS_MODE6, 186 ALC662_AUTO, 187 ALC662_MODEL_LAST, 188}; 189 190/* ALC882 models */ 191enum { 192 ALC882_3ST_DIG, 193 ALC882_6ST_DIG, 194 ALC882_ARIMA, 195 ALC882_W2JC, 196 ALC882_TARGA, 197 ALC882_ASUS_A7J, 198 ALC882_ASUS_A7M, 199 ALC885_MACPRO, 200 ALC885_MBP3, 201 ALC885_IMAC24, 202 ALC882_AUTO, 203 ALC882_MODEL_LAST, 204}; 205 206/* ALC883 models */ 207enum { 208 ALC883_3ST_2ch_DIG, 209 ALC883_3ST_6ch_DIG, 210 ALC883_3ST_6ch, 211 ALC883_6ST_DIG, 212 ALC883_TARGA_DIG, 213 ALC883_TARGA_2ch_DIG, 214 ALC883_ACER, 215 ALC883_ACER_ASPIRE, 216 ALC883_MEDION, 217 ALC883_MEDION_MD2, 218 ALC883_LAPTOP_EAPD, 219 ALC883_LENOVO_101E_2ch, 220 ALC883_LENOVO_NB0763, 221 ALC888_LENOVO_MS7195_DIG, 222 ALC888_LENOVO_SKY, 223 ALC883_HAIER_W66, 224 ALC888_3ST_HP, 225 ALC888_6ST_DELL, 226 ALC883_MITAC, 227 ALC883_CLEVO_M720, 228 ALC883_FUJITSU_PI2515, 229 ALC883_3ST_6ch_INTEL, 230 ALC888_ASUS_M90V, 231 ALC888_ASUS_EEE1601, 232 ALC883_AUTO, 233 ALC883_MODEL_LAST, 234}; 235 236/* for GPIO Poll */ 237#define GPIO_MASK 0x03 238 239struct alc_spec { 240 /* codec parameterization */ 241 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */ 242 unsigned int num_mixers; 243 struct snd_kcontrol_new *cap_mixer; /* capture mixer */ 244 245 const struct hda_verb *init_verbs[5]; /* initialization verbs 246 * don't forget NULL 247 * termination! 248 */ 249 unsigned int num_init_verbs; 250 251 char *stream_name_analog; /* analog PCM stream */ 252 struct hda_pcm_stream *stream_analog_playback; 253 struct hda_pcm_stream *stream_analog_capture; 254 struct hda_pcm_stream *stream_analog_alt_playback; 255 struct hda_pcm_stream *stream_analog_alt_capture; 256 257 char *stream_name_digital; /* digital PCM stream */ 258 struct hda_pcm_stream *stream_digital_playback; 259 struct hda_pcm_stream *stream_digital_capture; 260 261 /* playback */ 262 struct hda_multi_out multiout; /* playback set-up 263 * max_channels, dacs must be set 264 * dig_out_nid and hp_nid are optional 265 */ 266 hda_nid_t alt_dac_nid; 267 268 /* capture */ 269 unsigned int num_adc_nids; 270 hda_nid_t *adc_nids; 271 hda_nid_t *capsrc_nids; 272 hda_nid_t dig_in_nid; /* digital-in NID; optional */ 273 unsigned char is_mix_capture; /* matrix-style capture (non-mux) */ 274 275 /* capture source */ 276 unsigned int num_mux_defs; 277 const struct hda_input_mux *input_mux; 278 unsigned int cur_mux[3]; 279 280 /* channel model */ 281 const struct hda_channel_mode *channel_mode; 282 int num_channel_mode; 283 int need_dac_fix; 284 285 /* PCM information */ 286 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */ 287 288 /* dynamic controls, init_verbs and input_mux */ 289 struct auto_pin_cfg autocfg; 290 struct snd_array kctls; 291 struct hda_input_mux private_imux; 292 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; 293 294 /* hooks */ 295 void (*init_hook)(struct hda_codec *codec); 296 void (*unsol_event)(struct hda_codec *codec, unsigned int res); 297 298 /* for pin sensing */ 299 unsigned int sense_updated: 1; 300 unsigned int jack_present: 1; 301 unsigned int master_sw: 1; 302 303 /* for virtual master */ 304 hda_nid_t vmaster_nid; 305#ifdef CONFIG_SND_HDA_POWER_SAVE 306 struct hda_loopback_check loopback; 307#endif 308 309 /* for PLL fix */ 310 hda_nid_t pll_nid; 311 unsigned int pll_coef_idx, pll_coef_bit; 312 313#ifdef SND_HDA_NEEDS_RESUME 314#define ALC_MAX_PINS 16 315 unsigned int num_pins; 316 hda_nid_t pin_nids[ALC_MAX_PINS]; 317 unsigned int pin_cfgs[ALC_MAX_PINS]; 318#endif 319}; 320 321/* 322 * configuration template - to be copied to the spec instance 323 */ 324struct alc_config_preset { 325 struct snd_kcontrol_new *mixers[5]; /* should be identical size 326 * with spec 327 */ 328 struct snd_kcontrol_new *cap_mixer; /* capture mixer */ 329 const struct hda_verb *init_verbs[5]; 330 unsigned int num_dacs; 331 hda_nid_t *dac_nids; 332 hda_nid_t dig_out_nid; /* optional */ 333 hda_nid_t hp_nid; /* optional */ 334 unsigned int num_adc_nids; 335 hda_nid_t *adc_nids; 336 hda_nid_t *capsrc_nids; 337 hda_nid_t dig_in_nid; 338 unsigned int num_channel_mode; 339 const struct hda_channel_mode *channel_mode; 340 int need_dac_fix; 341 unsigned int num_mux_defs; 342 const struct hda_input_mux *input_mux; 343 void (*unsol_event)(struct hda_codec *, unsigned int); 344 void (*init_hook)(struct hda_codec *); 345#ifdef CONFIG_SND_HDA_POWER_SAVE 346 struct hda_amp_list *loopbacks; 347#endif 348}; 349 350 351/* 352 * input MUX handling 353 */ 354static int alc_mux_enum_info(struct snd_kcontrol *kcontrol, 355 struct snd_ctl_elem_info *uinfo) 356{ 357 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 358 struct alc_spec *spec = codec->spec; 359 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id); 360 if (mux_idx >= spec->num_mux_defs) 361 mux_idx = 0; 362 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo); 363} 364 365static int alc_mux_enum_get(struct snd_kcontrol *kcontrol, 366 struct snd_ctl_elem_value *ucontrol) 367{ 368 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 369 struct alc_spec *spec = codec->spec; 370 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 371 372 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx]; 373 return 0; 374} 375 376static int alc_mux_enum_put(struct snd_kcontrol *kcontrol, 377 struct snd_ctl_elem_value *ucontrol) 378{ 379 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 380 struct alc_spec *spec = codec->spec; 381 const struct hda_input_mux *imux = spec->input_mux; 382 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 383 hda_nid_t nid = spec->capsrc_nids ? 384 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx]; 385 386 if (spec->is_mix_capture) { 387 /* Matrix-mixer style (e.g. ALC882) */ 388 unsigned int *cur_val = &spec->cur_mux[adc_idx]; 389 unsigned int i, idx; 390 391 idx = ucontrol->value.enumerated.item[0]; 392 if (idx >= imux->num_items) 393 idx = imux->num_items - 1; 394 if (*cur_val == idx) 395 return 0; 396 for (i = 0; i < imux->num_items; i++) { 397 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE; 398 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 399 imux->items[i].index, 400 HDA_AMP_MUTE, v); 401 } 402 *cur_val = idx; 403 return 1; 404 } else { 405 /* MUX style (e.g. ALC880) */ 406 unsigned int mux_idx; 407 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx; 408 return snd_hda_input_mux_put(codec, &spec->input_mux[mux_idx], 409 ucontrol, nid, 410 &spec->cur_mux[adc_idx]); 411 } 412} 413 414/* 415 * channel mode setting 416 */ 417static int alc_ch_mode_info(struct snd_kcontrol *kcontrol, 418 struct snd_ctl_elem_info *uinfo) 419{ 420 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 421 struct alc_spec *spec = codec->spec; 422 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode, 423 spec->num_channel_mode); 424} 425 426static int alc_ch_mode_get(struct snd_kcontrol *kcontrol, 427 struct snd_ctl_elem_value *ucontrol) 428{ 429 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 430 struct alc_spec *spec = codec->spec; 431 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode, 432 spec->num_channel_mode, 433 spec->multiout.max_channels); 434} 435 436static int alc_ch_mode_put(struct snd_kcontrol *kcontrol, 437 struct snd_ctl_elem_value *ucontrol) 438{ 439 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 440 struct alc_spec *spec = codec->spec; 441 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode, 442 spec->num_channel_mode, 443 &spec->multiout.max_channels); 444 if (err >= 0 && spec->need_dac_fix) 445 spec->multiout.num_dacs = spec->multiout.max_channels / 2; 446 return err; 447} 448 449/* 450 * Control the mode of pin widget settings via the mixer. "pc" is used 451 * instead of "%" to avoid consequences of accidently treating the % as 452 * being part of a format specifier. Maximum allowed length of a value is 453 * 63 characters plus NULL terminator. 454 * 455 * Note: some retasking pin complexes seem to ignore requests for input 456 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these 457 * are requested. Therefore order this list so that this behaviour will not 458 * cause problems when mixer clients move through the enum sequentially. 459 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of 460 * March 2006. 461 */ 462static char *alc_pin_mode_names[] = { 463 "Mic 50pc bias", "Mic 80pc bias", 464 "Line in", "Line out", "Headphone out", 465}; 466static unsigned char alc_pin_mode_values[] = { 467 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP, 468}; 469/* The control can present all 5 options, or it can limit the options based 470 * in the pin being assumed to be exclusively an input or an output pin. In 471 * addition, "input" pins may or may not process the mic bias option 472 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to 473 * accept requests for bias as of chip versions up to March 2006) and/or 474 * wiring in the computer. 475 */ 476#define ALC_PIN_DIR_IN 0x00 477#define ALC_PIN_DIR_OUT 0x01 478#define ALC_PIN_DIR_INOUT 0x02 479#define ALC_PIN_DIR_IN_NOMICBIAS 0x03 480#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04 481 482/* Info about the pin modes supported by the different pin direction modes. 483 * For each direction the minimum and maximum values are given. 484 */ 485static signed char alc_pin_mode_dir_info[5][2] = { 486 { 0, 2 }, /* ALC_PIN_DIR_IN */ 487 { 3, 4 }, /* ALC_PIN_DIR_OUT */ 488 { 0, 4 }, /* ALC_PIN_DIR_INOUT */ 489 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */ 490 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */ 491}; 492#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0]) 493#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1]) 494#define alc_pin_mode_n_items(_dir) \ 495 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1) 496 497static int alc_pin_mode_info(struct snd_kcontrol *kcontrol, 498 struct snd_ctl_elem_info *uinfo) 499{ 500 unsigned int item_num = uinfo->value.enumerated.item; 501 unsigned char dir = (kcontrol->private_value >> 16) & 0xff; 502 503 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 504 uinfo->count = 1; 505 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir); 506 507 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir)) 508 item_num = alc_pin_mode_min(dir); 509 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]); 510 return 0; 511} 512 513static int alc_pin_mode_get(struct snd_kcontrol *kcontrol, 514 struct snd_ctl_elem_value *ucontrol) 515{ 516 unsigned int i; 517 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 518 hda_nid_t nid = kcontrol->private_value & 0xffff; 519 unsigned char dir = (kcontrol->private_value >> 16) & 0xff; 520 long *valp = ucontrol->value.integer.value; 521 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0, 522 AC_VERB_GET_PIN_WIDGET_CONTROL, 523 0x00); 524 525 /* Find enumerated value for current pinctl setting */ 526 i = alc_pin_mode_min(dir); 527 while (alc_pin_mode_values[i] != pinctl && i <= alc_pin_mode_max(dir)) 528 i++; 529 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir); 530 return 0; 531} 532 533static int alc_pin_mode_put(struct snd_kcontrol *kcontrol, 534 struct snd_ctl_elem_value *ucontrol) 535{ 536 signed int change; 537 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 538 hda_nid_t nid = kcontrol->private_value & 0xffff; 539 unsigned char dir = (kcontrol->private_value >> 16) & 0xff; 540 long val = *ucontrol->value.integer.value; 541 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0, 542 AC_VERB_GET_PIN_WIDGET_CONTROL, 543 0x00); 544 545 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir)) 546 val = alc_pin_mode_min(dir); 547 548 change = pinctl != alc_pin_mode_values[val]; 549 if (change) { 550 /* Set pin mode to that requested */ 551 snd_hda_codec_write_cache(codec, nid, 0, 552 AC_VERB_SET_PIN_WIDGET_CONTROL, 553 alc_pin_mode_values[val]); 554 555 /* Also enable the retasking pin's input/output as required 556 * for the requested pin mode. Enum values of 2 or less are 557 * input modes. 558 * 559 * Dynamically switching the input/output buffers probably 560 * reduces noise slightly (particularly on input) so we'll 561 * do it. However, having both input and output buffers 562 * enabled simultaneously doesn't seem to be problematic if 563 * this turns out to be necessary in the future. 564 */ 565 if (val <= 2) { 566 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, 567 HDA_AMP_MUTE, HDA_AMP_MUTE); 568 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0, 569 HDA_AMP_MUTE, 0); 570 } else { 571 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0, 572 HDA_AMP_MUTE, HDA_AMP_MUTE); 573 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, 574 HDA_AMP_MUTE, 0); 575 } 576 } 577 return change; 578} 579 580#define ALC_PIN_MODE(xname, nid, dir) \ 581 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 582 .info = alc_pin_mode_info, \ 583 .get = alc_pin_mode_get, \ 584 .put = alc_pin_mode_put, \ 585 .private_value = nid | (dir<<16) } 586 587/* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged 588 * together using a mask with more than one bit set. This control is 589 * currently used only by the ALC260 test model. At this stage they are not 590 * needed for any "production" models. 591 */ 592#ifdef CONFIG_SND_DEBUG 593#define alc_gpio_data_info snd_ctl_boolean_mono_info 594 595static int alc_gpio_data_get(struct snd_kcontrol *kcontrol, 596 struct snd_ctl_elem_value *ucontrol) 597{ 598 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 599 hda_nid_t nid = kcontrol->private_value & 0xffff; 600 unsigned char mask = (kcontrol->private_value >> 16) & 0xff; 601 long *valp = ucontrol->value.integer.value; 602 unsigned int val = snd_hda_codec_read(codec, nid, 0, 603 AC_VERB_GET_GPIO_DATA, 0x00); 604 605 *valp = (val & mask) != 0; 606 return 0; 607} 608static int alc_gpio_data_put(struct snd_kcontrol *kcontrol, 609 struct snd_ctl_elem_value *ucontrol) 610{ 611 signed int change; 612 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 613 hda_nid_t nid = kcontrol->private_value & 0xffff; 614 unsigned char mask = (kcontrol->private_value >> 16) & 0xff; 615 long val = *ucontrol->value.integer.value; 616 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0, 617 AC_VERB_GET_GPIO_DATA, 618 0x00); 619 620 /* Set/unset the masked GPIO bit(s) as needed */ 621 change = (val == 0 ? 0 : mask) != (gpio_data & mask); 622 if (val == 0) 623 gpio_data &= ~mask; 624 else 625 gpio_data |= mask; 626 snd_hda_codec_write_cache(codec, nid, 0, 627 AC_VERB_SET_GPIO_DATA, gpio_data); 628 629 return change; 630} 631#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \ 632 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 633 .info = alc_gpio_data_info, \ 634 .get = alc_gpio_data_get, \ 635 .put = alc_gpio_data_put, \ 636 .private_value = nid | (mask<<16) } 637#endif /* CONFIG_SND_DEBUG */ 638 639/* A switch control to allow the enabling of the digital IO pins on the 640 * ALC260. This is incredibly simplistic; the intention of this control is 641 * to provide something in the test model allowing digital outputs to be 642 * identified if present. If models are found which can utilise these 643 * outputs a more complete mixer control can be devised for those models if 644 * necessary. 645 */ 646#ifdef CONFIG_SND_DEBUG 647#define alc_spdif_ctrl_info snd_ctl_boolean_mono_info 648 649static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol, 650 struct snd_ctl_elem_value *ucontrol) 651{ 652 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 653 hda_nid_t nid = kcontrol->private_value & 0xffff; 654 unsigned char mask = (kcontrol->private_value >> 16) & 0xff; 655 long *valp = ucontrol->value.integer.value; 656 unsigned int val = snd_hda_codec_read(codec, nid, 0, 657 AC_VERB_GET_DIGI_CONVERT_1, 0x00); 658 659 *valp = (val & mask) != 0; 660 return 0; 661} 662static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol, 663 struct snd_ctl_elem_value *ucontrol) 664{ 665 signed int change; 666 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 667 hda_nid_t nid = kcontrol->private_value & 0xffff; 668 unsigned char mask = (kcontrol->private_value >> 16) & 0xff; 669 long val = *ucontrol->value.integer.value; 670 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0, 671 AC_VERB_GET_DIGI_CONVERT_1, 672 0x00); 673 674 /* Set/unset the masked control bit(s) as needed */ 675 change = (val == 0 ? 0 : mask) != (ctrl_data & mask); 676 if (val==0) 677 ctrl_data &= ~mask; 678 else 679 ctrl_data |= mask; 680 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, 681 ctrl_data); 682 683 return change; 684} 685#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \ 686 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 687 .info = alc_spdif_ctrl_info, \ 688 .get = alc_spdif_ctrl_get, \ 689 .put = alc_spdif_ctrl_put, \ 690 .private_value = nid | (mask<<16) } 691#endif /* CONFIG_SND_DEBUG */ 692 693/* A switch control to allow the enabling EAPD digital outputs on the ALC26x. 694 * Again, this is only used in the ALC26x test models to help identify when 695 * the EAPD line must be asserted for features to work. 696 */ 697#ifdef CONFIG_SND_DEBUG 698#define alc_eapd_ctrl_info snd_ctl_boolean_mono_info 699 700static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol, 701 struct snd_ctl_elem_value *ucontrol) 702{ 703 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 704 hda_nid_t nid = kcontrol->private_value & 0xffff; 705 unsigned char mask = (kcontrol->private_value >> 16) & 0xff; 706 long *valp = ucontrol->value.integer.value; 707 unsigned int val = snd_hda_codec_read(codec, nid, 0, 708 AC_VERB_GET_EAPD_BTLENABLE, 0x00); 709 710 *valp = (val & mask) != 0; 711 return 0; 712} 713 714static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol, 715 struct snd_ctl_elem_value *ucontrol) 716{ 717 int change; 718 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 719 hda_nid_t nid = kcontrol->private_value & 0xffff; 720 unsigned char mask = (kcontrol->private_value >> 16) & 0xff; 721 long val = *ucontrol->value.integer.value; 722 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0, 723 AC_VERB_GET_EAPD_BTLENABLE, 724 0x00); 725 726 /* Set/unset the masked control bit(s) as needed */ 727 change = (!val ? 0 : mask) != (ctrl_data & mask); 728 if (!val) 729 ctrl_data &= ~mask; 730 else 731 ctrl_data |= mask; 732 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE, 733 ctrl_data); 734 735 return change; 736} 737 738#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \ 739 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 740 .info = alc_eapd_ctrl_info, \ 741 .get = alc_eapd_ctrl_get, \ 742 .put = alc_eapd_ctrl_put, \ 743 .private_value = nid | (mask<<16) } 744#endif /* CONFIG_SND_DEBUG */ 745 746/* 747 */ 748static void add_mixer(struct alc_spec *spec, struct snd_kcontrol_new *mix) 749{ 750 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers))) 751 return; 752 spec->mixers[spec->num_mixers++] = mix; 753} 754 755static void add_verb(struct alc_spec *spec, const struct hda_verb *verb) 756{ 757 if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs))) 758 return; 759 spec->init_verbs[spec->num_init_verbs++] = verb; 760} 761 762/* 763 * set up from the preset table 764 */ 765static void setup_preset(struct alc_spec *spec, 766 const struct alc_config_preset *preset) 767{ 768 int i; 769 770 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++) 771 add_mixer(spec, preset->mixers[i]); 772 spec->cap_mixer = preset->cap_mixer; 773 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i]; 774 i++) 775 add_verb(spec, preset->init_verbs[i]); 776 777 spec->channel_mode = preset->channel_mode; 778 spec->num_channel_mode = preset->num_channel_mode; 779 spec->need_dac_fix = preset->need_dac_fix; 780 781 spec->multiout.max_channels = spec->channel_mode[0].channels; 782 783 spec->multiout.num_dacs = preset->num_dacs; 784 spec->multiout.dac_nids = preset->dac_nids; 785 spec->multiout.dig_out_nid = preset->dig_out_nid; 786 spec->multiout.hp_nid = preset->hp_nid; 787 788 spec->num_mux_defs = preset->num_mux_defs; 789 if (!spec->num_mux_defs) 790 spec->num_mux_defs = 1; 791 spec->input_mux = preset->input_mux; 792 793 spec->num_adc_nids = preset->num_adc_nids; 794 spec->adc_nids = preset->adc_nids; 795 spec->capsrc_nids = preset->capsrc_nids; 796 spec->dig_in_nid = preset->dig_in_nid; 797 798 spec->unsol_event = preset->unsol_event; 799 spec->init_hook = preset->init_hook; 800#ifdef CONFIG_SND_HDA_POWER_SAVE 801 spec->loopback.amplist = preset->loopbacks; 802#endif 803} 804 805/* Enable GPIO mask and set output */ 806static struct hda_verb alc_gpio1_init_verbs[] = { 807 {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, 808 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, 809 {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, 810 { } 811}; 812 813static struct hda_verb alc_gpio2_init_verbs[] = { 814 {0x01, AC_VERB_SET_GPIO_MASK, 0x02}, 815 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02}, 816 {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, 817 { } 818}; 819 820static struct hda_verb alc_gpio3_init_verbs[] = { 821 {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, 822 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03}, 823 {0x01, AC_VERB_SET_GPIO_DATA, 0x03}, 824 { } 825}; 826 827/* 828 * Fix hardware PLL issue 829 * On some codecs, the analog PLL gating control must be off while 830 * the default value is 1. 831 */ 832static void alc_fix_pll(struct hda_codec *codec) 833{ 834 struct alc_spec *spec = codec->spec; 835 unsigned int val; 836 837 if (!spec->pll_nid) 838 return; 839 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX, 840 spec->pll_coef_idx); 841 val = snd_hda_codec_read(codec, spec->pll_nid, 0, 842 AC_VERB_GET_PROC_COEF, 0); 843 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX, 844 spec->pll_coef_idx); 845 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF, 846 val & ~(1 << spec->pll_coef_bit)); 847} 848 849static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid, 850 unsigned int coef_idx, unsigned int coef_bit) 851{ 852 struct alc_spec *spec = codec->spec; 853 spec->pll_nid = nid; 854 spec->pll_coef_idx = coef_idx; 855 spec->pll_coef_bit = coef_bit; 856 alc_fix_pll(codec); 857} 858 859static void alc_sku_automute(struct hda_codec *codec) 860{ 861 struct alc_spec *spec = codec->spec; 862 unsigned int present; 863 unsigned int hp_nid = spec->autocfg.hp_pins[0]; 864 unsigned int sp_nid = spec->autocfg.speaker_pins[0]; 865 866 /* need to execute and sync at first */ 867 snd_hda_codec_read(codec, hp_nid, 0, AC_VERB_SET_PIN_SENSE, 0); 868 present = snd_hda_codec_read(codec, hp_nid, 0, 869 AC_VERB_GET_PIN_SENSE, 0); 870 spec->jack_present = (present & 0x80000000) != 0; 871 snd_hda_codec_write(codec, sp_nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 872 spec->jack_present ? 0 : PIN_OUT); 873} 874 875#if 0 /* it's broken in some acses -- temporarily disabled */ 876static void alc_mic_automute(struct hda_codec *codec) 877{ 878 struct alc_spec *spec = codec->spec; 879 unsigned int present; 880 unsigned int mic_nid = spec->autocfg.input_pins[AUTO_PIN_MIC]; 881 unsigned int fmic_nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC]; 882 unsigned int mix_nid = spec->capsrc_nids[0]; 883 unsigned int capsrc_idx_mic, capsrc_idx_fmic; 884 885 capsrc_idx_mic = mic_nid - 0x18; 886 capsrc_idx_fmic = fmic_nid - 0x18; 887 present = snd_hda_codec_read(codec, mic_nid, 0, 888 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 889 snd_hda_codec_write(codec, mix_nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, 890 0x7000 | (capsrc_idx_mic << 8) | (present ? 0 : 0x80)); 891 snd_hda_codec_write(codec, mix_nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, 892 0x7000 | (capsrc_idx_fmic << 8) | (present ? 0x80 : 0)); 893 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, capsrc_idx_fmic, 894 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 895} 896#else 897#define alc_mic_automute(codec) /* NOP */ 898#endif /* disabled */ 899 900/* unsolicited event for HP jack sensing */ 901static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res) 902{ 903 if (codec->vendor_id == 0x10ec0880) 904 res >>= 28; 905 else 906 res >>= 26; 907 if (res == ALC880_HP_EVENT) 908 alc_sku_automute(codec); 909 910 if (res == ALC880_MIC_EVENT) 911 alc_mic_automute(codec); 912} 913 914static void alc_inithook(struct hda_codec *codec) 915{ 916 alc_sku_automute(codec); 917 alc_mic_automute(codec); 918} 919 920/* additional initialization for ALC888 variants */ 921static void alc888_coef_init(struct hda_codec *codec) 922{ 923 unsigned int tmp; 924 925 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0); 926 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0); 927 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7); 928 if ((tmp & 0xf0) == 2) 929 /* alc888S-VC */ 930 snd_hda_codec_read(codec, 0x20, 0, 931 AC_VERB_SET_PROC_COEF, 0x830); 932 else 933 /* alc888-VB */ 934 snd_hda_codec_read(codec, 0x20, 0, 935 AC_VERB_SET_PROC_COEF, 0x3030); 936} 937 938/* 32-bit subsystem ID for BIOS loading in HD Audio codec. 939 * 31 ~ 16 : Manufacture ID 940 * 15 ~ 8 : SKU ID 941 * 7 ~ 0 : Assembly ID 942 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36 943 */ 944static void alc_subsystem_id(struct hda_codec *codec, 945 unsigned int porta, unsigned int porte, 946 unsigned int portd) 947{ 948 unsigned int ass, tmp, i; 949 unsigned nid; 950 struct alc_spec *spec = codec->spec; 951 952 ass = codec->subsystem_id & 0xffff; 953 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1)) 954 goto do_sku; 955 956 /* 957 * 31~30 : port conetcivity 958 * 29~21 : reserve 959 * 20 : PCBEEP input 960 * 19~16 : Check sum (15:1) 961 * 15~1 : Custom 962 * 0 : override 963 */ 964 nid = 0x1d; 965 if (codec->vendor_id == 0x10ec0260) 966 nid = 0x17; 967 ass = snd_hda_codec_read(codec, nid, 0, 968 AC_VERB_GET_CONFIG_DEFAULT, 0); 969 if (!(ass & 1) && !(ass & 0x100000)) 970 return; 971 if ((ass >> 30) != 1) /* no physical connection */ 972 return; 973 974 /* check sum */ 975 tmp = 0; 976 for (i = 1; i < 16; i++) { 977 if ((ass >> i) & 1) 978 tmp++; 979 } 980 if (((ass >> 16) & 0xf) != tmp) 981 return; 982do_sku: 983 /* 984 * 0 : override 985 * 1 : Swap Jack 986 * 2 : 0 --> Desktop, 1 --> Laptop 987 * 3~5 : External Amplifier control 988 * 7~6 : Reserved 989 */ 990 tmp = (ass & 0x38) >> 3; /* external Amp control */ 991 switch (tmp) { 992 case 1: 993 snd_hda_sequence_write(codec, alc_gpio1_init_verbs); 994 break; 995 case 3: 996 snd_hda_sequence_write(codec, alc_gpio2_init_verbs); 997 break; 998 case 7: 999 snd_hda_sequence_write(codec, alc_gpio3_init_verbs); 1000 break; 1001 case 5: /* set EAPD output high */ 1002 switch (codec->vendor_id) { 1003 case 0x10ec0260: 1004 snd_hda_codec_write(codec, 0x0f, 0, 1005 AC_VERB_SET_EAPD_BTLENABLE, 2); 1006 snd_hda_codec_write(codec, 0x10, 0, 1007 AC_VERB_SET_EAPD_BTLENABLE, 2); 1008 break; 1009 case 0x10ec0262: 1010 case 0x10ec0267: 1011 case 0x10ec0268: 1012 case 0x10ec0269: 1013 case 0x10ec0660: 1014 case 0x10ec0662: 1015 case 0x10ec0663: 1016 case 0x10ec0862: 1017 case 0x10ec0889: 1018 snd_hda_codec_write(codec, 0x14, 0, 1019 AC_VERB_SET_EAPD_BTLENABLE, 2); 1020 snd_hda_codec_write(codec, 0x15, 0, 1021 AC_VERB_SET_EAPD_BTLENABLE, 2); 1022 break; 1023 } 1024 switch (codec->vendor_id) { 1025 case 0x10ec0260: 1026 snd_hda_codec_write(codec, 0x1a, 0, 1027 AC_VERB_SET_COEF_INDEX, 7); 1028 tmp = snd_hda_codec_read(codec, 0x1a, 0, 1029 AC_VERB_GET_PROC_COEF, 0); 1030 snd_hda_codec_write(codec, 0x1a, 0, 1031 AC_VERB_SET_COEF_INDEX, 7); 1032 snd_hda_codec_write(codec, 0x1a, 0, 1033 AC_VERB_SET_PROC_COEF, 1034 tmp | 0x2010); 1035 break; 1036 case 0x10ec0262: 1037 case 0x10ec0880: 1038 case 0x10ec0882: 1039 case 0x10ec0883: 1040 case 0x10ec0885: 1041 case 0x10ec0889: 1042 snd_hda_codec_write(codec, 0x20, 0, 1043 AC_VERB_SET_COEF_INDEX, 7); 1044 tmp = snd_hda_codec_read(codec, 0x20, 0, 1045 AC_VERB_GET_PROC_COEF, 0); 1046 snd_hda_codec_write(codec, 0x20, 0, 1047 AC_VERB_SET_COEF_INDEX, 7); 1048 snd_hda_codec_write(codec, 0x20, 0, 1049 AC_VERB_SET_PROC_COEF, 1050 tmp | 0x2010); 1051 break; 1052 case 0x10ec0888: 1053 /*alc888_coef_init(codec);*/ /* called in alc_init() */ 1054 break; 1055 case 0x10ec0267: 1056 case 0x10ec0268: 1057 snd_hda_codec_write(codec, 0x20, 0, 1058 AC_VERB_SET_COEF_INDEX, 7); 1059 tmp = snd_hda_codec_read(codec, 0x20, 0, 1060 AC_VERB_GET_PROC_COEF, 0); 1061 snd_hda_codec_write(codec, 0x20, 0, 1062 AC_VERB_SET_COEF_INDEX, 7); 1063 snd_hda_codec_write(codec, 0x20, 0, 1064 AC_VERB_SET_PROC_COEF, 1065 tmp | 0x3000); 1066 break; 1067 } 1068 default: 1069 break; 1070 } 1071 1072 /* is laptop or Desktop and enable the function "Mute internal speaker 1073 * when the external headphone out jack is plugged" 1074 */ 1075 if (!(ass & 0x8000)) 1076 return; 1077 /* 1078 * 10~8 : Jack location 1079 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered 1080 * 14~13: Resvered 1081 * 15 : 1 --> enable the function "Mute internal speaker 1082 * when the external headphone out jack is plugged" 1083 */ 1084 if (!spec->autocfg.speaker_pins[0]) { 1085 if (spec->autocfg.line_out_pins[0]) 1086 spec->autocfg.speaker_pins[0] = 1087 spec->autocfg.line_out_pins[0]; 1088 else 1089 return; 1090 } 1091 1092 if (!spec->autocfg.hp_pins[0]) { 1093 tmp = (ass >> 11) & 0x3; /* HP to chassis */ 1094 if (tmp == 0) 1095 spec->autocfg.hp_pins[0] = porta; 1096 else if (tmp == 1) 1097 spec->autocfg.hp_pins[0] = porte; 1098 else if (tmp == 2) 1099 spec->autocfg.hp_pins[0] = portd; 1100 else 1101 return; 1102 } 1103 if (spec->autocfg.hp_pins[0]) 1104 snd_hda_codec_write(codec, spec->autocfg.hp_pins[0], 0, 1105 AC_VERB_SET_UNSOLICITED_ENABLE, 1106 AC_USRSP_EN | ALC880_HP_EVENT); 1107 1108#if 0 /* it's broken in some acses -- temporarily disabled */ 1109 if (spec->autocfg.input_pins[AUTO_PIN_MIC] && 1110 spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC]) 1111 snd_hda_codec_write(codec, 1112 spec->autocfg.input_pins[AUTO_PIN_MIC], 0, 1113 AC_VERB_SET_UNSOLICITED_ENABLE, 1114 AC_USRSP_EN | ALC880_MIC_EVENT); 1115#endif /* disabled */ 1116 1117 spec->unsol_event = alc_sku_unsol_event; 1118} 1119 1120/* 1121 * Fix-up pin default configurations 1122 */ 1123 1124struct alc_pincfg { 1125 hda_nid_t nid; 1126 u32 val; 1127}; 1128 1129static void alc_fix_pincfg(struct hda_codec *codec, 1130 const struct snd_pci_quirk *quirk, 1131 const struct alc_pincfg **pinfix) 1132{ 1133 const struct alc_pincfg *cfg; 1134 1135 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk); 1136 if (!quirk) 1137 return; 1138 1139 cfg = pinfix[quirk->value]; 1140 for (; cfg->nid; cfg++) { 1141 int i; 1142 u32 val = cfg->val; 1143 for (i = 0; i < 4; i++) { 1144 snd_hda_codec_write(codec, cfg->nid, 0, 1145 AC_VERB_SET_CONFIG_DEFAULT_BYTES_0 + i, 1146 val & 0xff); 1147 val >>= 8; 1148 } 1149 } 1150} 1151 1152/* 1153 * ALC880 3-stack model 1154 * 1155 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e) 1156 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18, 1157 * F-Mic = 0x1b, HP = 0x19 1158 */ 1159 1160static hda_nid_t alc880_dac_nids[4] = { 1161 /* front, rear, clfe, rear_surr */ 1162 0x02, 0x05, 0x04, 0x03 1163}; 1164 1165static hda_nid_t alc880_adc_nids[3] = { 1166 /* ADC0-2 */ 1167 0x07, 0x08, 0x09, 1168}; 1169 1170/* The datasheet says the node 0x07 is connected from inputs, 1171 * but it shows zero connection in the real implementation on some devices. 1172 * Note: this is a 915GAV bug, fixed on 915GLV 1173 */ 1174static hda_nid_t alc880_adc_nids_alt[2] = { 1175 /* ADC1-2 */ 1176 0x08, 0x09, 1177}; 1178 1179#define ALC880_DIGOUT_NID 0x06 1180#define ALC880_DIGIN_NID 0x0a 1181 1182static struct hda_input_mux alc880_capture_source = { 1183 .num_items = 4, 1184 .items = { 1185 { "Mic", 0x0 }, 1186 { "Front Mic", 0x3 }, 1187 { "Line", 0x2 }, 1188 { "CD", 0x4 }, 1189 }, 1190}; 1191 1192/* channel source setting (2/6 channel selection for 3-stack) */ 1193/* 2ch mode */ 1194static struct hda_verb alc880_threestack_ch2_init[] = { 1195 /* set line-in to input, mute it */ 1196 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 1197 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 1198 /* set mic-in to input vref 80%, mute it */ 1199 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 1200 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 1201 { } /* end */ 1202}; 1203 1204/* 6ch mode */ 1205static struct hda_verb alc880_threestack_ch6_init[] = { 1206 /* set line-in to output, unmute it */ 1207 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 1208 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 1209 /* set mic-in to output, unmute it */ 1210 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 1211 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 1212 { } /* end */ 1213}; 1214 1215static struct hda_channel_mode alc880_threestack_modes[2] = { 1216 { 2, alc880_threestack_ch2_init }, 1217 { 6, alc880_threestack_ch6_init }, 1218}; 1219 1220static struct snd_kcontrol_new alc880_three_stack_mixer[] = { 1221 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 1222 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 1223 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 1224 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT), 1225 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 1226 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 1227 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 1228 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 1229 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 1230 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 1231 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 1232 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 1233 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 1234 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 1235 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT), 1236 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT), 1237 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 1238 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 1239 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT), 1240 { 1241 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1242 .name = "Channel Mode", 1243 .info = alc_ch_mode_info, 1244 .get = alc_ch_mode_get, 1245 .put = alc_ch_mode_put, 1246 }, 1247 { } /* end */ 1248}; 1249 1250/* capture mixer elements */ 1251static int alc_cap_vol_info(struct snd_kcontrol *kcontrol, 1252 struct snd_ctl_elem_info *uinfo) 1253{ 1254 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 1255 struct alc_spec *spec = codec->spec; 1256 int err; 1257 1258 mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */ 1259 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0, 1260 HDA_INPUT); 1261 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo); 1262 mutex_unlock(&codec->spdif_mutex); /* reuse spdif_mutex */ 1263 return err; 1264} 1265 1266static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag, 1267 unsigned int size, unsigned int __user *tlv) 1268{ 1269 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 1270 struct alc_spec *spec = codec->spec; 1271 int err; 1272 1273 mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */ 1274 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0, 1275 HDA_INPUT); 1276 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv); 1277 mutex_unlock(&codec->spdif_mutex); /* reuse spdif_mutex */ 1278 return err; 1279} 1280 1281typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol, 1282 struct snd_ctl_elem_value *ucontrol); 1283 1284static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol, 1285 struct snd_ctl_elem_value *ucontrol, 1286 getput_call_t func) 1287{ 1288 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 1289 struct alc_spec *spec = codec->spec; 1290 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 1291 int err; 1292 1293 mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */ 1294 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx], 1295 3, 0, HDA_INPUT); 1296 err = func(kcontrol, ucontrol); 1297 mutex_unlock(&codec->spdif_mutex); /* reuse spdif_mutex */ 1298 return err; 1299} 1300 1301static int alc_cap_vol_get(struct snd_kcontrol *kcontrol, 1302 struct snd_ctl_elem_value *ucontrol) 1303{ 1304 return alc_cap_getput_caller(kcontrol, ucontrol, 1305 snd_hda_mixer_amp_volume_get); 1306} 1307 1308static int alc_cap_vol_put(struct snd_kcontrol *kcontrol, 1309 struct snd_ctl_elem_value *ucontrol) 1310{ 1311 return alc_cap_getput_caller(kcontrol, ucontrol, 1312 snd_hda_mixer_amp_volume_put); 1313} 1314 1315/* capture mixer elements */ 1316#define alc_cap_sw_info snd_ctl_boolean_stereo_info 1317 1318static int alc_cap_sw_get(struct snd_kcontrol *kcontrol, 1319 struct snd_ctl_elem_value *ucontrol) 1320{ 1321 return alc_cap_getput_caller(kcontrol, ucontrol, 1322 snd_hda_mixer_amp_switch_get); 1323} 1324 1325static int alc_cap_sw_put(struct snd_kcontrol *kcontrol, 1326 struct snd_ctl_elem_value *ucontrol) 1327{ 1328 return alc_cap_getput_caller(kcontrol, ucontrol, 1329 snd_hda_mixer_amp_switch_put); 1330} 1331 1332#define DEFINE_CAPMIX(num) \ 1333static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \ 1334 { \ 1335 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 1336 .name = "Capture Switch", \ 1337 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \ 1338 .count = num, \ 1339 .info = alc_cap_sw_info, \ 1340 .get = alc_cap_sw_get, \ 1341 .put = alc_cap_sw_put, \ 1342 }, \ 1343 { \ 1344 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 1345 .name = "Capture Volume", \ 1346 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \ 1347 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \ 1348 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \ 1349 .count = num, \ 1350 .info = alc_cap_vol_info, \ 1351 .get = alc_cap_vol_get, \ 1352 .put = alc_cap_vol_put, \ 1353 .tlv = { .c = alc_cap_vol_tlv }, \ 1354 }, \ 1355 { \ 1356 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 1357 /* .name = "Capture Source", */ \ 1358 .name = "Input Source", \ 1359 .count = num, \ 1360 .info = alc_mux_enum_info, \ 1361 .get = alc_mux_enum_get, \ 1362 .put = alc_mux_enum_put, \ 1363 }, \ 1364 { } /* end */ \ 1365} 1366 1367/* up to three ADCs */ 1368DEFINE_CAPMIX(1); 1369DEFINE_CAPMIX(2); 1370DEFINE_CAPMIX(3); 1371 1372 1373/* 1374 * ALC880 5-stack model 1375 * 1376 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d), 1377 * Side = 0x02 (0xd) 1378 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16 1379 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19 1380 */ 1381 1382/* additional mixers to alc880_three_stack_mixer */ 1383static struct snd_kcontrol_new alc880_five_stack_mixer[] = { 1384 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 1385 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT), 1386 { } /* end */ 1387}; 1388 1389/* channel source setting (6/8 channel selection for 5-stack) */ 1390/* 6ch mode */ 1391static struct hda_verb alc880_fivestack_ch6_init[] = { 1392 /* set line-in to input, mute it */ 1393 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 1394 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 1395 { } /* end */ 1396}; 1397 1398/* 8ch mode */ 1399static struct hda_verb alc880_fivestack_ch8_init[] = { 1400 /* set line-in to output, unmute it */ 1401 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 1402 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 1403 { } /* end */ 1404}; 1405 1406static struct hda_channel_mode alc880_fivestack_modes[2] = { 1407 { 6, alc880_fivestack_ch6_init }, 1408 { 8, alc880_fivestack_ch8_init }, 1409}; 1410 1411 1412/* 1413 * ALC880 6-stack model 1414 * 1415 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e), 1416 * Side = 0x05 (0x0f) 1417 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17, 1418 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b 1419 */ 1420 1421static hda_nid_t alc880_6st_dac_nids[4] = { 1422 /* front, rear, clfe, rear_surr */ 1423 0x02, 0x03, 0x04, 0x05 1424}; 1425 1426static struct hda_input_mux alc880_6stack_capture_source = { 1427 .num_items = 4, 1428 .items = { 1429 { "Mic", 0x0 }, 1430 { "Front Mic", 0x1 }, 1431 { "Line", 0x2 }, 1432 { "CD", 0x4 }, 1433 }, 1434}; 1435 1436/* fixed 8-channels */ 1437static struct hda_channel_mode alc880_sixstack_modes[1] = { 1438 { 8, NULL }, 1439}; 1440 1441static struct snd_kcontrol_new alc880_six_stack_mixer[] = { 1442 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 1443 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 1444 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 1445 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 1446 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 1447 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 1448 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 1449 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 1450 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 1451 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 1452 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 1453 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 1454 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 1455 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 1456 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 1457 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 1458 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 1459 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 1460 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 1461 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 1462 { 1463 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1464 .name = "Channel Mode", 1465 .info = alc_ch_mode_info, 1466 .get = alc_ch_mode_get, 1467 .put = alc_ch_mode_put, 1468 }, 1469 { } /* end */ 1470}; 1471 1472 1473/* 1474 * ALC880 W810 model 1475 * 1476 * W810 has rear IO for: 1477 * Front (DAC 02) 1478 * Surround (DAC 03) 1479 * Center/LFE (DAC 04) 1480 * Digital out (06) 1481 * 1482 * The system also has a pair of internal speakers, and a headphone jack. 1483 * These are both connected to Line2 on the codec, hence to DAC 02. 1484 * 1485 * There is a variable resistor to control the speaker or headphone 1486 * volume. This is a hardware-only device without a software API. 1487 * 1488 * Plugging headphones in will disable the internal speakers. This is 1489 * implemented in hardware, not via the driver using jack sense. In 1490 * a similar fashion, plugging into the rear socket marked "front" will 1491 * disable both the speakers and headphones. 1492 * 1493 * For input, there's a microphone jack, and an "audio in" jack. 1494 * These may not do anything useful with this driver yet, because I 1495 * haven't setup any initialization verbs for these yet... 1496 */ 1497 1498static hda_nid_t alc880_w810_dac_nids[3] = { 1499 /* front, rear/surround, clfe */ 1500 0x02, 0x03, 0x04 1501}; 1502 1503/* fixed 6 channels */ 1504static struct hda_channel_mode alc880_w810_modes[1] = { 1505 { 6, NULL } 1506}; 1507 1508/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */ 1509static struct snd_kcontrol_new alc880_w810_base_mixer[] = { 1510 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 1511 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 1512 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 1513 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 1514 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 1515 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 1516 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 1517 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 1518 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 1519 { } /* end */ 1520}; 1521 1522 1523/* 1524 * Z710V model 1525 * 1526 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d) 1527 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?), 1528 * Line = 0x1a 1529 */ 1530 1531static hda_nid_t alc880_z71v_dac_nids[1] = { 1532 0x02 1533}; 1534#define ALC880_Z71V_HP_DAC 0x03 1535 1536/* fixed 2 channels */ 1537static struct hda_channel_mode alc880_2_jack_modes[1] = { 1538 { 2, NULL } 1539}; 1540 1541static struct snd_kcontrol_new alc880_z71v_mixer[] = { 1542 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 1543 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 1544 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 1545 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT), 1546 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 1547 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 1548 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 1549 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 1550 { } /* end */ 1551}; 1552 1553 1554/* 1555 * ALC880 F1734 model 1556 * 1557 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d) 1558 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18 1559 */ 1560 1561static hda_nid_t alc880_f1734_dac_nids[1] = { 1562 0x03 1563}; 1564#define ALC880_F1734_HP_DAC 0x02 1565 1566static struct snd_kcontrol_new alc880_f1734_mixer[] = { 1567 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 1568 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), 1569 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 1570 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 1571 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 1572 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 1573 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 1574 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 1575 { } /* end */ 1576}; 1577 1578static struct hda_input_mux alc880_f1734_capture_source = { 1579 .num_items = 2, 1580 .items = { 1581 { "Mic", 0x1 }, 1582 { "CD", 0x4 }, 1583 }, 1584}; 1585 1586 1587/* 1588 * ALC880 ASUS model 1589 * 1590 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e) 1591 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16, 1592 * Mic = 0x18, Line = 0x1a 1593 */ 1594 1595#define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */ 1596#define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */ 1597 1598static struct snd_kcontrol_new alc880_asus_mixer[] = { 1599 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 1600 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 1601 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 1602 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 1603 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 1604 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 1605 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 1606 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 1607 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 1608 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 1609 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 1610 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 1611 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 1612 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 1613 { 1614 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1615 .name = "Channel Mode", 1616 .info = alc_ch_mode_info, 1617 .get = alc_ch_mode_get, 1618 .put = alc_ch_mode_put, 1619 }, 1620 { } /* end */ 1621}; 1622 1623/* 1624 * ALC880 ASUS W1V model 1625 * 1626 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e) 1627 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16, 1628 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b 1629 */ 1630 1631/* additional mixers to alc880_asus_mixer */ 1632static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = { 1633 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT), 1634 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT), 1635 { } /* end */ 1636}; 1637 1638/* additional mixers to alc880_asus_mixer */ 1639static struct snd_kcontrol_new alc880_pcbeep_mixer[] = { 1640 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 1641 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 1642 { } /* end */ 1643}; 1644 1645/* TCL S700 */ 1646static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = { 1647 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 1648 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 1649 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 1650 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT), 1651 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT), 1652 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT), 1653 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT), 1654 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 1655 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 1656 { } /* end */ 1657}; 1658 1659/* Uniwill */ 1660static struct snd_kcontrol_new alc880_uniwill_mixer[] = { 1661 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 1662 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), 1663 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 1664 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 1665 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 1666 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 1667 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 1668 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 1669 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 1670 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 1671 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 1672 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 1673 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 1674 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 1675 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 1676 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 1677 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 1678 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 1679 { 1680 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1681 .name = "Channel Mode", 1682 .info = alc_ch_mode_info, 1683 .get = alc_ch_mode_get, 1684 .put = alc_ch_mode_put, 1685 }, 1686 { } /* end */ 1687}; 1688 1689static struct snd_kcontrol_new alc880_fujitsu_mixer[] = { 1690 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 1691 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), 1692 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 1693 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 1694 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 1695 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 1696 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 1697 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 1698 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 1699 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 1700 { } /* end */ 1701}; 1702 1703static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = { 1704 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 1705 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), 1706 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 1707 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 1708 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 1709 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 1710 { } /* end */ 1711}; 1712 1713/* 1714 * virtual master controls 1715 */ 1716 1717/* 1718 * slave controls for virtual master 1719 */ 1720static const char *alc_slave_vols[] = { 1721 "Front Playback Volume", 1722 "Surround Playback Volume", 1723 "Center Playback Volume", 1724 "LFE Playback Volume", 1725 "Side Playback Volume", 1726 "Headphone Playback Volume", 1727 "Speaker Playback Volume", 1728 "Mono Playback Volume", 1729 "Line-Out Playback Volume", 1730 "PCM Playback Volume", 1731 NULL, 1732}; 1733 1734static const char *alc_slave_sws[] = { 1735 "Front Playback Switch", 1736 "Surround Playback Switch", 1737 "Center Playback Switch", 1738 "LFE Playback Switch", 1739 "Side Playback Switch", 1740 "Headphone Playback Switch", 1741 "Speaker Playback Switch", 1742 "Mono Playback Switch", 1743 "IEC958 Playback Switch", 1744 NULL, 1745}; 1746 1747/* 1748 * build control elements 1749 */ 1750 1751static void alc_free_kctls(struct hda_codec *codec); 1752 1753static int alc_build_controls(struct hda_codec *codec) 1754{ 1755 struct alc_spec *spec = codec->spec; 1756 int err; 1757 int i; 1758 1759 for (i = 0; i < spec->num_mixers; i++) { 1760 err = snd_hda_add_new_ctls(codec, spec->mixers[i]); 1761 if (err < 0) 1762 return err; 1763 } 1764 if (spec->cap_mixer) { 1765 err = snd_hda_add_new_ctls(codec, spec->cap_mixer); 1766 if (err < 0) 1767 return err; 1768 } 1769 if (spec->multiout.dig_out_nid) { 1770 err = snd_hda_create_spdif_out_ctls(codec, 1771 spec->multiout.dig_out_nid); 1772 if (err < 0) 1773 return err; 1774 err = snd_hda_create_spdif_share_sw(codec, 1775 &spec->multiout); 1776 if (err < 0) 1777 return err; 1778 spec->multiout.share_spdif = 1; 1779 } 1780 if (spec->dig_in_nid) { 1781 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid); 1782 if (err < 0) 1783 return err; 1784 } 1785 1786 /* if we have no master control, let's create it */ 1787 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) { 1788 unsigned int vmaster_tlv[4]; 1789 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid, 1790 HDA_OUTPUT, vmaster_tlv); 1791 err = snd_hda_add_vmaster(codec, "Master Playback Volume", 1792 vmaster_tlv, alc_slave_vols); 1793 if (err < 0) 1794 return err; 1795 } 1796 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) { 1797 err = snd_hda_add_vmaster(codec, "Master Playback Switch", 1798 NULL, alc_slave_sws); 1799 if (err < 0) 1800 return err; 1801 } 1802 1803 alc_free_kctls(codec); /* no longer needed */ 1804 return 0; 1805} 1806 1807 1808/* 1809 * initialize the codec volumes, etc 1810 */ 1811 1812/* 1813 * generic initialization of ADC, input mixers and output mixers 1814 */ 1815static struct hda_verb alc880_volume_init_verbs[] = { 1816 /* 1817 * Unmute ADC0-2 and set the default input to mic-in 1818 */ 1819 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 1820 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1821 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 1822 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1823 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 1824 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1825 1826 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 1827 * mixer widget 1828 * Note: PASD motherboards uses the Line In 2 as the input for front 1829 * panel mic (mic 2) 1830 */ 1831 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 1832 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 1833 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 1834 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 1835 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 1836 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 1837 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, 1838 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, 1839 1840 /* 1841 * Set up output mixers (0x0c - 0x0f) 1842 */ 1843 /* set vol=0 to output mixers */ 1844 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 1845 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 1846 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 1847 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 1848 /* set up input amps for analog loopback */ 1849 /* Amp Indices: DAC = 0, mixer = 1 */ 1850 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 1851 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 1852 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 1853 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 1854 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 1855 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 1856 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 1857 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 1858 1859 { } 1860}; 1861 1862/* 1863 * 3-stack pin configuration: 1864 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b 1865 */ 1866static struct hda_verb alc880_pin_3stack_init_verbs[] = { 1867 /* 1868 * preset connection lists of input pins 1869 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround 1870 */ 1871 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ 1872 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 1873 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */ 1874 1875 /* 1876 * Set pin mode and muting 1877 */ 1878 /* set front pin widgets 0x14 for output */ 1879 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1880 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1881 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 1882 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1883 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1884 /* Mic2 (as headphone out) for HP output */ 1885 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1886 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1887 /* Line In pin widget for input */ 1888 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1889 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1890 /* Line2 (as front mic) pin widget for input and vref at 80% */ 1891 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1892 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1893 /* CD pin widget for input */ 1894 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1895 1896 { } 1897}; 1898 1899/* 1900 * 5-stack pin configuration: 1901 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19, 1902 * line-in/side = 0x1a, f-mic = 0x1b 1903 */ 1904static struct hda_verb alc880_pin_5stack_init_verbs[] = { 1905 /* 1906 * preset connection lists of input pins 1907 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround 1908 */ 1909 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 1910 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */ 1911 1912 /* 1913 * Set pin mode and muting 1914 */ 1915 /* set pin widgets 0x14-0x17 for output */ 1916 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1917 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1918 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1919 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1920 /* unmute pins for output (no gain on this amp) */ 1921 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1922 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1923 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1924 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1925 1926 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 1927 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1928 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1929 /* Mic2 (as headphone out) for HP output */ 1930 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1931 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1932 /* Line In pin widget for input */ 1933 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1934 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1935 /* Line2 (as front mic) pin widget for input and vref at 80% */ 1936 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1937 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1938 /* CD pin widget for input */ 1939 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1940 1941 { } 1942}; 1943 1944/* 1945 * W810 pin configuration: 1946 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b 1947 */ 1948static struct hda_verb alc880_pin_w810_init_verbs[] = { 1949 /* hphone/speaker input selector: front DAC */ 1950 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0}, 1951 1952 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1953 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1954 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1955 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1956 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1957 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1958 1959 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1960 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1961 1962 { } 1963}; 1964 1965/* 1966 * Z71V pin configuration: 1967 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?) 1968 */ 1969static struct hda_verb alc880_pin_z71v_init_verbs[] = { 1970 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1971 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1972 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1973 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1974 1975 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1976 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1977 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1978 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1979 1980 { } 1981}; 1982 1983/* 1984 * 6-stack pin configuration: 1985 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18, 1986 * f-mic = 0x19, line = 0x1a, HP = 0x1b 1987 */ 1988static struct hda_verb alc880_pin_6stack_init_verbs[] = { 1989 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 1990 1991 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1992 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1993 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1994 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1995 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1996 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1997 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1998 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1999 2000 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2001 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2002 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2003 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2004 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2005 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2006 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 2007 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2008 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2009 2010 { } 2011}; 2012 2013/* 2014 * Uniwill pin configuration: 2015 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19, 2016 * line = 0x1a 2017 */ 2018static struct hda_verb alc880_uniwill_init_verbs[] = { 2019 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 2020 2021 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 2022 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2023 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 2024 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2025 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 2026 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2027 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2028 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2029 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 2030 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 2031 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 2032 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 2033 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 2034 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 2035 2036 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2037 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2038 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2039 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2040 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2041 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2042 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */ 2043 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */ 2044 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2045 2046 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 2047 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 2048 2049 { } 2050}; 2051 2052/* 2053* Uniwill P53 2054* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19, 2055 */ 2056static struct hda_verb alc880_uniwill_p53_init_verbs[] = { 2057 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 2058 2059 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 2060 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2061 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 2062 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2063 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 2064 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2065 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 2066 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 2067 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 2068 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 2069 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 2070 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 2071 2072 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2073 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2074 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2075 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2076 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2077 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2078 2079 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 2080 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT}, 2081 2082 { } 2083}; 2084 2085static struct hda_verb alc880_beep_init_verbs[] = { 2086 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) }, 2087 { } 2088}; 2089 2090/* toggle speaker-output according to the hp-jack state */ 2091static void alc880_uniwill_hp_automute(struct hda_codec *codec) 2092{ 2093 unsigned int present; 2094 unsigned char bits; 2095 2096 present = snd_hda_codec_read(codec, 0x14, 0, 2097 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 2098 bits = present ? HDA_AMP_MUTE : 0; 2099 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 2100 HDA_AMP_MUTE, bits); 2101 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0, 2102 HDA_AMP_MUTE, bits); 2103} 2104 2105/* auto-toggle front mic */ 2106static void alc880_uniwill_mic_automute(struct hda_codec *codec) 2107{ 2108 unsigned int present; 2109 unsigned char bits; 2110 2111 present = snd_hda_codec_read(codec, 0x18, 0, 2112 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 2113 bits = present ? HDA_AMP_MUTE : 0; 2114 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits); 2115} 2116 2117static void alc880_uniwill_automute(struct hda_codec *codec) 2118{ 2119 alc880_uniwill_hp_automute(codec); 2120 alc880_uniwill_mic_automute(codec); 2121} 2122 2123static void alc880_uniwill_unsol_event(struct hda_codec *codec, 2124 unsigned int res) 2125{ 2126 /* Looks like the unsol event is incompatible with the standard 2127 * definition. 4bit tag is placed at 28 bit! 2128 */ 2129 switch (res >> 28) { 2130 case ALC880_HP_EVENT: 2131 alc880_uniwill_hp_automute(codec); 2132 break; 2133 case ALC880_MIC_EVENT: 2134 alc880_uniwill_mic_automute(codec); 2135 break; 2136 } 2137} 2138 2139static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec) 2140{ 2141 unsigned int present; 2142 unsigned char bits; 2143 2144 present = snd_hda_codec_read(codec, 0x14, 0, 2145 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 2146 bits = present ? HDA_AMP_MUTE : 0; 2147 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, HDA_AMP_MUTE, bits); 2148} 2149 2150static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec) 2151{ 2152 unsigned int present; 2153 2154 present = snd_hda_codec_read(codec, 0x21, 0, 2155 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0); 2156 present &= HDA_AMP_VOLMASK; 2157 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0, 2158 HDA_AMP_VOLMASK, present); 2159 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0, 2160 HDA_AMP_VOLMASK, present); 2161} 2162 2163static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec, 2164 unsigned int res) 2165{ 2166 /* Looks like the unsol event is incompatible with the standard 2167 * definition. 4bit tag is placed at 28 bit! 2168 */ 2169 if ((res >> 28) == ALC880_HP_EVENT) 2170 alc880_uniwill_p53_hp_automute(codec); 2171 if ((res >> 28) == ALC880_DCVOL_EVENT) 2172 alc880_uniwill_p53_dcvol_automute(codec); 2173} 2174 2175/* 2176 * F1734 pin configuration: 2177 * HP = 0x14, speaker-out = 0x15, mic = 0x18 2178 */ 2179static struct hda_verb alc880_pin_f1734_init_verbs[] = { 2180 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01}, 2181 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, 2182 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, 2183 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, 2184 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, 2185 2186 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 2187 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2188 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2189 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2190 2191 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2192 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2193 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, 2194 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2195 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2196 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2197 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2198 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2199 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2200 2201 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT}, 2202 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT}, 2203 2204 { } 2205}; 2206 2207/* 2208 * ASUS pin configuration: 2209 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a 2210 */ 2211static struct hda_verb alc880_pin_asus_init_verbs[] = { 2212 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, 2213 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, 2214 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, 2215 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, 2216 2217 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 2218 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2219 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2220 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2221 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2222 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2223 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2224 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2225 2226 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2227 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2228 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2229 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2230 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2231 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2232 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2233 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2234 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2235 2236 { } 2237}; 2238 2239/* Enable GPIO mask and set output */ 2240#define alc880_gpio1_init_verbs alc_gpio1_init_verbs 2241#define alc880_gpio2_init_verbs alc_gpio2_init_verbs 2242 2243/* Clevo m520g init */ 2244static struct hda_verb alc880_pin_clevo_init_verbs[] = { 2245 /* headphone output */ 2246 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01}, 2247 /* line-out */ 2248 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2249 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2250 /* Line-in */ 2251 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2252 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2253 /* CD */ 2254 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2255 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2256 /* Mic1 (rear panel) */ 2257 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2258 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2259 /* Mic2 (front panel) */ 2260 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2261 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2262 /* headphone */ 2263 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 2264 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2265 /* change to EAPD mode */ 2266 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 2267 {0x20, AC_VERB_SET_PROC_COEF, 0x3060}, 2268 2269 { } 2270}; 2271 2272static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = { 2273 /* change to EAPD mode */ 2274 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 2275 {0x20, AC_VERB_SET_PROC_COEF, 0x3060}, 2276 2277 /* Headphone output */ 2278 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 2279 /* Front output*/ 2280 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2281 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 2282 2283 /* Line In pin widget for input */ 2284 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2285 /* CD pin widget for input */ 2286 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2287 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 2288 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2289 2290 /* change to EAPD mode */ 2291 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 2292 {0x20, AC_VERB_SET_PROC_COEF, 0x3070}, 2293 2294 { } 2295}; 2296 2297/* 2298 * LG m1 express dual 2299 * 2300 * Pin assignment: 2301 * Rear Line-In/Out (blue): 0x14 2302 * Build-in Mic-In: 0x15 2303 * Speaker-out: 0x17 2304 * HP-Out (green): 0x1b 2305 * Mic-In/Out (red): 0x19 2306 * SPDIF-Out: 0x1e 2307 */ 2308 2309/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */ 2310static hda_nid_t alc880_lg_dac_nids[3] = { 2311 0x05, 0x02, 0x03 2312}; 2313 2314/* seems analog CD is not working */ 2315static struct hda_input_mux alc880_lg_capture_source = { 2316 .num_items = 3, 2317 .items = { 2318 { "Mic", 0x1 }, 2319 { "Line", 0x5 }, 2320 { "Internal Mic", 0x6 }, 2321 }, 2322}; 2323 2324/* 2,4,6 channel modes */ 2325static struct hda_verb alc880_lg_ch2_init[] = { 2326 /* set line-in and mic-in to input */ 2327 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 2328 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 2329 { } 2330}; 2331 2332static struct hda_verb alc880_lg_ch4_init[] = { 2333 /* set line-in to out and mic-in to input */ 2334 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, 2335 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 2336 { } 2337}; 2338 2339static struct hda_verb alc880_lg_ch6_init[] = { 2340 /* set line-in and mic-in to output */ 2341 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, 2342 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, 2343 { } 2344}; 2345 2346static struct hda_channel_mode alc880_lg_ch_modes[3] = { 2347 { 2, alc880_lg_ch2_init }, 2348 { 4, alc880_lg_ch4_init }, 2349 { 6, alc880_lg_ch6_init }, 2350}; 2351 2352static struct snd_kcontrol_new alc880_lg_mixer[] = { 2353 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 2354 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT), 2355 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2356 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT), 2357 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT), 2358 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT), 2359 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT), 2360 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT), 2361 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 2362 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 2363 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT), 2364 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT), 2365 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT), 2366 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT), 2367 { 2368 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2369 .name = "Channel Mode", 2370 .info = alc_ch_mode_info, 2371 .get = alc_ch_mode_get, 2372 .put = alc_ch_mode_put, 2373 }, 2374 { } /* end */ 2375}; 2376 2377static struct hda_verb alc880_lg_init_verbs[] = { 2378 /* set capture source to mic-in */ 2379 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 2380 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 2381 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 2382 /* mute all amp mixer inputs */ 2383 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)}, 2384 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, 2385 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, 2386 /* line-in to input */ 2387 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2388 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2389 /* built-in mic */ 2390 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2391 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2392 /* speaker-out */ 2393 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 2394 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2395 /* mic-in to input */ 2396 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01}, 2397 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2398 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2399 /* HP-out */ 2400 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03}, 2401 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 2402 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2403 /* jack sense */ 2404 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1}, 2405 { } 2406}; 2407 2408/* toggle speaker-output according to the hp-jack state */ 2409static void alc880_lg_automute(struct hda_codec *codec) 2410{ 2411 unsigned int present; 2412 unsigned char bits; 2413 2414 present = snd_hda_codec_read(codec, 0x1b, 0, 2415 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 2416 bits = present ? HDA_AMP_MUTE : 0; 2417 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0, 2418 HDA_AMP_MUTE, bits); 2419} 2420 2421static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res) 2422{ 2423 /* Looks like the unsol event is incompatible with the standard 2424 * definition. 4bit tag is placed at 28 bit! 2425 */ 2426 if ((res >> 28) == 0x01) 2427 alc880_lg_automute(codec); 2428} 2429 2430/* 2431 * LG LW20 2432 * 2433 * Pin assignment: 2434 * Speaker-out: 0x14 2435 * Mic-In: 0x18 2436 * Built-in Mic-In: 0x19 2437 * Line-In: 0x1b 2438 * HP-Out: 0x1a 2439 * SPDIF-Out: 0x1e 2440 */ 2441 2442static struct hda_input_mux alc880_lg_lw_capture_source = { 2443 .num_items = 3, 2444 .items = { 2445 { "Mic", 0x0 }, 2446 { "Internal Mic", 0x1 }, 2447 { "Line In", 0x2 }, 2448 }, 2449}; 2450 2451#define alc880_lg_lw_modes alc880_threestack_modes 2452 2453static struct snd_kcontrol_new alc880_lg_lw_mixer[] = { 2454 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2455 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 2456 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 2457 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT), 2458 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 2459 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 2460 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 2461 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 2462 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 2463 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 2464 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 2465 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 2466 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 2467 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 2468 { 2469 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2470 .name = "Channel Mode", 2471 .info = alc_ch_mode_info, 2472 .get = alc_ch_mode_get, 2473 .put = alc_ch_mode_put, 2474 }, 2475 { } /* end */ 2476}; 2477 2478static struct hda_verb alc880_lg_lw_init_verbs[] = { 2479 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 2480 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ 2481 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */ 2482 2483 /* set capture source to mic-in */ 2484 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 2485 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 2486 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 2487 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, 2488 /* speaker-out */ 2489 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 2490 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2491 /* HP-out */ 2492 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 2493 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2494 /* mic-in to input */ 2495 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2496 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2497 /* built-in mic */ 2498 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2499 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2500 /* jack sense */ 2501 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1}, 2502 { } 2503}; 2504 2505/* toggle speaker-output according to the hp-jack state */ 2506static void alc880_lg_lw_automute(struct hda_codec *codec) 2507{ 2508 unsigned int present; 2509 unsigned char bits; 2510 2511 present = snd_hda_codec_read(codec, 0x1b, 0, 2512 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 2513 bits = present ? HDA_AMP_MUTE : 0; 2514 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 2515 HDA_AMP_MUTE, bits); 2516} 2517 2518static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res) 2519{ 2520 /* Looks like the unsol event is incompatible with the standard 2521 * definition. 4bit tag is placed at 28 bit! 2522 */ 2523 if ((res >> 28) == 0x01) 2524 alc880_lg_lw_automute(codec); 2525} 2526 2527static struct snd_kcontrol_new alc880_medion_rim_mixer[] = { 2528 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2529 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT), 2530 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 2531 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 2532 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 2533 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT), 2534 { } /* end */ 2535}; 2536 2537static struct hda_input_mux alc880_medion_rim_capture_source = { 2538 .num_items = 2, 2539 .items = { 2540 { "Mic", 0x0 }, 2541 { "Internal Mic", 0x1 }, 2542 }, 2543}; 2544 2545static struct hda_verb alc880_medion_rim_init_verbs[] = { 2546 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 2547 2548 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 2549 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2550 2551 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 2552 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2553 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2554 /* Mic2 (as headphone out) for HP output */ 2555 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 2556 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2557 /* Internal Speaker */ 2558 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2559 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2560 2561 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 2562 {0x20, AC_VERB_SET_PROC_COEF, 0x3060}, 2563 2564 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 2565 { } 2566}; 2567 2568/* toggle speaker-output according to the hp-jack state */ 2569static void alc880_medion_rim_automute(struct hda_codec *codec) 2570{ 2571 unsigned int present; 2572 unsigned char bits; 2573 2574 present = snd_hda_codec_read(codec, 0x14, 0, 2575 AC_VERB_GET_PIN_SENSE, 0) 2576 & AC_PINSENSE_PRESENCE; 2577 bits = present ? HDA_AMP_MUTE : 0; 2578 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0, 2579 HDA_AMP_MUTE, bits); 2580 if (present) 2581 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0); 2582 else 2583 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2); 2584} 2585 2586static void alc880_medion_rim_unsol_event(struct hda_codec *codec, 2587 unsigned int res) 2588{ 2589 /* Looks like the unsol event is incompatible with the standard 2590 * definition. 4bit tag is placed at 28 bit! 2591 */ 2592 if ((res >> 28) == ALC880_HP_EVENT) 2593 alc880_medion_rim_automute(codec); 2594} 2595 2596#ifdef CONFIG_SND_HDA_POWER_SAVE 2597static struct hda_amp_list alc880_loopbacks[] = { 2598 { 0x0b, HDA_INPUT, 0 }, 2599 { 0x0b, HDA_INPUT, 1 }, 2600 { 0x0b, HDA_INPUT, 2 }, 2601 { 0x0b, HDA_INPUT, 3 }, 2602 { 0x0b, HDA_INPUT, 4 }, 2603 { } /* end */ 2604}; 2605 2606static struct hda_amp_list alc880_lg_loopbacks[] = { 2607 { 0x0b, HDA_INPUT, 1 }, 2608 { 0x0b, HDA_INPUT, 6 }, 2609 { 0x0b, HDA_INPUT, 7 }, 2610 { } /* end */ 2611}; 2612#endif 2613 2614/* 2615 * Common callbacks 2616 */ 2617 2618static int alc_init(struct hda_codec *codec) 2619{ 2620 struct alc_spec *spec = codec->spec; 2621 unsigned int i; 2622 2623 alc_fix_pll(codec); 2624 if (codec->vendor_id == 0x10ec0888) 2625 alc888_coef_init(codec); 2626 2627 for (i = 0; i < spec->num_init_verbs; i++) 2628 snd_hda_sequence_write(codec, spec->init_verbs[i]); 2629 2630 if (spec->init_hook) 2631 spec->init_hook(codec); 2632 2633 return 0; 2634} 2635 2636static void alc_unsol_event(struct hda_codec *codec, unsigned int res) 2637{ 2638 struct alc_spec *spec = codec->spec; 2639 2640 if (spec->unsol_event) 2641 spec->unsol_event(codec, res); 2642} 2643 2644#ifdef CONFIG_SND_HDA_POWER_SAVE 2645static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid) 2646{ 2647 struct alc_spec *spec = codec->spec; 2648 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid); 2649} 2650#endif 2651 2652/* 2653 * Analog playback callbacks 2654 */ 2655static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo, 2656 struct hda_codec *codec, 2657 struct snd_pcm_substream *substream) 2658{ 2659 struct alc_spec *spec = codec->spec; 2660 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream, 2661 hinfo); 2662} 2663 2664static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo, 2665 struct hda_codec *codec, 2666 unsigned int stream_tag, 2667 unsigned int format, 2668 struct snd_pcm_substream *substream) 2669{ 2670 struct alc_spec *spec = codec->spec; 2671 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, 2672 stream_tag, format, substream); 2673} 2674 2675static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, 2676 struct hda_codec *codec, 2677 struct snd_pcm_substream *substream) 2678{ 2679 struct alc_spec *spec = codec->spec; 2680 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); 2681} 2682 2683/* 2684 * Digital out 2685 */ 2686static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo, 2687 struct hda_codec *codec, 2688 struct snd_pcm_substream *substream) 2689{ 2690 struct alc_spec *spec = codec->spec; 2691 return snd_hda_multi_out_dig_open(codec, &spec->multiout); 2692} 2693 2694static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, 2695 struct hda_codec *codec, 2696 unsigned int stream_tag, 2697 unsigned int format, 2698 struct snd_pcm_substream *substream) 2699{ 2700 struct alc_spec *spec = codec->spec; 2701 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, 2702 stream_tag, format, substream); 2703} 2704 2705static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, 2706 struct hda_codec *codec, 2707 struct snd_pcm_substream *substream) 2708{ 2709 struct alc_spec *spec = codec->spec; 2710 return snd_hda_multi_out_dig_close(codec, &spec->multiout); 2711} 2712 2713/* 2714 * Analog capture 2715 */ 2716static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo, 2717 struct hda_codec *codec, 2718 unsigned int stream_tag, 2719 unsigned int format, 2720 struct snd_pcm_substream *substream) 2721{ 2722 struct alc_spec *spec = codec->spec; 2723 2724 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1], 2725 stream_tag, 0, format); 2726 return 0; 2727} 2728 2729static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, 2730 struct hda_codec *codec, 2731 struct snd_pcm_substream *substream) 2732{ 2733 struct alc_spec *spec = codec->spec; 2734 2735 snd_hda_codec_cleanup_stream(codec, 2736 spec->adc_nids[substream->number + 1]); 2737 return 0; 2738} 2739 2740 2741/* 2742 */ 2743static struct hda_pcm_stream alc880_pcm_analog_playback = { 2744 .substreams = 1, 2745 .channels_min = 2, 2746 .channels_max = 8, 2747 /* NID is set in alc_build_pcms */ 2748 .ops = { 2749 .open = alc880_playback_pcm_open, 2750 .prepare = alc880_playback_pcm_prepare, 2751 .cleanup = alc880_playback_pcm_cleanup 2752 }, 2753}; 2754 2755static struct hda_pcm_stream alc880_pcm_analog_capture = { 2756 .substreams = 1, 2757 .channels_min = 2, 2758 .channels_max = 2, 2759 /* NID is set in alc_build_pcms */ 2760}; 2761 2762static struct hda_pcm_stream alc880_pcm_analog_alt_playback = { 2763 .substreams = 1, 2764 .channels_min = 2, 2765 .channels_max = 2, 2766 /* NID is set in alc_build_pcms */ 2767}; 2768 2769static struct hda_pcm_stream alc880_pcm_analog_alt_capture = { 2770 .substreams = 2, /* can be overridden */ 2771 .channels_min = 2, 2772 .channels_max = 2, 2773 /* NID is set in alc_build_pcms */ 2774 .ops = { 2775 .prepare = alc880_alt_capture_pcm_prepare, 2776 .cleanup = alc880_alt_capture_pcm_cleanup 2777 }, 2778}; 2779 2780static struct hda_pcm_stream alc880_pcm_digital_playback = { 2781 .substreams = 1, 2782 .channels_min = 2, 2783 .channels_max = 2, 2784 /* NID is set in alc_build_pcms */ 2785 .ops = { 2786 .open = alc880_dig_playback_pcm_open, 2787 .close = alc880_dig_playback_pcm_close, 2788 .prepare = alc880_dig_playback_pcm_prepare 2789 }, 2790}; 2791 2792static struct hda_pcm_stream alc880_pcm_digital_capture = { 2793 .substreams = 1, 2794 .channels_min = 2, 2795 .channels_max = 2, 2796 /* NID is set in alc_build_pcms */ 2797}; 2798 2799/* Used by alc_build_pcms to flag that a PCM has no playback stream */ 2800static struct hda_pcm_stream alc_pcm_null_stream = { 2801 .substreams = 0, 2802 .channels_min = 0, 2803 .channels_max = 0, 2804}; 2805 2806static int alc_build_pcms(struct hda_codec *codec) 2807{ 2808 struct alc_spec *spec = codec->spec; 2809 struct hda_pcm *info = spec->pcm_rec; 2810 int i; 2811 2812 codec->num_pcms = 1; 2813 codec->pcm_info = info; 2814 2815 info->name = spec->stream_name_analog; 2816 if (spec->stream_analog_playback) { 2817 if (snd_BUG_ON(!spec->multiout.dac_nids)) 2818 return -EINVAL; 2819 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback); 2820 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0]; 2821 } 2822 if (spec->stream_analog_capture) { 2823 if (snd_BUG_ON(!spec->adc_nids)) 2824 return -EINVAL; 2825 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture); 2826 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0]; 2827 } 2828 2829 if (spec->channel_mode) { 2830 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0; 2831 for (i = 0; i < spec->num_channel_mode; i++) { 2832 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) { 2833 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels; 2834 } 2835 } 2836 } 2837 2838 /* SPDIF for stream index #1 */ 2839 if (spec->multiout.dig_out_nid || spec->dig_in_nid) { 2840 codec->num_pcms = 2; 2841 info = spec->pcm_rec + 1; 2842 info->name = spec->stream_name_digital; 2843 info->pcm_type = HDA_PCM_TYPE_SPDIF; 2844 if (spec->multiout.dig_out_nid && 2845 spec->stream_digital_playback) { 2846 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback); 2847 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid; 2848 } 2849 if (spec->dig_in_nid && 2850 spec->stream_digital_capture) { 2851 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture); 2852 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid; 2853 } 2854 /* FIXME: do we need this for all Realtek codec models? */ 2855 codec->spdif_status_reset = 1; 2856 } 2857 2858 /* If the use of more than one ADC is requested for the current 2859 * model, configure a second analog capture-only PCM. 2860 */ 2861 /* Additional Analaog capture for index #2 */ 2862 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) || 2863 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) { 2864 codec->num_pcms = 3; 2865 info = spec->pcm_rec + 2; 2866 info->name = spec->stream_name_analog; 2867 if (spec->alt_dac_nid) { 2868 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = 2869 *spec->stream_analog_alt_playback; 2870 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 2871 spec->alt_dac_nid; 2872 } else { 2873 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = 2874 alc_pcm_null_stream; 2875 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0; 2876 } 2877 if (spec->num_adc_nids > 1) { 2878 info->stream[SNDRV_PCM_STREAM_CAPTURE] = 2879 *spec->stream_analog_alt_capture; 2880 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 2881 spec->adc_nids[1]; 2882 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = 2883 spec->num_adc_nids - 1; 2884 } else { 2885 info->stream[SNDRV_PCM_STREAM_CAPTURE] = 2886 alc_pcm_null_stream; 2887 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0; 2888 } 2889 } 2890 2891 return 0; 2892} 2893 2894static void alc_free_kctls(struct hda_codec *codec) 2895{ 2896 struct alc_spec *spec = codec->spec; 2897 2898 if (spec->kctls.list) { 2899 struct snd_kcontrol_new *kctl = spec->kctls.list; 2900 int i; 2901 for (i = 0; i < spec->kctls.used; i++) 2902 kfree(kctl[i].name); 2903 } 2904 snd_array_free(&spec->kctls); 2905} 2906 2907static void alc_free(struct hda_codec *codec) 2908{ 2909 struct alc_spec *spec = codec->spec; 2910 2911 if (!spec) 2912 return; 2913 2914 alc_free_kctls(codec); 2915 kfree(spec); 2916 codec->spec = NULL; /* to be sure */ 2917} 2918 2919#ifdef SND_HDA_NEEDS_RESUME 2920static void store_pin_configs(struct hda_codec *codec) 2921{ 2922 struct alc_spec *spec = codec->spec; 2923 hda_nid_t nid, end_nid; 2924 2925 end_nid = codec->start_nid + codec->num_nodes; 2926 for (nid = codec->start_nid; nid < end_nid; nid++) { 2927 unsigned int wid_caps = get_wcaps(codec, nid); 2928 unsigned int wid_type = 2929 (wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; 2930 if (wid_type != AC_WID_PIN) 2931 continue; 2932 if (spec->num_pins >= ARRAY_SIZE(spec->pin_nids)) 2933 break; 2934 spec->pin_nids[spec->num_pins] = nid; 2935 spec->pin_cfgs[spec->num_pins] = 2936 snd_hda_codec_read(codec, nid, 0, 2937 AC_VERB_GET_CONFIG_DEFAULT, 0); 2938 spec->num_pins++; 2939 } 2940} 2941 2942static void resume_pin_configs(struct hda_codec *codec) 2943{ 2944 struct alc_spec *spec = codec->spec; 2945 int i; 2946 2947 for (i = 0; i < spec->num_pins; i++) { 2948 hda_nid_t pin_nid = spec->pin_nids[i]; 2949 unsigned int pin_config = spec->pin_cfgs[i]; 2950 snd_hda_codec_write(codec, pin_nid, 0, 2951 AC_VERB_SET_CONFIG_DEFAULT_BYTES_0, 2952 pin_config & 0x000000ff); 2953 snd_hda_codec_write(codec, pin_nid, 0, 2954 AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 2955 (pin_config & 0x0000ff00) >> 8); 2956 snd_hda_codec_write(codec, pin_nid, 0, 2957 AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 2958 (pin_config & 0x00ff0000) >> 16); 2959 snd_hda_codec_write(codec, pin_nid, 0, 2960 AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 2961 pin_config >> 24); 2962 } 2963} 2964 2965static int alc_resume(struct hda_codec *codec) 2966{ 2967 resume_pin_configs(codec); 2968 codec->patch_ops.init(codec); 2969 snd_hda_codec_resume_amp(codec); 2970 snd_hda_codec_resume_cache(codec); 2971 return 0; 2972} 2973#else 2974#define store_pin_configs(codec) 2975#endif 2976 2977/* 2978 */ 2979static struct hda_codec_ops alc_patch_ops = { 2980 .build_controls = alc_build_controls, 2981 .build_pcms = alc_build_pcms, 2982 .init = alc_init, 2983 .free = alc_free, 2984 .unsol_event = alc_unsol_event, 2985#ifdef SND_HDA_NEEDS_RESUME 2986 .resume = alc_resume, 2987#endif 2988#ifdef CONFIG_SND_HDA_POWER_SAVE 2989 .check_power_status = alc_check_power_status, 2990#endif 2991}; 2992 2993 2994/* 2995 * Test configuration for debugging 2996 * 2997 * Almost all inputs/outputs are enabled. I/O pins can be configured via 2998 * enum controls. 2999 */ 3000#ifdef CONFIG_SND_DEBUG 3001static hda_nid_t alc880_test_dac_nids[4] = { 3002 0x02, 0x03, 0x04, 0x05 3003}; 3004 3005static struct hda_input_mux alc880_test_capture_source = { 3006 .num_items = 7, 3007 .items = { 3008 { "In-1", 0x0 }, 3009 { "In-2", 0x1 }, 3010 { "In-3", 0x2 }, 3011 { "In-4", 0x3 }, 3012 { "CD", 0x4 }, 3013 { "Front", 0x5 }, 3014 { "Surround", 0x6 }, 3015 }, 3016}; 3017 3018static struct hda_channel_mode alc880_test_modes[4] = { 3019 { 2, NULL }, 3020 { 4, NULL }, 3021 { 6, NULL }, 3022 { 8, NULL }, 3023}; 3024 3025static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol, 3026 struct snd_ctl_elem_info *uinfo) 3027{ 3028 static char *texts[] = { 3029 "N/A", "Line Out", "HP Out", 3030 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%" 3031 }; 3032 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 3033 uinfo->count = 1; 3034 uinfo->value.enumerated.items = 8; 3035 if (uinfo->value.enumerated.item >= 8) 3036 uinfo->value.enumerated.item = 7; 3037 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); 3038 return 0; 3039} 3040 3041static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol, 3042 struct snd_ctl_elem_value *ucontrol) 3043{ 3044 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 3045 hda_nid_t nid = (hda_nid_t)kcontrol->private_value; 3046 unsigned int pin_ctl, item = 0; 3047 3048 pin_ctl = snd_hda_codec_read(codec, nid, 0, 3049 AC_VERB_GET_PIN_WIDGET_CONTROL, 0); 3050 if (pin_ctl & AC_PINCTL_OUT_EN) { 3051 if (pin_ctl & AC_PINCTL_HP_EN) 3052 item = 2; 3053 else 3054 item = 1; 3055 } else if (pin_ctl & AC_PINCTL_IN_EN) { 3056 switch (pin_ctl & AC_PINCTL_VREFEN) { 3057 case AC_PINCTL_VREF_HIZ: item = 3; break; 3058 case AC_PINCTL_VREF_50: item = 4; break; 3059 case AC_PINCTL_VREF_GRD: item = 5; break; 3060 case AC_PINCTL_VREF_80: item = 6; break; 3061 case AC_PINCTL_VREF_100: item = 7; break; 3062 } 3063 } 3064 ucontrol->value.enumerated.item[0] = item; 3065 return 0; 3066} 3067 3068static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol, 3069 struct snd_ctl_elem_value *ucontrol) 3070{ 3071 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 3072 hda_nid_t nid = (hda_nid_t)kcontrol->private_value; 3073 static unsigned int ctls[] = { 3074 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN, 3075 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ, 3076 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50, 3077 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD, 3078 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80, 3079 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100, 3080 }; 3081 unsigned int old_ctl, new_ctl; 3082 3083 old_ctl = snd_hda_codec_read(codec, nid, 0, 3084 AC_VERB_GET_PIN_WIDGET_CONTROL, 0); 3085 new_ctl = ctls[ucontrol->value.enumerated.item[0]]; 3086 if (old_ctl != new_ctl) { 3087 int val; 3088 snd_hda_codec_write_cache(codec, nid, 0, 3089 AC_VERB_SET_PIN_WIDGET_CONTROL, 3090 new_ctl); 3091 val = ucontrol->value.enumerated.item[0] >= 3 ? 3092 HDA_AMP_MUTE : 0; 3093 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, 3094 HDA_AMP_MUTE, val); 3095 return 1; 3096 } 3097 return 0; 3098} 3099 3100static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol, 3101 struct snd_ctl_elem_info *uinfo) 3102{ 3103 static char *texts[] = { 3104 "Front", "Surround", "CLFE", "Side" 3105 }; 3106 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 3107 uinfo->count = 1; 3108 uinfo->value.enumerated.items = 4; 3109 if (uinfo->value.enumerated.item >= 4) 3110 uinfo->value.enumerated.item = 3; 3111 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); 3112 return 0; 3113} 3114 3115static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol, 3116 struct snd_ctl_elem_value *ucontrol) 3117{ 3118 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 3119 hda_nid_t nid = (hda_nid_t)kcontrol->private_value; 3120 unsigned int sel; 3121 3122 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0); 3123 ucontrol->value.enumerated.item[0] = sel & 3; 3124 return 0; 3125} 3126 3127static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol, 3128 struct snd_ctl_elem_value *ucontrol) 3129{ 3130 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 3131 hda_nid_t nid = (hda_nid_t)kcontrol->private_value; 3132 unsigned int sel; 3133 3134 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3; 3135 if (ucontrol->value.enumerated.item[0] != sel) { 3136 sel = ucontrol->value.enumerated.item[0] & 3; 3137 snd_hda_codec_write_cache(codec, nid, 0, 3138 AC_VERB_SET_CONNECT_SEL, sel); 3139 return 1; 3140 } 3141 return 0; 3142} 3143 3144#define PIN_CTL_TEST(xname,nid) { \ 3145 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 3146 .name = xname, \ 3147 .info = alc_test_pin_ctl_info, \ 3148 .get = alc_test_pin_ctl_get, \ 3149 .put = alc_test_pin_ctl_put, \ 3150 .private_value = nid \ 3151 } 3152 3153#define PIN_SRC_TEST(xname,nid) { \ 3154 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 3155 .name = xname, \ 3156 .info = alc_test_pin_src_info, \ 3157 .get = alc_test_pin_src_get, \ 3158 .put = alc_test_pin_src_put, \ 3159 .private_value = nid \ 3160 } 3161 3162static struct snd_kcontrol_new alc880_test_mixer[] = { 3163 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 3164 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 3165 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT), 3166 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 3167 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 3168 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 3169 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT), 3170 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 3171 PIN_CTL_TEST("Front Pin Mode", 0x14), 3172 PIN_CTL_TEST("Surround Pin Mode", 0x15), 3173 PIN_CTL_TEST("CLFE Pin Mode", 0x16), 3174 PIN_CTL_TEST("Side Pin Mode", 0x17), 3175 PIN_CTL_TEST("In-1 Pin Mode", 0x18), 3176 PIN_CTL_TEST("In-2 Pin Mode", 0x19), 3177 PIN_CTL_TEST("In-3 Pin Mode", 0x1a), 3178 PIN_CTL_TEST("In-4 Pin Mode", 0x1b), 3179 PIN_SRC_TEST("In-1 Pin Source", 0x18), 3180 PIN_SRC_TEST("In-2 Pin Source", 0x19), 3181 PIN_SRC_TEST("In-3 Pin Source", 0x1a), 3182 PIN_SRC_TEST("In-4 Pin Source", 0x1b), 3183 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT), 3184 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT), 3185 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT), 3186 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT), 3187 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT), 3188 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT), 3189 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT), 3190 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT), 3191 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT), 3192 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT), 3193 { 3194 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 3195 .name = "Channel Mode", 3196 .info = alc_ch_mode_info, 3197 .get = alc_ch_mode_get, 3198 .put = alc_ch_mode_put, 3199 }, 3200 { } /* end */ 3201}; 3202 3203static struct hda_verb alc880_test_init_verbs[] = { 3204 /* Unmute inputs of 0x0c - 0x0f */ 3205 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3206 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 3207 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3208 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 3209 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3210 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 3211 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3212 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 3213 /* Vol output for 0x0c-0x0f */ 3214 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3215 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3216 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3217 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3218 /* Set output pins 0x14-0x17 */ 3219 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3220 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3221 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3222 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3223 /* Unmute output pins 0x14-0x17 */ 3224 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3225 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3226 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3227 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3228 /* Set input pins 0x18-0x1c */ 3229 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3230 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3231 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3232 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3233 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3234 /* Mute input pins 0x18-0x1b */ 3235 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3236 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3237 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3238 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3239 /* ADC set up */ 3240 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3241 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 3242 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3243 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 3244 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3245 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 3246 /* Analog input/passthru */ 3247 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3248 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 3249 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 3250 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 3251 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 3252 { } 3253}; 3254#endif 3255 3256/* 3257 */ 3258 3259static const char *alc880_models[ALC880_MODEL_LAST] = { 3260 [ALC880_3ST] = "3stack", 3261 [ALC880_TCL_S700] = "tcl", 3262 [ALC880_3ST_DIG] = "3stack-digout", 3263 [ALC880_CLEVO] = "clevo", 3264 [ALC880_5ST] = "5stack", 3265 [ALC880_5ST_DIG] = "5stack-digout", 3266 [ALC880_W810] = "w810", 3267 [ALC880_Z71V] = "z71v", 3268 [ALC880_6ST] = "6stack", 3269 [ALC880_6ST_DIG] = "6stack-digout", 3270 [ALC880_ASUS] = "asus", 3271 [ALC880_ASUS_W1V] = "asus-w1v", 3272 [ALC880_ASUS_DIG] = "asus-dig", 3273 [ALC880_ASUS_DIG2] = "asus-dig2", 3274 [ALC880_UNIWILL_DIG] = "uniwill", 3275 [ALC880_UNIWILL_P53] = "uniwill-p53", 3276 [ALC880_FUJITSU] = "fujitsu", 3277 [ALC880_F1734] = "F1734", 3278 [ALC880_LG] = "lg", 3279 [ALC880_LG_LW] = "lg-lw", 3280 [ALC880_MEDION_RIM] = "medion", 3281#ifdef CONFIG_SND_DEBUG 3282 [ALC880_TEST] = "test", 3283#endif 3284 [ALC880_AUTO] = "auto", 3285}; 3286 3287static struct snd_pci_quirk alc880_cfg_tbl[] = { 3288 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810), 3289 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG), 3290 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST), 3291 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG), 3292 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG), 3293 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG), 3294 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG), 3295 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG), 3296 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST), 3297 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG), 3298 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST), 3299 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V), 3300 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG), 3301 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG), 3302 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG), 3303 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG), 3304 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG), 3305 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V), 3306 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */ 3307 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG), 3308 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG), 3309 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG), 3310 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG), 3311 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST), 3312 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST), 3313 SND_PCI_QUIRK(0x1043, 0, "ASUS", ALC880_ASUS), /* default ASUS */ 3314 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST), 3315 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST), 3316 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST), 3317 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST), 3318 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST), 3319 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG), 3320 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG), 3321 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG), 3322 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG), 3323 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO), 3324 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO), 3325 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2), 3326 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG), 3327 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG), 3328 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734), 3329 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL), 3330 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53), 3331 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810), 3332 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM), 3333 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG), 3334 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG), 3335 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734), 3336 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU), 3337 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL), 3338 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU), 3339 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW), 3340 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG), 3341 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG), 3342 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW), 3343 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700), 3344 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */ 3345 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG), 3346 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG), 3347 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG), 3348 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG), 3349 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG), 3350 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG), 3351 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG), 3352 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG), 3353 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG), 3354 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG), 3355 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG), 3356 SND_PCI_QUIRK(0x8086, 0, "Intel mobo", ALC880_3ST), /* default Intel */ 3357 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG), 3358 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG), 3359 {} 3360}; 3361 3362/* 3363 * ALC880 codec presets 3364 */ 3365static struct alc_config_preset alc880_presets[] = { 3366 [ALC880_3ST] = { 3367 .mixers = { alc880_three_stack_mixer }, 3368 .init_verbs = { alc880_volume_init_verbs, 3369 alc880_pin_3stack_init_verbs }, 3370 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 3371 .dac_nids = alc880_dac_nids, 3372 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), 3373 .channel_mode = alc880_threestack_modes, 3374 .need_dac_fix = 1, 3375 .input_mux = &alc880_capture_source, 3376 }, 3377 [ALC880_3ST_DIG] = { 3378 .mixers = { alc880_three_stack_mixer }, 3379 .init_verbs = { alc880_volume_init_verbs, 3380 alc880_pin_3stack_init_verbs }, 3381 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 3382 .dac_nids = alc880_dac_nids, 3383 .dig_out_nid = ALC880_DIGOUT_NID, 3384 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), 3385 .channel_mode = alc880_threestack_modes, 3386 .need_dac_fix = 1, 3387 .input_mux = &alc880_capture_source, 3388 }, 3389 [ALC880_TCL_S700] = { 3390 .mixers = { alc880_tcl_s700_mixer }, 3391 .init_verbs = { alc880_volume_init_verbs, 3392 alc880_pin_tcl_S700_init_verbs, 3393 alc880_gpio2_init_verbs }, 3394 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 3395 .dac_nids = alc880_dac_nids, 3396 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */ 3397 .num_adc_nids = 1, /* single ADC */ 3398 .hp_nid = 0x03, 3399 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), 3400 .channel_mode = alc880_2_jack_modes, 3401 .input_mux = &alc880_capture_source, 3402 }, 3403 [ALC880_5ST] = { 3404 .mixers = { alc880_three_stack_mixer, 3405 alc880_five_stack_mixer}, 3406 .init_verbs = { alc880_volume_init_verbs, 3407 alc880_pin_5stack_init_verbs }, 3408 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 3409 .dac_nids = alc880_dac_nids, 3410 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes), 3411 .channel_mode = alc880_fivestack_modes, 3412 .input_mux = &alc880_capture_source, 3413 }, 3414 [ALC880_5ST_DIG] = { 3415 .mixers = { alc880_three_stack_mixer, 3416 alc880_five_stack_mixer }, 3417 .init_verbs = { alc880_volume_init_verbs, 3418 alc880_pin_5stack_init_verbs }, 3419 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 3420 .dac_nids = alc880_dac_nids, 3421 .dig_out_nid = ALC880_DIGOUT_NID, 3422 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes), 3423 .channel_mode = alc880_fivestack_modes, 3424 .input_mux = &alc880_capture_source, 3425 }, 3426 [ALC880_6ST] = { 3427 .mixers = { alc880_six_stack_mixer }, 3428 .init_verbs = { alc880_volume_init_verbs, 3429 alc880_pin_6stack_init_verbs }, 3430 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids), 3431 .dac_nids = alc880_6st_dac_nids, 3432 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes), 3433 .channel_mode = alc880_sixstack_modes, 3434 .input_mux = &alc880_6stack_capture_source, 3435 }, 3436 [ALC880_6ST_DIG] = { 3437 .mixers = { alc880_six_stack_mixer }, 3438 .init_verbs = { alc880_volume_init_verbs, 3439 alc880_pin_6stack_init_verbs }, 3440 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids), 3441 .dac_nids = alc880_6st_dac_nids, 3442 .dig_out_nid = ALC880_DIGOUT_NID, 3443 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes), 3444 .channel_mode = alc880_sixstack_modes, 3445 .input_mux = &alc880_6stack_capture_source, 3446 }, 3447 [ALC880_W810] = { 3448 .mixers = { alc880_w810_base_mixer }, 3449 .init_verbs = { alc880_volume_init_verbs, 3450 alc880_pin_w810_init_verbs, 3451 alc880_gpio2_init_verbs }, 3452 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids), 3453 .dac_nids = alc880_w810_dac_nids, 3454 .dig_out_nid = ALC880_DIGOUT_NID, 3455 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes), 3456 .channel_mode = alc880_w810_modes, 3457 .input_mux = &alc880_capture_source, 3458 }, 3459 [ALC880_Z71V] = { 3460 .mixers = { alc880_z71v_mixer }, 3461 .init_verbs = { alc880_volume_init_verbs, 3462 alc880_pin_z71v_init_verbs }, 3463 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids), 3464 .dac_nids = alc880_z71v_dac_nids, 3465 .dig_out_nid = ALC880_DIGOUT_NID, 3466 .hp_nid = 0x03, 3467 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), 3468 .channel_mode = alc880_2_jack_modes, 3469 .input_mux = &alc880_capture_source, 3470 }, 3471 [ALC880_F1734] = { 3472 .mixers = { alc880_f1734_mixer }, 3473 .init_verbs = { alc880_volume_init_verbs, 3474 alc880_pin_f1734_init_verbs }, 3475 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids), 3476 .dac_nids = alc880_f1734_dac_nids, 3477 .hp_nid = 0x02, 3478 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), 3479 .channel_mode = alc880_2_jack_modes, 3480 .input_mux = &alc880_f1734_capture_source, 3481 .unsol_event = alc880_uniwill_p53_unsol_event, 3482 .init_hook = alc880_uniwill_p53_hp_automute, 3483 }, 3484 [ALC880_ASUS] = { 3485 .mixers = { alc880_asus_mixer }, 3486 .init_verbs = { alc880_volume_init_verbs, 3487 alc880_pin_asus_init_verbs, 3488 alc880_gpio1_init_verbs }, 3489 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 3490 .dac_nids = alc880_asus_dac_nids, 3491 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), 3492 .channel_mode = alc880_asus_modes, 3493 .need_dac_fix = 1, 3494 .input_mux = &alc880_capture_source, 3495 }, 3496 [ALC880_ASUS_DIG] = { 3497 .mixers = { alc880_asus_mixer }, 3498 .init_verbs = { alc880_volume_init_verbs, 3499 alc880_pin_asus_init_verbs, 3500 alc880_gpio1_init_verbs }, 3501 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 3502 .dac_nids = alc880_asus_dac_nids, 3503 .dig_out_nid = ALC880_DIGOUT_NID, 3504 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), 3505 .channel_mode = alc880_asus_modes, 3506 .need_dac_fix = 1, 3507 .input_mux = &alc880_capture_source, 3508 }, 3509 [ALC880_ASUS_DIG2] = { 3510 .mixers = { alc880_asus_mixer }, 3511 .init_verbs = { alc880_volume_init_verbs, 3512 alc880_pin_asus_init_verbs, 3513 alc880_gpio2_init_verbs }, /* use GPIO2 */ 3514 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 3515 .dac_nids = alc880_asus_dac_nids, 3516 .dig_out_nid = ALC880_DIGOUT_NID, 3517 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), 3518 .channel_mode = alc880_asus_modes, 3519 .need_dac_fix = 1, 3520 .input_mux = &alc880_capture_source, 3521 }, 3522 [ALC880_ASUS_W1V] = { 3523 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer }, 3524 .init_verbs = { alc880_volume_init_verbs, 3525 alc880_pin_asus_init_verbs, 3526 alc880_gpio1_init_verbs }, 3527 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 3528 .dac_nids = alc880_asus_dac_nids, 3529 .dig_out_nid = ALC880_DIGOUT_NID, 3530 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), 3531 .channel_mode = alc880_asus_modes, 3532 .need_dac_fix = 1, 3533 .input_mux = &alc880_capture_source, 3534 }, 3535 [ALC880_UNIWILL_DIG] = { 3536 .mixers = { alc880_asus_mixer, alc880_pcbeep_mixer }, 3537 .init_verbs = { alc880_volume_init_verbs, 3538 alc880_pin_asus_init_verbs }, 3539 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 3540 .dac_nids = alc880_asus_dac_nids, 3541 .dig_out_nid = ALC880_DIGOUT_NID, 3542 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), 3543 .channel_mode = alc880_asus_modes, 3544 .need_dac_fix = 1, 3545 .input_mux = &alc880_capture_source, 3546 }, 3547 [ALC880_UNIWILL] = { 3548 .mixers = { alc880_uniwill_mixer }, 3549 .init_verbs = { alc880_volume_init_verbs, 3550 alc880_uniwill_init_verbs }, 3551 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 3552 .dac_nids = alc880_asus_dac_nids, 3553 .dig_out_nid = ALC880_DIGOUT_NID, 3554 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), 3555 .channel_mode = alc880_threestack_modes, 3556 .need_dac_fix = 1, 3557 .input_mux = &alc880_capture_source, 3558 .unsol_event = alc880_uniwill_unsol_event, 3559 .init_hook = alc880_uniwill_automute, 3560 }, 3561 [ALC880_UNIWILL_P53] = { 3562 .mixers = { alc880_uniwill_p53_mixer }, 3563 .init_verbs = { alc880_volume_init_verbs, 3564 alc880_uniwill_p53_init_verbs }, 3565 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 3566 .dac_nids = alc880_asus_dac_nids, 3567 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes), 3568 .channel_mode = alc880_threestack_modes, 3569 .input_mux = &alc880_capture_source, 3570 .unsol_event = alc880_uniwill_p53_unsol_event, 3571 .init_hook = alc880_uniwill_p53_hp_automute, 3572 }, 3573 [ALC880_FUJITSU] = { 3574 .mixers = { alc880_fujitsu_mixer, 3575 alc880_pcbeep_mixer, }, 3576 .init_verbs = { alc880_volume_init_verbs, 3577 alc880_uniwill_p53_init_verbs, 3578 alc880_beep_init_verbs }, 3579 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 3580 .dac_nids = alc880_dac_nids, 3581 .dig_out_nid = ALC880_DIGOUT_NID, 3582 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), 3583 .channel_mode = alc880_2_jack_modes, 3584 .input_mux = &alc880_capture_source, 3585 .unsol_event = alc880_uniwill_p53_unsol_event, 3586 .init_hook = alc880_uniwill_p53_hp_automute, 3587 }, 3588 [ALC880_CLEVO] = { 3589 .mixers = { alc880_three_stack_mixer }, 3590 .init_verbs = { alc880_volume_init_verbs, 3591 alc880_pin_clevo_init_verbs }, 3592 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 3593 .dac_nids = alc880_dac_nids, 3594 .hp_nid = 0x03, 3595 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), 3596 .channel_mode = alc880_threestack_modes, 3597 .need_dac_fix = 1, 3598 .input_mux = &alc880_capture_source, 3599 }, 3600 [ALC880_LG] = { 3601 .mixers = { alc880_lg_mixer }, 3602 .init_verbs = { alc880_volume_init_verbs, 3603 alc880_lg_init_verbs }, 3604 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids), 3605 .dac_nids = alc880_lg_dac_nids, 3606 .dig_out_nid = ALC880_DIGOUT_NID, 3607 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes), 3608 .channel_mode = alc880_lg_ch_modes, 3609 .need_dac_fix = 1, 3610 .input_mux = &alc880_lg_capture_source, 3611 .unsol_event = alc880_lg_unsol_event, 3612 .init_hook = alc880_lg_automute, 3613#ifdef CONFIG_SND_HDA_POWER_SAVE 3614 .loopbacks = alc880_lg_loopbacks, 3615#endif 3616 }, 3617 [ALC880_LG_LW] = { 3618 .mixers = { alc880_lg_lw_mixer }, 3619 .init_verbs = { alc880_volume_init_verbs, 3620 alc880_lg_lw_init_verbs }, 3621 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 3622 .dac_nids = alc880_dac_nids, 3623 .dig_out_nid = ALC880_DIGOUT_NID, 3624 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes), 3625 .channel_mode = alc880_lg_lw_modes, 3626 .input_mux = &alc880_lg_lw_capture_source, 3627 .unsol_event = alc880_lg_lw_unsol_event, 3628 .init_hook = alc880_lg_lw_automute, 3629 }, 3630 [ALC880_MEDION_RIM] = { 3631 .mixers = { alc880_medion_rim_mixer }, 3632 .init_verbs = { alc880_volume_init_verbs, 3633 alc880_medion_rim_init_verbs, 3634 alc_gpio2_init_verbs }, 3635 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 3636 .dac_nids = alc880_dac_nids, 3637 .dig_out_nid = ALC880_DIGOUT_NID, 3638 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), 3639 .channel_mode = alc880_2_jack_modes, 3640 .input_mux = &alc880_medion_rim_capture_source, 3641 .unsol_event = alc880_medion_rim_unsol_event, 3642 .init_hook = alc880_medion_rim_automute, 3643 }, 3644#ifdef CONFIG_SND_DEBUG 3645 [ALC880_TEST] = { 3646 .mixers = { alc880_test_mixer }, 3647 .init_verbs = { alc880_test_init_verbs }, 3648 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids), 3649 .dac_nids = alc880_test_dac_nids, 3650 .dig_out_nid = ALC880_DIGOUT_NID, 3651 .num_channel_mode = ARRAY_SIZE(alc880_test_modes), 3652 .channel_mode = alc880_test_modes, 3653 .input_mux = &alc880_test_capture_source, 3654 }, 3655#endif 3656}; 3657 3658/* 3659 * Automatic parse of I/O pins from the BIOS configuration 3660 */ 3661 3662enum { 3663 ALC_CTL_WIDGET_VOL, 3664 ALC_CTL_WIDGET_MUTE, 3665 ALC_CTL_BIND_MUTE, 3666}; 3667static struct snd_kcontrol_new alc880_control_templates[] = { 3668 HDA_CODEC_VOLUME(NULL, 0, 0, 0), 3669 HDA_CODEC_MUTE(NULL, 0, 0, 0), 3670 HDA_BIND_MUTE(NULL, 0, 0, 0), 3671}; 3672 3673/* add dynamic controls */ 3674static int add_control(struct alc_spec *spec, int type, const char *name, 3675 unsigned long val) 3676{ 3677 struct snd_kcontrol_new *knew; 3678 3679 snd_array_init(&spec->kctls, sizeof(*knew), 32); 3680 knew = snd_array_new(&spec->kctls); 3681 if (!knew) 3682 return -ENOMEM; 3683 *knew = alc880_control_templates[type]; 3684 knew->name = kstrdup(name, GFP_KERNEL); 3685 if (!knew->name) 3686 return -ENOMEM; 3687 knew->private_value = val; 3688 return 0; 3689} 3690 3691#define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17) 3692#define alc880_fixed_pin_idx(nid) ((nid) - 0x14) 3693#define alc880_is_multi_pin(nid) ((nid) >= 0x18) 3694#define alc880_multi_pin_idx(nid) ((nid) - 0x18) 3695#define alc880_is_input_pin(nid) ((nid) >= 0x18) 3696#define alc880_input_pin_idx(nid) ((nid) - 0x18) 3697#define alc880_idx_to_dac(nid) ((nid) + 0x02) 3698#define alc880_dac_to_idx(nid) ((nid) - 0x02) 3699#define alc880_idx_to_mixer(nid) ((nid) + 0x0c) 3700#define alc880_idx_to_selector(nid) ((nid) + 0x10) 3701#define ALC880_PIN_CD_NID 0x1c 3702 3703/* fill in the dac_nids table from the parsed pin configuration */ 3704static int alc880_auto_fill_dac_nids(struct alc_spec *spec, 3705 const struct auto_pin_cfg *cfg) 3706{ 3707 hda_nid_t nid; 3708 int assigned[4]; 3709 int i, j; 3710 3711 memset(assigned, 0, sizeof(assigned)); 3712 spec->multiout.dac_nids = spec->private_dac_nids; 3713 3714 /* check the pins hardwired to audio widget */ 3715 for (i = 0; i < cfg->line_outs; i++) { 3716 nid = cfg->line_out_pins[i]; 3717 if (alc880_is_fixed_pin(nid)) { 3718 int idx = alc880_fixed_pin_idx(nid); 3719 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx); 3720 assigned[idx] = 1; 3721 } 3722 } 3723 /* left pins can be connect to any audio widget */ 3724 for (i = 0; i < cfg->line_outs; i++) { 3725 nid = cfg->line_out_pins[i]; 3726 if (alc880_is_fixed_pin(nid)) 3727 continue; 3728 /* search for an empty channel */ 3729 for (j = 0; j < cfg->line_outs; j++) { 3730 if (!assigned[j]) { 3731 spec->multiout.dac_nids[i] = 3732 alc880_idx_to_dac(j); 3733 assigned[j] = 1; 3734 break; 3735 } 3736 } 3737 } 3738 spec->multiout.num_dacs = cfg->line_outs; 3739 return 0; 3740} 3741 3742/* add playback controls from the parsed DAC table */ 3743static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec, 3744 const struct auto_pin_cfg *cfg) 3745{ 3746 char name[32]; 3747 static const char *chname[4] = { 3748 "Front", "Surround", NULL /*CLFE*/, "Side" 3749 }; 3750 hda_nid_t nid; 3751 int i, err; 3752 3753 for (i = 0; i < cfg->line_outs; i++) { 3754 if (!spec->multiout.dac_nids[i]) 3755 continue; 3756 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i])); 3757 if (i == 2) { 3758 /* Center/LFE */ 3759 err = add_control(spec, ALC_CTL_WIDGET_VOL, 3760 "Center Playback Volume", 3761 HDA_COMPOSE_AMP_VAL(nid, 1, 0, 3762 HDA_OUTPUT)); 3763 if (err < 0) 3764 return err; 3765 err = add_control(spec, ALC_CTL_WIDGET_VOL, 3766 "LFE Playback Volume", 3767 HDA_COMPOSE_AMP_VAL(nid, 2, 0, 3768 HDA_OUTPUT)); 3769 if (err < 0) 3770 return err; 3771 err = add_control(spec, ALC_CTL_BIND_MUTE, 3772 "Center Playback Switch", 3773 HDA_COMPOSE_AMP_VAL(nid, 1, 2, 3774 HDA_INPUT)); 3775 if (err < 0) 3776 return err; 3777 err = add_control(spec, ALC_CTL_BIND_MUTE, 3778 "LFE Playback Switch", 3779 HDA_COMPOSE_AMP_VAL(nid, 2, 2, 3780 HDA_INPUT)); 3781 if (err < 0) 3782 return err; 3783 } else { 3784 sprintf(name, "%s Playback Volume", chname[i]); 3785 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, 3786 HDA_COMPOSE_AMP_VAL(nid, 3, 0, 3787 HDA_OUTPUT)); 3788 if (err < 0) 3789 return err; 3790 sprintf(name, "%s Playback Switch", chname[i]); 3791 err = add_control(spec, ALC_CTL_BIND_MUTE, name, 3792 HDA_COMPOSE_AMP_VAL(nid, 3, 2, 3793 HDA_INPUT)); 3794 if (err < 0) 3795 return err; 3796 } 3797 } 3798 return 0; 3799} 3800 3801/* add playback controls for speaker and HP outputs */ 3802static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin, 3803 const char *pfx) 3804{ 3805 hda_nid_t nid; 3806 int err; 3807 char name[32]; 3808 3809 if (!pin) 3810 return 0; 3811 3812 if (alc880_is_fixed_pin(pin)) { 3813 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); 3814 /* specify the DAC as the extra output */ 3815 if (!spec->multiout.hp_nid) 3816 spec->multiout.hp_nid = nid; 3817 else 3818 spec->multiout.extra_out_nid[0] = nid; 3819 /* control HP volume/switch on the output mixer amp */ 3820 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin)); 3821 sprintf(name, "%s Playback Volume", pfx); 3822 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, 3823 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); 3824 if (err < 0) 3825 return err; 3826 sprintf(name, "%s Playback Switch", pfx); 3827 err = add_control(spec, ALC_CTL_BIND_MUTE, name, 3828 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT)); 3829 if (err < 0) 3830 return err; 3831 } else if (alc880_is_multi_pin(pin)) { 3832 /* set manual connection */ 3833 /* we have only a switch on HP-out PIN */ 3834 sprintf(name, "%s Playback Switch", pfx); 3835 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, 3836 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); 3837 if (err < 0) 3838 return err; 3839 } 3840 return 0; 3841} 3842 3843/* create input playback/capture controls for the given pin */ 3844static int new_analog_input(struct alc_spec *spec, hda_nid_t pin, 3845 const char *ctlname, 3846 int idx, hda_nid_t mix_nid) 3847{ 3848 char name[32]; 3849 int err; 3850 3851 sprintf(name, "%s Playback Volume", ctlname); 3852 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, 3853 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT)); 3854 if (err < 0) 3855 return err; 3856 sprintf(name, "%s Playback Switch", ctlname); 3857 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, 3858 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT)); 3859 if (err < 0) 3860 return err; 3861 return 0; 3862} 3863 3864/* create playback/capture controls for input pins */ 3865static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec, 3866 const struct auto_pin_cfg *cfg) 3867{ 3868 struct hda_input_mux *imux = &spec->private_imux; 3869 int i, err, idx; 3870 3871 for (i = 0; i < AUTO_PIN_LAST; i++) { 3872 if (alc880_is_input_pin(cfg->input_pins[i])) { 3873 idx = alc880_input_pin_idx(cfg->input_pins[i]); 3874 err = new_analog_input(spec, cfg->input_pins[i], 3875 auto_pin_cfg_labels[i], 3876 idx, 0x0b); 3877 if (err < 0) 3878 return err; 3879 imux->items[imux->num_items].label = 3880 auto_pin_cfg_labels[i]; 3881 imux->items[imux->num_items].index = 3882 alc880_input_pin_idx(cfg->input_pins[i]); 3883 imux->num_items++; 3884 } 3885 } 3886 return 0; 3887} 3888 3889static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid, 3890 unsigned int pin_type) 3891{ 3892 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 3893 pin_type); 3894 /* unmute pin */ 3895 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, 3896 AMP_OUT_UNMUTE); 3897} 3898 3899static void alc880_auto_set_output_and_unmute(struct hda_codec *codec, 3900 hda_nid_t nid, int pin_type, 3901 int dac_idx) 3902{ 3903 alc_set_pin_output(codec, nid, pin_type); 3904 /* need the manual connection? */ 3905 if (alc880_is_multi_pin(nid)) { 3906 struct alc_spec *spec = codec->spec; 3907 int idx = alc880_multi_pin_idx(nid); 3908 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0, 3909 AC_VERB_SET_CONNECT_SEL, 3910 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx])); 3911 } 3912} 3913 3914static int get_pin_type(int line_out_type) 3915{ 3916 if (line_out_type == AUTO_PIN_HP_OUT) 3917 return PIN_HP; 3918 else 3919 return PIN_OUT; 3920} 3921 3922static void alc880_auto_init_multi_out(struct hda_codec *codec) 3923{ 3924 struct alc_spec *spec = codec->spec; 3925 int i; 3926 3927 alc_subsystem_id(codec, 0x15, 0x1b, 0x14); 3928 for (i = 0; i < spec->autocfg.line_outs; i++) { 3929 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 3930 int pin_type = get_pin_type(spec->autocfg.line_out_type); 3931 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i); 3932 } 3933} 3934 3935static void alc880_auto_init_extra_out(struct hda_codec *codec) 3936{ 3937 struct alc_spec *spec = codec->spec; 3938 hda_nid_t pin; 3939 3940 pin = spec->autocfg.speaker_pins[0]; 3941 if (pin) /* connect to front */ 3942 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0); 3943 pin = spec->autocfg.hp_pins[0]; 3944 if (pin) /* connect to front */ 3945 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); 3946} 3947 3948static void alc880_auto_init_analog_input(struct hda_codec *codec) 3949{ 3950 struct alc_spec *spec = codec->spec; 3951 int i; 3952 3953 for (i = 0; i < AUTO_PIN_LAST; i++) { 3954 hda_nid_t nid = spec->autocfg.input_pins[i]; 3955 if (alc880_is_input_pin(nid)) { 3956 snd_hda_codec_write(codec, nid, 0, 3957 AC_VERB_SET_PIN_WIDGET_CONTROL, 3958 i <= AUTO_PIN_FRONT_MIC ? 3959 PIN_VREF80 : PIN_IN); 3960 if (nid != ALC880_PIN_CD_NID) 3961 snd_hda_codec_write(codec, nid, 0, 3962 AC_VERB_SET_AMP_GAIN_MUTE, 3963 AMP_OUT_MUTE); 3964 } 3965 } 3966} 3967 3968/* parse the BIOS configuration and set up the alc_spec */ 3969/* return 1 if successful, 0 if the proper config is not found, 3970 * or a negative error code 3971 */ 3972static int alc880_parse_auto_config(struct hda_codec *codec) 3973{ 3974 struct alc_spec *spec = codec->spec; 3975 int err; 3976 static hda_nid_t alc880_ignore[] = { 0x1d, 0 }; 3977 3978 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 3979 alc880_ignore); 3980 if (err < 0) 3981 return err; 3982 if (!spec->autocfg.line_outs) 3983 return 0; /* can't find valid BIOS pin config */ 3984 3985 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); 3986 if (err < 0) 3987 return err; 3988 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg); 3989 if (err < 0) 3990 return err; 3991 err = alc880_auto_create_extra_out(spec, 3992 spec->autocfg.speaker_pins[0], 3993 "Speaker"); 3994 if (err < 0) 3995 return err; 3996 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0], 3997 "Headphone"); 3998 if (err < 0) 3999 return err; 4000 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg); 4001 if (err < 0) 4002 return err; 4003 4004 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 4005 4006 if (spec->autocfg.dig_out_pin) 4007 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID; 4008 if (spec->autocfg.dig_in_pin) 4009 spec->dig_in_nid = ALC880_DIGIN_NID; 4010 4011 if (spec->kctls.list) 4012 add_mixer(spec, spec->kctls.list); 4013 4014 add_verb(spec, alc880_volume_init_verbs); 4015 4016 spec->num_mux_defs = 1; 4017 spec->input_mux = &spec->private_imux; 4018 4019 store_pin_configs(codec); 4020 return 1; 4021} 4022 4023/* additional initialization for auto-configuration model */ 4024static void alc880_auto_init(struct hda_codec *codec) 4025{ 4026 struct alc_spec *spec = codec->spec; 4027 alc880_auto_init_multi_out(codec); 4028 alc880_auto_init_extra_out(codec); 4029 alc880_auto_init_analog_input(codec); 4030 if (spec->unsol_event) 4031 alc_inithook(codec); 4032} 4033 4034/* 4035 * OK, here we have finally the patch for ALC880 4036 */ 4037 4038static void set_capture_mixer(struct alc_spec *spec) 4039{ 4040 static struct snd_kcontrol_new *caps[3] = { 4041 alc_capture_mixer1, 4042 alc_capture_mixer2, 4043 alc_capture_mixer3, 4044 }; 4045 if (spec->num_adc_nids > 0 && spec->num_adc_nids < 3) 4046 spec->cap_mixer = caps[spec->num_adc_nids - 1]; 4047} 4048 4049static int patch_alc880(struct hda_codec *codec) 4050{ 4051 struct alc_spec *spec; 4052 int board_config; 4053 int err; 4054 4055 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 4056 if (spec == NULL) 4057 return -ENOMEM; 4058 4059 codec->spec = spec; 4060 4061 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST, 4062 alc880_models, 4063 alc880_cfg_tbl); 4064 if (board_config < 0) { 4065 printk(KERN_INFO "hda_codec: Unknown model for ALC880, " 4066 "trying auto-probe from BIOS...\n"); 4067 board_config = ALC880_AUTO; 4068 } 4069 4070 if (board_config == ALC880_AUTO) { 4071 /* automatic parse from the BIOS config */ 4072 err = alc880_parse_auto_config(codec); 4073 if (err < 0) { 4074 alc_free(codec); 4075 return err; 4076 } else if (!err) { 4077 printk(KERN_INFO 4078 "hda_codec: Cannot set up configuration " 4079 "from BIOS. Using 3-stack mode...\n"); 4080 board_config = ALC880_3ST; 4081 } 4082 } 4083 4084 if (board_config != ALC880_AUTO) 4085 setup_preset(spec, &alc880_presets[board_config]); 4086 4087 spec->stream_name_analog = "ALC880 Analog"; 4088 spec->stream_analog_playback = &alc880_pcm_analog_playback; 4089 spec->stream_analog_capture = &alc880_pcm_analog_capture; 4090 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture; 4091 4092 spec->stream_name_digital = "ALC880 Digital"; 4093 spec->stream_digital_playback = &alc880_pcm_digital_playback; 4094 spec->stream_digital_capture = &alc880_pcm_digital_capture; 4095 4096 if (!spec->adc_nids && spec->input_mux) { 4097 /* check whether NID 0x07 is valid */ 4098 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]); 4099 /* get type */ 4100 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; 4101 if (wcap != AC_WID_AUD_IN) { 4102 spec->adc_nids = alc880_adc_nids_alt; 4103 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt); 4104 } else { 4105 spec->adc_nids = alc880_adc_nids; 4106 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids); 4107 } 4108 } 4109 set_capture_mixer(spec); 4110 4111 spec->vmaster_nid = 0x0c; 4112 4113 codec->patch_ops = alc_patch_ops; 4114 if (board_config == ALC880_AUTO) 4115 spec->init_hook = alc880_auto_init; 4116#ifdef CONFIG_SND_HDA_POWER_SAVE 4117 if (!spec->loopback.amplist) 4118 spec->loopback.amplist = alc880_loopbacks; 4119#endif 4120 4121 return 0; 4122} 4123 4124 4125/* 4126 * ALC260 support 4127 */ 4128 4129static hda_nid_t alc260_dac_nids[1] = { 4130 /* front */ 4131 0x02, 4132}; 4133 4134static hda_nid_t alc260_adc_nids[1] = { 4135 /* ADC0 */ 4136 0x04, 4137}; 4138 4139static hda_nid_t alc260_adc_nids_alt[1] = { 4140 /* ADC1 */ 4141 0x05, 4142}; 4143 4144/* NIDs used when simultaneous access to both ADCs makes sense. Note that 4145 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC. 4146 */ 4147static hda_nid_t alc260_dual_adc_nids[2] = { 4148 /* ADC0, ADC1 */ 4149 0x04, 0x05 4150}; 4151 4152#define ALC260_DIGOUT_NID 0x03 4153#define ALC260_DIGIN_NID 0x06 4154 4155static struct hda_input_mux alc260_capture_source = { 4156 .num_items = 4, 4157 .items = { 4158 { "Mic", 0x0 }, 4159 { "Front Mic", 0x1 }, 4160 { "Line", 0x2 }, 4161 { "CD", 0x4 }, 4162 }, 4163}; 4164 4165/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack, 4166 * headphone jack and the internal CD lines since these are the only pins at 4167 * which audio can appear. For flexibility, also allow the option of 4168 * recording the mixer output on the second ADC (ADC0 doesn't have a 4169 * connection to the mixer output). 4170 */ 4171static struct hda_input_mux alc260_fujitsu_capture_sources[2] = { 4172 { 4173 .num_items = 3, 4174 .items = { 4175 { "Mic/Line", 0x0 }, 4176 { "CD", 0x4 }, 4177 { "Headphone", 0x2 }, 4178 }, 4179 }, 4180 { 4181 .num_items = 4, 4182 .items = { 4183 { "Mic/Line", 0x0 }, 4184 { "CD", 0x4 }, 4185 { "Headphone", 0x2 }, 4186 { "Mixer", 0x5 }, 4187 }, 4188 }, 4189 4190}; 4191 4192/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to 4193 * the Fujitsu S702x, but jacks are marked differently. 4194 */ 4195static struct hda_input_mux alc260_acer_capture_sources[2] = { 4196 { 4197 .num_items = 4, 4198 .items = { 4199 { "Mic", 0x0 }, 4200 { "Line", 0x2 }, 4201 { "CD", 0x4 }, 4202 { "Headphone", 0x5 }, 4203 }, 4204 }, 4205 { 4206 .num_items = 5, 4207 .items = { 4208 { "Mic", 0x0 }, 4209 { "Line", 0x2 }, 4210 { "CD", 0x4 }, 4211 { "Headphone", 0x6 }, 4212 { "Mixer", 0x5 }, 4213 }, 4214 }, 4215}; 4216/* 4217 * This is just place-holder, so there's something for alc_build_pcms to look 4218 * at when it calculates the maximum number of channels. ALC260 has no mixer 4219 * element which allows changing the channel mode, so the verb list is 4220 * never used. 4221 */ 4222static struct hda_channel_mode alc260_modes[1] = { 4223 { 2, NULL }, 4224}; 4225 4226 4227/* Mixer combinations 4228 * 4229 * basic: base_output + input + pc_beep + capture 4230 * HP: base_output + input + capture_alt 4231 * HP_3013: hp_3013 + input + capture 4232 * fujitsu: fujitsu + capture 4233 * acer: acer + capture 4234 */ 4235 4236static struct snd_kcontrol_new alc260_base_output_mixer[] = { 4237 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT), 4238 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT), 4239 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT), 4240 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT), 4241 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), 4242 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT), 4243 { } /* end */ 4244}; 4245 4246static struct snd_kcontrol_new alc260_input_mixer[] = { 4247 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), 4248 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), 4249 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), 4250 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT), 4251 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), 4252 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT), 4253 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT), 4254 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT), 4255 { } /* end */ 4256}; 4257 4258static struct snd_kcontrol_new alc260_pc_beep_mixer[] = { 4259 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT), 4260 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT), 4261 { } /* end */ 4262}; 4263 4264/* update HP, line and mono out pins according to the master switch */ 4265static void alc260_hp_master_update(struct hda_codec *codec, 4266 hda_nid_t hp, hda_nid_t line, 4267 hda_nid_t mono) 4268{ 4269 struct alc_spec *spec = codec->spec; 4270 unsigned int val = spec->master_sw ? PIN_HP : 0; 4271 /* change HP and line-out pins */ 4272 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 4273 val); 4274 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 4275 val); 4276 /* mono (speaker) depending on the HP jack sense */ 4277 val = (val && !spec->jack_present) ? PIN_OUT : 0; 4278 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 4279 val); 4280} 4281 4282static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol, 4283 struct snd_ctl_elem_value *ucontrol) 4284{ 4285 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 4286 struct alc_spec *spec = codec->spec; 4287 *ucontrol->value.integer.value = spec->master_sw; 4288 return 0; 4289} 4290 4291static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol, 4292 struct snd_ctl_elem_value *ucontrol) 4293{ 4294 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 4295 struct alc_spec *spec = codec->spec; 4296 int val = !!*ucontrol->value.integer.value; 4297 hda_nid_t hp, line, mono; 4298 4299 if (val == spec->master_sw) 4300 return 0; 4301 spec->master_sw = val; 4302 hp = (kcontrol->private_value >> 16) & 0xff; 4303 line = (kcontrol->private_value >> 8) & 0xff; 4304 mono = kcontrol->private_value & 0xff; 4305 alc260_hp_master_update(codec, hp, line, mono); 4306 return 1; 4307} 4308 4309static struct snd_kcontrol_new alc260_hp_output_mixer[] = { 4310 { 4311 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 4312 .name = "Master Playback Switch", 4313 .info = snd_ctl_boolean_mono_info, 4314 .get = alc260_hp_master_sw_get, 4315 .put = alc260_hp_master_sw_put, 4316 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11 4317 }, 4318 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT), 4319 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT), 4320 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT), 4321 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT), 4322 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, 4323 HDA_OUTPUT), 4324 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT), 4325 { } /* end */ 4326}; 4327 4328static struct hda_verb alc260_hp_unsol_verbs[] = { 4329 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 4330 {}, 4331}; 4332 4333static void alc260_hp_automute(struct hda_codec *codec) 4334{ 4335 struct alc_spec *spec = codec->spec; 4336 unsigned int present; 4337 4338 present = snd_hda_codec_read(codec, 0x10, 0, 4339 AC_VERB_GET_PIN_SENSE, 0); 4340 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0; 4341 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11); 4342} 4343 4344static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res) 4345{ 4346 if ((res >> 26) == ALC880_HP_EVENT) 4347 alc260_hp_automute(codec); 4348} 4349 4350static struct snd_kcontrol_new alc260_hp_3013_mixer[] = { 4351 { 4352 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 4353 .name = "Master Playback Switch", 4354 .info = snd_ctl_boolean_mono_info, 4355 .get = alc260_hp_master_sw_get, 4356 .put = alc260_hp_master_sw_put, 4357 .private_value = (0x10 << 16) | (0x15 << 8) | 0x11 4358 }, 4359 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT), 4360 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT), 4361 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT), 4362 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT), 4363 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT), 4364 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 4365 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), 4366 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT), 4367 { } /* end */ 4368}; 4369 4370static struct hda_bind_ctls alc260_dc7600_bind_master_vol = { 4371 .ops = &snd_hda_bind_vol, 4372 .values = { 4373 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT), 4374 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT), 4375 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT), 4376 0 4377 }, 4378}; 4379 4380static struct hda_bind_ctls alc260_dc7600_bind_switch = { 4381 .ops = &snd_hda_bind_sw, 4382 .values = { 4383 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT), 4384 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT), 4385 0 4386 }, 4387}; 4388 4389static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = { 4390 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol), 4391 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch), 4392 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT), 4393 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT), 4394 { } /* end */ 4395}; 4396 4397static struct hda_verb alc260_hp_3013_unsol_verbs[] = { 4398 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 4399 {}, 4400}; 4401 4402static void alc260_hp_3013_automute(struct hda_codec *codec) 4403{ 4404 struct alc_spec *spec = codec->spec; 4405 unsigned int present; 4406 4407 present = snd_hda_codec_read(codec, 0x15, 0, 4408 AC_VERB_GET_PIN_SENSE, 0); 4409 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0; 4410 alc260_hp_master_update(codec, 0x10, 0x15, 0x11); 4411} 4412 4413static void alc260_hp_3013_unsol_event(struct hda_codec *codec, 4414 unsigned int res) 4415{ 4416 if ((res >> 26) == ALC880_HP_EVENT) 4417 alc260_hp_3013_automute(codec); 4418} 4419 4420static void alc260_hp_3012_automute(struct hda_codec *codec) 4421{ 4422 unsigned int present, bits; 4423 4424 present = snd_hda_codec_read(codec, 0x10, 0, 4425 AC_VERB_GET_PIN_SENSE, 0) & AC_PINSENSE_PRESENCE; 4426 4427 bits = present ? 0 : PIN_OUT; 4428 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 4429 bits); 4430 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 4431 bits); 4432 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 4433 bits); 4434} 4435 4436static void alc260_hp_3012_unsol_event(struct hda_codec *codec, 4437 unsigned int res) 4438{ 4439 if ((res >> 26) == ALC880_HP_EVENT) 4440 alc260_hp_3012_automute(codec); 4441} 4442 4443/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12, 4444 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10. 4445 */ 4446static struct snd_kcontrol_new alc260_fujitsu_mixer[] = { 4447 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT), 4448 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT), 4449 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT), 4450 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), 4451 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), 4452 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT), 4453 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT), 4454 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN), 4455 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT), 4456 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT), 4457 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT), 4458 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT), 4459 { } /* end */ 4460}; 4461 4462/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current 4463 * versions of the ALC260 don't act on requests to enable mic bias from NID 4464 * 0x0f (used to drive the headphone jack in these laptops). The ALC260 4465 * datasheet doesn't mention this restriction. At this stage it's not clear 4466 * whether this behaviour is intentional or is a hardware bug in chip 4467 * revisions available in early 2006. Therefore for now allow the 4468 * "Headphone Jack Mode" control to span all choices, but if it turns out 4469 * that the lack of mic bias for this NID is intentional we could change the 4470 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS. 4471 * 4472 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006 4473 * don't appear to make the mic bias available from the "line" jack, even 4474 * though the NID used for this jack (0x14) can supply it. The theory is 4475 * that perhaps Acer have included blocking capacitors between the ALC260 4476 * and the output jack. If this turns out to be the case for all such 4477 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT 4478 * to ALC_PIN_DIR_INOUT_NOMICBIAS. 4479 * 4480 * The C20x Tablet series have a mono internal speaker which is controlled 4481 * via the chip's Mono sum widget and pin complex, so include the necessary 4482 * controls for such models. On models without a "mono speaker" the control 4483 * won't do anything. 4484 */ 4485static struct snd_kcontrol_new alc260_acer_mixer[] = { 4486 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), 4487 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT), 4488 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT), 4489 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, 4490 HDA_OUTPUT), 4491 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, 4492 HDA_INPUT), 4493 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), 4494 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), 4495 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), 4496 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT), 4497 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN), 4498 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), 4499 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT), 4500 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT), 4501 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT), 4502 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT), 4503 { } /* end */ 4504}; 4505 4506/* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12, 4507 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17. 4508 */ 4509static struct snd_kcontrol_new alc260_will_mixer[] = { 4510 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), 4511 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT), 4512 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), 4513 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT), 4514 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN), 4515 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), 4516 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT), 4517 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT), 4518 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), 4519 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), 4520 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT), 4521 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT), 4522 { } /* end */ 4523}; 4524 4525/* Replacer 672V ALC260 pin usage: Mic jack = 0x12, 4526 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f. 4527 */ 4528static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = { 4529 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), 4530 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT), 4531 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), 4532 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT), 4533 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN), 4534 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT), 4535 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT), 4536 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), 4537 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT), 4538 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT), 4539 { } /* end */ 4540}; 4541 4542/* 4543 * initialization verbs 4544 */ 4545static struct hda_verb alc260_init_verbs[] = { 4546 /* Line In pin widget for input */ 4547 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 4548 /* CD pin widget for input */ 4549 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 4550 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 4551 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 4552 /* Mic2 (front panel) pin widget for input and vref at 80% */ 4553 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 4554 /* LINE-2 is used for line-out in rear */ 4555 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4556 /* select line-out */ 4557 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00}, 4558 /* LINE-OUT pin */ 4559 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4560 /* enable HP */ 4561 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 4562 /* enable Mono */ 4563 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4564 /* mute capture amp left and right */ 4565 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4566 /* set connection select to line in (default select for this ADC) */ 4567 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02}, 4568 /* mute capture amp left and right */ 4569 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4570 /* set connection select to line in (default select for this ADC) */ 4571 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02}, 4572 /* set vol=0 Line-Out mixer amp left and right */ 4573 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4574 /* unmute pin widget amp left and right (no gain on this amp) */ 4575 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4576 /* set vol=0 HP mixer amp left and right */ 4577 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4578 /* unmute pin widget amp left and right (no gain on this amp) */ 4579 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4580 /* set vol=0 Mono mixer amp left and right */ 4581 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4582 /* unmute pin widget amp left and right (no gain on this amp) */ 4583 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4584 /* unmute LINE-2 out pin */ 4585 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4586 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & 4587 * Line In 2 = 0x03 4588 */ 4589 /* mute analog inputs */ 4590 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4591 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4592 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 4593 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 4594 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 4595 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */ 4596 /* mute Front out path */ 4597 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4598 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4599 /* mute Headphone out path */ 4600 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4601 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4602 /* mute Mono out path */ 4603 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4604 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4605 { } 4606}; 4607 4608#if 0 /* should be identical with alc260_init_verbs? */ 4609static struct hda_verb alc260_hp_init_verbs[] = { 4610 /* Headphone and output */ 4611 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 4612 /* mono output */ 4613 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 4614 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 4615 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 4616 /* Mic2 (front panel) pin widget for input and vref at 80% */ 4617 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 4618 /* Line In pin widget for input */ 4619 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 4620 /* Line-2 pin widget for output */ 4621 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 4622 /* CD pin widget for input */ 4623 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 4624 /* unmute amp left and right */ 4625 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000}, 4626 /* set connection select to line in (default select for this ADC) */ 4627 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02}, 4628 /* unmute Line-Out mixer amp left and right (volume = 0) */ 4629 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 4630 /* mute pin widget amp left and right (no gain on this amp) */ 4631 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 4632 /* unmute HP mixer amp left and right (volume = 0) */ 4633 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 4634 /* mute pin widget amp left and right (no gain on this amp) */ 4635 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 4636 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & 4637 * Line In 2 = 0x03 4638 */ 4639 /* mute analog inputs */ 4640 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4641 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4642 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 4643 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 4644 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 4645 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */ 4646 /* Unmute Front out path */ 4647 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 4648 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 4649 /* Unmute Headphone out path */ 4650 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 4651 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 4652 /* Unmute Mono out path */ 4653 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 4654 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 4655 { } 4656}; 4657#endif 4658 4659static struct hda_verb alc260_hp_3013_init_verbs[] = { 4660 /* Line out and output */ 4661 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 4662 /* mono output */ 4663 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 4664 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 4665 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 4666 /* Mic2 (front panel) pin widget for input and vref at 80% */ 4667 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 4668 /* Line In pin widget for input */ 4669 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 4670 /* Headphone pin widget for output */ 4671 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 4672 /* CD pin widget for input */ 4673 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 4674 /* unmute amp left and right */ 4675 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000}, 4676 /* set connection select to line in (default select for this ADC) */ 4677 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02}, 4678 /* unmute Line-Out mixer amp left and right (volume = 0) */ 4679 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 4680 /* mute pin widget amp left and right (no gain on this amp) */ 4681 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 4682 /* unmute HP mixer amp left and right (volume = 0) */ 4683 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 4684 /* mute pin widget amp left and right (no gain on this amp) */ 4685 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 4686 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & 4687 * Line In 2 = 0x03 4688 */ 4689 /* mute analog inputs */ 4690 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4691 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4692 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 4693 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 4694 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 4695 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */ 4696 /* Unmute Front out path */ 4697 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 4698 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 4699 /* Unmute Headphone out path */ 4700 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 4701 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 4702 /* Unmute Mono out path */ 4703 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 4704 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 4705 { } 4706}; 4707 4708/* Initialisation sequence for ALC260 as configured in Fujitsu S702x 4709 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD 4710 * audio = 0x16, internal speaker = 0x10. 4711 */ 4712static struct hda_verb alc260_fujitsu_init_verbs[] = { 4713 /* Disable all GPIOs */ 4714 {0x01, AC_VERB_SET_GPIO_MASK, 0}, 4715 /* Internal speaker is connected to headphone pin */ 4716 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 4717 /* Headphone/Line-out jack connects to Line1 pin; make it an output */ 4718 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4719 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */ 4720 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 4721 /* Ensure all other unused pins are disabled and muted. */ 4722 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 4723 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4724 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 4725 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4726 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 4727 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4728 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 4729 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4730 4731 /* Disable digital (SPDIF) pins */ 4732 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0}, 4733 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0}, 4734 4735 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus 4736 * when acting as an output. 4737 */ 4738 {0x0d, AC_VERB_SET_CONNECT_SEL, 0}, 4739 4740 /* Start with output sum widgets muted and their output gains at min */ 4741 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4742 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4743 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4744 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4745 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4746 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4747 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4748 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4749 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4750 4751 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */ 4752 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4753 /* Unmute Line1 pin widget output buffer since it starts as an output. 4754 * If the pin mode is changed by the user the pin mode control will 4755 * take care of enabling the pin's input/output buffers as needed. 4756 * Therefore there's no need to enable the input buffer at this 4757 * stage. 4758 */ 4759 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4760 /* Unmute input buffer of pin widget used for Line-in (no equiv 4761 * mixer ctrl) 4762 */ 4763 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4764 4765 /* Mute capture amp left and right */ 4766 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4767 /* Set ADC connection select to match default mixer setting - line 4768 * in (on mic1 pin) 4769 */ 4770 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, 4771 4772 /* Do the same for the second ADC: mute capture input amp and 4773 * set ADC connection to line in (on mic1 pin) 4774 */ 4775 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4776 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, 4777 4778 /* Mute all inputs to mixer widget (even unconnected ones) */ 4779 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */ 4780 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */ 4781 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */ 4782 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */ 4783 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */ 4784 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */ 4785 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */ 4786 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */ 4787 4788 { } 4789}; 4790 4791/* Initialisation sequence for ALC260 as configured in Acer TravelMate and 4792 * similar laptops (adapted from Fujitsu init verbs). 4793 */ 4794static struct hda_verb alc260_acer_init_verbs[] = { 4795 /* On TravelMate laptops, GPIO 0 enables the internal speaker and 4796 * the headphone jack. Turn this on and rely on the standard mute 4797 * methods whenever the user wants to turn these outputs off. 4798 */ 4799 {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, 4800 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, 4801 {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, 4802 /* Internal speaker/Headphone jack is connected to Line-out pin */ 4803 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 4804 /* Internal microphone/Mic jack is connected to Mic1 pin */ 4805 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, 4806 /* Line In jack is connected to Line1 pin */ 4807 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 4808 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */ 4809 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 4810 /* Ensure all other unused pins are disabled and muted. */ 4811 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 4812 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4813 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 4814 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4815 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 4816 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4817 /* Disable digital (SPDIF) pins */ 4818 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0}, 4819 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0}, 4820 4821 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum 4822 * bus when acting as outputs. 4823 */ 4824 {0x0b, AC_VERB_SET_CONNECT_SEL, 0}, 4825 {0x0d, AC_VERB_SET_CONNECT_SEL, 0}, 4826 4827 /* Start with output sum widgets muted and their output gains at min */ 4828 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4829 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4830 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4831 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4832 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4833 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4834 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4835 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4836 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4837 4838 /* Unmute Line-out pin widget amp left and right 4839 * (no equiv mixer ctrl) 4840 */ 4841 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4842 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */ 4843 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4844 /* Unmute Mic1 and Line1 pin widget input buffers since they start as 4845 * inputs. If the pin mode is changed by the user the pin mode control 4846 * will take care of enabling the pin's input/output buffers as needed. 4847 * Therefore there's no need to enable the input buffer at this 4848 * stage. 4849 */ 4850 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4851 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4852 4853 /* Mute capture amp left and right */ 4854 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4855 /* Set ADC connection select to match default mixer setting - mic 4856 * (on mic1 pin) 4857 */ 4858 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, 4859 4860 /* Do similar with the second ADC: mute capture input amp and 4861 * set ADC connection to mic to match ALSA's default state. 4862 */ 4863 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4864 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, 4865 4866 /* Mute all inputs to mixer widget (even unconnected ones) */ 4867 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */ 4868 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */ 4869 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */ 4870 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */ 4871 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */ 4872 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */ 4873 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */ 4874 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */ 4875 4876 { } 4877}; 4878 4879static struct hda_verb alc260_will_verbs[] = { 4880 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 4881 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00}, 4882 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00}, 4883 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02}, 4884 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07}, 4885 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040}, 4886 {} 4887}; 4888 4889static struct hda_verb alc260_replacer_672v_verbs[] = { 4890 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02}, 4891 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07}, 4892 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050}, 4893 4894 {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, 4895 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, 4896 {0x01, AC_VERB_SET_GPIO_DATA, 0x00}, 4897 4898 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 4899 {} 4900}; 4901 4902/* toggle speaker-output according to the hp-jack state */ 4903static void alc260_replacer_672v_automute(struct hda_codec *codec) 4904{ 4905 unsigned int present; 4906 4907 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */ 4908 present = snd_hda_codec_read(codec, 0x0f, 0, 4909 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 4910 if (present) { 4911 snd_hda_codec_write_cache(codec, 0x01, 0, 4912 AC_VERB_SET_GPIO_DATA, 1); 4913 snd_hda_codec_write_cache(codec, 0x0f, 0, 4914 AC_VERB_SET_PIN_WIDGET_CONTROL, 4915 PIN_HP); 4916 } else { 4917 snd_hda_codec_write_cache(codec, 0x01, 0, 4918 AC_VERB_SET_GPIO_DATA, 0); 4919 snd_hda_codec_write_cache(codec, 0x0f, 0, 4920 AC_VERB_SET_PIN_WIDGET_CONTROL, 4921 PIN_OUT); 4922 } 4923} 4924 4925static void alc260_replacer_672v_unsol_event(struct hda_codec *codec, 4926 unsigned int res) 4927{ 4928 if ((res >> 26) == ALC880_HP_EVENT) 4929 alc260_replacer_672v_automute(codec); 4930} 4931 4932static struct hda_verb alc260_hp_dc7600_verbs[] = { 4933 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01}, 4934 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 4935 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4936 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 4937 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4938 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4939 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 4940 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 4941 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 4942 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 4943 {} 4944}; 4945 4946/* Test configuration for debugging, modelled after the ALC880 test 4947 * configuration. 4948 */ 4949#ifdef CONFIG_SND_DEBUG 4950static hda_nid_t alc260_test_dac_nids[1] = { 4951 0x02, 4952}; 4953static hda_nid_t alc260_test_adc_nids[2] = { 4954 0x04, 0x05, 4955}; 4956/* For testing the ALC260, each input MUX needs its own definition since 4957 * the signal assignments are different. This assumes that the first ADC 4958 * is NID 0x04. 4959 */ 4960static struct hda_input_mux alc260_test_capture_sources[2] = { 4961 { 4962 .num_items = 7, 4963 .items = { 4964 { "MIC1 pin", 0x0 }, 4965 { "MIC2 pin", 0x1 }, 4966 { "LINE1 pin", 0x2 }, 4967 { "LINE2 pin", 0x3 }, 4968 { "CD pin", 0x4 }, 4969 { "LINE-OUT pin", 0x5 }, 4970 { "HP-OUT pin", 0x6 }, 4971 }, 4972 }, 4973 { 4974 .num_items = 8, 4975 .items = { 4976 { "MIC1 pin", 0x0 }, 4977 { "MIC2 pin", 0x1 }, 4978 { "LINE1 pin", 0x2 }, 4979 { "LINE2 pin", 0x3 }, 4980 { "CD pin", 0x4 }, 4981 { "Mixer", 0x5 }, 4982 { "LINE-OUT pin", 0x6 }, 4983 { "HP-OUT pin", 0x7 }, 4984 }, 4985 }, 4986}; 4987static struct snd_kcontrol_new alc260_test_mixer[] = { 4988 /* Output driver widgets */ 4989 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), 4990 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT), 4991 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT), 4992 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT), 4993 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT), 4994 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT), 4995 4996 /* Modes for retasking pin widgets 4997 * Note: the ALC260 doesn't seem to act on requests to enable mic 4998 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't 4999 * mention this restriction. At this stage it's not clear whether 5000 * this behaviour is intentional or is a hardware bug in chip 5001 * revisions available at least up until early 2006. Therefore for 5002 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all 5003 * choices, but if it turns out that the lack of mic bias for these 5004 * NIDs is intentional we could change their modes from 5005 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS. 5006 */ 5007 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT), 5008 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT), 5009 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT), 5010 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT), 5011 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT), 5012 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT), 5013 5014 /* Loopback mixer controls */ 5015 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT), 5016 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT), 5017 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT), 5018 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT), 5019 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT), 5020 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT), 5021 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT), 5022 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT), 5023 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), 5024 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), 5025 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT), 5026 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT), 5027 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT), 5028 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT), 5029 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT), 5030 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT), 5031 5032 /* Controls for GPIO pins, assuming they are configured as outputs */ 5033 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01), 5034 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02), 5035 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04), 5036 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08), 5037 5038 /* Switches to allow the digital IO pins to be enabled. The datasheet 5039 * is ambigious as to which NID is which; testing on laptops which 5040 * make this output available should provide clarification. 5041 */ 5042 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01), 5043 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01), 5044 5045 /* A switch allowing EAPD to be enabled. Some laptops seem to use 5046 * this output to turn on an external amplifier. 5047 */ 5048 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02), 5049 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02), 5050 5051 { } /* end */ 5052}; 5053static struct hda_verb alc260_test_init_verbs[] = { 5054 /* Enable all GPIOs as outputs with an initial value of 0 */ 5055 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f}, 5056 {0x01, AC_VERB_SET_GPIO_DATA, 0x00}, 5057 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f}, 5058 5059 /* Enable retasking pins as output, initially without power amp */ 5060 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5061 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5062 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5063 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5064 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5065 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5066 5067 /* Disable digital (SPDIF) pins initially, but users can enable 5068 * them via a mixer switch. In the case of SPDIF-out, this initverb 5069 * payload also sets the generation to 0, output to be in "consumer" 5070 * PCM format, copyright asserted, no pre-emphasis and no validity 5071 * control. 5072 */ 5073 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0}, 5074 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0}, 5075 5076 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the 5077 * OUT1 sum bus when acting as an output. 5078 */ 5079 {0x0b, AC_VERB_SET_CONNECT_SEL, 0}, 5080 {0x0c, AC_VERB_SET_CONNECT_SEL, 0}, 5081 {0x0d, AC_VERB_SET_CONNECT_SEL, 0}, 5082 {0x0e, AC_VERB_SET_CONNECT_SEL, 0}, 5083 5084 /* Start with output sum widgets muted and their output gains at min */ 5085 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5086 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 5087 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5088 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5089 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 5090 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5091 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5092 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 5093 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5094 5095 /* Unmute retasking pin widget output buffers since the default 5096 * state appears to be output. As the pin mode is changed by the 5097 * user the pin mode control will take care of enabling the pin's 5098 * input/output buffers as needed. 5099 */ 5100 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5101 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5102 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5103 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5104 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5105 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5106 /* Also unmute the mono-out pin widget */ 5107 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5108 5109 /* Mute capture amp left and right */ 5110 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5111 /* Set ADC connection select to match default mixer setting (mic1 5112 * pin) 5113 */ 5114 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, 5115 5116 /* Do the same for the second ADC: mute capture input amp and 5117 * set ADC connection to mic1 pin 5118 */ 5119 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5120 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, 5121 5122 /* Mute all inputs to mixer widget (even unconnected ones) */ 5123 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */ 5124 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */ 5125 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */ 5126 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */ 5127 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */ 5128 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */ 5129 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */ 5130 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */ 5131 5132 { } 5133}; 5134#endif 5135 5136#define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback 5137#define alc260_pcm_analog_capture alc880_pcm_analog_capture 5138 5139#define alc260_pcm_digital_playback alc880_pcm_digital_playback 5140#define alc260_pcm_digital_capture alc880_pcm_digital_capture 5141 5142/* 5143 * for BIOS auto-configuration 5144 */ 5145 5146static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid, 5147 const char *pfx, int *vol_bits) 5148{ 5149 hda_nid_t nid_vol; 5150 unsigned long vol_val, sw_val; 5151 char name[32]; 5152 int err; 5153 5154 if (nid >= 0x0f && nid < 0x11) { 5155 nid_vol = nid - 0x7; 5156 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT); 5157 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT); 5158 } else if (nid == 0x11) { 5159 nid_vol = nid - 0x7; 5160 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT); 5161 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT); 5162 } else if (nid >= 0x12 && nid <= 0x15) { 5163 nid_vol = 0x08; 5164 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT); 5165 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT); 5166 } else 5167 return 0; /* N/A */ 5168 5169 if (!(*vol_bits & (1 << nid_vol))) { 5170 /* first control for the volume widget */ 5171 snprintf(name, sizeof(name), "%s Playback Volume", pfx); 5172 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val); 5173 if (err < 0) 5174 return err; 5175 *vol_bits |= (1 << nid_vol); 5176 } 5177 snprintf(name, sizeof(name), "%s Playback Switch", pfx); 5178 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val); 5179 if (err < 0) 5180 return err; 5181 return 1; 5182} 5183 5184/* add playback controls from the parsed DAC table */ 5185static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec, 5186 const struct auto_pin_cfg *cfg) 5187{ 5188 hda_nid_t nid; 5189 int err; 5190 int vols = 0; 5191 5192 spec->multiout.num_dacs = 1; 5193 spec->multiout.dac_nids = spec->private_dac_nids; 5194 spec->multiout.dac_nids[0] = 0x02; 5195 5196 nid = cfg->line_out_pins[0]; 5197 if (nid) { 5198 err = alc260_add_playback_controls(spec, nid, "Front", &vols); 5199 if (err < 0) 5200 return err; 5201 } 5202 5203 nid = cfg->speaker_pins[0]; 5204 if (nid) { 5205 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols); 5206 if (err < 0) 5207 return err; 5208 } 5209 5210 nid = cfg->hp_pins[0]; 5211 if (nid) { 5212 err = alc260_add_playback_controls(spec, nid, "Headphone", 5213 &vols); 5214 if (err < 0) 5215 return err; 5216 } 5217 return 0; 5218} 5219 5220/* create playback/capture controls for input pins */ 5221static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec, 5222 const struct auto_pin_cfg *cfg) 5223{ 5224 struct hda_input_mux *imux = &spec->private_imux; 5225 int i, err, idx; 5226 5227 for (i = 0; i < AUTO_PIN_LAST; i++) { 5228 if (cfg->input_pins[i] >= 0x12) { 5229 idx = cfg->input_pins[i] - 0x12; 5230 err = new_analog_input(spec, cfg->input_pins[i], 5231 auto_pin_cfg_labels[i], idx, 5232 0x07); 5233 if (err < 0) 5234 return err; 5235 imux->items[imux->num_items].label = 5236 auto_pin_cfg_labels[i]; 5237 imux->items[imux->num_items].index = idx; 5238 imux->num_items++; 5239 } 5240 if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){ 5241 idx = cfg->input_pins[i] - 0x09; 5242 err = new_analog_input(spec, cfg->input_pins[i], 5243 auto_pin_cfg_labels[i], idx, 5244 0x07); 5245 if (err < 0) 5246 return err; 5247 imux->items[imux->num_items].label = 5248 auto_pin_cfg_labels[i]; 5249 imux->items[imux->num_items].index = idx; 5250 imux->num_items++; 5251 } 5252 } 5253 return 0; 5254} 5255 5256static void alc260_auto_set_output_and_unmute(struct hda_codec *codec, 5257 hda_nid_t nid, int pin_type, 5258 int sel_idx) 5259{ 5260 alc_set_pin_output(codec, nid, pin_type); 5261 /* need the manual connection? */ 5262 if (nid >= 0x12) { 5263 int idx = nid - 0x12; 5264 snd_hda_codec_write(codec, idx + 0x0b, 0, 5265 AC_VERB_SET_CONNECT_SEL, sel_idx); 5266 } 5267} 5268 5269static void alc260_auto_init_multi_out(struct hda_codec *codec) 5270{ 5271 struct alc_spec *spec = codec->spec; 5272 hda_nid_t nid; 5273 5274 alc_subsystem_id(codec, 0x10, 0x15, 0x0f); 5275 nid = spec->autocfg.line_out_pins[0]; 5276 if (nid) { 5277 int pin_type = get_pin_type(spec->autocfg.line_out_type); 5278 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0); 5279 } 5280 5281 nid = spec->autocfg.speaker_pins[0]; 5282 if (nid) 5283 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0); 5284 5285 nid = spec->autocfg.hp_pins[0]; 5286 if (nid) 5287 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0); 5288} 5289 5290#define ALC260_PIN_CD_NID 0x16 5291static void alc260_auto_init_analog_input(struct hda_codec *codec) 5292{ 5293 struct alc_spec *spec = codec->spec; 5294 int i; 5295 5296 for (i = 0; i < AUTO_PIN_LAST; i++) { 5297 hda_nid_t nid = spec->autocfg.input_pins[i]; 5298 if (nid >= 0x12) { 5299 snd_hda_codec_write(codec, nid, 0, 5300 AC_VERB_SET_PIN_WIDGET_CONTROL, 5301 i <= AUTO_PIN_FRONT_MIC ? 5302 PIN_VREF80 : PIN_IN); 5303 if (nid != ALC260_PIN_CD_NID) 5304 snd_hda_codec_write(codec, nid, 0, 5305 AC_VERB_SET_AMP_GAIN_MUTE, 5306 AMP_OUT_MUTE); 5307 } 5308 } 5309} 5310 5311/* 5312 * generic initialization of ADC, input mixers and output mixers 5313 */ 5314static struct hda_verb alc260_volume_init_verbs[] = { 5315 /* 5316 * Unmute ADC0-1 and set the default input to mic-in 5317 */ 5318 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, 5319 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5320 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, 5321 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5322 5323 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 5324 * mixer widget 5325 * Note: PASD motherboards uses the Line In 2 as the input for 5326 * front panel mic (mic 2) 5327 */ 5328 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 5329 /* mute analog inputs */ 5330 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5331 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 5332 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 5333 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 5334 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 5335 5336 /* 5337 * Set up output mixers (0x08 - 0x0a) 5338 */ 5339 /* set vol=0 to output mixers */ 5340 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5341 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5342 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5343 /* set up input amps for analog loopback */ 5344 /* Amp Indices: DAC = 0, mixer = 1 */ 5345 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5346 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 5347 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5348 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 5349 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5350 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 5351 5352 { } 5353}; 5354 5355static int alc260_parse_auto_config(struct hda_codec *codec) 5356{ 5357 struct alc_spec *spec = codec->spec; 5358 int err; 5359 static hda_nid_t alc260_ignore[] = { 0x17, 0 }; 5360 5361 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 5362 alc260_ignore); 5363 if (err < 0) 5364 return err; 5365 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg); 5366 if (err < 0) 5367 return err; 5368 if (!spec->kctls.list) 5369 return 0; /* can't find valid BIOS pin config */ 5370 err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg); 5371 if (err < 0) 5372 return err; 5373 5374 spec->multiout.max_channels = 2; 5375 5376 if (spec->autocfg.dig_out_pin) 5377 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID; 5378 if (spec->kctls.list) 5379 add_mixer(spec, spec->kctls.list); 5380 5381 add_verb(spec, alc260_volume_init_verbs); 5382 5383 spec->num_mux_defs = 1; 5384 spec->input_mux = &spec->private_imux; 5385 5386 store_pin_configs(codec); 5387 return 1; 5388} 5389 5390/* additional initialization for auto-configuration model */ 5391static void alc260_auto_init(struct hda_codec *codec) 5392{ 5393 struct alc_spec *spec = codec->spec; 5394 alc260_auto_init_multi_out(codec); 5395 alc260_auto_init_analog_input(codec); 5396 if (spec->unsol_event) 5397 alc_inithook(codec); 5398} 5399 5400#ifdef CONFIG_SND_HDA_POWER_SAVE 5401static struct hda_amp_list alc260_loopbacks[] = { 5402 { 0x07, HDA_INPUT, 0 }, 5403 { 0x07, HDA_INPUT, 1 }, 5404 { 0x07, HDA_INPUT, 2 }, 5405 { 0x07, HDA_INPUT, 3 }, 5406 { 0x07, HDA_INPUT, 4 }, 5407 { } /* end */ 5408}; 5409#endif 5410 5411/* 5412 * ALC260 configurations 5413 */ 5414static const char *alc260_models[ALC260_MODEL_LAST] = { 5415 [ALC260_BASIC] = "basic", 5416 [ALC260_HP] = "hp", 5417 [ALC260_HP_3013] = "hp-3013", 5418 [ALC260_HP_DC7600] = "hp-dc7600", 5419 [ALC260_FUJITSU_S702X] = "fujitsu", 5420 [ALC260_ACER] = "acer", 5421 [ALC260_WILL] = "will", 5422 [ALC260_REPLACER_672V] = "replacer", 5423#ifdef CONFIG_SND_DEBUG 5424 [ALC260_TEST] = "test", 5425#endif 5426 [ALC260_AUTO] = "auto", 5427}; 5428 5429static struct snd_pci_quirk alc260_cfg_tbl[] = { 5430 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER), 5431 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER), 5432 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013), 5433 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013), 5434 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013), 5435 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013), 5436 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600), 5437 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013), 5438 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP), 5439 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP), 5440 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP), 5441 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC), 5442 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC), 5443 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC), 5444 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X), 5445 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC), 5446 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V), 5447 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL), 5448 {} 5449}; 5450 5451static struct alc_config_preset alc260_presets[] = { 5452 [ALC260_BASIC] = { 5453 .mixers = { alc260_base_output_mixer, 5454 alc260_input_mixer, 5455 alc260_pc_beep_mixer }, 5456 .init_verbs = { alc260_init_verbs }, 5457 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 5458 .dac_nids = alc260_dac_nids, 5459 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids), 5460 .adc_nids = alc260_adc_nids, 5461 .num_channel_mode = ARRAY_SIZE(alc260_modes), 5462 .channel_mode = alc260_modes, 5463 .input_mux = &alc260_capture_source, 5464 }, 5465 [ALC260_HP] = { 5466 .mixers = { alc260_hp_output_mixer, 5467 alc260_input_mixer }, 5468 .init_verbs = { alc260_init_verbs, 5469 alc260_hp_unsol_verbs }, 5470 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 5471 .dac_nids = alc260_dac_nids, 5472 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt), 5473 .adc_nids = alc260_adc_nids_alt, 5474 .num_channel_mode = ARRAY_SIZE(alc260_modes), 5475 .channel_mode = alc260_modes, 5476 .input_mux = &alc260_capture_source, 5477 .unsol_event = alc260_hp_unsol_event, 5478 .init_hook = alc260_hp_automute, 5479 }, 5480 [ALC260_HP_DC7600] = { 5481 .mixers = { alc260_hp_dc7600_mixer, 5482 alc260_input_mixer }, 5483 .init_verbs = { alc260_init_verbs, 5484 alc260_hp_dc7600_verbs }, 5485 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 5486 .dac_nids = alc260_dac_nids, 5487 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt), 5488 .adc_nids = alc260_adc_nids_alt, 5489 .num_channel_mode = ARRAY_SIZE(alc260_modes), 5490 .channel_mode = alc260_modes, 5491 .input_mux = &alc260_capture_source, 5492 .unsol_event = alc260_hp_3012_unsol_event, 5493 .init_hook = alc260_hp_3012_automute, 5494 }, 5495 [ALC260_HP_3013] = { 5496 .mixers = { alc260_hp_3013_mixer, 5497 alc260_input_mixer }, 5498 .init_verbs = { alc260_hp_3013_init_verbs, 5499 alc260_hp_3013_unsol_verbs }, 5500 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 5501 .dac_nids = alc260_dac_nids, 5502 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt), 5503 .adc_nids = alc260_adc_nids_alt, 5504 .num_channel_mode = ARRAY_SIZE(alc260_modes), 5505 .channel_mode = alc260_modes, 5506 .input_mux = &alc260_capture_source, 5507 .unsol_event = alc260_hp_3013_unsol_event, 5508 .init_hook = alc260_hp_3013_automute, 5509 }, 5510 [ALC260_FUJITSU_S702X] = { 5511 .mixers = { alc260_fujitsu_mixer }, 5512 .init_verbs = { alc260_fujitsu_init_verbs }, 5513 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 5514 .dac_nids = alc260_dac_nids, 5515 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids), 5516 .adc_nids = alc260_dual_adc_nids, 5517 .num_channel_mode = ARRAY_SIZE(alc260_modes), 5518 .channel_mode = alc260_modes, 5519 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources), 5520 .input_mux = alc260_fujitsu_capture_sources, 5521 }, 5522 [ALC260_ACER] = { 5523 .mixers = { alc260_acer_mixer }, 5524 .init_verbs = { alc260_acer_init_verbs }, 5525 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 5526 .dac_nids = alc260_dac_nids, 5527 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids), 5528 .adc_nids = alc260_dual_adc_nids, 5529 .num_channel_mode = ARRAY_SIZE(alc260_modes), 5530 .channel_mode = alc260_modes, 5531 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources), 5532 .input_mux = alc260_acer_capture_sources, 5533 }, 5534 [ALC260_WILL] = { 5535 .mixers = { alc260_will_mixer }, 5536 .init_verbs = { alc260_init_verbs, alc260_will_verbs }, 5537 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 5538 .dac_nids = alc260_dac_nids, 5539 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids), 5540 .adc_nids = alc260_adc_nids, 5541 .dig_out_nid = ALC260_DIGOUT_NID, 5542 .num_channel_mode = ARRAY_SIZE(alc260_modes), 5543 .channel_mode = alc260_modes, 5544 .input_mux = &alc260_capture_source, 5545 }, 5546 [ALC260_REPLACER_672V] = { 5547 .mixers = { alc260_replacer_672v_mixer }, 5548 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs }, 5549 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 5550 .dac_nids = alc260_dac_nids, 5551 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids), 5552 .adc_nids = alc260_adc_nids, 5553 .dig_out_nid = ALC260_DIGOUT_NID, 5554 .num_channel_mode = ARRAY_SIZE(alc260_modes), 5555 .channel_mode = alc260_modes, 5556 .input_mux = &alc260_capture_source, 5557 .unsol_event = alc260_replacer_672v_unsol_event, 5558 .init_hook = alc260_replacer_672v_automute, 5559 }, 5560#ifdef CONFIG_SND_DEBUG 5561 [ALC260_TEST] = { 5562 .mixers = { alc260_test_mixer }, 5563 .init_verbs = { alc260_test_init_verbs }, 5564 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids), 5565 .dac_nids = alc260_test_dac_nids, 5566 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids), 5567 .adc_nids = alc260_test_adc_nids, 5568 .num_channel_mode = ARRAY_SIZE(alc260_modes), 5569 .channel_mode = alc260_modes, 5570 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources), 5571 .input_mux = alc260_test_capture_sources, 5572 }, 5573#endif 5574}; 5575 5576static int patch_alc260(struct hda_codec *codec) 5577{ 5578 struct alc_spec *spec; 5579 int err, board_config; 5580 5581 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 5582 if (spec == NULL) 5583 return -ENOMEM; 5584 5585 codec->spec = spec; 5586 5587 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST, 5588 alc260_models, 5589 alc260_cfg_tbl); 5590 if (board_config < 0) { 5591 snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, " 5592 "trying auto-probe from BIOS...\n"); 5593 board_config = ALC260_AUTO; 5594 } 5595 5596 if (board_config == ALC260_AUTO) { 5597 /* automatic parse from the BIOS config */ 5598 err = alc260_parse_auto_config(codec); 5599 if (err < 0) { 5600 alc_free(codec); 5601 return err; 5602 } else if (!err) { 5603 printk(KERN_INFO 5604 "hda_codec: Cannot set up configuration " 5605 "from BIOS. Using base mode...\n"); 5606 board_config = ALC260_BASIC; 5607 } 5608 } 5609 5610 if (board_config != ALC260_AUTO) 5611 setup_preset(spec, &alc260_presets[board_config]); 5612 5613 spec->stream_name_analog = "ALC260 Analog"; 5614 spec->stream_analog_playback = &alc260_pcm_analog_playback; 5615 spec->stream_analog_capture = &alc260_pcm_analog_capture; 5616 5617 spec->stream_name_digital = "ALC260 Digital"; 5618 spec->stream_digital_playback = &alc260_pcm_digital_playback; 5619 spec->stream_digital_capture = &alc260_pcm_digital_capture; 5620 5621 set_capture_mixer(spec); 5622 5623 spec->vmaster_nid = 0x08; 5624 5625 codec->patch_ops = alc_patch_ops; 5626 if (board_config == ALC260_AUTO) 5627 spec->init_hook = alc260_auto_init; 5628#ifdef CONFIG_SND_HDA_POWER_SAVE 5629 if (!spec->loopback.amplist) 5630 spec->loopback.amplist = alc260_loopbacks; 5631#endif 5632 5633 return 0; 5634} 5635 5636 5637/* 5638 * ALC882 support 5639 * 5640 * ALC882 is almost identical with ALC880 but has cleaner and more flexible 5641 * configuration. Each pin widget can choose any input DACs and a mixer. 5642 * Each ADC is connected from a mixer of all inputs. This makes possible 5643 * 6-channel independent captures. 5644 * 5645 * In addition, an independent DAC for the multi-playback (not used in this 5646 * driver yet). 5647 */ 5648#define ALC882_DIGOUT_NID 0x06 5649#define ALC882_DIGIN_NID 0x0a 5650 5651static struct hda_channel_mode alc882_ch_modes[1] = { 5652 { 8, NULL } 5653}; 5654 5655static hda_nid_t alc882_dac_nids[4] = { 5656 /* front, rear, clfe, rear_surr */ 5657 0x02, 0x03, 0x04, 0x05 5658}; 5659 5660/* identical with ALC880 */ 5661#define alc882_adc_nids alc880_adc_nids 5662#define alc882_adc_nids_alt alc880_adc_nids_alt 5663 5664static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 }; 5665static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 }; 5666 5667/* input MUX */ 5668/* FIXME: should be a matrix-type input source selection */ 5669 5670static struct hda_input_mux alc882_capture_source = { 5671 .num_items = 4, 5672 .items = { 5673 { "Mic", 0x0 }, 5674 { "Front Mic", 0x1 }, 5675 { "Line", 0x2 }, 5676 { "CD", 0x4 }, 5677 }, 5678}; 5679/* 5680 * 2ch mode 5681 */ 5682static struct hda_verb alc882_3ST_ch2_init[] = { 5683 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 5684 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 5685 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 5686 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 5687 { } /* end */ 5688}; 5689 5690/* 5691 * 6ch mode 5692 */ 5693static struct hda_verb alc882_3ST_ch6_init[] = { 5694 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 5695 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 5696 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, 5697 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 5698 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 5699 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 5700 { } /* end */ 5701}; 5702 5703static struct hda_channel_mode alc882_3ST_6ch_modes[2] = { 5704 { 2, alc882_3ST_ch2_init }, 5705 { 6, alc882_3ST_ch6_init }, 5706}; 5707 5708/* 5709 * 6ch mode 5710 */ 5711static struct hda_verb alc882_sixstack_ch6_init[] = { 5712 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 5713 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 5714 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 5715 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 5716 { } /* end */ 5717}; 5718 5719/* 5720 * 8ch mode 5721 */ 5722static struct hda_verb alc882_sixstack_ch8_init[] = { 5723 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 5724 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 5725 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 5726 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 5727 { } /* end */ 5728}; 5729 5730static struct hda_channel_mode alc882_sixstack_modes[2] = { 5731 { 6, alc882_sixstack_ch6_init }, 5732 { 8, alc882_sixstack_ch8_init }, 5733}; 5734 5735/* 5736 * macbook pro ALC885 can switch LineIn to LineOut without loosing Mic 5737 */ 5738 5739/* 5740 * 2ch mode 5741 */ 5742static struct hda_verb alc885_mbp_ch2_init[] = { 5743 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 5744 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5745 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 5746 { } /* end */ 5747}; 5748 5749/* 5750 * 6ch mode 5751 */ 5752static struct hda_verb alc885_mbp_ch6_init[] = { 5753 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 5754 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5755 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 5756 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5757 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 5758 { } /* end */ 5759}; 5760 5761static struct hda_channel_mode alc885_mbp_6ch_modes[2] = { 5762 { 2, alc885_mbp_ch2_init }, 5763 { 6, alc885_mbp_ch6_init }, 5764}; 5765 5766 5767/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 5768 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b 5769 */ 5770static struct snd_kcontrol_new alc882_base_mixer[] = { 5771 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 5772 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 5773 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 5774 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 5775 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 5776 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 5777 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 5778 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 5779 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 5780 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 5781 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 5782 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 5783 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 5784 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 5785 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 5786 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 5787 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 5788 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 5789 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 5790 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 5791 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 5792 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 5793 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 5794 { } /* end */ 5795}; 5796 5797static struct snd_kcontrol_new alc885_mbp3_mixer[] = { 5798 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 5799 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT), 5800 HDA_CODEC_MUTE ("Speaker Playback Switch", 0x14, 0x00, HDA_OUTPUT), 5801 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0d, 0x00, HDA_OUTPUT), 5802 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 5803 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 5804 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT), 5805 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT), 5806 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT), 5807 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT), 5808 { } /* end */ 5809}; 5810static struct snd_kcontrol_new alc882_w2jc_mixer[] = { 5811 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 5812 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 5813 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 5814 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 5815 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 5816 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 5817 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 5818 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 5819 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 5820 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 5821 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 5822 { } /* end */ 5823}; 5824 5825static struct snd_kcontrol_new alc882_targa_mixer[] = { 5826 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 5827 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 5828 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 5829 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 5830 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 5831 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 5832 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 5833 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 5834 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 5835 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 5836 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 5837 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 5838 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 5839 { } /* end */ 5840}; 5841 5842/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ??? 5843 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c 5844 */ 5845static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = { 5846 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 5847 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 5848 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 5849 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT), 5850 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 5851 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 5852 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 5853 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 5854 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT), 5855 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT), 5856 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 5857 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 5858 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 5859 { } /* end */ 5860}; 5861 5862static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = { 5863 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 5864 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 5865 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 5866 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 5867 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 5868 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 5869 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 5870 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 5871 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 5872 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 5873 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 5874 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 5875 { } /* end */ 5876}; 5877 5878static struct snd_kcontrol_new alc882_chmode_mixer[] = { 5879 { 5880 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 5881 .name = "Channel Mode", 5882 .info = alc_ch_mode_info, 5883 .get = alc_ch_mode_get, 5884 .put = alc_ch_mode_put, 5885 }, 5886 { } /* end */ 5887}; 5888 5889static struct hda_verb alc882_init_verbs[] = { 5890 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 5891 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5892 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5893 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 5894 /* Rear mixer */ 5895 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5896 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5897 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 5898 /* CLFE mixer */ 5899 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5900 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5901 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 5902 /* Side mixer */ 5903 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5904 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5905 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 5906 5907 /* Front Pin: output 0 (0x0c) */ 5908 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5909 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5910 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 5911 /* Rear Pin: output 1 (0x0d) */ 5912 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5913 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5914 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 5915 /* CLFE Pin: output 2 (0x0e) */ 5916 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5917 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5918 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, 5919 /* Side Pin: output 3 (0x0f) */ 5920 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5921 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5922 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, 5923 /* Mic (rear) pin: input vref at 80% */ 5924 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 5925 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 5926 /* Front Mic pin: input vref at 80% */ 5927 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 5928 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 5929 /* Line In pin: input */ 5930 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 5931 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 5932 /* Line-2 In: Headphone output (output 0 - 0x0c) */ 5933 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 5934 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5935 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 5936 /* CD pin widget for input */ 5937 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 5938 5939 /* FIXME: use matrix-type input source selection */ 5940 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 5941 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 5942 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5943 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 5944 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 5945 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 5946 /* Input mixer2 */ 5947 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5948 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 5949 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 5950 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 5951 /* Input mixer3 */ 5952 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5953 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 5954 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 5955 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 5956 /* ADC1: mute amp left and right */ 5957 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5958 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 5959 /* ADC2: mute amp left and right */ 5960 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5961 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 5962 /* ADC3: mute amp left and right */ 5963 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5964 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 5965 5966 { } 5967}; 5968 5969static struct hda_verb alc882_eapd_verbs[] = { 5970 /* change to EAPD mode */ 5971 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 5972 {0x20, AC_VERB_SET_PROC_COEF, 0x3060}, 5973 { } 5974}; 5975 5976/* Mac Pro test */ 5977static struct snd_kcontrol_new alc882_macpro_mixer[] = { 5978 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 5979 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 5980 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT), 5981 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT), 5982 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT), 5983 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT), 5984 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT), 5985 { } /* end */ 5986}; 5987 5988static struct hda_verb alc882_macpro_init_verbs[] = { 5989 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 5990 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5991 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5992 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 5993 /* Front Pin: output 0 (0x0c) */ 5994 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5995 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5996 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 5997 /* Front Mic pin: input vref at 80% */ 5998 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 5999 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 6000 /* Speaker: output */ 6001 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6002 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6003 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04}, 6004 /* Headphone output (output 0 - 0x0c) */ 6005 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6006 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6007 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00}, 6008 6009 /* FIXME: use matrix-type input source selection */ 6010 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 6011 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 6012 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6013 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 6014 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 6015 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 6016 /* Input mixer2 */ 6017 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6018 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 6019 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 6020 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 6021 /* Input mixer3 */ 6022 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6023 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 6024 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 6025 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 6026 /* ADC1: mute amp left and right */ 6027 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6028 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 6029 /* ADC2: mute amp left and right */ 6030 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6031 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 6032 /* ADC3: mute amp left and right */ 6033 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6034 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 6035 6036 { } 6037}; 6038 6039/* Macbook Pro rev3 */ 6040static struct hda_verb alc885_mbp3_init_verbs[] = { 6041 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 6042 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6043 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6044 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6045 /* Rear mixer */ 6046 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6047 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6048 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6049 /* Front Pin: output 0 (0x0c) */ 6050 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6051 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6052 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 6053 /* HP Pin: output 0 (0x0d) */ 6054 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, 6055 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 6056 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 6057 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 6058 /* Mic (rear) pin: input vref at 80% */ 6059 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 6060 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 6061 /* Front Mic pin: input vref at 80% */ 6062 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 6063 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 6064 /* Line In pin: use output 1 when in LineOut mode */ 6065 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 6066 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 6067 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, 6068 6069 /* FIXME: use matrix-type input source selection */ 6070 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 6071 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 6072 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6073 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 6074 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 6075 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 6076 /* Input mixer2 */ 6077 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6078 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 6079 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 6080 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 6081 /* Input mixer3 */ 6082 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6083 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 6084 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 6085 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 6086 /* ADC1: mute amp left and right */ 6087 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6088 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 6089 /* ADC2: mute amp left and right */ 6090 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6091 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 6092 /* ADC3: mute amp left and right */ 6093 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6094 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 6095 6096 { } 6097}; 6098 6099/* iMac 24 mixer. */ 6100static struct snd_kcontrol_new alc885_imac24_mixer[] = { 6101 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 6102 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT), 6103 { } /* end */ 6104}; 6105 6106/* iMac 24 init verbs. */ 6107static struct hda_verb alc885_imac24_init_verbs[] = { 6108 /* Internal speakers: output 0 (0x0c) */ 6109 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6110 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6111 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00}, 6112 /* Internal speakers: output 0 (0x0c) */ 6113 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6114 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6115 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00}, 6116 /* Headphone: output 0 (0x0c) */ 6117 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6118 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6119 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 6120 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 6121 /* Front Mic: input vref at 80% */ 6122 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 6123 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 6124 { } 6125}; 6126 6127/* Toggle speaker-output according to the hp-jack state */ 6128static void alc885_imac24_automute(struct hda_codec *codec) 6129{ 6130 unsigned int present; 6131 6132 present = snd_hda_codec_read(codec, 0x14, 0, 6133 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 6134 snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0, 6135 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 6136 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0, 6137 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 6138} 6139 6140/* Processes unsolicited events. */ 6141static void alc885_imac24_unsol_event(struct hda_codec *codec, 6142 unsigned int res) 6143{ 6144 /* Headphone insertion or removal. */ 6145 if ((res >> 26) == ALC880_HP_EVENT) 6146 alc885_imac24_automute(codec); 6147} 6148 6149static void alc885_mbp3_automute(struct hda_codec *codec) 6150{ 6151 unsigned int present; 6152 6153 present = snd_hda_codec_read(codec, 0x15, 0, 6154 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 6155 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 6156 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 6157 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 6158 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE); 6159 6160} 6161static void alc885_mbp3_unsol_event(struct hda_codec *codec, 6162 unsigned int res) 6163{ 6164 /* Headphone insertion or removal. */ 6165 if ((res >> 26) == ALC880_HP_EVENT) 6166 alc885_mbp3_automute(codec); 6167} 6168 6169 6170static struct hda_verb alc882_targa_verbs[] = { 6171 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6172 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 6173 6174 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6175 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6176 6177 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ 6178 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */ 6179 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 6180 6181 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 6182 {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, 6183 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03}, 6184 {0x01, AC_VERB_SET_GPIO_DATA, 0x03}, 6185 { } /* end */ 6186}; 6187 6188/* toggle speaker-output according to the hp-jack state */ 6189static void alc882_targa_automute(struct hda_codec *codec) 6190{ 6191 unsigned int present; 6192 6193 present = snd_hda_codec_read(codec, 0x14, 0, 6194 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 6195 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0, 6196 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 6197 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA, 6198 present ? 1 : 3); 6199} 6200 6201static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res) 6202{ 6203 /* Looks like the unsol event is incompatible with the standard 6204 * definition. 4bit tag is placed at 26 bit! 6205 */ 6206 if (((res >> 26) == ALC880_HP_EVENT)) { 6207 alc882_targa_automute(codec); 6208 } 6209} 6210 6211static struct hda_verb alc882_asus_a7j_verbs[] = { 6212 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6213 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 6214 6215 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6216 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6217 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6218 6219 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */ 6220 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 6221 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */ 6222 6223 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ 6224 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */ 6225 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 6226 { } /* end */ 6227}; 6228 6229static struct hda_verb alc882_asus_a7m_verbs[] = { 6230 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6231 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 6232 6233 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6234 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6235 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6236 6237 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */ 6238 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 6239 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */ 6240 6241 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ 6242 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */ 6243 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 6244 { } /* end */ 6245}; 6246 6247static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted) 6248{ 6249 unsigned int gpiostate, gpiomask, gpiodir; 6250 6251 gpiostate = snd_hda_codec_read(codec, codec->afg, 0, 6252 AC_VERB_GET_GPIO_DATA, 0); 6253 6254 if (!muted) 6255 gpiostate |= (1 << pin); 6256 else 6257 gpiostate &= ~(1 << pin); 6258 6259 gpiomask = snd_hda_codec_read(codec, codec->afg, 0, 6260 AC_VERB_GET_GPIO_MASK, 0); 6261 gpiomask |= (1 << pin); 6262 6263 gpiodir = snd_hda_codec_read(codec, codec->afg, 0, 6264 AC_VERB_GET_GPIO_DIRECTION, 0); 6265 gpiodir |= (1 << pin); 6266 6267 6268 snd_hda_codec_write(codec, codec->afg, 0, 6269 AC_VERB_SET_GPIO_MASK, gpiomask); 6270 snd_hda_codec_write(codec, codec->afg, 0, 6271 AC_VERB_SET_GPIO_DIRECTION, gpiodir); 6272 6273 msleep(1); 6274 6275 snd_hda_codec_write(codec, codec->afg, 0, 6276 AC_VERB_SET_GPIO_DATA, gpiostate); 6277} 6278 6279/* set up GPIO at initialization */ 6280static void alc885_macpro_init_hook(struct hda_codec *codec) 6281{ 6282 alc882_gpio_mute(codec, 0, 0); 6283 alc882_gpio_mute(codec, 1, 0); 6284} 6285 6286/* set up GPIO and update auto-muting at initialization */ 6287static void alc885_imac24_init_hook(struct hda_codec *codec) 6288{ 6289 alc885_macpro_init_hook(codec); 6290 alc885_imac24_automute(codec); 6291} 6292 6293/* 6294 * generic initialization of ADC, input mixers and output mixers 6295 */ 6296static struct hda_verb alc882_auto_init_verbs[] = { 6297 /* 6298 * Unmute ADC0-2 and set the default input to mic-in 6299 */ 6300 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 6301 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6302 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 6303 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6304 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 6305 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6306 6307 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 6308 * mixer widget 6309 * Note: PASD motherboards uses the Line In 2 as the input for 6310 * front panel mic (mic 2) 6311 */ 6312 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 6313 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6314 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6315 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 6316 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 6317 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 6318 6319 /* 6320 * Set up output mixers (0x0c - 0x0f) 6321 */ 6322 /* set vol=0 to output mixers */ 6323 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6324 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6325 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6326 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6327 /* set up input amps for analog loopback */ 6328 /* Amp Indices: DAC = 0, mixer = 1 */ 6329 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6330 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 6331 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6332 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 6333 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6334 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 6335 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6336 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 6337 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6338 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 6339 6340 /* FIXME: use matrix-type input source selection */ 6341 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 6342 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 6343 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 6344 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 6345 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 6346 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 6347 /* Input mixer2 */ 6348 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 6349 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 6350 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 6351 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 6352 /* Input mixer3 */ 6353 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 6354 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 6355 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 6356 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 6357 6358 { } 6359}; 6360 6361#ifdef CONFIG_SND_HDA_POWER_SAVE 6362#define alc882_loopbacks alc880_loopbacks 6363#endif 6364 6365/* pcm configuration: identiacal with ALC880 */ 6366#define alc882_pcm_analog_playback alc880_pcm_analog_playback 6367#define alc882_pcm_analog_capture alc880_pcm_analog_capture 6368#define alc882_pcm_digital_playback alc880_pcm_digital_playback 6369#define alc882_pcm_digital_capture alc880_pcm_digital_capture 6370 6371/* 6372 * configuration and preset 6373 */ 6374static const char *alc882_models[ALC882_MODEL_LAST] = { 6375 [ALC882_3ST_DIG] = "3stack-dig", 6376 [ALC882_6ST_DIG] = "6stack-dig", 6377 [ALC882_ARIMA] = "arima", 6378 [ALC882_W2JC] = "w2jc", 6379 [ALC882_TARGA] = "targa", 6380 [ALC882_ASUS_A7J] = "asus-a7j", 6381 [ALC882_ASUS_A7M] = "asus-a7m", 6382 [ALC885_MACPRO] = "macpro", 6383 [ALC885_MBP3] = "mbp3", 6384 [ALC885_IMAC24] = "imac24", 6385 [ALC882_AUTO] = "auto", 6386}; 6387 6388static struct snd_pci_quirk alc882_cfg_tbl[] = { 6389 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG), 6390 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J), 6391 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J), 6392 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M), 6393 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC), 6394 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG), 6395 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG), 6396 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG), 6397 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG), 6398 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */ 6399 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG), 6400 SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), 6401 {} 6402}; 6403 6404static struct alc_config_preset alc882_presets[] = { 6405 [ALC882_3ST_DIG] = { 6406 .mixers = { alc882_base_mixer }, 6407 .init_verbs = { alc882_init_verbs }, 6408 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 6409 .dac_nids = alc882_dac_nids, 6410 .dig_out_nid = ALC882_DIGOUT_NID, 6411 .dig_in_nid = ALC882_DIGIN_NID, 6412 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes), 6413 .channel_mode = alc882_ch_modes, 6414 .need_dac_fix = 1, 6415 .input_mux = &alc882_capture_source, 6416 }, 6417 [ALC882_6ST_DIG] = { 6418 .mixers = { alc882_base_mixer, alc882_chmode_mixer }, 6419 .init_verbs = { alc882_init_verbs }, 6420 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 6421 .dac_nids = alc882_dac_nids, 6422 .dig_out_nid = ALC882_DIGOUT_NID, 6423 .dig_in_nid = ALC882_DIGIN_NID, 6424 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes), 6425 .channel_mode = alc882_sixstack_modes, 6426 .input_mux = &alc882_capture_source, 6427 }, 6428 [ALC882_ARIMA] = { 6429 .mixers = { alc882_base_mixer, alc882_chmode_mixer }, 6430 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs }, 6431 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 6432 .dac_nids = alc882_dac_nids, 6433 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes), 6434 .channel_mode = alc882_sixstack_modes, 6435 .input_mux = &alc882_capture_source, 6436 }, 6437 [ALC882_W2JC] = { 6438 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer }, 6439 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs, 6440 alc880_gpio1_init_verbs }, 6441 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 6442 .dac_nids = alc882_dac_nids, 6443 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), 6444 .channel_mode = alc880_threestack_modes, 6445 .need_dac_fix = 1, 6446 .input_mux = &alc882_capture_source, 6447 .dig_out_nid = ALC882_DIGOUT_NID, 6448 }, 6449 [ALC885_MBP3] = { 6450 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer }, 6451 .init_verbs = { alc885_mbp3_init_verbs, 6452 alc880_gpio1_init_verbs }, 6453 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 6454 .dac_nids = alc882_dac_nids, 6455 .channel_mode = alc885_mbp_6ch_modes, 6456 .num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes), 6457 .input_mux = &alc882_capture_source, 6458 .dig_out_nid = ALC882_DIGOUT_NID, 6459 .dig_in_nid = ALC882_DIGIN_NID, 6460 .unsol_event = alc885_mbp3_unsol_event, 6461 .init_hook = alc885_mbp3_automute, 6462 }, 6463 [ALC885_MACPRO] = { 6464 .mixers = { alc882_macpro_mixer }, 6465 .init_verbs = { alc882_macpro_init_verbs }, 6466 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 6467 .dac_nids = alc882_dac_nids, 6468 .dig_out_nid = ALC882_DIGOUT_NID, 6469 .dig_in_nid = ALC882_DIGIN_NID, 6470 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes), 6471 .channel_mode = alc882_ch_modes, 6472 .input_mux = &alc882_capture_source, 6473 .init_hook = alc885_macpro_init_hook, 6474 }, 6475 [ALC885_IMAC24] = { 6476 .mixers = { alc885_imac24_mixer }, 6477 .init_verbs = { alc885_imac24_init_verbs }, 6478 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 6479 .dac_nids = alc882_dac_nids, 6480 .dig_out_nid = ALC882_DIGOUT_NID, 6481 .dig_in_nid = ALC882_DIGIN_NID, 6482 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes), 6483 .channel_mode = alc882_ch_modes, 6484 .input_mux = &alc882_capture_source, 6485 .unsol_event = alc885_imac24_unsol_event, 6486 .init_hook = alc885_imac24_init_hook, 6487 }, 6488 [ALC882_TARGA] = { 6489 .mixers = { alc882_targa_mixer, alc882_chmode_mixer }, 6490 .init_verbs = { alc882_init_verbs, alc882_targa_verbs}, 6491 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 6492 .dac_nids = alc882_dac_nids, 6493 .dig_out_nid = ALC882_DIGOUT_NID, 6494 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids), 6495 .adc_nids = alc882_adc_nids, 6496 .capsrc_nids = alc882_capsrc_nids, 6497 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes), 6498 .channel_mode = alc882_3ST_6ch_modes, 6499 .need_dac_fix = 1, 6500 .input_mux = &alc882_capture_source, 6501 .unsol_event = alc882_targa_unsol_event, 6502 .init_hook = alc882_targa_automute, 6503 }, 6504 [ALC882_ASUS_A7J] = { 6505 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer }, 6506 .init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs}, 6507 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 6508 .dac_nids = alc882_dac_nids, 6509 .dig_out_nid = ALC882_DIGOUT_NID, 6510 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids), 6511 .adc_nids = alc882_adc_nids, 6512 .capsrc_nids = alc882_capsrc_nids, 6513 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes), 6514 .channel_mode = alc882_3ST_6ch_modes, 6515 .need_dac_fix = 1, 6516 .input_mux = &alc882_capture_source, 6517 }, 6518 [ALC882_ASUS_A7M] = { 6519 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer }, 6520 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs, 6521 alc880_gpio1_init_verbs, 6522 alc882_asus_a7m_verbs }, 6523 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 6524 .dac_nids = alc882_dac_nids, 6525 .dig_out_nid = ALC882_DIGOUT_NID, 6526 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), 6527 .channel_mode = alc880_threestack_modes, 6528 .need_dac_fix = 1, 6529 .input_mux = &alc882_capture_source, 6530 }, 6531}; 6532 6533 6534/* 6535 * Pin config fixes 6536 */ 6537enum { 6538 PINFIX_ABIT_AW9D_MAX 6539}; 6540 6541static struct alc_pincfg alc882_abit_aw9d_pinfix[] = { 6542 { 0x15, 0x01080104 }, /* side */ 6543 { 0x16, 0x01011012 }, /* rear */ 6544 { 0x17, 0x01016011 }, /* clfe */ 6545 { } 6546}; 6547 6548static const struct alc_pincfg *alc882_pin_fixes[] = { 6549 [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix, 6550}; 6551 6552static struct snd_pci_quirk alc882_pinfix_tbl[] = { 6553 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX), 6554 {} 6555}; 6556 6557/* 6558 * BIOS auto configuration 6559 */ 6560static void alc882_auto_set_output_and_unmute(struct hda_codec *codec, 6561 hda_nid_t nid, int pin_type, 6562 int dac_idx) 6563{ 6564 /* set as output */ 6565 struct alc_spec *spec = codec->spec; 6566 int idx; 6567 6568 alc_set_pin_output(codec, nid, pin_type); 6569 if (spec->multiout.dac_nids[dac_idx] == 0x25) 6570 idx = 4; 6571 else 6572 idx = spec->multiout.dac_nids[dac_idx] - 2; 6573 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx); 6574 6575} 6576 6577static void alc882_auto_init_multi_out(struct hda_codec *codec) 6578{ 6579 struct alc_spec *spec = codec->spec; 6580 int i; 6581 6582 alc_subsystem_id(codec, 0x15, 0x1b, 0x14); 6583 for (i = 0; i <= HDA_SIDE; i++) { 6584 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 6585 int pin_type = get_pin_type(spec->autocfg.line_out_type); 6586 if (nid) 6587 alc882_auto_set_output_and_unmute(codec, nid, pin_type, 6588 i); 6589 } 6590} 6591 6592static void alc882_auto_init_hp_out(struct hda_codec *codec) 6593{ 6594 struct alc_spec *spec = codec->spec; 6595 hda_nid_t pin; 6596 6597 pin = spec->autocfg.hp_pins[0]; 6598 if (pin) /* connect to front */ 6599 /* use dac 0 */ 6600 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); 6601 pin = spec->autocfg.speaker_pins[0]; 6602 if (pin) 6603 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0); 6604} 6605 6606#define alc882_is_input_pin(nid) alc880_is_input_pin(nid) 6607#define ALC882_PIN_CD_NID ALC880_PIN_CD_NID 6608 6609static void alc882_auto_init_analog_input(struct hda_codec *codec) 6610{ 6611 struct alc_spec *spec = codec->spec; 6612 int i; 6613 6614 for (i = 0; i < AUTO_PIN_LAST; i++) { 6615 hda_nid_t nid = spec->autocfg.input_pins[i]; 6616 unsigned int vref; 6617 if (!nid) 6618 continue; 6619 vref = PIN_IN; 6620 if (1 /*i <= AUTO_PIN_FRONT_MIC*/) { 6621 unsigned int pincap; 6622 pincap = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP); 6623 if ((pincap >> AC_PINCAP_VREF_SHIFT) & 6624 AC_PINCAP_VREF_80) 6625 vref = PIN_VREF80; 6626 } 6627 snd_hda_codec_write(codec, nid, 0, 6628 AC_VERB_SET_PIN_WIDGET_CONTROL, vref); 6629 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP) 6630 snd_hda_codec_write(codec, nid, 0, 6631 AC_VERB_SET_AMP_GAIN_MUTE, 6632 AMP_OUT_MUTE); 6633 } 6634} 6635 6636static void alc882_auto_init_input_src(struct hda_codec *codec) 6637{ 6638 struct alc_spec *spec = codec->spec; 6639 const struct hda_input_mux *imux = spec->input_mux; 6640 int c; 6641 6642 for (c = 0; c < spec->num_adc_nids; c++) { 6643 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS]; 6644 hda_nid_t nid = spec->capsrc_nids[c]; 6645 int conns, mute, idx, item; 6646 6647 conns = snd_hda_get_connections(codec, nid, conn_list, 6648 ARRAY_SIZE(conn_list)); 6649 if (conns < 0) 6650 continue; 6651 for (idx = 0; idx < conns; idx++) { 6652 /* if the current connection is the selected one, 6653 * unmute it as default - otherwise mute it 6654 */ 6655 mute = AMP_IN_MUTE(idx); 6656 for (item = 0; item < imux->num_items; item++) { 6657 if (imux->items[item].index == idx) { 6658 if (spec->cur_mux[c] == item) 6659 mute = AMP_IN_UNMUTE(idx); 6660 break; 6661 } 6662 } 6663 snd_hda_codec_write(codec, nid, 0, 6664 AC_VERB_SET_AMP_GAIN_MUTE, mute); 6665 } 6666 } 6667} 6668 6669/* add mic boosts if needed */ 6670static int alc_auto_add_mic_boost(struct hda_codec *codec) 6671{ 6672 struct alc_spec *spec = codec->spec; 6673 int err; 6674 hda_nid_t nid; 6675 6676 nid = spec->autocfg.input_pins[AUTO_PIN_MIC]; 6677 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) { 6678 err = add_control(spec, ALC_CTL_WIDGET_VOL, 6679 "Mic Boost", 6680 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT)); 6681 if (err < 0) 6682 return err; 6683 } 6684 nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC]; 6685 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) { 6686 err = add_control(spec, ALC_CTL_WIDGET_VOL, 6687 "Front Mic Boost", 6688 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT)); 6689 if (err < 0) 6690 return err; 6691 } 6692 return 0; 6693} 6694 6695/* almost identical with ALC880 parser... */ 6696static int alc882_parse_auto_config(struct hda_codec *codec) 6697{ 6698 struct alc_spec *spec = codec->spec; 6699 int err = alc880_parse_auto_config(codec); 6700 6701 if (err < 0) 6702 return err; 6703 else if (!err) 6704 return 0; /* no config found */ 6705 6706 err = alc_auto_add_mic_boost(codec); 6707 if (err < 0) 6708 return err; 6709 6710 /* hack - override the init verbs */ 6711 spec->init_verbs[0] = alc882_auto_init_verbs; 6712 6713 return 1; /* config found */ 6714} 6715 6716/* additional initialization for auto-configuration model */ 6717static void alc882_auto_init(struct hda_codec *codec) 6718{ 6719 struct alc_spec *spec = codec->spec; 6720 alc882_auto_init_multi_out(codec); 6721 alc882_auto_init_hp_out(codec); 6722 alc882_auto_init_analog_input(codec); 6723 alc882_auto_init_input_src(codec); 6724 if (spec->unsol_event) 6725 alc_inithook(codec); 6726} 6727 6728static int patch_alc883(struct hda_codec *codec); /* called in patch_alc882() */ 6729 6730static int patch_alc882(struct hda_codec *codec) 6731{ 6732 struct alc_spec *spec; 6733 int err, board_config; 6734 6735 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 6736 if (spec == NULL) 6737 return -ENOMEM; 6738 6739 codec->spec = spec; 6740 6741 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST, 6742 alc882_models, 6743 alc882_cfg_tbl); 6744 6745 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) { 6746 /* Pick up systems that don't supply PCI SSID */ 6747 switch (codec->subsystem_id) { 6748 case 0x106b0c00: /* Mac Pro */ 6749 board_config = ALC885_MACPRO; 6750 break; 6751 case 0x106b1000: /* iMac 24 */ 6752 case 0x106b2800: /* AppleTV */ 6753 board_config = ALC885_IMAC24; 6754 break; 6755 case 0x106b00a1: /* Macbook (might be wrong - PCI SSID?) */ 6756 case 0x106b00a4: /* MacbookPro4,1 */ 6757 case 0x106b2c00: /* Macbook Pro rev3 */ 6758 case 0x106b3600: /* Macbook 3.1 */ 6759 board_config = ALC885_MBP3; 6760 break; 6761 default: 6762 /* ALC889A is handled better as ALC888-compatible */ 6763 if (codec->revision_id == 0x100101 || 6764 codec->revision_id == 0x100103) { 6765 alc_free(codec); 6766 return patch_alc883(codec); 6767 } 6768 printk(KERN_INFO "hda_codec: Unknown model for ALC882, " 6769 "trying auto-probe from BIOS...\n"); 6770 board_config = ALC882_AUTO; 6771 } 6772 } 6773 6774 alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes); 6775 6776 if (board_config == ALC882_AUTO) { 6777 /* automatic parse from the BIOS config */ 6778 err = alc882_parse_auto_config(codec); 6779 if (err < 0) { 6780 alc_free(codec); 6781 return err; 6782 } else if (!err) { 6783 printk(KERN_INFO 6784 "hda_codec: Cannot set up configuration " 6785 "from BIOS. Using base mode...\n"); 6786 board_config = ALC882_3ST_DIG; 6787 } 6788 } 6789 6790 if (board_config != ALC882_AUTO) 6791 setup_preset(spec, &alc882_presets[board_config]); 6792 6793 if (codec->vendor_id == 0x10ec0885) { 6794 spec->stream_name_analog = "ALC885 Analog"; 6795 spec->stream_name_digital = "ALC885 Digital"; 6796 } else { 6797 spec->stream_name_analog = "ALC882 Analog"; 6798 spec->stream_name_digital = "ALC882 Digital"; 6799 } 6800 6801 spec->stream_analog_playback = &alc882_pcm_analog_playback; 6802 spec->stream_analog_capture = &alc882_pcm_analog_capture; 6803 /* FIXME: setup DAC5 */ 6804 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/ 6805 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture; 6806 6807 spec->stream_digital_playback = &alc882_pcm_digital_playback; 6808 spec->stream_digital_capture = &alc882_pcm_digital_capture; 6809 6810 spec->is_mix_capture = 1; /* matrix-style capture */ 6811 if (!spec->adc_nids && spec->input_mux) { 6812 /* check whether NID 0x07 is valid */ 6813 unsigned int wcap = get_wcaps(codec, 0x07); 6814 /* get type */ 6815 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; 6816 if (wcap != AC_WID_AUD_IN) { 6817 spec->adc_nids = alc882_adc_nids_alt; 6818 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt); 6819 spec->capsrc_nids = alc882_capsrc_nids_alt; 6820 } else { 6821 spec->adc_nids = alc882_adc_nids; 6822 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids); 6823 spec->capsrc_nids = alc882_capsrc_nids; 6824 } 6825 } 6826 set_capture_mixer(spec); 6827 6828 spec->vmaster_nid = 0x0c; 6829 6830 codec->patch_ops = alc_patch_ops; 6831 if (board_config == ALC882_AUTO) 6832 spec->init_hook = alc882_auto_init; 6833#ifdef CONFIG_SND_HDA_POWER_SAVE 6834 if (!spec->loopback.amplist) 6835 spec->loopback.amplist = alc882_loopbacks; 6836#endif 6837 6838 return 0; 6839} 6840 6841/* 6842 * ALC883 support 6843 * 6844 * ALC883 is almost identical with ALC880 but has cleaner and more flexible 6845 * configuration. Each pin widget can choose any input DACs and a mixer. 6846 * Each ADC is connected from a mixer of all inputs. This makes possible 6847 * 6-channel independent captures. 6848 * 6849 * In addition, an independent DAC for the multi-playback (not used in this 6850 * driver yet). 6851 */ 6852#define ALC883_DIGOUT_NID 0x06 6853#define ALC883_DIGIN_NID 0x0a 6854 6855static hda_nid_t alc883_dac_nids[4] = { 6856 /* front, rear, clfe, rear_surr */ 6857 0x02, 0x03, 0x04, 0x05 6858}; 6859 6860static hda_nid_t alc883_adc_nids[2] = { 6861 /* ADC1-2 */ 6862 0x08, 0x09, 6863}; 6864 6865static hda_nid_t alc883_adc_nids_alt[1] = { 6866 /* ADC1 */ 6867 0x08, 6868}; 6869 6870static hda_nid_t alc883_capsrc_nids[2] = { 0x23, 0x22 }; 6871 6872/* input MUX */ 6873/* FIXME: should be a matrix-type input source selection */ 6874 6875static struct hda_input_mux alc883_capture_source = { 6876 .num_items = 4, 6877 .items = { 6878 { "Mic", 0x0 }, 6879 { "Front Mic", 0x1 }, 6880 { "Line", 0x2 }, 6881 { "CD", 0x4 }, 6882 }, 6883}; 6884 6885static struct hda_input_mux alc883_3stack_6ch_intel = { 6886 .num_items = 4, 6887 .items = { 6888 { "Mic", 0x1 }, 6889 { "Front Mic", 0x0 }, 6890 { "Line", 0x2 }, 6891 { "CD", 0x4 }, 6892 }, 6893}; 6894 6895static struct hda_input_mux alc883_lenovo_101e_capture_source = { 6896 .num_items = 2, 6897 .items = { 6898 { "Mic", 0x1 }, 6899 { "Line", 0x2 }, 6900 }, 6901}; 6902 6903static struct hda_input_mux alc883_lenovo_nb0763_capture_source = { 6904 .num_items = 4, 6905 .items = { 6906 { "Mic", 0x0 }, 6907 { "iMic", 0x1 }, 6908 { "Line", 0x2 }, 6909 { "CD", 0x4 }, 6910 }, 6911}; 6912 6913static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = { 6914 .num_items = 2, 6915 .items = { 6916 { "Mic", 0x0 }, 6917 { "Int Mic", 0x1 }, 6918 }, 6919}; 6920 6921static struct hda_input_mux alc883_lenovo_sky_capture_source = { 6922 .num_items = 3, 6923 .items = { 6924 { "Mic", 0x0 }, 6925 { "Front Mic", 0x1 }, 6926 { "Line", 0x4 }, 6927 }, 6928}; 6929 6930static struct hda_input_mux alc883_asus_eee1601_capture_source = { 6931 .num_items = 2, 6932 .items = { 6933 { "Mic", 0x0 }, 6934 { "Line", 0x2 }, 6935 }, 6936}; 6937 6938/* 6939 * 2ch mode 6940 */ 6941static struct hda_channel_mode alc883_3ST_2ch_modes[1] = { 6942 { 2, NULL } 6943}; 6944 6945/* 6946 * 2ch mode 6947 */ 6948static struct hda_verb alc883_3ST_ch2_init[] = { 6949 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 6950 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 6951 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 6952 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 6953 { } /* end */ 6954}; 6955 6956/* 6957 * 4ch mode 6958 */ 6959static struct hda_verb alc883_3ST_ch4_init[] = { 6960 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 6961 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 6962 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 6963 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 6964 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 6965 { } /* end */ 6966}; 6967 6968/* 6969 * 6ch mode 6970 */ 6971static struct hda_verb alc883_3ST_ch6_init[] = { 6972 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 6973 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 6974 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, 6975 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 6976 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 6977 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 6978 { } /* end */ 6979}; 6980 6981static struct hda_channel_mode alc883_3ST_6ch_modes[3] = { 6982 { 2, alc883_3ST_ch2_init }, 6983 { 4, alc883_3ST_ch4_init }, 6984 { 6, alc883_3ST_ch6_init }, 6985}; 6986 6987/* 6988 * 2ch mode 6989 */ 6990static struct hda_verb alc883_3ST_ch2_intel_init[] = { 6991 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 6992 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 6993 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 6994 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 6995 { } /* end */ 6996}; 6997 6998/* 6999 * 4ch mode 7000 */ 7001static struct hda_verb alc883_3ST_ch4_intel_init[] = { 7002 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 7003 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7004 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7005 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7006 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7007 { } /* end */ 7008}; 7009 7010/* 7011 * 6ch mode 7012 */ 7013static struct hda_verb alc883_3ST_ch6_intel_init[] = { 7014 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7015 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7016 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 }, 7017 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7018 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7019 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7020 { } /* end */ 7021}; 7022 7023static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = { 7024 { 2, alc883_3ST_ch2_intel_init }, 7025 { 4, alc883_3ST_ch4_intel_init }, 7026 { 6, alc883_3ST_ch6_intel_init }, 7027}; 7028 7029/* 7030 * 6ch mode 7031 */ 7032static struct hda_verb alc883_sixstack_ch6_init[] = { 7033 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 7034 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7035 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7036 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7037 { } /* end */ 7038}; 7039 7040/* 7041 * 8ch mode 7042 */ 7043static struct hda_verb alc883_sixstack_ch8_init[] = { 7044 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7045 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7046 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7047 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7048 { } /* end */ 7049}; 7050 7051static struct hda_channel_mode alc883_sixstack_modes[2] = { 7052 { 6, alc883_sixstack_ch6_init }, 7053 { 8, alc883_sixstack_ch8_init }, 7054}; 7055 7056static struct hda_verb alc883_medion_eapd_verbs[] = { 7057 /* eanable EAPD on medion laptop */ 7058 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 7059 {0x20, AC_VERB_SET_PROC_COEF, 0x3070}, 7060 { } 7061}; 7062 7063/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 7064 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b 7065 */ 7066 7067static struct snd_kcontrol_new alc883_base_mixer[] = { 7068 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7069 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 7070 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 7071 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 7072 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 7073 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 7074 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 7075 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 7076 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 7077 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 7078 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 7079 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 7080 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 7081 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 7082 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 7083 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7084 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 7085 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7086 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 7087 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 7088 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 7089 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 7090 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 7091 { } /* end */ 7092}; 7093 7094static struct snd_kcontrol_new alc883_mitac_mixer[] = { 7095 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7096 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 7097 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 7098 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 7099 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 7100 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 7101 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 7102 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7103 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 7104 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7105 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 7106 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 7107 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 7108 { } /* end */ 7109}; 7110 7111static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = { 7112 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7113 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), 7114 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 7115 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 7116 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7117 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 7118 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7119 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 7120 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 7121 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 7122 { } /* end */ 7123}; 7124 7125static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = { 7126 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7127 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), 7128 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 7129 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 7130 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7131 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 7132 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7133 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 7134 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 7135 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 7136 { } /* end */ 7137}; 7138 7139static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = { 7140 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7141 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 7142 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 7143 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 7144 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 7145 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 7146 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 7147 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7148 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 7149 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7150 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 7151 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 7152 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 7153 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 7154 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 7155 { } /* end */ 7156}; 7157 7158static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = { 7159 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7160 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 7161 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 7162 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 7163 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 7164 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 7165 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 7166 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 7167 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 7168 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 7169 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 7170 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 7171 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 7172 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7173 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 7174 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7175 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 7176 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 7177 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 7178 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 7179 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 7180 { } /* end */ 7181}; 7182 7183static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = { 7184 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7185 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 7186 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 7187 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 7188 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, 7189 HDA_OUTPUT), 7190 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 7191 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 7192 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 7193 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 7194 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 7195 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 7196 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 7197 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 7198 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 7199 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT), 7200 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 7201 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7202 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT), 7203 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7204 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 7205 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 7206 { } /* end */ 7207}; 7208 7209static struct snd_kcontrol_new alc883_fivestack_mixer[] = { 7210 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7211 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 7212 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 7213 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 7214 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 7215 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 7216 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 7217 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 7218 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 7219 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 7220 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 7221 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 7222 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 7223 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7224 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 7225 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7226 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 7227 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 7228 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 7229 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 7230 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 7231 { } /* end */ 7232}; 7233 7234static struct snd_kcontrol_new alc883_tagra_mixer[] = { 7235 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7236 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 7237 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 7238 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 7239 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 7240 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 7241 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 7242 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 7243 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 7244 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 7245 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 7246 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 7247 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 7248 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7249 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 7250 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7251 { } /* end */ 7252}; 7253 7254static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = { 7255 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7256 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 7257 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 7258 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 7259 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 7260 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7261 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 7262 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7263 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 7264 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 7265 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 7266 { } /* end */ 7267}; 7268 7269static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = { 7270 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7271 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 7272 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 7273 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 7274 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 7275 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 7276 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 7277 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 7278 { } /* end */ 7279}; 7280 7281static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = { 7282 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7283 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT), 7284 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 7285 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 7286 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 7287 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7288 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7289 HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT), 7290 HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT), 7291 { } /* end */ 7292}; 7293 7294static struct snd_kcontrol_new alc883_medion_md2_mixer[] = { 7295 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7296 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 7297 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT), 7298 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 7299 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 7300 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7301 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7302 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 7303 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 7304 { } /* end */ 7305}; 7306 7307static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = { 7308 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7309 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 7310 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 7311 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 7312 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 7313 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7314 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 7315 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7316 { } /* end */ 7317}; 7318 7319static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = { 7320 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7321 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 7322 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT), 7323 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT), 7324 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 7325 0x0d, 1, 0x0, HDA_OUTPUT), 7326 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT), 7327 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT), 7328 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT), 7329 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 7330 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 7331 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 7332 HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x1a, 0x0, HDA_OUTPUT), 7333 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 7334 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 7335 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 7336 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 7337 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7338 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 7339 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7340 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 7341 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 7342 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 7343 { } /* end */ 7344}; 7345 7346static struct hda_bind_ctls alc883_bind_cap_vol = { 7347 .ops = &snd_hda_bind_vol, 7348 .values = { 7349 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT), 7350 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT), 7351 0 7352 }, 7353}; 7354 7355static struct hda_bind_ctls alc883_bind_cap_switch = { 7356 .ops = &snd_hda_bind_sw, 7357 .values = { 7358 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT), 7359 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT), 7360 0 7361 }, 7362}; 7363 7364static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = { 7365 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7366 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 7367 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 7368 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 7369 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 7370 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7371 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 7372 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7373 { } /* end */ 7374}; 7375 7376static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = { 7377 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol), 7378 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch), 7379 { 7380 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 7381 /* .name = "Capture Source", */ 7382 .name = "Input Source", 7383 .count = 1, 7384 .info = alc_mux_enum_info, 7385 .get = alc_mux_enum_get, 7386 .put = alc_mux_enum_put, 7387 }, 7388 { } /* end */ 7389}; 7390 7391static struct snd_kcontrol_new alc883_chmode_mixer[] = { 7392 { 7393 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 7394 .name = "Channel Mode", 7395 .info = alc_ch_mode_info, 7396 .get = alc_ch_mode_get, 7397 .put = alc_ch_mode_put, 7398 }, 7399 { } /* end */ 7400}; 7401 7402static struct hda_verb alc883_init_verbs[] = { 7403 /* ADC1: mute amp left and right */ 7404 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7405 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 7406 /* ADC2: mute amp left and right */ 7407 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7408 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 7409 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 7410 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 7411 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7412 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7413 /* Rear mixer */ 7414 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 7415 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7416 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7417 /* CLFE mixer */ 7418 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 7419 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7420 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7421 /* Side mixer */ 7422 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 7423 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7424 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7425 7426 /* mute analog input loopbacks */ 7427 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7428 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7429 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 7430 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 7431 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 7432 7433 /* Front Pin: output 0 (0x0c) */ 7434 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 7435 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7436 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 7437 /* Rear Pin: output 1 (0x0d) */ 7438 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 7439 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7440 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 7441 /* CLFE Pin: output 2 (0x0e) */ 7442 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 7443 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7444 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, 7445 /* Side Pin: output 3 (0x0f) */ 7446 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 7447 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7448 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, 7449 /* Mic (rear) pin: input vref at 80% */ 7450 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 7451 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 7452 /* Front Mic pin: input vref at 80% */ 7453 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 7454 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 7455 /* Line In pin: input */ 7456 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 7457 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 7458 /* Line-2 In: Headphone output (output 0 - 0x0c) */ 7459 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 7460 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7461 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 7462 /* CD pin widget for input */ 7463 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 7464 7465 /* FIXME: use matrix-type input source selection */ 7466 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 7467 /* Input mixer2 */ 7468 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7469 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7470 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 7471 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 7472 /* Input mixer3 */ 7473 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7474 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7475 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 7476 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 7477 { } 7478}; 7479 7480/* toggle speaker-output according to the hp-jack state */ 7481static void alc883_mitac_hp_automute(struct hda_codec *codec) 7482{ 7483 unsigned int present; 7484 7485 present = snd_hda_codec_read(codec, 0x15, 0, 7486 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 7487 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 7488 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 7489 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0, 7490 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 7491} 7492 7493/* auto-toggle front mic */ 7494/* 7495static void alc883_mitac_mic_automute(struct hda_codec *codec) 7496{ 7497 unsigned int present; 7498 unsigned char bits; 7499 7500 present = snd_hda_codec_read(codec, 0x18, 0, 7501 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 7502 bits = present ? HDA_AMP_MUTE : 0; 7503 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits); 7504} 7505*/ 7506 7507static void alc883_mitac_automute(struct hda_codec *codec) 7508{ 7509 alc883_mitac_hp_automute(codec); 7510 /* alc883_mitac_mic_automute(codec); */ 7511} 7512 7513static void alc883_mitac_unsol_event(struct hda_codec *codec, 7514 unsigned int res) 7515{ 7516 switch (res >> 26) { 7517 case ALC880_HP_EVENT: 7518 alc883_mitac_hp_automute(codec); 7519 break; 7520 case ALC880_MIC_EVENT: 7521 /* alc883_mitac_mic_automute(codec); */ 7522 break; 7523 } 7524} 7525 7526static struct hda_verb alc883_mitac_verbs[] = { 7527 /* HP */ 7528 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 7529 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 7530 /* Subwoofer */ 7531 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02}, 7532 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 7533 7534 /* enable unsolicited event */ 7535 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 7536 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */ 7537 7538 { } /* end */ 7539}; 7540 7541static struct hda_verb alc883_clevo_m720_verbs[] = { 7542 /* HP */ 7543 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 7544 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 7545 /* Int speaker */ 7546 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01}, 7547 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 7548 7549 /* enable unsolicited event */ 7550 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 7551 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, 7552 7553 { } /* end */ 7554}; 7555 7556static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = { 7557 /* HP */ 7558 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 7559 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 7560 /* Subwoofer */ 7561 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 7562 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 7563 7564 /* enable unsolicited event */ 7565 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 7566 7567 { } /* end */ 7568}; 7569 7570static struct hda_verb alc883_tagra_verbs[] = { 7571 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7572 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 7573 7574 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 7575 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 7576 7577 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ 7578 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */ 7579 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 7580 7581 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 7582 {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, 7583 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03}, 7584 {0x01, AC_VERB_SET_GPIO_DATA, 0x03}, 7585 7586 { } /* end */ 7587}; 7588 7589static struct hda_verb alc883_lenovo_101e_verbs[] = { 7590 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 7591 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN}, 7592 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN}, 7593 { } /* end */ 7594}; 7595 7596static struct hda_verb alc883_lenovo_nb0763_verbs[] = { 7597 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 7598 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 7599 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 7600 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 7601 { } /* end */ 7602}; 7603 7604static struct hda_verb alc888_lenovo_ms7195_verbs[] = { 7605 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7606 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 7607 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 7608 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN}, 7609 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 7610 { } /* end */ 7611}; 7612 7613static struct hda_verb alc883_haier_w66_verbs[] = { 7614 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7615 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 7616 7617 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 7618 7619 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 7620 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 7621 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 7622 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 7623 { } /* end */ 7624}; 7625 7626static struct hda_verb alc888_lenovo_sky_verbs[] = { 7627 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7628 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 7629 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7630 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7631 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7632 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 7633 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00}, 7634 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 7635 { } /* end */ 7636}; 7637 7638static struct hda_verb alc888_3st_hp_verbs[] = { 7639 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */ 7640 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */ 7641 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */ 7642 { } 7643}; 7644 7645static struct hda_verb alc888_6st_dell_verbs[] = { 7646 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 7647 { } 7648}; 7649 7650static struct hda_verb alc888_3st_hp_2ch_init[] = { 7651 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 7652 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7653 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 7654 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7655 { } 7656}; 7657 7658static struct hda_verb alc888_3st_hp_6ch_init[] = { 7659 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7660 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7661 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7662 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7663 { } 7664}; 7665 7666static struct hda_channel_mode alc888_3st_hp_modes[2] = { 7667 { 2, alc888_3st_hp_2ch_init }, 7668 { 6, alc888_3st_hp_6ch_init }, 7669}; 7670 7671/* toggle front-jack and RCA according to the hp-jack state */ 7672static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec) 7673{ 7674 unsigned int present; 7675 7676 present = snd_hda_codec_read(codec, 0x1b, 0, 7677 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 7678 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 7679 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 7680 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 7681 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 7682} 7683 7684/* toggle RCA according to the front-jack state */ 7685static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec) 7686{ 7687 unsigned int present; 7688 7689 present = snd_hda_codec_read(codec, 0x14, 0, 7690 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 7691 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 7692 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 7693} 7694 7695static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec, 7696 unsigned int res) 7697{ 7698 if ((res >> 26) == ALC880_HP_EVENT) 7699 alc888_lenovo_ms7195_front_automute(codec); 7700 if ((res >> 26) == ALC880_FRONT_EVENT) 7701 alc888_lenovo_ms7195_rca_automute(codec); 7702} 7703 7704static struct hda_verb alc883_medion_md2_verbs[] = { 7705 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7706 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 7707 7708 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 7709 7710 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 7711 { } /* end */ 7712}; 7713 7714/* toggle speaker-output according to the hp-jack state */ 7715static void alc883_medion_md2_automute(struct hda_codec *codec) 7716{ 7717 unsigned int present; 7718 7719 present = snd_hda_codec_read(codec, 0x14, 0, 7720 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 7721 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 7722 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 7723} 7724 7725static void alc883_medion_md2_unsol_event(struct hda_codec *codec, 7726 unsigned int res) 7727{ 7728 if ((res >> 26) == ALC880_HP_EVENT) 7729 alc883_medion_md2_automute(codec); 7730} 7731 7732/* toggle speaker-output according to the hp-jack state */ 7733static void alc883_tagra_automute(struct hda_codec *codec) 7734{ 7735 unsigned int present; 7736 unsigned char bits; 7737 7738 present = snd_hda_codec_read(codec, 0x14, 0, 7739 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 7740 bits = present ? HDA_AMP_MUTE : 0; 7741 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0, 7742 HDA_AMP_MUTE, bits); 7743 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA, 7744 present ? 1 : 3); 7745} 7746 7747static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res) 7748{ 7749 if ((res >> 26) == ALC880_HP_EVENT) 7750 alc883_tagra_automute(codec); 7751} 7752 7753/* toggle speaker-output according to the hp-jack state */ 7754static void alc883_clevo_m720_hp_automute(struct hda_codec *codec) 7755{ 7756 unsigned int present; 7757 unsigned char bits; 7758 7759 present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0) 7760 & AC_PINSENSE_PRESENCE; 7761 bits = present ? HDA_AMP_MUTE : 0; 7762 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 7763 HDA_AMP_MUTE, bits); 7764} 7765 7766static void alc883_clevo_m720_mic_automute(struct hda_codec *codec) 7767{ 7768 unsigned int present; 7769 7770 present = snd_hda_codec_read(codec, 0x18, 0, 7771 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 7772 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, 7773 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 7774} 7775 7776static void alc883_clevo_m720_automute(struct hda_codec *codec) 7777{ 7778 alc883_clevo_m720_hp_automute(codec); 7779 alc883_clevo_m720_mic_automute(codec); 7780} 7781 7782static void alc883_clevo_m720_unsol_event(struct hda_codec *codec, 7783 unsigned int res) 7784{ 7785 switch (res >> 26) { 7786 case ALC880_HP_EVENT: 7787 alc883_clevo_m720_hp_automute(codec); 7788 break; 7789 case ALC880_MIC_EVENT: 7790 alc883_clevo_m720_mic_automute(codec); 7791 break; 7792 } 7793} 7794 7795/* toggle speaker-output according to the hp-jack state */ 7796static void alc883_2ch_fujitsu_pi2515_automute(struct hda_codec *codec) 7797{ 7798 unsigned int present; 7799 unsigned char bits; 7800 7801 present = snd_hda_codec_read(codec, 0x14, 0, AC_VERB_GET_PIN_SENSE, 0) 7802 & AC_PINSENSE_PRESENCE; 7803 bits = present ? HDA_AMP_MUTE : 0; 7804 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 7805 HDA_AMP_MUTE, bits); 7806} 7807 7808static void alc883_2ch_fujitsu_pi2515_unsol_event(struct hda_codec *codec, 7809 unsigned int res) 7810{ 7811 if ((res >> 26) == ALC880_HP_EVENT) 7812 alc883_2ch_fujitsu_pi2515_automute(codec); 7813} 7814 7815static void alc883_haier_w66_automute(struct hda_codec *codec) 7816{ 7817 unsigned int present; 7818 unsigned char bits; 7819 7820 present = snd_hda_codec_read(codec, 0x1b, 0, 7821 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 7822 bits = present ? 0x80 : 0; 7823 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 7824 0x80, bits); 7825} 7826 7827static void alc883_haier_w66_unsol_event(struct hda_codec *codec, 7828 unsigned int res) 7829{ 7830 if ((res >> 26) == ALC880_HP_EVENT) 7831 alc883_haier_w66_automute(codec); 7832} 7833 7834static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec) 7835{ 7836 unsigned int present; 7837 unsigned char bits; 7838 7839 present = snd_hda_codec_read(codec, 0x14, 0, 7840 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 7841 bits = present ? HDA_AMP_MUTE : 0; 7842 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 7843 HDA_AMP_MUTE, bits); 7844} 7845 7846static void alc883_lenovo_101e_all_automute(struct hda_codec *codec) 7847{ 7848 unsigned int present; 7849 unsigned char bits; 7850 7851 present = snd_hda_codec_read(codec, 0x1b, 0, 7852 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 7853 bits = present ? HDA_AMP_MUTE : 0; 7854 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 7855 HDA_AMP_MUTE, bits); 7856 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 7857 HDA_AMP_MUTE, bits); 7858} 7859 7860static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec, 7861 unsigned int res) 7862{ 7863 if ((res >> 26) == ALC880_HP_EVENT) 7864 alc883_lenovo_101e_all_automute(codec); 7865 if ((res >> 26) == ALC880_FRONT_EVENT) 7866 alc883_lenovo_101e_ispeaker_automute(codec); 7867} 7868 7869/* toggle speaker-output according to the hp-jack state */ 7870static void alc883_acer_aspire_automute(struct hda_codec *codec) 7871{ 7872 unsigned int present; 7873 7874 present = snd_hda_codec_read(codec, 0x14, 0, 7875 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 7876 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 7877 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 7878 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0, 7879 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 7880} 7881 7882static void alc883_acer_aspire_unsol_event(struct hda_codec *codec, 7883 unsigned int res) 7884{ 7885 if ((res >> 26) == ALC880_HP_EVENT) 7886 alc883_acer_aspire_automute(codec); 7887} 7888 7889static struct hda_verb alc883_acer_eapd_verbs[] = { 7890 /* HP Pin: output 0 (0x0c) */ 7891 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 7892 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7893 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 7894 /* Front Pin: output 0 (0x0c) */ 7895 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 7896 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 7897 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 7898 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, 7899 /* eanable EAPD on medion laptop */ 7900 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 7901 {0x20, AC_VERB_SET_PROC_COEF, 0x3050}, 7902 /* enable unsolicited event */ 7903 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 7904 { } 7905}; 7906 7907static void alc888_6st_dell_front_automute(struct hda_codec *codec) 7908{ 7909 unsigned int present; 7910 7911 present = snd_hda_codec_read(codec, 0x1b, 0, 7912 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 7913 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 7914 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 7915 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 7916 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 7917 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0, 7918 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 7919 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0, 7920 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 7921} 7922 7923static void alc888_6st_dell_unsol_event(struct hda_codec *codec, 7924 unsigned int res) 7925{ 7926 switch (res >> 26) { 7927 case ALC880_HP_EVENT: 7928 printk("hp_event\n"); 7929 alc888_6st_dell_front_automute(codec); 7930 break; 7931 } 7932} 7933 7934static void alc888_lenovo_sky_front_automute(struct hda_codec *codec) 7935{ 7936 unsigned int mute; 7937 unsigned int present; 7938 7939 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0); 7940 present = snd_hda_codec_read(codec, 0x1b, 0, 7941 AC_VERB_GET_PIN_SENSE, 0); 7942 present = (present & 0x80000000) != 0; 7943 if (present) { 7944 /* mute internal speaker */ 7945 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 7946 HDA_AMP_MUTE, HDA_AMP_MUTE); 7947 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 7948 HDA_AMP_MUTE, HDA_AMP_MUTE); 7949 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0, 7950 HDA_AMP_MUTE, HDA_AMP_MUTE); 7951 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0, 7952 HDA_AMP_MUTE, HDA_AMP_MUTE); 7953 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0, 7954 HDA_AMP_MUTE, HDA_AMP_MUTE); 7955 } else { 7956 /* unmute internal speaker if necessary */ 7957 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0); 7958 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 7959 HDA_AMP_MUTE, mute); 7960 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 7961 HDA_AMP_MUTE, mute); 7962 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0, 7963 HDA_AMP_MUTE, mute); 7964 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0, 7965 HDA_AMP_MUTE, mute); 7966 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0, 7967 HDA_AMP_MUTE, mute); 7968 } 7969} 7970 7971static void alc883_lenovo_sky_unsol_event(struct hda_codec *codec, 7972 unsigned int res) 7973{ 7974 if ((res >> 26) == ALC880_HP_EVENT) 7975 alc888_lenovo_sky_front_automute(codec); 7976} 7977 7978/* 7979 * generic initialization of ADC, input mixers and output mixers 7980 */ 7981static struct hda_verb alc883_auto_init_verbs[] = { 7982 /* 7983 * Unmute ADC0-2 and set the default input to mic-in 7984 */ 7985 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 7986 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7987 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 7988 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7989 7990 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 7991 * mixer widget 7992 * Note: PASD motherboards uses the Line In 2 as the input for 7993 * front panel mic (mic 2) 7994 */ 7995 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 7996 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7997 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7998 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 7999 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8000 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8001 8002 /* 8003 * Set up output mixers (0x0c - 0x0f) 8004 */ 8005 /* set vol=0 to output mixers */ 8006 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8007 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8008 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8009 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8010 /* set up input amps for analog loopback */ 8011 /* Amp Indices: DAC = 0, mixer = 1 */ 8012 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8013 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8014 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8015 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8016 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8017 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8018 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8019 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8020 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8021 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8022 8023 /* FIXME: use matrix-type input source selection */ 8024 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 8025 /* Input mixer1 */ 8026 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8027 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8028 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 8029 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */ 8030 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, 8031 /* Input mixer2 */ 8032 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8033 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8034 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 8035 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */ 8036 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, 8037 8038 { } 8039}; 8040 8041static struct hda_verb alc888_asus_m90v_verbs[] = { 8042 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8043 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8044 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8045 /* enable unsolicited event */ 8046 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 8047 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, 8048 { } /* end */ 8049}; 8050 8051static void alc883_nb_mic_automute(struct hda_codec *codec) 8052{ 8053 unsigned int present; 8054 8055 present = snd_hda_codec_read(codec, 0x18, 0, 8056 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 8057 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE, 8058 0x7000 | (0x00 << 8) | (present ? 0 : 0x80)); 8059 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE, 8060 0x7000 | (0x01 << 8) | (present ? 0x80 : 0)); 8061} 8062 8063static void alc883_M90V_speaker_automute(struct hda_codec *codec) 8064{ 8065 unsigned int present; 8066 unsigned char bits; 8067 8068 present = snd_hda_codec_read(codec, 0x1b, 0, 8069 AC_VERB_GET_PIN_SENSE, 0) 8070 & AC_PINSENSE_PRESENCE; 8071 bits = present ? 0 : PIN_OUT; 8072 snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 8073 bits); 8074 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 8075 bits); 8076 snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 8077 bits); 8078} 8079 8080static void alc883_mode2_unsol_event(struct hda_codec *codec, 8081 unsigned int res) 8082{ 8083 switch (res >> 26) { 8084 case ALC880_HP_EVENT: 8085 alc883_M90V_speaker_automute(codec); 8086 break; 8087 case ALC880_MIC_EVENT: 8088 alc883_nb_mic_automute(codec); 8089 break; 8090 } 8091} 8092 8093static void alc883_mode2_inithook(struct hda_codec *codec) 8094{ 8095 alc883_M90V_speaker_automute(codec); 8096 alc883_nb_mic_automute(codec); 8097} 8098 8099static struct hda_verb alc888_asus_eee1601_verbs[] = { 8100 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8101 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8102 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8103 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8104 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8105 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b}, 8106 {0x20, AC_VERB_SET_PROC_COEF, 0x0838}, 8107 /* enable unsolicited event */ 8108 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 8109 { } /* end */ 8110}; 8111 8112static void alc883_eee1601_speaker_automute(struct hda_codec *codec) 8113{ 8114 unsigned int present; 8115 unsigned char bits; 8116 8117 present = snd_hda_codec_read(codec, 0x14, 0, 8118 AC_VERB_GET_PIN_SENSE, 0) 8119 & AC_PINSENSE_PRESENCE; 8120 bits = present ? 0 : PIN_OUT; 8121 snd_hda_codec_write(codec, 0x1b, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 8122 bits); 8123} 8124 8125static void alc883_eee1601_unsol_event(struct hda_codec *codec, 8126 unsigned int res) 8127{ 8128 switch (res >> 26) { 8129 case ALC880_HP_EVENT: 8130 alc883_eee1601_speaker_automute(codec); 8131 break; 8132 } 8133} 8134 8135static void alc883_eee1601_inithook(struct hda_codec *codec) 8136{ 8137 alc883_eee1601_speaker_automute(codec); 8138} 8139 8140#ifdef CONFIG_SND_HDA_POWER_SAVE 8141#define alc883_loopbacks alc880_loopbacks 8142#endif 8143 8144/* pcm configuration: identiacal with ALC880 */ 8145#define alc883_pcm_analog_playback alc880_pcm_analog_playback 8146#define alc883_pcm_analog_capture alc880_pcm_analog_capture 8147#define alc883_pcm_analog_alt_capture alc880_pcm_analog_alt_capture 8148#define alc883_pcm_digital_playback alc880_pcm_digital_playback 8149#define alc883_pcm_digital_capture alc880_pcm_digital_capture 8150 8151/* 8152 * configuration and preset 8153 */ 8154static const char *alc883_models[ALC883_MODEL_LAST] = { 8155 [ALC883_3ST_2ch_DIG] = "3stack-dig", 8156 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig", 8157 [ALC883_3ST_6ch] = "3stack-6ch", 8158 [ALC883_6ST_DIG] = "6stack-dig", 8159 [ALC883_TARGA_DIG] = "targa-dig", 8160 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig", 8161 [ALC883_ACER] = "acer", 8162 [ALC883_ACER_ASPIRE] = "acer-aspire", 8163 [ALC883_MEDION] = "medion", 8164 [ALC883_MEDION_MD2] = "medion-md2", 8165 [ALC883_LAPTOP_EAPD] = "laptop-eapd", 8166 [ALC883_LENOVO_101E_2ch] = "lenovo-101e", 8167 [ALC883_LENOVO_NB0763] = "lenovo-nb0763", 8168 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig", 8169 [ALC888_LENOVO_SKY] = "lenovo-sky", 8170 [ALC883_HAIER_W66] = "haier-w66", 8171 [ALC888_3ST_HP] = "3stack-hp", 8172 [ALC888_6ST_DELL] = "6stack-dell", 8173 [ALC883_MITAC] = "mitac", 8174 [ALC883_CLEVO_M720] = "clevo-m720", 8175 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515", 8176 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel", 8177 [ALC883_AUTO] = "auto", 8178}; 8179 8180static struct snd_pci_quirk alc883_cfg_tbl[] = { 8181 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG), 8182 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE), 8183 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE), 8184 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE), 8185 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE), 8186 SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER), /* default Acer */ 8187 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL), 8188 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG), 8189 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP), 8190 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP), 8191 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG), 8192 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V), 8193 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG), 8194 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601), 8195 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG), 8196 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG), 8197 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC), 8198 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD), 8199 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL), 8200 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch), 8201 SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG), 8202 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG), 8203 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG), 8204 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG), 8205 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC883_TARGA_2ch_DIG), 8206 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG), 8207 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG), 8208 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG), 8209 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG), 8210 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG), 8211 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG), 8212 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG), 8213 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG), 8214 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG), 8215 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG), 8216 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG), 8217 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG), 8218 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG), 8219 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG), 8220 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG), 8221 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG), 8222 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG), 8223 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG), 8224 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG), 8225 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720), 8226 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720), 8227 SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD), 8228 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch), 8229 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION), 8230 SND_PCI_QUIRK(0x1734, 0x1108, "Fujitsu AMILO Pi2515", ALC883_FUJITSU_PI2515), 8231 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch), 8232 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763), 8233 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763), 8234 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763), 8235 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY), 8236 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2), 8237 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG), 8238 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66), 8239 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL), 8240 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL), 8241 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch), 8242 {} 8243}; 8244 8245static struct alc_config_preset alc883_presets[] = { 8246 [ALC883_3ST_2ch_DIG] = { 8247 .mixers = { alc883_3ST_2ch_mixer }, 8248 .init_verbs = { alc883_init_verbs }, 8249 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 8250 .dac_nids = alc883_dac_nids, 8251 .dig_out_nid = ALC883_DIGOUT_NID, 8252 .dig_in_nid = ALC883_DIGIN_NID, 8253 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 8254 .channel_mode = alc883_3ST_2ch_modes, 8255 .input_mux = &alc883_capture_source, 8256 }, 8257 [ALC883_3ST_6ch_DIG] = { 8258 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, 8259 .init_verbs = { alc883_init_verbs }, 8260 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 8261 .dac_nids = alc883_dac_nids, 8262 .dig_out_nid = ALC883_DIGOUT_NID, 8263 .dig_in_nid = ALC883_DIGIN_NID, 8264 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 8265 .channel_mode = alc883_3ST_6ch_modes, 8266 .need_dac_fix = 1, 8267 .input_mux = &alc883_capture_source, 8268 }, 8269 [ALC883_3ST_6ch] = { 8270 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, 8271 .init_verbs = { alc883_init_verbs }, 8272 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 8273 .dac_nids = alc883_dac_nids, 8274 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 8275 .channel_mode = alc883_3ST_6ch_modes, 8276 .need_dac_fix = 1, 8277 .input_mux = &alc883_capture_source, 8278 }, 8279 [ALC883_3ST_6ch_INTEL] = { 8280 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer }, 8281 .init_verbs = { alc883_init_verbs }, 8282 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 8283 .dac_nids = alc883_dac_nids, 8284 .dig_out_nid = ALC883_DIGOUT_NID, 8285 .dig_in_nid = ALC883_DIGIN_NID, 8286 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes), 8287 .channel_mode = alc883_3ST_6ch_intel_modes, 8288 .need_dac_fix = 1, 8289 .input_mux = &alc883_3stack_6ch_intel, 8290 }, 8291 [ALC883_6ST_DIG] = { 8292 .mixers = { alc883_base_mixer, alc883_chmode_mixer }, 8293 .init_verbs = { alc883_init_verbs }, 8294 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 8295 .dac_nids = alc883_dac_nids, 8296 .dig_out_nid = ALC883_DIGOUT_NID, 8297 .dig_in_nid = ALC883_DIGIN_NID, 8298 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), 8299 .channel_mode = alc883_sixstack_modes, 8300 .input_mux = &alc883_capture_source, 8301 }, 8302 [ALC883_TARGA_DIG] = { 8303 .mixers = { alc883_tagra_mixer, alc883_chmode_mixer }, 8304 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs}, 8305 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 8306 .dac_nids = alc883_dac_nids, 8307 .dig_out_nid = ALC883_DIGOUT_NID, 8308 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 8309 .channel_mode = alc883_3ST_6ch_modes, 8310 .need_dac_fix = 1, 8311 .input_mux = &alc883_capture_source, 8312 .unsol_event = alc883_tagra_unsol_event, 8313 .init_hook = alc883_tagra_automute, 8314 }, 8315 [ALC883_TARGA_2ch_DIG] = { 8316 .mixers = { alc883_tagra_2ch_mixer}, 8317 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs}, 8318 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 8319 .dac_nids = alc883_dac_nids, 8320 .adc_nids = alc883_adc_nids_alt, 8321 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt), 8322 .dig_out_nid = ALC883_DIGOUT_NID, 8323 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 8324 .channel_mode = alc883_3ST_2ch_modes, 8325 .input_mux = &alc883_capture_source, 8326 .unsol_event = alc883_tagra_unsol_event, 8327 .init_hook = alc883_tagra_automute, 8328 }, 8329 [ALC883_ACER] = { 8330 .mixers = { alc883_base_mixer }, 8331 /* On TravelMate laptops, GPIO 0 enables the internal speaker 8332 * and the headphone jack. Turn this on and rely on the 8333 * standard mute methods whenever the user wants to turn 8334 * these outputs off. 8335 */ 8336 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs }, 8337 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 8338 .dac_nids = alc883_dac_nids, 8339 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 8340 .channel_mode = alc883_3ST_2ch_modes, 8341 .input_mux = &alc883_capture_source, 8342 }, 8343 [ALC883_ACER_ASPIRE] = { 8344 .mixers = { alc883_acer_aspire_mixer }, 8345 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs }, 8346 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 8347 .dac_nids = alc883_dac_nids, 8348 .dig_out_nid = ALC883_DIGOUT_NID, 8349 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 8350 .channel_mode = alc883_3ST_2ch_modes, 8351 .input_mux = &alc883_capture_source, 8352 .unsol_event = alc883_acer_aspire_unsol_event, 8353 .init_hook = alc883_acer_aspire_automute, 8354 }, 8355 [ALC883_MEDION] = { 8356 .mixers = { alc883_fivestack_mixer, 8357 alc883_chmode_mixer }, 8358 .init_verbs = { alc883_init_verbs, 8359 alc883_medion_eapd_verbs }, 8360 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 8361 .dac_nids = alc883_dac_nids, 8362 .adc_nids = alc883_adc_nids_alt, 8363 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt), 8364 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), 8365 .channel_mode = alc883_sixstack_modes, 8366 .input_mux = &alc883_capture_source, 8367 }, 8368 [ALC883_MEDION_MD2] = { 8369 .mixers = { alc883_medion_md2_mixer}, 8370 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs}, 8371 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 8372 .dac_nids = alc883_dac_nids, 8373 .dig_out_nid = ALC883_DIGOUT_NID, 8374 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 8375 .channel_mode = alc883_3ST_2ch_modes, 8376 .input_mux = &alc883_capture_source, 8377 .unsol_event = alc883_medion_md2_unsol_event, 8378 .init_hook = alc883_medion_md2_automute, 8379 }, 8380 [ALC883_LAPTOP_EAPD] = { 8381 .mixers = { alc883_base_mixer }, 8382 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs }, 8383 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 8384 .dac_nids = alc883_dac_nids, 8385 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 8386 .channel_mode = alc883_3ST_2ch_modes, 8387 .input_mux = &alc883_capture_source, 8388 }, 8389 [ALC883_CLEVO_M720] = { 8390 .mixers = { alc883_clevo_m720_mixer }, 8391 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs }, 8392 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 8393 .dac_nids = alc883_dac_nids, 8394 .dig_out_nid = ALC883_DIGOUT_NID, 8395 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 8396 .channel_mode = alc883_3ST_2ch_modes, 8397 .input_mux = &alc883_capture_source, 8398 .unsol_event = alc883_clevo_m720_unsol_event, 8399 .init_hook = alc883_clevo_m720_automute, 8400 }, 8401 [ALC883_LENOVO_101E_2ch] = { 8402 .mixers = { alc883_lenovo_101e_2ch_mixer}, 8403 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs}, 8404 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 8405 .dac_nids = alc883_dac_nids, 8406 .adc_nids = alc883_adc_nids_alt, 8407 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt), 8408 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 8409 .channel_mode = alc883_3ST_2ch_modes, 8410 .input_mux = &alc883_lenovo_101e_capture_source, 8411 .unsol_event = alc883_lenovo_101e_unsol_event, 8412 .init_hook = alc883_lenovo_101e_all_automute, 8413 }, 8414 [ALC883_LENOVO_NB0763] = { 8415 .mixers = { alc883_lenovo_nb0763_mixer }, 8416 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs}, 8417 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 8418 .dac_nids = alc883_dac_nids, 8419 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 8420 .channel_mode = alc883_3ST_2ch_modes, 8421 .need_dac_fix = 1, 8422 .input_mux = &alc883_lenovo_nb0763_capture_source, 8423 .unsol_event = alc883_medion_md2_unsol_event, 8424 .init_hook = alc883_medion_md2_automute, 8425 }, 8426 [ALC888_LENOVO_MS7195_DIG] = { 8427 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, 8428 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs}, 8429 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 8430 .dac_nids = alc883_dac_nids, 8431 .dig_out_nid = ALC883_DIGOUT_NID, 8432 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 8433 .channel_mode = alc883_3ST_6ch_modes, 8434 .need_dac_fix = 1, 8435 .input_mux = &alc883_capture_source, 8436 .unsol_event = alc883_lenovo_ms7195_unsol_event, 8437 .init_hook = alc888_lenovo_ms7195_front_automute, 8438 }, 8439 [ALC883_HAIER_W66] = { 8440 .mixers = { alc883_tagra_2ch_mixer}, 8441 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs}, 8442 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 8443 .dac_nids = alc883_dac_nids, 8444 .dig_out_nid = ALC883_DIGOUT_NID, 8445 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 8446 .channel_mode = alc883_3ST_2ch_modes, 8447 .input_mux = &alc883_capture_source, 8448 .unsol_event = alc883_haier_w66_unsol_event, 8449 .init_hook = alc883_haier_w66_automute, 8450 }, 8451 [ALC888_3ST_HP] = { 8452 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, 8453 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs }, 8454 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 8455 .dac_nids = alc883_dac_nids, 8456 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes), 8457 .channel_mode = alc888_3st_hp_modes, 8458 .need_dac_fix = 1, 8459 .input_mux = &alc883_capture_source, 8460 }, 8461 [ALC888_6ST_DELL] = { 8462 .mixers = { alc883_base_mixer, alc883_chmode_mixer }, 8463 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs }, 8464 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 8465 .dac_nids = alc883_dac_nids, 8466 .dig_out_nid = ALC883_DIGOUT_NID, 8467 .dig_in_nid = ALC883_DIGIN_NID, 8468 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), 8469 .channel_mode = alc883_sixstack_modes, 8470 .input_mux = &alc883_capture_source, 8471 .unsol_event = alc888_6st_dell_unsol_event, 8472 .init_hook = alc888_6st_dell_front_automute, 8473 }, 8474 [ALC883_MITAC] = { 8475 .mixers = { alc883_mitac_mixer }, 8476 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs }, 8477 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 8478 .dac_nids = alc883_dac_nids, 8479 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 8480 .channel_mode = alc883_3ST_2ch_modes, 8481 .input_mux = &alc883_capture_source, 8482 .unsol_event = alc883_mitac_unsol_event, 8483 .init_hook = alc883_mitac_automute, 8484 }, 8485 [ALC883_FUJITSU_PI2515] = { 8486 .mixers = { alc883_2ch_fujitsu_pi2515_mixer }, 8487 .init_verbs = { alc883_init_verbs, 8488 alc883_2ch_fujitsu_pi2515_verbs}, 8489 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 8490 .dac_nids = alc883_dac_nids, 8491 .dig_out_nid = ALC883_DIGOUT_NID, 8492 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 8493 .channel_mode = alc883_3ST_2ch_modes, 8494 .input_mux = &alc883_fujitsu_pi2515_capture_source, 8495 .unsol_event = alc883_2ch_fujitsu_pi2515_unsol_event, 8496 .init_hook = alc883_2ch_fujitsu_pi2515_automute, 8497 }, 8498 [ALC888_LENOVO_SKY] = { 8499 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer }, 8500 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs}, 8501 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 8502 .dac_nids = alc883_dac_nids, 8503 .dig_out_nid = ALC883_DIGOUT_NID, 8504 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), 8505 .channel_mode = alc883_sixstack_modes, 8506 .need_dac_fix = 1, 8507 .input_mux = &alc883_lenovo_sky_capture_source, 8508 .unsol_event = alc883_lenovo_sky_unsol_event, 8509 .init_hook = alc888_lenovo_sky_front_automute, 8510 }, 8511 [ALC888_ASUS_M90V] = { 8512 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, 8513 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs }, 8514 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 8515 .dac_nids = alc883_dac_nids, 8516 .dig_out_nid = ALC883_DIGOUT_NID, 8517 .dig_in_nid = ALC883_DIGIN_NID, 8518 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 8519 .channel_mode = alc883_3ST_6ch_modes, 8520 .need_dac_fix = 1, 8521 .input_mux = &alc883_fujitsu_pi2515_capture_source, 8522 .unsol_event = alc883_mode2_unsol_event, 8523 .init_hook = alc883_mode2_inithook, 8524 }, 8525 [ALC888_ASUS_EEE1601] = { 8526 .mixers = { alc883_asus_eee1601_mixer }, 8527 .cap_mixer = alc883_asus_eee1601_cap_mixer, 8528 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs }, 8529 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 8530 .dac_nids = alc883_dac_nids, 8531 .dig_out_nid = ALC883_DIGOUT_NID, 8532 .dig_in_nid = ALC883_DIGIN_NID, 8533 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 8534 .channel_mode = alc883_3ST_2ch_modes, 8535 .need_dac_fix = 1, 8536 .input_mux = &alc883_asus_eee1601_capture_source, 8537 .unsol_event = alc883_eee1601_unsol_event, 8538 .init_hook = alc883_eee1601_inithook, 8539 }, 8540}; 8541 8542 8543/* 8544 * BIOS auto configuration 8545 */ 8546static void alc883_auto_set_output_and_unmute(struct hda_codec *codec, 8547 hda_nid_t nid, int pin_type, 8548 int dac_idx) 8549{ 8550 /* set as output */ 8551 struct alc_spec *spec = codec->spec; 8552 int idx; 8553 8554 alc_set_pin_output(codec, nid, pin_type); 8555 if (spec->multiout.dac_nids[dac_idx] == 0x25) 8556 idx = 4; 8557 else 8558 idx = spec->multiout.dac_nids[dac_idx] - 2; 8559 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx); 8560 8561} 8562 8563static void alc883_auto_init_multi_out(struct hda_codec *codec) 8564{ 8565 struct alc_spec *spec = codec->spec; 8566 int i; 8567 8568 alc_subsystem_id(codec, 0x15, 0x1b, 0x14); 8569 for (i = 0; i <= HDA_SIDE; i++) { 8570 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 8571 int pin_type = get_pin_type(spec->autocfg.line_out_type); 8572 if (nid) 8573 alc883_auto_set_output_and_unmute(codec, nid, pin_type, 8574 i); 8575 } 8576} 8577 8578static void alc883_auto_init_hp_out(struct hda_codec *codec) 8579{ 8580 struct alc_spec *spec = codec->spec; 8581 hda_nid_t pin; 8582 8583 pin = spec->autocfg.hp_pins[0]; 8584 if (pin) /* connect to front */ 8585 /* use dac 0 */ 8586 alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); 8587 pin = spec->autocfg.speaker_pins[0]; 8588 if (pin) 8589 alc883_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0); 8590} 8591 8592#define alc883_is_input_pin(nid) alc880_is_input_pin(nid) 8593#define ALC883_PIN_CD_NID ALC880_PIN_CD_NID 8594 8595static void alc883_auto_init_analog_input(struct hda_codec *codec) 8596{ 8597 struct alc_spec *spec = codec->spec; 8598 int i; 8599 8600 for (i = 0; i < AUTO_PIN_LAST; i++) { 8601 hda_nid_t nid = spec->autocfg.input_pins[i]; 8602 if (alc883_is_input_pin(nid)) { 8603 snd_hda_codec_write(codec, nid, 0, 8604 AC_VERB_SET_PIN_WIDGET_CONTROL, 8605 (i <= AUTO_PIN_FRONT_MIC ? 8606 PIN_VREF80 : PIN_IN)); 8607 if (nid != ALC883_PIN_CD_NID) 8608 snd_hda_codec_write(codec, nid, 0, 8609 AC_VERB_SET_AMP_GAIN_MUTE, 8610 AMP_OUT_MUTE); 8611 } 8612 } 8613} 8614 8615#define alc883_auto_init_input_src alc882_auto_init_input_src 8616 8617/* almost identical with ALC880 parser... */ 8618static int alc883_parse_auto_config(struct hda_codec *codec) 8619{ 8620 struct alc_spec *spec = codec->spec; 8621 int err = alc880_parse_auto_config(codec); 8622 8623 if (err < 0) 8624 return err; 8625 else if (!err) 8626 return 0; /* no config found */ 8627 8628 err = alc_auto_add_mic_boost(codec); 8629 if (err < 0) 8630 return err; 8631 8632 /* hack - override the init verbs */ 8633 spec->init_verbs[0] = alc883_auto_init_verbs; 8634 8635 return 1; /* config found */ 8636} 8637 8638/* additional initialization for auto-configuration model */ 8639static void alc883_auto_init(struct hda_codec *codec) 8640{ 8641 struct alc_spec *spec = codec->spec; 8642 alc883_auto_init_multi_out(codec); 8643 alc883_auto_init_hp_out(codec); 8644 alc883_auto_init_analog_input(codec); 8645 alc883_auto_init_input_src(codec); 8646 if (spec->unsol_event) 8647 alc_inithook(codec); 8648} 8649 8650static int patch_alc883(struct hda_codec *codec) 8651{ 8652 struct alc_spec *spec; 8653 int err, board_config; 8654 8655 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 8656 if (spec == NULL) 8657 return -ENOMEM; 8658 8659 codec->spec = spec; 8660 8661 alc_fix_pll_init(codec, 0x20, 0x0a, 10); 8662 8663 board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST, 8664 alc883_models, 8665 alc883_cfg_tbl); 8666 if (board_config < 0) { 8667 printk(KERN_INFO "hda_codec: Unknown model for ALC883, " 8668 "trying auto-probe from BIOS...\n"); 8669 board_config = ALC883_AUTO; 8670 } 8671 8672 if (board_config == ALC883_AUTO) { 8673 /* automatic parse from the BIOS config */ 8674 err = alc883_parse_auto_config(codec); 8675 if (err < 0) { 8676 alc_free(codec); 8677 return err; 8678 } else if (!err) { 8679 printk(KERN_INFO 8680 "hda_codec: Cannot set up configuration " 8681 "from BIOS. Using base mode...\n"); 8682 board_config = ALC883_3ST_2ch_DIG; 8683 } 8684 } 8685 8686 if (board_config != ALC883_AUTO) 8687 setup_preset(spec, &alc883_presets[board_config]); 8688 8689 switch (codec->vendor_id) { 8690 case 0x10ec0888: 8691 if (codec->revision_id == 0x100101) { 8692 spec->stream_name_analog = "ALC1200 Analog"; 8693 spec->stream_name_digital = "ALC1200 Digital"; 8694 } else { 8695 spec->stream_name_analog = "ALC888 Analog"; 8696 spec->stream_name_digital = "ALC888 Digital"; 8697 } 8698 break; 8699 case 0x10ec0889: 8700 spec->stream_name_analog = "ALC889 Analog"; 8701 spec->stream_name_digital = "ALC889 Digital"; 8702 break; 8703 default: 8704 spec->stream_name_analog = "ALC883 Analog"; 8705 spec->stream_name_digital = "ALC883 Digital"; 8706 break; 8707 } 8708 8709 spec->stream_analog_playback = &alc883_pcm_analog_playback; 8710 spec->stream_analog_capture = &alc883_pcm_analog_capture; 8711 spec->stream_analog_alt_capture = &alc883_pcm_analog_alt_capture; 8712 8713 spec->stream_digital_playback = &alc883_pcm_digital_playback; 8714 spec->stream_digital_capture = &alc883_pcm_digital_capture; 8715 8716 if (!spec->num_adc_nids) { 8717 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids); 8718 spec->adc_nids = alc883_adc_nids; 8719 } 8720 if (!spec->capsrc_nids) 8721 spec->capsrc_nids = alc883_capsrc_nids; 8722 spec->is_mix_capture = 1; /* matrix-style capture */ 8723 if (!spec->cap_mixer) 8724 set_capture_mixer(spec); 8725 8726 spec->vmaster_nid = 0x0c; 8727 8728 codec->patch_ops = alc_patch_ops; 8729 if (board_config == ALC883_AUTO) 8730 spec->init_hook = alc883_auto_init; 8731 8732#ifdef CONFIG_SND_HDA_POWER_SAVE 8733 if (!spec->loopback.amplist) 8734 spec->loopback.amplist = alc883_loopbacks; 8735#endif 8736 8737 return 0; 8738} 8739 8740/* 8741 * ALC262 support 8742 */ 8743 8744#define ALC262_DIGOUT_NID ALC880_DIGOUT_NID 8745#define ALC262_DIGIN_NID ALC880_DIGIN_NID 8746 8747#define alc262_dac_nids alc260_dac_nids 8748#define alc262_adc_nids alc882_adc_nids 8749#define alc262_adc_nids_alt alc882_adc_nids_alt 8750#define alc262_capsrc_nids alc882_capsrc_nids 8751#define alc262_capsrc_nids_alt alc882_capsrc_nids_alt 8752 8753#define alc262_modes alc260_modes 8754#define alc262_capture_source alc882_capture_source 8755 8756static hda_nid_t alc262_dmic_adc_nids[1] = { 8757 /* ADC0 */ 8758 0x09 8759}; 8760 8761static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 }; 8762 8763static struct snd_kcontrol_new alc262_base_mixer[] = { 8764 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8765 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 8766 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 8767 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 8768 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8769 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8770 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8771 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8772 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8773 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 8774 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 8775 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 8776 /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT), 8777 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */ 8778 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT), 8779 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 8780 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 8781 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT), 8782 { } /* end */ 8783}; 8784 8785static struct snd_kcontrol_new alc262_hippo1_mixer[] = { 8786 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8787 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 8788 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 8789 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 8790 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8791 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8792 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8793 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8794 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8795 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 8796 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 8797 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 8798 /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT), 8799 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */ 8800 /*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/ 8801 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 8802 { } /* end */ 8803}; 8804 8805/* update HP, line and mono-out pins according to the master switch */ 8806static void alc262_hp_master_update(struct hda_codec *codec) 8807{ 8808 struct alc_spec *spec = codec->spec; 8809 int val = spec->master_sw; 8810 8811 /* HP & line-out */ 8812 snd_hda_codec_write_cache(codec, 0x1b, 0, 8813 AC_VERB_SET_PIN_WIDGET_CONTROL, 8814 val ? PIN_HP : 0); 8815 snd_hda_codec_write_cache(codec, 0x15, 0, 8816 AC_VERB_SET_PIN_WIDGET_CONTROL, 8817 val ? PIN_HP : 0); 8818 /* mono (speaker) depending on the HP jack sense */ 8819 val = val && !spec->jack_present; 8820 snd_hda_codec_write_cache(codec, 0x16, 0, 8821 AC_VERB_SET_PIN_WIDGET_CONTROL, 8822 val ? PIN_OUT : 0); 8823} 8824 8825static void alc262_hp_bpc_automute(struct hda_codec *codec) 8826{ 8827 struct alc_spec *spec = codec->spec; 8828 unsigned int presence; 8829 presence = snd_hda_codec_read(codec, 0x1b, 0, 8830 AC_VERB_GET_PIN_SENSE, 0); 8831 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE); 8832 alc262_hp_master_update(codec); 8833} 8834 8835static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res) 8836{ 8837 if ((res >> 26) != ALC880_HP_EVENT) 8838 return; 8839 alc262_hp_bpc_automute(codec); 8840} 8841 8842static void alc262_hp_wildwest_automute(struct hda_codec *codec) 8843{ 8844 struct alc_spec *spec = codec->spec; 8845 unsigned int presence; 8846 presence = snd_hda_codec_read(codec, 0x15, 0, 8847 AC_VERB_GET_PIN_SENSE, 0); 8848 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE); 8849 alc262_hp_master_update(codec); 8850} 8851 8852static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec, 8853 unsigned int res) 8854{ 8855 if ((res >> 26) != ALC880_HP_EVENT) 8856 return; 8857 alc262_hp_wildwest_automute(codec); 8858} 8859 8860static int alc262_hp_master_sw_get(struct snd_kcontrol *kcontrol, 8861 struct snd_ctl_elem_value *ucontrol) 8862{ 8863 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 8864 struct alc_spec *spec = codec->spec; 8865 *ucontrol->value.integer.value = spec->master_sw; 8866 return 0; 8867} 8868 8869static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol, 8870 struct snd_ctl_elem_value *ucontrol) 8871{ 8872 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 8873 struct alc_spec *spec = codec->spec; 8874 int val = !!*ucontrol->value.integer.value; 8875 8876 if (val == spec->master_sw) 8877 return 0; 8878 spec->master_sw = val; 8879 alc262_hp_master_update(codec); 8880 return 1; 8881} 8882 8883static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = { 8884 { 8885 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 8886 .name = "Master Playback Switch", 8887 .info = snd_ctl_boolean_mono_info, 8888 .get = alc262_hp_master_sw_get, 8889 .put = alc262_hp_master_sw_put, 8890 }, 8891 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8892 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT), 8893 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 8894 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0, 8895 HDA_OUTPUT), 8896 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0, 8897 HDA_OUTPUT), 8898 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8899 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8900 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8901 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 8902 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 8903 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 8904 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8905 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8906 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 8907 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 8908 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT), 8909 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), 8910 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT), 8911 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT), 8912 { } /* end */ 8913}; 8914 8915static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = { 8916 { 8917 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 8918 .name = "Master Playback Switch", 8919 .info = snd_ctl_boolean_mono_info, 8920 .get = alc262_hp_master_sw_get, 8921 .put = alc262_hp_master_sw_put, 8922 }, 8923 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8924 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 8925 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 8926 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 8927 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0, 8928 HDA_OUTPUT), 8929 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0, 8930 HDA_OUTPUT), 8931 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT), 8932 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT), 8933 HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT), 8934 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT), 8935 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT), 8936 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 8937 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 8938 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT), 8939 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), 8940 { } /* end */ 8941}; 8942 8943static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = { 8944 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8945 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8946 HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT), 8947 { } /* end */ 8948}; 8949 8950/* mute/unmute internal speaker according to the hp jack and mute state */ 8951static void alc262_hp_t5735_automute(struct hda_codec *codec, int force) 8952{ 8953 struct alc_spec *spec = codec->spec; 8954 8955 if (force || !spec->sense_updated) { 8956 unsigned int present; 8957 present = snd_hda_codec_read(codec, 0x15, 0, 8958 AC_VERB_GET_PIN_SENSE, 0); 8959 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0; 8960 spec->sense_updated = 1; 8961 } 8962 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0, HDA_AMP_MUTE, 8963 spec->jack_present ? HDA_AMP_MUTE : 0); 8964} 8965 8966static void alc262_hp_t5735_unsol_event(struct hda_codec *codec, 8967 unsigned int res) 8968{ 8969 if ((res >> 26) != ALC880_HP_EVENT) 8970 return; 8971 alc262_hp_t5735_automute(codec, 1); 8972} 8973 8974static void alc262_hp_t5735_init_hook(struct hda_codec *codec) 8975{ 8976 alc262_hp_t5735_automute(codec, 1); 8977} 8978 8979static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = { 8980 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8981 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 8982 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 8983 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 8984 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8985 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8986 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8987 { } /* end */ 8988}; 8989 8990static struct hda_verb alc262_hp_t5735_verbs[] = { 8991 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8992 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8993 8994 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 8995 { } 8996}; 8997 8998static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = { 8999 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9000 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 9001 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT), 9002 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT), 9003 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT), 9004 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT), 9005 { } /* end */ 9006}; 9007 9008static struct hda_verb alc262_hp_rp5700_verbs[] = { 9009 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9010 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9011 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9012 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9013 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 9014 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 9015 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 9016 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 9017 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))}, 9018 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))}, 9019 {} 9020}; 9021 9022static struct hda_input_mux alc262_hp_rp5700_capture_source = { 9023 .num_items = 1, 9024 .items = { 9025 { "Line", 0x1 }, 9026 }, 9027}; 9028 9029/* bind hp and internal speaker mute (with plug check) */ 9030static int alc262_sony_master_sw_put(struct snd_kcontrol *kcontrol, 9031 struct snd_ctl_elem_value *ucontrol) 9032{ 9033 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 9034 long *valp = ucontrol->value.integer.value; 9035 int change; 9036 9037 /* change hp mute */ 9038 change = snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0, 9039 HDA_AMP_MUTE, 9040 valp[0] ? 0 : HDA_AMP_MUTE); 9041 change |= snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0, 9042 HDA_AMP_MUTE, 9043 valp[1] ? 0 : HDA_AMP_MUTE); 9044 if (change) { 9045 /* change speaker according to HP jack state */ 9046 struct alc_spec *spec = codec->spec; 9047 unsigned int mute; 9048 if (spec->jack_present) 9049 mute = HDA_AMP_MUTE; 9050 else 9051 mute = snd_hda_codec_amp_read(codec, 0x15, 0, 9052 HDA_OUTPUT, 0); 9053 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 9054 HDA_AMP_MUTE, mute); 9055 } 9056 return change; 9057} 9058 9059static struct snd_kcontrol_new alc262_sony_mixer[] = { 9060 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9061 { 9062 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 9063 .name = "Master Playback Switch", 9064 .info = snd_hda_mixer_amp_switch_info, 9065 .get = snd_hda_mixer_amp_switch_get, 9066 .put = alc262_sony_master_sw_put, 9067 .private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT), 9068 }, 9069 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9070 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9071 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 9072 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 9073 { } /* end */ 9074}; 9075 9076static struct snd_kcontrol_new alc262_benq_t31_mixer[] = { 9077 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9078 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 9079 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 9080 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9081 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9082 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 9083 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 9084 { } /* end */ 9085}; 9086 9087#define alc262_capture_mixer alc882_capture_mixer 9088#define alc262_capture_alt_mixer alc882_capture_alt_mixer 9089 9090/* 9091 * generic initialization of ADC, input mixers and output mixers 9092 */ 9093static struct hda_verb alc262_init_verbs[] = { 9094 /* 9095 * Unmute ADC0-2 and set the default input to mic-in 9096 */ 9097 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 9098 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9099 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 9100 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9101 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 9102 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9103 9104 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 9105 * mixer widget 9106 * Note: PASD motherboards uses the Line In 2 as the input for 9107 * front panel mic (mic 2) 9108 */ 9109 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 9110 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 9111 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 9112 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 9113 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 9114 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 9115 9116 /* 9117 * Set up output mixers (0x0c - 0x0e) 9118 */ 9119 /* set vol=0 to output mixers */ 9120 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 9121 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 9122 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 9123 /* set up input amps for analog loopback */ 9124 /* Amp Indices: DAC = 0, mixer = 1 */ 9125 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9126 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9127 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9128 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9129 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9130 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9131 9132 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 9133 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 9134 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 9135 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 9136 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 9137 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 9138 9139 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 9140 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 9141 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 9142 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 9143 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 9144 9145 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 9146 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 9147 9148 /* FIXME: use matrix-type input source selection */ 9149 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 9150 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 9151 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 9152 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 9153 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 9154 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 9155 /* Input mixer2 */ 9156 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 9157 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 9158 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 9159 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 9160 /* Input mixer3 */ 9161 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 9162 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 9163 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 9164 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 9165 9166 { } 9167}; 9168 9169static struct hda_verb alc262_eapd_verbs[] = { 9170 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 9171 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, 9172 { } 9173}; 9174 9175static struct hda_verb alc262_hippo_unsol_verbs[] = { 9176 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 9177 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9178 {} 9179}; 9180 9181static struct hda_verb alc262_hippo1_unsol_verbs[] = { 9182 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 9183 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 9184 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 9185 9186 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 9187 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9188 {} 9189}; 9190 9191static struct hda_verb alc262_sony_unsol_verbs[] = { 9192 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 9193 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9194 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic 9195 9196 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 9197 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9198 {} 9199}; 9200 9201static struct hda_input_mux alc262_dmic_capture_source = { 9202 .num_items = 2, 9203 .items = { 9204 { "Int DMic", 0x9 }, 9205 { "Mic", 0x0 }, 9206 }, 9207}; 9208 9209static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = { 9210 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9211 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 9212 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 9213 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9214 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9215 { } /* end */ 9216}; 9217 9218static struct hda_verb alc262_toshiba_s06_verbs[] = { 9219 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 9220 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9221 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9222 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9223 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09}, 9224 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 9225 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 9226 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 9227 {} 9228}; 9229 9230static void alc262_dmic_automute(struct hda_codec *codec) 9231{ 9232 unsigned int present; 9233 9234 present = snd_hda_codec_read(codec, 0x18, 0, 9235 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 9236 snd_hda_codec_write(codec, 0x22, 0, 9237 AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x09); 9238} 9239 9240/* toggle speaker-output according to the hp-jack state */ 9241static void alc262_toshiba_s06_speaker_automute(struct hda_codec *codec) 9242{ 9243 unsigned int present; 9244 unsigned char bits; 9245 9246 present = snd_hda_codec_read(codec, 0x15, 0, 9247 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 9248 bits = present ? 0 : PIN_OUT; 9249 snd_hda_codec_write(codec, 0x14, 0, 9250 AC_VERB_SET_PIN_WIDGET_CONTROL, bits); 9251} 9252 9253 9254 9255/* unsolicited event for HP jack sensing */ 9256static void alc262_toshiba_s06_unsol_event(struct hda_codec *codec, 9257 unsigned int res) 9258{ 9259 if ((res >> 26) == ALC880_HP_EVENT) 9260 alc262_toshiba_s06_speaker_automute(codec); 9261 if ((res >> 26) == ALC880_MIC_EVENT) 9262 alc262_dmic_automute(codec); 9263 9264} 9265 9266static void alc262_toshiba_s06_init_hook(struct hda_codec *codec) 9267{ 9268 alc262_toshiba_s06_speaker_automute(codec); 9269 alc262_dmic_automute(codec); 9270} 9271 9272/* mute/unmute internal speaker according to the hp jack and mute state */ 9273static void alc262_hippo_automute(struct hda_codec *codec) 9274{ 9275 struct alc_spec *spec = codec->spec; 9276 unsigned int mute; 9277 unsigned int present; 9278 9279 /* need to execute and sync at first */ 9280 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0); 9281 present = snd_hda_codec_read(codec, 0x15, 0, 9282 AC_VERB_GET_PIN_SENSE, 0); 9283 spec->jack_present = (present & 0x80000000) != 0; 9284 if (spec->jack_present) { 9285 /* mute internal speaker */ 9286 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 9287 HDA_AMP_MUTE, HDA_AMP_MUTE); 9288 } else { 9289 /* unmute internal speaker if necessary */ 9290 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0); 9291 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 9292 HDA_AMP_MUTE, mute); 9293 } 9294} 9295 9296/* unsolicited event for HP jack sensing */ 9297static void alc262_hippo_unsol_event(struct hda_codec *codec, 9298 unsigned int res) 9299{ 9300 if ((res >> 26) != ALC880_HP_EVENT) 9301 return; 9302 alc262_hippo_automute(codec); 9303} 9304 9305static void alc262_hippo1_automute(struct hda_codec *codec) 9306{ 9307 unsigned int mute; 9308 unsigned int present; 9309 9310 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0); 9311 present = snd_hda_codec_read(codec, 0x1b, 0, 9312 AC_VERB_GET_PIN_SENSE, 0); 9313 present = (present & 0x80000000) != 0; 9314 if (present) { 9315 /* mute internal speaker */ 9316 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 9317 HDA_AMP_MUTE, HDA_AMP_MUTE); 9318 } else { 9319 /* unmute internal speaker if necessary */ 9320 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0); 9321 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 9322 HDA_AMP_MUTE, mute); 9323 } 9324} 9325 9326/* unsolicited event for HP jack sensing */ 9327static void alc262_hippo1_unsol_event(struct hda_codec *codec, 9328 unsigned int res) 9329{ 9330 if ((res >> 26) != ALC880_HP_EVENT) 9331 return; 9332 alc262_hippo1_automute(codec); 9333} 9334 9335/* 9336 * nec model 9337 * 0x15 = headphone 9338 * 0x16 = internal speaker 9339 * 0x18 = external mic 9340 */ 9341 9342static struct snd_kcontrol_new alc262_nec_mixer[] = { 9343 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 9344 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT), 9345 9346 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9347 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9348 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 9349 9350 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 9351 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 9352 { } /* end */ 9353}; 9354 9355static struct hda_verb alc262_nec_verbs[] = { 9356 /* Unmute Speaker */ 9357 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9358 9359 /* Headphone */ 9360 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 9361 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9362 9363 /* External mic to headphone */ 9364 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9365 /* External mic to speaker */ 9366 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9367 {} 9368}; 9369 9370/* 9371 * fujitsu model 9372 * 0x14 = headphone/spdif-out, 0x15 = internal speaker, 9373 * 0x1b = port replicator headphone out 9374 */ 9375 9376#define ALC_HP_EVENT 0x37 9377 9378static struct hda_verb alc262_fujitsu_unsol_verbs[] = { 9379 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, 9380 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9381 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, 9382 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9383 {} 9384}; 9385 9386static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = { 9387 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, 9388 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9389 {} 9390}; 9391 9392static struct hda_input_mux alc262_fujitsu_capture_source = { 9393 .num_items = 3, 9394 .items = { 9395 { "Mic", 0x0 }, 9396 { "Int Mic", 0x1 }, 9397 { "CD", 0x4 }, 9398 }, 9399}; 9400 9401static struct hda_input_mux alc262_HP_capture_source = { 9402 .num_items = 5, 9403 .items = { 9404 { "Mic", 0x0 }, 9405 { "Front Mic", 0x1 }, 9406 { "Line", 0x2 }, 9407 { "CD", 0x4 }, 9408 { "AUX IN", 0x6 }, 9409 }, 9410}; 9411 9412static struct hda_input_mux alc262_HP_D7000_capture_source = { 9413 .num_items = 4, 9414 .items = { 9415 { "Mic", 0x0 }, 9416 { "Front Mic", 0x2 }, 9417 { "Line", 0x1 }, 9418 { "CD", 0x4 }, 9419 }, 9420}; 9421 9422/* mute/unmute internal speaker according to the hp jacks and mute state */ 9423static void alc262_fujitsu_automute(struct hda_codec *codec, int force) 9424{ 9425 struct alc_spec *spec = codec->spec; 9426 unsigned int mute; 9427 9428 if (force || !spec->sense_updated) { 9429 unsigned int present; 9430 /* need to execute and sync at first */ 9431 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0); 9432 /* check laptop HP jack */ 9433 present = snd_hda_codec_read(codec, 0x14, 0, 9434 AC_VERB_GET_PIN_SENSE, 0); 9435 /* need to execute and sync at first */ 9436 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0); 9437 /* check docking HP jack */ 9438 present |= snd_hda_codec_read(codec, 0x1b, 0, 9439 AC_VERB_GET_PIN_SENSE, 0); 9440 if (present & AC_PINSENSE_PRESENCE) 9441 spec->jack_present = 1; 9442 else 9443 spec->jack_present = 0; 9444 spec->sense_updated = 1; 9445 } 9446 /* unmute internal speaker only if both HPs are unplugged and 9447 * master switch is on 9448 */ 9449 if (spec->jack_present) 9450 mute = HDA_AMP_MUTE; 9451 else 9452 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0); 9453 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 9454 HDA_AMP_MUTE, mute); 9455} 9456 9457/* unsolicited event for HP jack sensing */ 9458static void alc262_fujitsu_unsol_event(struct hda_codec *codec, 9459 unsigned int res) 9460{ 9461 if ((res >> 26) != ALC_HP_EVENT) 9462 return; 9463 alc262_fujitsu_automute(codec, 1); 9464} 9465 9466static void alc262_fujitsu_init_hook(struct hda_codec *codec) 9467{ 9468 alc262_fujitsu_automute(codec, 1); 9469} 9470 9471/* bind volumes of both NID 0x0c and 0x0d */ 9472static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = { 9473 .ops = &snd_hda_bind_vol, 9474 .values = { 9475 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT), 9476 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT), 9477 0 9478 }, 9479}; 9480 9481/* mute/unmute internal speaker according to the hp jack and mute state */ 9482static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force) 9483{ 9484 struct alc_spec *spec = codec->spec; 9485 unsigned int mute; 9486 9487 if (force || !spec->sense_updated) { 9488 unsigned int present_int_hp; 9489 /* need to execute and sync at first */ 9490 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0); 9491 present_int_hp = snd_hda_codec_read(codec, 0x1b, 0, 9492 AC_VERB_GET_PIN_SENSE, 0); 9493 spec->jack_present = (present_int_hp & 0x80000000) != 0; 9494 spec->sense_updated = 1; 9495 } 9496 if (spec->jack_present) { 9497 /* mute internal speaker */ 9498 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 9499 HDA_AMP_MUTE, HDA_AMP_MUTE); 9500 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0, 9501 HDA_AMP_MUTE, HDA_AMP_MUTE); 9502 } else { 9503 /* unmute internal speaker if necessary */ 9504 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0); 9505 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 9506 HDA_AMP_MUTE, mute); 9507 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0, 9508 HDA_AMP_MUTE, mute); 9509 } 9510} 9511 9512/* unsolicited event for HP jack sensing */ 9513static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec, 9514 unsigned int res) 9515{ 9516 if ((res >> 26) != ALC_HP_EVENT) 9517 return; 9518 alc262_lenovo_3000_automute(codec, 1); 9519} 9520 9521/* bind hp and internal speaker mute (with plug check) */ 9522static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol, 9523 struct snd_ctl_elem_value *ucontrol) 9524{ 9525 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 9526 long *valp = ucontrol->value.integer.value; 9527 int change; 9528 9529 change = snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 9530 HDA_AMP_MUTE, 9531 valp ? 0 : HDA_AMP_MUTE); 9532 change |= snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0, 9533 HDA_AMP_MUTE, 9534 valp ? 0 : HDA_AMP_MUTE); 9535 9536 if (change) 9537 alc262_fujitsu_automute(codec, 0); 9538 return change; 9539} 9540 9541static struct snd_kcontrol_new alc262_fujitsu_mixer[] = { 9542 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol), 9543 { 9544 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 9545 .name = "Master Playback Switch", 9546 .info = snd_hda_mixer_amp_switch_info, 9547 .get = snd_hda_mixer_amp_switch_get, 9548 .put = alc262_fujitsu_master_sw_put, 9549 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 9550 }, 9551 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 9552 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 9553 HDA_CODEC_VOLUME("PC Speaker Volume", 0x0b, 0x05, HDA_INPUT), 9554 HDA_CODEC_MUTE("PC Speaker Switch", 0x0b, 0x05, HDA_INPUT), 9555 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 9556 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9557 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9558 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 9559 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 9560 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 9561 { } /* end */ 9562}; 9563 9564/* bind hp and internal speaker mute (with plug check) */ 9565static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol, 9566 struct snd_ctl_elem_value *ucontrol) 9567{ 9568 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 9569 long *valp = ucontrol->value.integer.value; 9570 int change; 9571 9572 change = snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0, 9573 HDA_AMP_MUTE, 9574 valp ? 0 : HDA_AMP_MUTE); 9575 9576 if (change) 9577 alc262_lenovo_3000_automute(codec, 0); 9578 return change; 9579} 9580 9581static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = { 9582 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol), 9583 { 9584 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 9585 .name = "Master Playback Switch", 9586 .info = snd_hda_mixer_amp_switch_info, 9587 .get = snd_hda_mixer_amp_switch_get, 9588 .put = alc262_lenovo_3000_master_sw_put, 9589 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT), 9590 }, 9591 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 9592 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 9593 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 9594 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9595 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9596 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 9597 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 9598 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 9599 { } /* end */ 9600}; 9601 9602static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = { 9603 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol), 9604 { 9605 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 9606 .name = "Master Playback Switch", 9607 .info = snd_hda_mixer_amp_switch_info, 9608 .get = snd_hda_mixer_amp_switch_get, 9609 .put = alc262_sony_master_sw_put, 9610 .private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT), 9611 }, 9612 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9613 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9614 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 9615 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 9616 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 9617 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 9618 { } /* end */ 9619}; 9620 9621/* additional init verbs for Benq laptops */ 9622static struct hda_verb alc262_EAPD_verbs[] = { 9623 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 9624 {0x20, AC_VERB_SET_PROC_COEF, 0x3070}, 9625 {} 9626}; 9627 9628static struct hda_verb alc262_benq_t31_EAPD_verbs[] = { 9629 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9630 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 9631 9632 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 9633 {0x20, AC_VERB_SET_PROC_COEF, 0x3050}, 9634 {} 9635}; 9636 9637/* Samsung Q1 Ultra Vista model setup */ 9638static struct snd_kcontrol_new alc262_ultra_mixer[] = { 9639 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9640 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT), 9641 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 9642 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 9643 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT), 9644 HDA_CODEC_VOLUME("Headphone Mic Boost", 0x15, 0, HDA_INPUT), 9645 { } /* end */ 9646}; 9647 9648static struct hda_verb alc262_ultra_verbs[] = { 9649 /* output mixer */ 9650 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 9651 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 9652 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 9653 /* speaker */ 9654 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9655 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 9656 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9657 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 9658 /* HP */ 9659 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9660 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 9661 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9662 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9663 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 9664 /* internal mic */ 9665 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 9666 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 9667 /* ADC, choose mic */ 9668 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 9669 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 9670 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9671 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 9672 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 9673 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 9674 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, 9675 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, 9676 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, 9677 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)}, 9678 {} 9679}; 9680 9681/* mute/unmute internal speaker according to the hp jack and mute state */ 9682static void alc262_ultra_automute(struct hda_codec *codec) 9683{ 9684 struct alc_spec *spec = codec->spec; 9685 unsigned int mute; 9686 9687 mute = 0; 9688 /* auto-mute only when HP is used as HP */ 9689 if (!spec->cur_mux[0]) { 9690 unsigned int present; 9691 /* need to execute and sync at first */ 9692 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0); 9693 present = snd_hda_codec_read(codec, 0x15, 0, 9694 AC_VERB_GET_PIN_SENSE, 0); 9695 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0; 9696 if (spec->jack_present) 9697 mute = HDA_AMP_MUTE; 9698 } 9699 /* mute/unmute internal speaker */ 9700 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 9701 HDA_AMP_MUTE, mute); 9702 /* mute/unmute HP */ 9703 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 9704 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE); 9705} 9706 9707/* unsolicited event for HP jack sensing */ 9708static void alc262_ultra_unsol_event(struct hda_codec *codec, 9709 unsigned int res) 9710{ 9711 if ((res >> 26) != ALC880_HP_EVENT) 9712 return; 9713 alc262_ultra_automute(codec); 9714} 9715 9716static struct hda_input_mux alc262_ultra_capture_source = { 9717 .num_items = 2, 9718 .items = { 9719 { "Mic", 0x1 }, 9720 { "Headphone", 0x7 }, 9721 }, 9722}; 9723 9724static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol, 9725 struct snd_ctl_elem_value *ucontrol) 9726{ 9727 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 9728 struct alc_spec *spec = codec->spec; 9729 int ret; 9730 9731 ret = alc_mux_enum_put(kcontrol, ucontrol); 9732 if (!ret) 9733 return 0; 9734 /* reprogram the HP pin as mic or HP according to the input source */ 9735 snd_hda_codec_write_cache(codec, 0x15, 0, 9736 AC_VERB_SET_PIN_WIDGET_CONTROL, 9737 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP); 9738 alc262_ultra_automute(codec); /* mute/unmute HP */ 9739 return ret; 9740} 9741 9742static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = { 9743 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT), 9744 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT), 9745 { 9746 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 9747 .name = "Capture Source", 9748 .info = alc_mux_enum_info, 9749 .get = alc_mux_enum_get, 9750 .put = alc262_ultra_mux_enum_put, 9751 }, 9752 { } /* end */ 9753}; 9754 9755/* add playback controls from the parsed DAC table */ 9756static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, 9757 const struct auto_pin_cfg *cfg) 9758{ 9759 hda_nid_t nid; 9760 int err; 9761 9762 spec->multiout.num_dacs = 1; /* only use one dac */ 9763 spec->multiout.dac_nids = spec->private_dac_nids; 9764 spec->multiout.dac_nids[0] = 2; 9765 9766 nid = cfg->line_out_pins[0]; 9767 if (nid) { 9768 err = add_control(spec, ALC_CTL_WIDGET_VOL, 9769 "Front Playback Volume", 9770 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT)); 9771 if (err < 0) 9772 return err; 9773 err = add_control(spec, ALC_CTL_WIDGET_MUTE, 9774 "Front Playback Switch", 9775 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); 9776 if (err < 0) 9777 return err; 9778 } 9779 9780 nid = cfg->speaker_pins[0]; 9781 if (nid) { 9782 if (nid == 0x16) { 9783 err = add_control(spec, ALC_CTL_WIDGET_VOL, 9784 "Speaker Playback Volume", 9785 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, 9786 HDA_OUTPUT)); 9787 if (err < 0) 9788 return err; 9789 err = add_control(spec, ALC_CTL_WIDGET_MUTE, 9790 "Speaker Playback Switch", 9791 HDA_COMPOSE_AMP_VAL(nid, 2, 0, 9792 HDA_OUTPUT)); 9793 if (err < 0) 9794 return err; 9795 } else { 9796 err = add_control(spec, ALC_CTL_WIDGET_MUTE, 9797 "Speaker Playback Switch", 9798 HDA_COMPOSE_AMP_VAL(nid, 3, 0, 9799 HDA_OUTPUT)); 9800 if (err < 0) 9801 return err; 9802 } 9803 } 9804 nid = cfg->hp_pins[0]; 9805 if (nid) { 9806 /* spec->multiout.hp_nid = 2; */ 9807 if (nid == 0x16) { 9808 err = add_control(spec, ALC_CTL_WIDGET_VOL, 9809 "Headphone Playback Volume", 9810 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, 9811 HDA_OUTPUT)); 9812 if (err < 0) 9813 return err; 9814 err = add_control(spec, ALC_CTL_WIDGET_MUTE, 9815 "Headphone Playback Switch", 9816 HDA_COMPOSE_AMP_VAL(nid, 2, 0, 9817 HDA_OUTPUT)); 9818 if (err < 0) 9819 return err; 9820 } else { 9821 err = add_control(spec, ALC_CTL_WIDGET_MUTE, 9822 "Headphone Playback Switch", 9823 HDA_COMPOSE_AMP_VAL(nid, 3, 0, 9824 HDA_OUTPUT)); 9825 if (err < 0) 9826 return err; 9827 } 9828 } 9829 return 0; 9830} 9831 9832/* identical with ALC880 */ 9833#define alc262_auto_create_analog_input_ctls \ 9834 alc880_auto_create_analog_input_ctls 9835 9836/* 9837 * generic initialization of ADC, input mixers and output mixers 9838 */ 9839static struct hda_verb alc262_volume_init_verbs[] = { 9840 /* 9841 * Unmute ADC0-2 and set the default input to mic-in 9842 */ 9843 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 9844 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9845 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 9846 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9847 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 9848 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9849 9850 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 9851 * mixer widget 9852 * Note: PASD motherboards uses the Line In 2 as the input for 9853 * front panel mic (mic 2) 9854 */ 9855 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 9856 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 9857 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 9858 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 9859 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 9860 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 9861 9862 /* 9863 * Set up output mixers (0x0c - 0x0f) 9864 */ 9865 /* set vol=0 to output mixers */ 9866 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 9867 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 9868 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 9869 9870 /* set up input amps for analog loopback */ 9871 /* Amp Indices: DAC = 0, mixer = 1 */ 9872 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9873 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9874 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9875 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9876 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9877 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9878 9879 /* FIXME: use matrix-type input source selection */ 9880 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 9881 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 9882 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 9883 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 9884 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 9885 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 9886 /* Input mixer2 */ 9887 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 9888 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 9889 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 9890 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 9891 /* Input mixer3 */ 9892 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 9893 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 9894 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 9895 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 9896 9897 { } 9898}; 9899 9900static struct hda_verb alc262_HP_BPC_init_verbs[] = { 9901 /* 9902 * Unmute ADC0-2 and set the default input to mic-in 9903 */ 9904 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 9905 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9906 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 9907 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9908 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 9909 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9910 9911 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 9912 * mixer widget 9913 * Note: PASD motherboards uses the Line In 2 as the input for 9914 * front panel mic (mic 2) 9915 */ 9916 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 9917 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 9918 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 9919 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 9920 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 9921 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 9922 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, 9923 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, 9924 9925 /* 9926 * Set up output mixers (0x0c - 0x0e) 9927 */ 9928 /* set vol=0 to output mixers */ 9929 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 9930 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 9931 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 9932 9933 /* set up input amps for analog loopback */ 9934 /* Amp Indices: DAC = 0, mixer = 1 */ 9935 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9936 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9937 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9938 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9939 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9940 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9941 9942 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9943 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 9944 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 9945 9946 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 9947 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 9948 9949 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 9950 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9951 9952 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 9953 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 9954 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 9955 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 9956 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 9957 9958 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, 9959 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 9960 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 9961 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, 9962 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 9963 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 9964 9965 9966 /* FIXME: use matrix-type input source selection */ 9967 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 9968 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 9969 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 9970 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, 9971 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, 9972 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, 9973 /* Input mixer2 */ 9974 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 9975 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, 9976 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, 9977 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, 9978 /* Input mixer3 */ 9979 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 9980 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, 9981 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, 9982 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, 9983 9984 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9985 9986 { } 9987}; 9988 9989static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = { 9990 /* 9991 * Unmute ADC0-2 and set the default input to mic-in 9992 */ 9993 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 9994 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9995 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 9996 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9997 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 9998 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9999 10000 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 10001 * mixer widget 10002 * Note: PASD motherboards uses the Line In 2 as the input for front 10003 * panel mic (mic 2) 10004 */ 10005 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 10006 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 10007 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 10008 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 10009 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 10010 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 10011 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, 10012 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, 10013 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, 10014 /* 10015 * Set up output mixers (0x0c - 0x0e) 10016 */ 10017 /* set vol=0 to output mixers */ 10018 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 10019 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 10020 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 10021 10022 /* set up input amps for analog loopback */ 10023 /* Amp Indices: DAC = 0, mixer = 1 */ 10024 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 10025 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 10026 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 10027 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 10028 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 10029 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 10030 10031 10032 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */ 10033 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */ 10034 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */ 10035 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */ 10036 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */ 10037 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */ 10038 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */ 10039 10040 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 10041 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 10042 10043 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 10044 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 10045 10046 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */ 10047 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 10048 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 10049 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, 10050 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 10051 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 10052 10053 /* FIXME: use matrix-type input source selection */ 10054 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 10055 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 10056 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/ 10057 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/ 10058 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/ 10059 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/ 10060 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/ 10061 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */ 10062 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/ 10063 /* Input mixer2 */ 10064 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 10065 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 10066 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, 10067 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, 10068 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, 10069 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */ 10070 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, 10071 /* Input mixer3 */ 10072 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 10073 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 10074 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, 10075 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, 10076 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, 10077 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */ 10078 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, 10079 10080 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 10081 10082 { } 10083}; 10084 10085static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = { 10086 10087 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */ 10088 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 10089 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01}, 10090 10091 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */ 10092 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */ 10093 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) }, 10094 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) }, 10095 10096 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */ 10097 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 10098 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 10099 {} 10100}; 10101 10102 10103#ifdef CONFIG_SND_HDA_POWER_SAVE 10104#define alc262_loopbacks alc880_loopbacks 10105#endif 10106 10107/* pcm configuration: identiacal with ALC880 */ 10108#define alc262_pcm_analog_playback alc880_pcm_analog_playback 10109#define alc262_pcm_analog_capture alc880_pcm_analog_capture 10110#define alc262_pcm_digital_playback alc880_pcm_digital_playback 10111#define alc262_pcm_digital_capture alc880_pcm_digital_capture 10112 10113/* 10114 * BIOS auto configuration 10115 */ 10116static int alc262_parse_auto_config(struct hda_codec *codec) 10117{ 10118 struct alc_spec *spec = codec->spec; 10119 int err; 10120 static hda_nid_t alc262_ignore[] = { 0x1d, 0 }; 10121 10122 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 10123 alc262_ignore); 10124 if (err < 0) 10125 return err; 10126 if (!spec->autocfg.line_outs) 10127 return 0; /* can't find valid BIOS pin config */ 10128 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg); 10129 if (err < 0) 10130 return err; 10131 err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg); 10132 if (err < 0) 10133 return err; 10134 10135 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 10136 10137 if (spec->autocfg.dig_out_pin) 10138 spec->multiout.dig_out_nid = ALC262_DIGOUT_NID; 10139 if (spec->autocfg.dig_in_pin) 10140 spec->dig_in_nid = ALC262_DIGIN_NID; 10141 10142 if (spec->kctls.list) 10143 add_mixer(spec, spec->kctls.list); 10144 10145 add_verb(spec, alc262_volume_init_verbs); 10146 spec->num_mux_defs = 1; 10147 spec->input_mux = &spec->private_imux; 10148 10149 err = alc_auto_add_mic_boost(codec); 10150 if (err < 0) 10151 return err; 10152 10153 store_pin_configs(codec); 10154 return 1; 10155} 10156 10157#define alc262_auto_init_multi_out alc882_auto_init_multi_out 10158#define alc262_auto_init_hp_out alc882_auto_init_hp_out 10159#define alc262_auto_init_analog_input alc882_auto_init_analog_input 10160#define alc262_auto_init_input_src alc882_auto_init_input_src 10161 10162 10163/* init callback for auto-configuration model -- overriding the default init */ 10164static void alc262_auto_init(struct hda_codec *codec) 10165{ 10166 struct alc_spec *spec = codec->spec; 10167 alc262_auto_init_multi_out(codec); 10168 alc262_auto_init_hp_out(codec); 10169 alc262_auto_init_analog_input(codec); 10170 alc262_auto_init_input_src(codec); 10171 if (spec->unsol_event) 10172 alc_inithook(codec); 10173} 10174 10175/* 10176 * configuration and preset 10177 */ 10178static const char *alc262_models[ALC262_MODEL_LAST] = { 10179 [ALC262_BASIC] = "basic", 10180 [ALC262_HIPPO] = "hippo", 10181 [ALC262_HIPPO_1] = "hippo_1", 10182 [ALC262_FUJITSU] = "fujitsu", 10183 [ALC262_HP_BPC] = "hp-bpc", 10184 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000", 10185 [ALC262_HP_TC_T5735] = "hp-tc-t5735", 10186 [ALC262_HP_RP5700] = "hp-rp5700", 10187 [ALC262_BENQ_ED8] = "benq", 10188 [ALC262_BENQ_T31] = "benq-t31", 10189 [ALC262_SONY_ASSAMD] = "sony-assamd", 10190 [ALC262_TOSHIBA_S06] = "toshiba-s06", 10191 [ALC262_TOSHIBA_RX1] = "toshiba-rx1", 10192 [ALC262_ULTRA] = "ultra", 10193 [ALC262_LENOVO_3000] = "lenovo-3000", 10194 [ALC262_NEC] = "nec", 10195 [ALC262_AUTO] = "auto", 10196}; 10197 10198static struct snd_pci_quirk alc262_cfg_tbl[] = { 10199 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO), 10200 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC), 10201 SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC), 10202 SND_PCI_QUIRK(0x103c, 0x12ff, "HP xw4550", ALC262_HP_BPC), 10203 SND_PCI_QUIRK(0x103c, 0x1306, "HP xw8600", ALC262_HP_BPC), 10204 SND_PCI_QUIRK(0x103c, 0x1307, "HP xw6600", ALC262_HP_BPC), 10205 SND_PCI_QUIRK(0x103c, 0x1308, "HP xw4600", ALC262_HP_BPC), 10206 SND_PCI_QUIRK(0x103c, 0x1309, "HP xw4*00", ALC262_HP_BPC), 10207 SND_PCI_QUIRK(0x103c, 0x130a, "HP xw6*00", ALC262_HP_BPC), 10208 SND_PCI_QUIRK(0x103c, 0x130b, "HP xw8*00", ALC262_HP_BPC), 10209 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL), 10210 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF), 10211 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL), 10212 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF), 10213 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL), 10214 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF), 10215 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL), 10216 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF), 10217 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC), 10218 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC), 10219 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC), 10220 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735", 10221 ALC262_HP_TC_T5735), 10222 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700), 10223 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD), 10224 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO), 10225 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD), 10226 SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD), 10227 SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD), 10228 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1", 10229 ALC262_TOSHIBA_RX1), 10230 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06), 10231 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU), 10232 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU), 10233 SND_PCI_QUIRK(0x144d, 0xc032, "Samsung Q1 Ultra", ALC262_ULTRA), 10234 SND_PCI_QUIRK(0x144d, 0xc039, "Samsung Q1U EL", ALC262_ULTRA), 10235 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000), 10236 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8), 10237 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31), 10238 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1), 10239 {} 10240}; 10241 10242static struct alc_config_preset alc262_presets[] = { 10243 [ALC262_BASIC] = { 10244 .mixers = { alc262_base_mixer }, 10245 .init_verbs = { alc262_init_verbs }, 10246 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 10247 .dac_nids = alc262_dac_nids, 10248 .hp_nid = 0x03, 10249 .num_channel_mode = ARRAY_SIZE(alc262_modes), 10250 .channel_mode = alc262_modes, 10251 .input_mux = &alc262_capture_source, 10252 }, 10253 [ALC262_HIPPO] = { 10254 .mixers = { alc262_base_mixer }, 10255 .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs}, 10256 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 10257 .dac_nids = alc262_dac_nids, 10258 .hp_nid = 0x03, 10259 .dig_out_nid = ALC262_DIGOUT_NID, 10260 .num_channel_mode = ARRAY_SIZE(alc262_modes), 10261 .channel_mode = alc262_modes, 10262 .input_mux = &alc262_capture_source, 10263 .unsol_event = alc262_hippo_unsol_event, 10264 .init_hook = alc262_hippo_automute, 10265 }, 10266 [ALC262_HIPPO_1] = { 10267 .mixers = { alc262_hippo1_mixer }, 10268 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs}, 10269 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 10270 .dac_nids = alc262_dac_nids, 10271 .hp_nid = 0x02, 10272 .dig_out_nid = ALC262_DIGOUT_NID, 10273 .num_channel_mode = ARRAY_SIZE(alc262_modes), 10274 .channel_mode = alc262_modes, 10275 .input_mux = &alc262_capture_source, 10276 .unsol_event = alc262_hippo1_unsol_event, 10277 .init_hook = alc262_hippo1_automute, 10278 }, 10279 [ALC262_FUJITSU] = { 10280 .mixers = { alc262_fujitsu_mixer }, 10281 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs, 10282 alc262_fujitsu_unsol_verbs }, 10283 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 10284 .dac_nids = alc262_dac_nids, 10285 .hp_nid = 0x03, 10286 .dig_out_nid = ALC262_DIGOUT_NID, 10287 .num_channel_mode = ARRAY_SIZE(alc262_modes), 10288 .channel_mode = alc262_modes, 10289 .input_mux = &alc262_fujitsu_capture_source, 10290 .unsol_event = alc262_fujitsu_unsol_event, 10291 .init_hook = alc262_fujitsu_init_hook, 10292 }, 10293 [ALC262_HP_BPC] = { 10294 .mixers = { alc262_HP_BPC_mixer }, 10295 .init_verbs = { alc262_HP_BPC_init_verbs }, 10296 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 10297 .dac_nids = alc262_dac_nids, 10298 .hp_nid = 0x03, 10299 .num_channel_mode = ARRAY_SIZE(alc262_modes), 10300 .channel_mode = alc262_modes, 10301 .input_mux = &alc262_HP_capture_source, 10302 .unsol_event = alc262_hp_bpc_unsol_event, 10303 .init_hook = alc262_hp_bpc_automute, 10304 }, 10305 [ALC262_HP_BPC_D7000_WF] = { 10306 .mixers = { alc262_HP_BPC_WildWest_mixer }, 10307 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs }, 10308 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 10309 .dac_nids = alc262_dac_nids, 10310 .hp_nid = 0x03, 10311 .num_channel_mode = ARRAY_SIZE(alc262_modes), 10312 .channel_mode = alc262_modes, 10313 .input_mux = &alc262_HP_D7000_capture_source, 10314 .unsol_event = alc262_hp_wildwest_unsol_event, 10315 .init_hook = alc262_hp_wildwest_automute, 10316 }, 10317 [ALC262_HP_BPC_D7000_WL] = { 10318 .mixers = { alc262_HP_BPC_WildWest_mixer, 10319 alc262_HP_BPC_WildWest_option_mixer }, 10320 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs }, 10321 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 10322 .dac_nids = alc262_dac_nids, 10323 .hp_nid = 0x03, 10324 .num_channel_mode = ARRAY_SIZE(alc262_modes), 10325 .channel_mode = alc262_modes, 10326 .input_mux = &alc262_HP_D7000_capture_source, 10327 .unsol_event = alc262_hp_wildwest_unsol_event, 10328 .init_hook = alc262_hp_wildwest_automute, 10329 }, 10330 [ALC262_HP_TC_T5735] = { 10331 .mixers = { alc262_hp_t5735_mixer }, 10332 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs }, 10333 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 10334 .dac_nids = alc262_dac_nids, 10335 .hp_nid = 0x03, 10336 .num_channel_mode = ARRAY_SIZE(alc262_modes), 10337 .channel_mode = alc262_modes, 10338 .input_mux = &alc262_capture_source, 10339 .unsol_event = alc262_hp_t5735_unsol_event, 10340 .init_hook = alc262_hp_t5735_init_hook, 10341 }, 10342 [ALC262_HP_RP5700] = { 10343 .mixers = { alc262_hp_rp5700_mixer }, 10344 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs }, 10345 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 10346 .dac_nids = alc262_dac_nids, 10347 .num_channel_mode = ARRAY_SIZE(alc262_modes), 10348 .channel_mode = alc262_modes, 10349 .input_mux = &alc262_hp_rp5700_capture_source, 10350 }, 10351 [ALC262_BENQ_ED8] = { 10352 .mixers = { alc262_base_mixer }, 10353 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs }, 10354 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 10355 .dac_nids = alc262_dac_nids, 10356 .hp_nid = 0x03, 10357 .num_channel_mode = ARRAY_SIZE(alc262_modes), 10358 .channel_mode = alc262_modes, 10359 .input_mux = &alc262_capture_source, 10360 }, 10361 [ALC262_SONY_ASSAMD] = { 10362 .mixers = { alc262_sony_mixer }, 10363 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs}, 10364 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 10365 .dac_nids = alc262_dac_nids, 10366 .hp_nid = 0x02, 10367 .num_channel_mode = ARRAY_SIZE(alc262_modes), 10368 .channel_mode = alc262_modes, 10369 .input_mux = &alc262_capture_source, 10370 .unsol_event = alc262_hippo_unsol_event, 10371 .init_hook = alc262_hippo_automute, 10372 }, 10373 [ALC262_BENQ_T31] = { 10374 .mixers = { alc262_benq_t31_mixer }, 10375 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs }, 10376 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 10377 .dac_nids = alc262_dac_nids, 10378 .hp_nid = 0x03, 10379 .num_channel_mode = ARRAY_SIZE(alc262_modes), 10380 .channel_mode = alc262_modes, 10381 .input_mux = &alc262_capture_source, 10382 .unsol_event = alc262_hippo_unsol_event, 10383 .init_hook = alc262_hippo_automute, 10384 }, 10385 [ALC262_ULTRA] = { 10386 .mixers = { alc262_ultra_mixer }, 10387 .cap_mixer = alc262_ultra_capture_mixer, 10388 .init_verbs = { alc262_ultra_verbs }, 10389 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 10390 .dac_nids = alc262_dac_nids, 10391 .num_channel_mode = ARRAY_SIZE(alc262_modes), 10392 .channel_mode = alc262_modes, 10393 .input_mux = &alc262_ultra_capture_source, 10394 .adc_nids = alc262_adc_nids, /* ADC0 */ 10395 .capsrc_nids = alc262_capsrc_nids, 10396 .num_adc_nids = 1, /* single ADC */ 10397 .unsol_event = alc262_ultra_unsol_event, 10398 .init_hook = alc262_ultra_automute, 10399 }, 10400 [ALC262_LENOVO_3000] = { 10401 .mixers = { alc262_lenovo_3000_mixer }, 10402 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs, 10403 alc262_lenovo_3000_unsol_verbs }, 10404 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 10405 .dac_nids = alc262_dac_nids, 10406 .hp_nid = 0x03, 10407 .dig_out_nid = ALC262_DIGOUT_NID, 10408 .num_channel_mode = ARRAY_SIZE(alc262_modes), 10409 .channel_mode = alc262_modes, 10410 .input_mux = &alc262_fujitsu_capture_source, 10411 .unsol_event = alc262_lenovo_3000_unsol_event, 10412 }, 10413 [ALC262_NEC] = { 10414 .mixers = { alc262_nec_mixer }, 10415 .init_verbs = { alc262_nec_verbs }, 10416 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 10417 .dac_nids = alc262_dac_nids, 10418 .hp_nid = 0x03, 10419 .num_channel_mode = ARRAY_SIZE(alc262_modes), 10420 .channel_mode = alc262_modes, 10421 .input_mux = &alc262_capture_source, 10422 }, 10423 [ALC262_TOSHIBA_S06] = { 10424 .mixers = { alc262_toshiba_s06_mixer }, 10425 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs, 10426 alc262_eapd_verbs }, 10427 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 10428 .capsrc_nids = alc262_dmic_capsrc_nids, 10429 .dac_nids = alc262_dac_nids, 10430 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */ 10431 .dig_out_nid = ALC262_DIGOUT_NID, 10432 .num_channel_mode = ARRAY_SIZE(alc262_modes), 10433 .channel_mode = alc262_modes, 10434 .input_mux = &alc262_dmic_capture_source, 10435 .unsol_event = alc262_toshiba_s06_unsol_event, 10436 .init_hook = alc262_toshiba_s06_init_hook, 10437 }, 10438 [ALC262_TOSHIBA_RX1] = { 10439 .mixers = { alc262_toshiba_rx1_mixer }, 10440 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs }, 10441 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 10442 .dac_nids = alc262_dac_nids, 10443 .hp_nid = 0x03, 10444 .num_channel_mode = ARRAY_SIZE(alc262_modes), 10445 .channel_mode = alc262_modes, 10446 .input_mux = &alc262_capture_source, 10447 .unsol_event = alc262_hippo_unsol_event, 10448 .init_hook = alc262_hippo_automute, 10449 }, 10450}; 10451 10452static int patch_alc262(struct hda_codec *codec) 10453{ 10454 struct alc_spec *spec; 10455 int board_config; 10456 int err; 10457 10458 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 10459 if (spec == NULL) 10460 return -ENOMEM; 10461 10462 codec->spec = spec; 10463#if 0 10464 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is 10465 * under-run 10466 */ 10467 { 10468 int tmp; 10469 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7); 10470 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0); 10471 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7); 10472 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80); 10473 } 10474#endif 10475 10476 alc_fix_pll_init(codec, 0x20, 0x0a, 10); 10477 10478 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST, 10479 alc262_models, 10480 alc262_cfg_tbl); 10481 10482 if (board_config < 0) { 10483 printk(KERN_INFO "hda_codec: Unknown model for ALC262, " 10484 "trying auto-probe from BIOS...\n"); 10485 board_config = ALC262_AUTO; 10486 } 10487 10488 if (board_config == ALC262_AUTO) { 10489 /* automatic parse from the BIOS config */ 10490 err = alc262_parse_auto_config(codec); 10491 if (err < 0) { 10492 alc_free(codec); 10493 return err; 10494 } else if (!err) { 10495 printk(KERN_INFO 10496 "hda_codec: Cannot set up configuration " 10497 "from BIOS. Using base mode...\n"); 10498 board_config = ALC262_BASIC; 10499 } 10500 } 10501 10502 if (board_config != ALC262_AUTO) 10503 setup_preset(spec, &alc262_presets[board_config]); 10504 10505 spec->stream_name_analog = "ALC262 Analog"; 10506 spec->stream_analog_playback = &alc262_pcm_analog_playback; 10507 spec->stream_analog_capture = &alc262_pcm_analog_capture; 10508 10509 spec->stream_name_digital = "ALC262 Digital"; 10510 spec->stream_digital_playback = &alc262_pcm_digital_playback; 10511 spec->stream_digital_capture = &alc262_pcm_digital_capture; 10512 10513 spec->is_mix_capture = 1; 10514 if (!spec->adc_nids && spec->input_mux) { 10515 /* check whether NID 0x07 is valid */ 10516 unsigned int wcap = get_wcaps(codec, 0x07); 10517 10518 /* get type */ 10519 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; 10520 if (wcap != AC_WID_AUD_IN) { 10521 spec->adc_nids = alc262_adc_nids_alt; 10522 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt); 10523 spec->capsrc_nids = alc262_capsrc_nids_alt; 10524 } else { 10525 spec->adc_nids = alc262_adc_nids; 10526 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids); 10527 spec->capsrc_nids = alc262_capsrc_nids; 10528 } 10529 } 10530 if (!spec->cap_mixer) 10531 set_capture_mixer(spec); 10532 10533 spec->vmaster_nid = 0x0c; 10534 10535 codec->patch_ops = alc_patch_ops; 10536 if (board_config == ALC262_AUTO) 10537 spec->init_hook = alc262_auto_init; 10538#ifdef CONFIG_SND_HDA_POWER_SAVE 10539 if (!spec->loopback.amplist) 10540 spec->loopback.amplist = alc262_loopbacks; 10541#endif 10542 10543 return 0; 10544} 10545 10546/* 10547 * ALC268 channel source setting (2 channel) 10548 */ 10549#define ALC268_DIGOUT_NID ALC880_DIGOUT_NID 10550#define alc268_modes alc260_modes 10551 10552static hda_nid_t alc268_dac_nids[2] = { 10553 /* front, hp */ 10554 0x02, 0x03 10555}; 10556 10557static hda_nid_t alc268_adc_nids[2] = { 10558 /* ADC0-1 */ 10559 0x08, 0x07 10560}; 10561 10562static hda_nid_t alc268_adc_nids_alt[1] = { 10563 /* ADC0 */ 10564 0x08 10565}; 10566 10567static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 }; 10568 10569static struct snd_kcontrol_new alc268_base_mixer[] = { 10570 /* output mixer control */ 10571 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), 10572 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 10573 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT), 10574 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 10575 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 10576 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 10577 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT), 10578 { } 10579}; 10580 10581/* bind Beep switches of both NID 0x0f and 0x10 */ 10582static struct hda_bind_ctls alc268_bind_beep_sw = { 10583 .ops = &snd_hda_bind_sw, 10584 .values = { 10585 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT), 10586 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT), 10587 0 10588 }, 10589}; 10590 10591static struct snd_kcontrol_new alc268_beep_mixer[] = { 10592 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT), 10593 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw), 10594 { } 10595}; 10596 10597static struct hda_verb alc268_eapd_verbs[] = { 10598 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 10599 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, 10600 { } 10601}; 10602 10603/* Toshiba specific */ 10604#define alc268_toshiba_automute alc262_hippo_automute 10605 10606static struct hda_verb alc268_toshiba_verbs[] = { 10607 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 10608 { } /* end */ 10609}; 10610 10611static struct hda_input_mux alc268_acer_lc_capture_source = { 10612 .num_items = 2, 10613 .items = { 10614 { "i-Mic", 0x6 }, 10615 { "E-Mic", 0x0 }, 10616 }, 10617}; 10618 10619/* Acer specific */ 10620/* bind volumes of both NID 0x02 and 0x03 */ 10621static struct hda_bind_ctls alc268_acer_bind_master_vol = { 10622 .ops = &snd_hda_bind_vol, 10623 .values = { 10624 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), 10625 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT), 10626 0 10627 }, 10628}; 10629 10630/* mute/unmute internal speaker according to the hp jack and mute state */ 10631static void alc268_acer_automute(struct hda_codec *codec, int force) 10632{ 10633 struct alc_spec *spec = codec->spec; 10634 unsigned int mute; 10635 10636 if (force || !spec->sense_updated) { 10637 unsigned int present; 10638 present = snd_hda_codec_read(codec, 0x14, 0, 10639 AC_VERB_GET_PIN_SENSE, 0); 10640 spec->jack_present = (present & 0x80000000) != 0; 10641 spec->sense_updated = 1; 10642 } 10643 if (spec->jack_present) 10644 mute = HDA_AMP_MUTE; /* mute internal speaker */ 10645 else /* unmute internal speaker if necessary */ 10646 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0); 10647 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 10648 HDA_AMP_MUTE, mute); 10649} 10650 10651 10652/* bind hp and internal speaker mute (with plug check) */ 10653static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol, 10654 struct snd_ctl_elem_value *ucontrol) 10655{ 10656 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 10657 long *valp = ucontrol->value.integer.value; 10658 int change; 10659 10660 change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0, 10661 HDA_AMP_MUTE, 10662 valp[0] ? 0 : HDA_AMP_MUTE); 10663 change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0, 10664 HDA_AMP_MUTE, 10665 valp[1] ? 0 : HDA_AMP_MUTE); 10666 if (change) 10667 alc268_acer_automute(codec, 0); 10668 return change; 10669} 10670 10671static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = { 10672 /* output mixer control */ 10673 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), 10674 { 10675 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 10676 .name = "Master Playback Switch", 10677 .info = snd_hda_mixer_amp_switch_info, 10678 .get = snd_hda_mixer_amp_switch_get, 10679 .put = alc268_acer_master_sw_put, 10680 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 10681 }, 10682 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT), 10683 { } 10684}; 10685 10686static struct snd_kcontrol_new alc268_acer_mixer[] = { 10687 /* output mixer control */ 10688 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), 10689 { 10690 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 10691 .name = "Master Playback Switch", 10692 .info = snd_hda_mixer_amp_switch_info, 10693 .get = snd_hda_mixer_amp_switch_get, 10694 .put = alc268_acer_master_sw_put, 10695 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 10696 }, 10697 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 10698 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), 10699 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT), 10700 { } 10701}; 10702 10703static struct hda_verb alc268_acer_aspire_one_verbs[] = { 10704 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 10705 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 10706 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 10707 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 10708 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06}, 10709 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017}, 10710 { } 10711}; 10712 10713static struct hda_verb alc268_acer_verbs[] = { 10714 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */ 10715 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 10716 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 10717 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 10718 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 10719 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 10720 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 10721 { } 10722}; 10723 10724/* unsolicited event for HP jack sensing */ 10725static void alc268_toshiba_unsol_event(struct hda_codec *codec, 10726 unsigned int res) 10727{ 10728 if ((res >> 26) != ALC880_HP_EVENT) 10729 return; 10730 alc268_toshiba_automute(codec); 10731} 10732 10733static void alc268_acer_unsol_event(struct hda_codec *codec, 10734 unsigned int res) 10735{ 10736 if ((res >> 26) != ALC880_HP_EVENT) 10737 return; 10738 alc268_acer_automute(codec, 1); 10739} 10740 10741static void alc268_acer_init_hook(struct hda_codec *codec) 10742{ 10743 alc268_acer_automute(codec, 1); 10744} 10745 10746/* toggle speaker-output according to the hp-jack state */ 10747static void alc268_aspire_one_speaker_automute(struct hda_codec *codec) 10748{ 10749 unsigned int present; 10750 unsigned char bits; 10751 10752 present = snd_hda_codec_read(codec, 0x15, 0, 10753 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 10754 bits = present ? AMP_IN_MUTE(0) : 0; 10755 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0, 10756 AMP_IN_MUTE(0), bits); 10757 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1, 10758 AMP_IN_MUTE(0), bits); 10759} 10760 10761 10762static void alc268_acer_mic_automute(struct hda_codec *codec) 10763{ 10764 unsigned int present; 10765 10766 present = snd_hda_codec_read(codec, 0x18, 0, 10767 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 10768 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_CONNECT_SEL, 10769 present ? 0x0 : 0x6); 10770} 10771 10772static void alc268_acer_lc_unsol_event(struct hda_codec *codec, 10773 unsigned int res) 10774{ 10775 if ((res >> 26) == ALC880_HP_EVENT) 10776 alc268_aspire_one_speaker_automute(codec); 10777 if ((res >> 26) == ALC880_MIC_EVENT) 10778 alc268_acer_mic_automute(codec); 10779} 10780 10781static void alc268_acer_lc_init_hook(struct hda_codec *codec) 10782{ 10783 alc268_aspire_one_speaker_automute(codec); 10784 alc268_acer_mic_automute(codec); 10785} 10786 10787static struct snd_kcontrol_new alc268_dell_mixer[] = { 10788 /* output mixer control */ 10789 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 10790 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 10791 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 10792 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 10793 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 10794 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), 10795 { } 10796}; 10797 10798static struct hda_verb alc268_dell_verbs[] = { 10799 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 10800 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 10801 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 10802 { } 10803}; 10804 10805/* mute/unmute internal speaker according to the hp jack and mute state */ 10806static void alc268_dell_automute(struct hda_codec *codec) 10807{ 10808 unsigned int present; 10809 unsigned int mute; 10810 10811 present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0); 10812 if (present & 0x80000000) 10813 mute = HDA_AMP_MUTE; 10814 else 10815 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0); 10816 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 10817 HDA_AMP_MUTE, mute); 10818} 10819 10820static void alc268_dell_unsol_event(struct hda_codec *codec, 10821 unsigned int res) 10822{ 10823 if ((res >> 26) != ALC880_HP_EVENT) 10824 return; 10825 alc268_dell_automute(codec); 10826} 10827 10828#define alc268_dell_init_hook alc268_dell_automute 10829 10830static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = { 10831 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT), 10832 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 10833 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT), 10834 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 10835 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT), 10836 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT), 10837 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT), 10838 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 10839 { } 10840}; 10841 10842static struct hda_verb alc267_quanta_il1_verbs[] = { 10843 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 10844 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, 10845 { } 10846}; 10847 10848static void alc267_quanta_il1_hp_automute(struct hda_codec *codec) 10849{ 10850 unsigned int present; 10851 10852 present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0) 10853 & AC_PINSENSE_PRESENCE; 10854 snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 10855 present ? 0 : PIN_OUT); 10856} 10857 10858static void alc267_quanta_il1_mic_automute(struct hda_codec *codec) 10859{ 10860 unsigned int present; 10861 10862 present = snd_hda_codec_read(codec, 0x18, 0, 10863 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 10864 snd_hda_codec_write(codec, 0x23, 0, 10865 AC_VERB_SET_CONNECT_SEL, 10866 present ? 0x00 : 0x01); 10867} 10868 10869static void alc267_quanta_il1_automute(struct hda_codec *codec) 10870{ 10871 alc267_quanta_il1_hp_automute(codec); 10872 alc267_quanta_il1_mic_automute(codec); 10873} 10874 10875static void alc267_quanta_il1_unsol_event(struct hda_codec *codec, 10876 unsigned int res) 10877{ 10878 switch (res >> 26) { 10879 case ALC880_HP_EVENT: 10880 alc267_quanta_il1_hp_automute(codec); 10881 break; 10882 case ALC880_MIC_EVENT: 10883 alc267_quanta_il1_mic_automute(codec); 10884 break; 10885 } 10886} 10887 10888/* 10889 * generic initialization of ADC, input mixers and output mixers 10890 */ 10891static struct hda_verb alc268_base_init_verbs[] = { 10892 /* Unmute DAC0-1 and set vol = 0 */ 10893 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 10894 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 10895 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 10896 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 10897 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 10898 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 10899 10900 /* 10901 * Set up output mixers (0x0c - 0x0e) 10902 */ 10903 /* set vol=0 to output mixers */ 10904 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 10905 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 10906 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 10907 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00}, 10908 10909 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 10910 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 10911 10912 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 10913 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 10914 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 10915 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 10916 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 10917 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 10918 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 10919 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 10920 10921 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 10922 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 10923 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 10924 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 10925 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 10926 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 10927 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 10928 10929 /* set PCBEEP vol = 0, mute connections */ 10930 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 10931 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 10932 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 10933 10934 /* Unmute Selector 23h,24h and set the default input to mic-in */ 10935 10936 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00}, 10937 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 10938 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00}, 10939 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 10940 10941 { } 10942}; 10943 10944/* 10945 * generic initialization of ADC, input mixers and output mixers 10946 */ 10947static struct hda_verb alc268_volume_init_verbs[] = { 10948 /* set output DAC */ 10949 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 10950 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 10951 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 10952 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 10953 10954 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 10955 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 10956 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 10957 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 10958 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 10959 10960 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 10961 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 10962 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 10963 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 10964 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 10965 10966 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 10967 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 10968 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 10969 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 10970 10971 /* set PCBEEP vol = 0, mute connections */ 10972 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 10973 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 10974 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 10975 10976 { } 10977}; 10978 10979static struct snd_kcontrol_new alc268_capture_alt_mixer[] = { 10980 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT), 10981 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT), 10982 { 10983 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 10984 /* The multiple "Capture Source" controls confuse alsamixer 10985 * So call somewhat different.. 10986 */ 10987 /* .name = "Capture Source", */ 10988 .name = "Input Source", 10989 .count = 1, 10990 .info = alc_mux_enum_info, 10991 .get = alc_mux_enum_get, 10992 .put = alc_mux_enum_put, 10993 }, 10994 { } /* end */ 10995}; 10996 10997static struct snd_kcontrol_new alc268_capture_mixer[] = { 10998 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT), 10999 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT), 11000 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT), 11001 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT), 11002 { 11003 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 11004 /* The multiple "Capture Source" controls confuse alsamixer 11005 * So call somewhat different.. 11006 */ 11007 /* .name = "Capture Source", */ 11008 .name = "Input Source", 11009 .count = 2, 11010 .info = alc_mux_enum_info, 11011 .get = alc_mux_enum_get, 11012 .put = alc_mux_enum_put, 11013 }, 11014 { } /* end */ 11015}; 11016 11017static struct hda_input_mux alc268_capture_source = { 11018 .num_items = 4, 11019 .items = { 11020 { "Mic", 0x0 }, 11021 { "Front Mic", 0x1 }, 11022 { "Line", 0x2 }, 11023 { "CD", 0x3 }, 11024 }, 11025}; 11026 11027static struct hda_input_mux alc268_acer_capture_source = { 11028 .num_items = 3, 11029 .items = { 11030 { "Mic", 0x0 }, 11031 { "Internal Mic", 0x6 }, 11032 { "Line", 0x2 }, 11033 }, 11034}; 11035 11036#ifdef CONFIG_SND_DEBUG 11037static struct snd_kcontrol_new alc268_test_mixer[] = { 11038 /* Volume widgets */ 11039 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT), 11040 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT), 11041 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT), 11042 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT), 11043 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT), 11044 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT), 11045 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT), 11046 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT), 11047 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT), 11048 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT), 11049 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT), 11050 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT), 11051 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT), 11052 /* The below appears problematic on some hardwares */ 11053 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/ 11054 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT), 11055 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT), 11056 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT), 11057 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT), 11058 11059 /* Modes for retasking pin widgets */ 11060 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT), 11061 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT), 11062 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT), 11063 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT), 11064 11065 /* Controls for GPIO pins, assuming they are configured as outputs */ 11066 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01), 11067 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02), 11068 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04), 11069 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08), 11070 11071 /* Switches to allow the digital SPDIF output pin to be enabled. 11072 * The ALC268 does not have an SPDIF input. 11073 */ 11074 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01), 11075 11076 /* A switch allowing EAPD to be enabled. Some laptops seem to use 11077 * this output to turn on an external amplifier. 11078 */ 11079 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02), 11080 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02), 11081 11082 { } /* end */ 11083}; 11084#endif 11085 11086/* create input playback/capture controls for the given pin */ 11087static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid, 11088 const char *ctlname, int idx) 11089{ 11090 char name[32]; 11091 int err; 11092 11093 sprintf(name, "%s Playback Volume", ctlname); 11094 if (nid == 0x14) { 11095 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, 11096 HDA_COMPOSE_AMP_VAL(0x02, 3, idx, 11097 HDA_OUTPUT)); 11098 if (err < 0) 11099 return err; 11100 } else if (nid == 0x15) { 11101 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, 11102 HDA_COMPOSE_AMP_VAL(0x03, 3, idx, 11103 HDA_OUTPUT)); 11104 if (err < 0) 11105 return err; 11106 } else 11107 return -1; 11108 sprintf(name, "%s Playback Switch", ctlname); 11109 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, 11110 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT)); 11111 if (err < 0) 11112 return err; 11113 return 0; 11114} 11115 11116/* add playback controls from the parsed DAC table */ 11117static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec, 11118 const struct auto_pin_cfg *cfg) 11119{ 11120 hda_nid_t nid; 11121 int err; 11122 11123 spec->multiout.num_dacs = 2; /* only use one dac */ 11124 spec->multiout.dac_nids = spec->private_dac_nids; 11125 spec->multiout.dac_nids[0] = 2; 11126 spec->multiout.dac_nids[1] = 3; 11127 11128 nid = cfg->line_out_pins[0]; 11129 if (nid) 11130 alc268_new_analog_output(spec, nid, "Front", 0); 11131 11132 nid = cfg->speaker_pins[0]; 11133 if (nid == 0x1d) { 11134 err = add_control(spec, ALC_CTL_WIDGET_VOL, 11135 "Speaker Playback Volume", 11136 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT)); 11137 if (err < 0) 11138 return err; 11139 } 11140 nid = cfg->hp_pins[0]; 11141 if (nid) 11142 alc268_new_analog_output(spec, nid, "Headphone", 0); 11143 11144 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2]; 11145 if (nid == 0x16) { 11146 err = add_control(spec, ALC_CTL_WIDGET_MUTE, 11147 "Mono Playback Switch", 11148 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT)); 11149 if (err < 0) 11150 return err; 11151 } 11152 return 0; 11153} 11154 11155/* create playback/capture controls for input pins */ 11156static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec, 11157 const struct auto_pin_cfg *cfg) 11158{ 11159 struct hda_input_mux *imux = &spec->private_imux; 11160 int i, idx1; 11161 11162 for (i = 0; i < AUTO_PIN_LAST; i++) { 11163 switch(cfg->input_pins[i]) { 11164 case 0x18: 11165 idx1 = 0; /* Mic 1 */ 11166 break; 11167 case 0x19: 11168 idx1 = 1; /* Mic 2 */ 11169 break; 11170 case 0x1a: 11171 idx1 = 2; /* Line In */ 11172 break; 11173 case 0x1c: 11174 idx1 = 3; /* CD */ 11175 break; 11176 case 0x12: 11177 case 0x13: 11178 idx1 = 6; /* digital mics */ 11179 break; 11180 default: 11181 continue; 11182 } 11183 imux->items[imux->num_items].label = auto_pin_cfg_labels[i]; 11184 imux->items[imux->num_items].index = idx1; 11185 imux->num_items++; 11186 } 11187 return 0; 11188} 11189 11190static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec) 11191{ 11192 struct alc_spec *spec = codec->spec; 11193 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0]; 11194 hda_nid_t hp_nid = spec->autocfg.hp_pins[0]; 11195 hda_nid_t line_nid = spec->autocfg.line_out_pins[0]; 11196 unsigned int dac_vol1, dac_vol2; 11197 11198 if (speaker_nid) { 11199 snd_hda_codec_write(codec, speaker_nid, 0, 11200 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); 11201 snd_hda_codec_write(codec, 0x0f, 0, 11202 AC_VERB_SET_AMP_GAIN_MUTE, 11203 AMP_IN_UNMUTE(1)); 11204 snd_hda_codec_write(codec, 0x10, 0, 11205 AC_VERB_SET_AMP_GAIN_MUTE, 11206 AMP_IN_UNMUTE(1)); 11207 } else { 11208 snd_hda_codec_write(codec, 0x0f, 0, 11209 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)); 11210 snd_hda_codec_write(codec, 0x10, 0, 11211 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)); 11212 } 11213 11214 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */ 11215 if (line_nid == 0x14) 11216 dac_vol2 = AMP_OUT_ZERO; 11217 else if (line_nid == 0x15) 11218 dac_vol1 = AMP_OUT_ZERO; 11219 if (hp_nid == 0x14) 11220 dac_vol2 = AMP_OUT_ZERO; 11221 else if (hp_nid == 0x15) 11222 dac_vol1 = AMP_OUT_ZERO; 11223 if (line_nid != 0x16 || hp_nid != 0x16 || 11224 spec->autocfg.line_out_pins[1] != 0x16 || 11225 spec->autocfg.line_out_pins[2] != 0x16) 11226 dac_vol1 = dac_vol2 = AMP_OUT_ZERO; 11227 11228 snd_hda_codec_write(codec, 0x02, 0, 11229 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1); 11230 snd_hda_codec_write(codec, 0x03, 0, 11231 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2); 11232} 11233 11234/* pcm configuration: identiacal with ALC880 */ 11235#define alc268_pcm_analog_playback alc880_pcm_analog_playback 11236#define alc268_pcm_analog_capture alc880_pcm_analog_capture 11237#define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture 11238#define alc268_pcm_digital_playback alc880_pcm_digital_playback 11239 11240/* 11241 * BIOS auto configuration 11242 */ 11243static int alc268_parse_auto_config(struct hda_codec *codec) 11244{ 11245 struct alc_spec *spec = codec->spec; 11246 int err; 11247 static hda_nid_t alc268_ignore[] = { 0 }; 11248 11249 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 11250 alc268_ignore); 11251 if (err < 0) 11252 return err; 11253 if (!spec->autocfg.line_outs) 11254 return 0; /* can't find valid BIOS pin config */ 11255 11256 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg); 11257 if (err < 0) 11258 return err; 11259 err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg); 11260 if (err < 0) 11261 return err; 11262 11263 spec->multiout.max_channels = 2; 11264 11265 /* digital only support output */ 11266 if (spec->autocfg.dig_out_pin) 11267 spec->multiout.dig_out_nid = ALC268_DIGOUT_NID; 11268 11269 if (spec->kctls.list) 11270 add_mixer(spec, spec->kctls.list); 11271 11272 if (spec->autocfg.speaker_pins[0] != 0x1d) 11273 add_mixer(spec, alc268_beep_mixer); 11274 11275 add_verb(spec, alc268_volume_init_verbs); 11276 spec->num_mux_defs = 1; 11277 spec->input_mux = &spec->private_imux; 11278 11279 err = alc_auto_add_mic_boost(codec); 11280 if (err < 0) 11281 return err; 11282 11283 store_pin_configs(codec); 11284 return 1; 11285} 11286 11287#define alc268_auto_init_multi_out alc882_auto_init_multi_out 11288#define alc268_auto_init_hp_out alc882_auto_init_hp_out 11289#define alc268_auto_init_analog_input alc882_auto_init_analog_input 11290 11291/* init callback for auto-configuration model -- overriding the default init */ 11292static void alc268_auto_init(struct hda_codec *codec) 11293{ 11294 struct alc_spec *spec = codec->spec; 11295 alc268_auto_init_multi_out(codec); 11296 alc268_auto_init_hp_out(codec); 11297 alc268_auto_init_mono_speaker_out(codec); 11298 alc268_auto_init_analog_input(codec); 11299 if (spec->unsol_event) 11300 alc_inithook(codec); 11301} 11302 11303/* 11304 * configuration and preset 11305 */ 11306static const char *alc268_models[ALC268_MODEL_LAST] = { 11307 [ALC267_QUANTA_IL1] = "quanta-il1", 11308 [ALC268_3ST] = "3stack", 11309 [ALC268_TOSHIBA] = "toshiba", 11310 [ALC268_ACER] = "acer", 11311 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire", 11312 [ALC268_DELL] = "dell", 11313 [ALC268_ZEPTO] = "zepto", 11314#ifdef CONFIG_SND_DEBUG 11315 [ALC268_TEST] = "test", 11316#endif 11317 [ALC268_AUTO] = "auto", 11318}; 11319 11320static struct snd_pci_quirk alc268_cfg_tbl[] = { 11321 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER), 11322 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER), 11323 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER), 11324 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER), 11325 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER), 11326 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One", 11327 ALC268_ACER_ASPIRE_ONE), 11328 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL), 11329 SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA), 11330 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST), 11331 SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA), 11332 SND_PCI_QUIRK(0x1179, 0xff50, "TOSHIBA A305", ALC268_TOSHIBA), 11333 SND_PCI_QUIRK(0x1179, 0xff64, "TOSHIBA L305", ALC268_TOSHIBA), 11334 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA), 11335 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER), 11336 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1), 11337 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO), 11338 {} 11339}; 11340 11341static struct alc_config_preset alc268_presets[] = { 11342 [ALC267_QUANTA_IL1] = { 11343 .mixers = { alc267_quanta_il1_mixer }, 11344 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 11345 alc267_quanta_il1_verbs }, 11346 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 11347 .dac_nids = alc268_dac_nids, 11348 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 11349 .adc_nids = alc268_adc_nids_alt, 11350 .hp_nid = 0x03, 11351 .num_channel_mode = ARRAY_SIZE(alc268_modes), 11352 .channel_mode = alc268_modes, 11353 .input_mux = &alc268_capture_source, 11354 .unsol_event = alc267_quanta_il1_unsol_event, 11355 .init_hook = alc267_quanta_il1_automute, 11356 }, 11357 [ALC268_3ST] = { 11358 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer, 11359 alc268_beep_mixer }, 11360 .init_verbs = { alc268_base_init_verbs }, 11361 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 11362 .dac_nids = alc268_dac_nids, 11363 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 11364 .adc_nids = alc268_adc_nids_alt, 11365 .capsrc_nids = alc268_capsrc_nids, 11366 .hp_nid = 0x03, 11367 .dig_out_nid = ALC268_DIGOUT_NID, 11368 .num_channel_mode = ARRAY_SIZE(alc268_modes), 11369 .channel_mode = alc268_modes, 11370 .input_mux = &alc268_capture_source, 11371 }, 11372 [ALC268_TOSHIBA] = { 11373 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer, 11374 alc268_beep_mixer }, 11375 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 11376 alc268_toshiba_verbs }, 11377 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 11378 .dac_nids = alc268_dac_nids, 11379 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 11380 .adc_nids = alc268_adc_nids_alt, 11381 .capsrc_nids = alc268_capsrc_nids, 11382 .hp_nid = 0x03, 11383 .num_channel_mode = ARRAY_SIZE(alc268_modes), 11384 .channel_mode = alc268_modes, 11385 .input_mux = &alc268_capture_source, 11386 .unsol_event = alc268_toshiba_unsol_event, 11387 .init_hook = alc268_toshiba_automute, 11388 }, 11389 [ALC268_ACER] = { 11390 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer, 11391 alc268_beep_mixer }, 11392 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 11393 alc268_acer_verbs }, 11394 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 11395 .dac_nids = alc268_dac_nids, 11396 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 11397 .adc_nids = alc268_adc_nids_alt, 11398 .capsrc_nids = alc268_capsrc_nids, 11399 .hp_nid = 0x02, 11400 .num_channel_mode = ARRAY_SIZE(alc268_modes), 11401 .channel_mode = alc268_modes, 11402 .input_mux = &alc268_acer_capture_source, 11403 .unsol_event = alc268_acer_unsol_event, 11404 .init_hook = alc268_acer_init_hook, 11405 }, 11406 [ALC268_ACER_ASPIRE_ONE] = { 11407 .mixers = { alc268_acer_aspire_one_mixer, 11408 alc268_capture_alt_mixer }, 11409 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 11410 alc268_acer_aspire_one_verbs }, 11411 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 11412 .dac_nids = alc268_dac_nids, 11413 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 11414 .adc_nids = alc268_adc_nids_alt, 11415 .capsrc_nids = alc268_capsrc_nids, 11416 .hp_nid = 0x03, 11417 .num_channel_mode = ARRAY_SIZE(alc268_modes), 11418 .channel_mode = alc268_modes, 11419 .input_mux = &alc268_acer_lc_capture_source, 11420 .unsol_event = alc268_acer_lc_unsol_event, 11421 .init_hook = alc268_acer_lc_init_hook, 11422 }, 11423 [ALC268_DELL] = { 11424 .mixers = { alc268_dell_mixer, alc268_beep_mixer }, 11425 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 11426 alc268_dell_verbs }, 11427 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 11428 .dac_nids = alc268_dac_nids, 11429 .hp_nid = 0x02, 11430 .num_channel_mode = ARRAY_SIZE(alc268_modes), 11431 .channel_mode = alc268_modes, 11432 .unsol_event = alc268_dell_unsol_event, 11433 .init_hook = alc268_dell_init_hook, 11434 .input_mux = &alc268_capture_source, 11435 }, 11436 [ALC268_ZEPTO] = { 11437 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer, 11438 alc268_beep_mixer }, 11439 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 11440 alc268_toshiba_verbs }, 11441 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 11442 .dac_nids = alc268_dac_nids, 11443 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 11444 .adc_nids = alc268_adc_nids_alt, 11445 .capsrc_nids = alc268_capsrc_nids, 11446 .hp_nid = 0x03, 11447 .dig_out_nid = ALC268_DIGOUT_NID, 11448 .num_channel_mode = ARRAY_SIZE(alc268_modes), 11449 .channel_mode = alc268_modes, 11450 .input_mux = &alc268_capture_source, 11451 .unsol_event = alc268_toshiba_unsol_event, 11452 .init_hook = alc268_toshiba_automute 11453 }, 11454#ifdef CONFIG_SND_DEBUG 11455 [ALC268_TEST] = { 11456 .mixers = { alc268_test_mixer, alc268_capture_mixer }, 11457 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 11458 alc268_volume_init_verbs }, 11459 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 11460 .dac_nids = alc268_dac_nids, 11461 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 11462 .adc_nids = alc268_adc_nids_alt, 11463 .capsrc_nids = alc268_capsrc_nids, 11464 .hp_nid = 0x03, 11465 .dig_out_nid = ALC268_DIGOUT_NID, 11466 .num_channel_mode = ARRAY_SIZE(alc268_modes), 11467 .channel_mode = alc268_modes, 11468 .input_mux = &alc268_capture_source, 11469 }, 11470#endif 11471}; 11472 11473static int patch_alc268(struct hda_codec *codec) 11474{ 11475 struct alc_spec *spec; 11476 int board_config; 11477 int err; 11478 11479 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); 11480 if (spec == NULL) 11481 return -ENOMEM; 11482 11483 codec->spec = spec; 11484 11485 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST, 11486 alc268_models, 11487 alc268_cfg_tbl); 11488 11489 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) { 11490 printk(KERN_INFO "hda_codec: Unknown model for ALC268, " 11491 "trying auto-probe from BIOS...\n"); 11492 board_config = ALC268_AUTO; 11493 } 11494 11495 if (board_config == ALC268_AUTO) { 11496 /* automatic parse from the BIOS config */ 11497 err = alc268_parse_auto_config(codec); 11498 if (err < 0) { 11499 alc_free(codec); 11500 return err; 11501 } else if (!err) { 11502 printk(KERN_INFO 11503 "hda_codec: Cannot set up configuration " 11504 "from BIOS. Using base mode...\n"); 11505 board_config = ALC268_3ST; 11506 } 11507 } 11508 11509 if (board_config != ALC268_AUTO) 11510 setup_preset(spec, &alc268_presets[board_config]); 11511 11512 if (codec->vendor_id == 0x10ec0267) { 11513 spec->stream_name_analog = "ALC267 Analog"; 11514 spec->stream_name_digital = "ALC267 Digital"; 11515 } else { 11516 spec->stream_name_analog = "ALC268 Analog"; 11517 spec->stream_name_digital = "ALC268 Digital"; 11518 } 11519 11520 spec->stream_analog_playback = &alc268_pcm_analog_playback; 11521 spec->stream_analog_capture = &alc268_pcm_analog_capture; 11522 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture; 11523 11524 spec->stream_digital_playback = &alc268_pcm_digital_playback; 11525 11526 if (!query_amp_caps(codec, 0x1d, HDA_INPUT)) 11527 /* override the amp caps for beep generator */ 11528 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT, 11529 (0x0c << AC_AMPCAP_OFFSET_SHIFT) | 11530 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) | 11531 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) | 11532 (0 << AC_AMPCAP_MUTE_SHIFT)); 11533 11534 if (!spec->adc_nids && spec->input_mux) { 11535 /* check whether NID 0x07 is valid */ 11536 unsigned int wcap = get_wcaps(codec, 0x07); 11537 int i; 11538 11539 /* get type */ 11540 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; 11541 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) { 11542 spec->adc_nids = alc268_adc_nids_alt; 11543 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt); 11544 add_mixer(spec, alc268_capture_alt_mixer); 11545 } else { 11546 spec->adc_nids = alc268_adc_nids; 11547 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids); 11548 add_mixer(spec, alc268_capture_mixer); 11549 } 11550 spec->capsrc_nids = alc268_capsrc_nids; 11551 /* set default input source */ 11552 for (i = 0; i < spec->num_adc_nids; i++) 11553 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i], 11554 0, AC_VERB_SET_CONNECT_SEL, 11555 spec->input_mux->items[0].index); 11556 } 11557 11558 spec->vmaster_nid = 0x02; 11559 11560 codec->patch_ops = alc_patch_ops; 11561 if (board_config == ALC268_AUTO) 11562 spec->init_hook = alc268_auto_init; 11563 11564 return 0; 11565} 11566 11567/* 11568 * ALC269 channel source setting (2 channel) 11569 */ 11570#define ALC269_DIGOUT_NID ALC880_DIGOUT_NID 11571 11572#define alc269_dac_nids alc260_dac_nids 11573 11574static hda_nid_t alc269_adc_nids[1] = { 11575 /* ADC1 */ 11576 0x08, 11577}; 11578 11579static hda_nid_t alc269_capsrc_nids[1] = { 11580 0x23, 11581}; 11582 11583/* NOTE: ADC2 (0x07) is connected from a recording *MIXER* (0x24), 11584 * not a mux! 11585 */ 11586 11587static struct hda_input_mux alc269_eeepc_dmic_capture_source = { 11588 .num_items = 2, 11589 .items = { 11590 { "i-Mic", 0x5 }, 11591 { "e-Mic", 0x0 }, 11592 }, 11593}; 11594 11595static struct hda_input_mux alc269_eeepc_amic_capture_source = { 11596 .num_items = 2, 11597 .items = { 11598 { "i-Mic", 0x1 }, 11599 { "e-Mic", 0x0 }, 11600 }, 11601}; 11602 11603#define alc269_modes alc260_modes 11604#define alc269_capture_source alc880_lg_lw_capture_source 11605 11606static struct snd_kcontrol_new alc269_base_mixer[] = { 11607 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 11608 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 11609 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 11610 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 11611 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11612 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11613 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x4, HDA_INPUT), 11614 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x4, HDA_INPUT), 11615 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 11616 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 11617 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 11618 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 11619 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 11620 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT), 11621 { } /* end */ 11622}; 11623 11624static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = { 11625 /* output mixer control */ 11626 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), 11627 { 11628 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 11629 .name = "Master Playback Switch", 11630 .info = snd_hda_mixer_amp_switch_info, 11631 .get = snd_hda_mixer_amp_switch_get, 11632 .put = alc268_acer_master_sw_put, 11633 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 11634 }, 11635 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11636 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11637 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 11638 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 11639 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 11640 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), 11641 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x04, HDA_INPUT), 11642 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x04, HDA_INPUT), 11643 { } 11644}; 11645 11646/* bind volumes of both NID 0x0c and 0x0d */ 11647static struct hda_bind_ctls alc269_epc_bind_vol = { 11648 .ops = &snd_hda_bind_vol, 11649 .values = { 11650 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), 11651 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT), 11652 0 11653 }, 11654}; 11655 11656static struct snd_kcontrol_new alc269_eeepc_mixer[] = { 11657 HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 11658 HDA_BIND_VOL("LineOut Playback Volume", &alc269_epc_bind_vol), 11659 HDA_CODEC_MUTE("LineOut Playback Switch", 0x15, 0x0, HDA_OUTPUT), 11660 { } /* end */ 11661}; 11662 11663/* capture mixer elements */ 11664static struct snd_kcontrol_new alc269_epc_capture_mixer[] = { 11665 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 11666 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 11667 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 11668 { } /* end */ 11669}; 11670 11671/* FSC amilo */ 11672static struct snd_kcontrol_new alc269_fujitsu_mixer[] = { 11673 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 11674 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 11675 HDA_BIND_VOL("PCM Playback Volume", &alc269_epc_bind_vol), 11676 { } /* end */ 11677}; 11678 11679/* beep control */ 11680static struct snd_kcontrol_new alc269_beep_mixer[] = { 11681 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x4, HDA_INPUT), 11682 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x4, HDA_INPUT), 11683 { } /* end */ 11684}; 11685 11686static struct hda_verb alc269_quanta_fl1_verbs[] = { 11687 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 11688 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 11689 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11690 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 11691 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 11692 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 11693 { } 11694}; 11695 11696/* toggle speaker-output according to the hp-jack state */ 11697static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec) 11698{ 11699 unsigned int present; 11700 unsigned char bits; 11701 11702 present = snd_hda_codec_read(codec, 0x15, 0, 11703 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 11704 bits = present ? AMP_IN_MUTE(0) : 0; 11705 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 11706 AMP_IN_MUTE(0), bits); 11707 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 11708 AMP_IN_MUTE(0), bits); 11709 11710 snd_hda_codec_write(codec, 0x20, 0, 11711 AC_VERB_SET_COEF_INDEX, 0x0c); 11712 snd_hda_codec_write(codec, 0x20, 0, 11713 AC_VERB_SET_PROC_COEF, 0x680); 11714 11715 snd_hda_codec_write(codec, 0x20, 0, 11716 AC_VERB_SET_COEF_INDEX, 0x0c); 11717 snd_hda_codec_write(codec, 0x20, 0, 11718 AC_VERB_SET_PROC_COEF, 0x480); 11719} 11720 11721static void alc269_quanta_fl1_mic_automute(struct hda_codec *codec) 11722{ 11723 unsigned int present; 11724 11725 present = snd_hda_codec_read(codec, 0x18, 0, 11726 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 11727 snd_hda_codec_write(codec, 0x23, 0, 11728 AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x1); 11729} 11730 11731static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec, 11732 unsigned int res) 11733{ 11734 if ((res >> 26) == ALC880_HP_EVENT) 11735 alc269_quanta_fl1_speaker_automute(codec); 11736 if ((res >> 26) == ALC880_MIC_EVENT) 11737 alc269_quanta_fl1_mic_automute(codec); 11738} 11739 11740static void alc269_quanta_fl1_init_hook(struct hda_codec *codec) 11741{ 11742 alc269_quanta_fl1_speaker_automute(codec); 11743 alc269_quanta_fl1_mic_automute(codec); 11744} 11745 11746static struct hda_verb alc269_eeepc_dmic_init_verbs[] = { 11747 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 11748 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05}, 11749 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 }, 11750 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))}, 11751 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 11752 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 11753 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 11754 {} 11755}; 11756 11757static struct hda_verb alc269_eeepc_amic_init_verbs[] = { 11758 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 11759 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01}, 11760 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 }, 11761 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))}, 11762 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 11763 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 11764 {} 11765}; 11766 11767/* toggle speaker-output according to the hp-jack state */ 11768static void alc269_speaker_automute(struct hda_codec *codec) 11769{ 11770 unsigned int present; 11771 unsigned char bits; 11772 11773 present = snd_hda_codec_read(codec, 0x15, 0, 11774 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 11775 bits = present ? AMP_IN_MUTE(0) : 0; 11776 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 11777 AMP_IN_MUTE(0), bits); 11778 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 11779 AMP_IN_MUTE(0), bits); 11780} 11781 11782static void alc269_eeepc_dmic_automute(struct hda_codec *codec) 11783{ 11784 unsigned int present; 11785 11786 present = snd_hda_codec_read(codec, 0x18, 0, 11787 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 11788 snd_hda_codec_write(codec, 0x23, 0, 11789 AC_VERB_SET_CONNECT_SEL, (present ? 0 : 5)); 11790} 11791 11792static void alc269_eeepc_amic_automute(struct hda_codec *codec) 11793{ 11794 unsigned int present; 11795 11796 present = snd_hda_codec_read(codec, 0x18, 0, 11797 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 11798 snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE, 11799 0x7000 | (0x00 << 8) | (present ? 0 : 0x80)); 11800 snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE, 11801 0x7000 | (0x01 << 8) | (present ? 0x80 : 0)); 11802} 11803 11804/* unsolicited event for HP jack sensing */ 11805static void alc269_eeepc_dmic_unsol_event(struct hda_codec *codec, 11806 unsigned int res) 11807{ 11808 if ((res >> 26) == ALC880_HP_EVENT) 11809 alc269_speaker_automute(codec); 11810 11811 if ((res >> 26) == ALC880_MIC_EVENT) 11812 alc269_eeepc_dmic_automute(codec); 11813} 11814 11815static void alc269_eeepc_dmic_inithook(struct hda_codec *codec) 11816{ 11817 alc269_speaker_automute(codec); 11818 alc269_eeepc_dmic_automute(codec); 11819} 11820 11821/* unsolicited event for HP jack sensing */ 11822static void alc269_eeepc_amic_unsol_event(struct hda_codec *codec, 11823 unsigned int res) 11824{ 11825 if ((res >> 26) == ALC880_HP_EVENT) 11826 alc269_speaker_automute(codec); 11827 11828 if ((res >> 26) == ALC880_MIC_EVENT) 11829 alc269_eeepc_amic_automute(codec); 11830} 11831 11832static void alc269_eeepc_amic_inithook(struct hda_codec *codec) 11833{ 11834 alc269_speaker_automute(codec); 11835 alc269_eeepc_amic_automute(codec); 11836} 11837 11838/* 11839 * generic initialization of ADC, input mixers and output mixers 11840 */ 11841static struct hda_verb alc269_init_verbs[] = { 11842 /* 11843 * Unmute ADC0 and set the default input to mic-in 11844 */ 11845 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11846 11847 /* Mute input amps (PCBeep, Line In, Mic 1 & Mic 2) of the 11848 * analog-loopback mixer widget 11849 * Note: PASD motherboards uses the Line In 2 as the input for 11850 * front panel mic (mic 2) 11851 */ 11852 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 11853 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 11854 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 11855 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 11856 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 11857 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 11858 11859 /* 11860 * Set up output mixers (0x0c - 0x0e) 11861 */ 11862 /* set vol=0 to output mixers */ 11863 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 11864 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 11865 11866 /* set up input amps for analog loopback */ 11867 /* Amp Indices: DAC = 0, mixer = 1 */ 11868 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11869 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11870 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11871 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11872 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11873 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11874 11875 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 11876 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11877 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 11878 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 11879 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 11880 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 11881 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 11882 11883 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 11884 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 11885 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 11886 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 11887 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 11888 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 11889 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 11890 11891 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 11892 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 11893 11894 /* FIXME: use matrix-type input source selection */ 11895 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */ 11896 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 11897 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 11898 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11899 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 11900 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 11901 11902 /* set EAPD */ 11903 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 11904 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, 11905 { } 11906}; 11907 11908/* add playback controls from the parsed DAC table */ 11909static int alc269_auto_create_multi_out_ctls(struct alc_spec *spec, 11910 const struct auto_pin_cfg *cfg) 11911{ 11912 hda_nid_t nid; 11913 int err; 11914 11915 spec->multiout.num_dacs = 1; /* only use one dac */ 11916 spec->multiout.dac_nids = spec->private_dac_nids; 11917 spec->multiout.dac_nids[0] = 2; 11918 11919 nid = cfg->line_out_pins[0]; 11920 if (nid) { 11921 err = add_control(spec, ALC_CTL_WIDGET_VOL, 11922 "Front Playback Volume", 11923 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT)); 11924 if (err < 0) 11925 return err; 11926 err = add_control(spec, ALC_CTL_WIDGET_MUTE, 11927 "Front Playback Switch", 11928 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); 11929 if (err < 0) 11930 return err; 11931 } 11932 11933 nid = cfg->speaker_pins[0]; 11934 if (nid) { 11935 if (!cfg->line_out_pins[0]) { 11936 err = add_control(spec, ALC_CTL_WIDGET_VOL, 11937 "Speaker Playback Volume", 11938 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, 11939 HDA_OUTPUT)); 11940 if (err < 0) 11941 return err; 11942 } 11943 if (nid == 0x16) { 11944 err = add_control(spec, ALC_CTL_WIDGET_MUTE, 11945 "Speaker Playback Switch", 11946 HDA_COMPOSE_AMP_VAL(nid, 2, 0, 11947 HDA_OUTPUT)); 11948 if (err < 0) 11949 return err; 11950 } else { 11951 err = add_control(spec, ALC_CTL_WIDGET_MUTE, 11952 "Speaker Playback Switch", 11953 HDA_COMPOSE_AMP_VAL(nid, 3, 0, 11954 HDA_OUTPUT)); 11955 if (err < 0) 11956 return err; 11957 } 11958 } 11959 nid = cfg->hp_pins[0]; 11960 if (nid) { 11961 /* spec->multiout.hp_nid = 2; */ 11962 if (!cfg->line_out_pins[0] && !cfg->speaker_pins[0]) { 11963 err = add_control(spec, ALC_CTL_WIDGET_VOL, 11964 "Headphone Playback Volume", 11965 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, 11966 HDA_OUTPUT)); 11967 if (err < 0) 11968 return err; 11969 } 11970 if (nid == 0x16) { 11971 err = add_control(spec, ALC_CTL_WIDGET_MUTE, 11972 "Headphone Playback Switch", 11973 HDA_COMPOSE_AMP_VAL(nid, 2, 0, 11974 HDA_OUTPUT)); 11975 if (err < 0) 11976 return err; 11977 } else { 11978 err = add_control(spec, ALC_CTL_WIDGET_MUTE, 11979 "Headphone Playback Switch", 11980 HDA_COMPOSE_AMP_VAL(nid, 3, 0, 11981 HDA_OUTPUT)); 11982 if (err < 0) 11983 return err; 11984 } 11985 } 11986 return 0; 11987} 11988 11989static int alc269_auto_create_analog_input_ctls(struct alc_spec *spec, 11990 const struct auto_pin_cfg *cfg) 11991{ 11992 int err; 11993 11994 err = alc880_auto_create_analog_input_ctls(spec, cfg); 11995 if (err < 0) 11996 return err; 11997 /* digital-mic input pin is excluded in alc880_auto_create..() 11998 * because it's under 0x18 11999 */ 12000 if (cfg->input_pins[AUTO_PIN_MIC] == 0x12 || 12001 cfg->input_pins[AUTO_PIN_FRONT_MIC] == 0x12) { 12002 struct hda_input_mux *imux = &spec->private_imux; 12003 imux->items[imux->num_items].label = "Int Mic"; 12004 imux->items[imux->num_items].index = 0x05; 12005 imux->num_items++; 12006 } 12007 return 0; 12008} 12009 12010#ifdef CONFIG_SND_HDA_POWER_SAVE 12011#define alc269_loopbacks alc880_loopbacks 12012#endif 12013 12014/* pcm configuration: identiacal with ALC880 */ 12015#define alc269_pcm_analog_playback alc880_pcm_analog_playback 12016#define alc269_pcm_analog_capture alc880_pcm_analog_capture 12017#define alc269_pcm_digital_playback alc880_pcm_digital_playback 12018#define alc269_pcm_digital_capture alc880_pcm_digital_capture 12019 12020/* 12021 * BIOS auto configuration 12022 */ 12023static int alc269_parse_auto_config(struct hda_codec *codec) 12024{ 12025 struct alc_spec *spec = codec->spec; 12026 int i, err; 12027 static hda_nid_t alc269_ignore[] = { 0x1d, 0 }; 12028 12029 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 12030 alc269_ignore); 12031 if (err < 0) 12032 return err; 12033 12034 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg); 12035 if (err < 0) 12036 return err; 12037 err = alc269_auto_create_analog_input_ctls(spec, &spec->autocfg); 12038 if (err < 0) 12039 return err; 12040 12041 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 12042 12043 if (spec->autocfg.dig_out_pin) 12044 spec->multiout.dig_out_nid = ALC269_DIGOUT_NID; 12045 12046 if (spec->kctls.list) 12047 add_mixer(spec, spec->kctls.list); 12048 12049 /* create a beep mixer control if the pin 0x1d isn't assigned */ 12050 for (i = 0; i < ARRAY_SIZE(spec->autocfg.input_pins); i++) 12051 if (spec->autocfg.input_pins[i] == 0x1d) 12052 break; 12053 if (i >= ARRAY_SIZE(spec->autocfg.input_pins)) 12054 add_mixer(spec, alc269_beep_mixer); 12055 12056 add_verb(spec, alc269_init_verbs); 12057 spec->num_mux_defs = 1; 12058 spec->input_mux = &spec->private_imux; 12059 /* set default input source */ 12060 snd_hda_codec_write_cache(codec, alc269_capsrc_nids[0], 12061 0, AC_VERB_SET_CONNECT_SEL, 12062 spec->input_mux->items[0].index); 12063 12064 err = alc_auto_add_mic_boost(codec); 12065 if (err < 0) 12066 return err; 12067 12068 if (!spec->cap_mixer) 12069 set_capture_mixer(spec); 12070 12071 store_pin_configs(codec); 12072 return 1; 12073} 12074 12075#define alc269_auto_init_multi_out alc882_auto_init_multi_out 12076#define alc269_auto_init_hp_out alc882_auto_init_hp_out 12077#define alc269_auto_init_analog_input alc882_auto_init_analog_input 12078 12079 12080/* init callback for auto-configuration model -- overriding the default init */ 12081static void alc269_auto_init(struct hda_codec *codec) 12082{ 12083 struct alc_spec *spec = codec->spec; 12084 alc269_auto_init_multi_out(codec); 12085 alc269_auto_init_hp_out(codec); 12086 alc269_auto_init_analog_input(codec); 12087 if (spec->unsol_event) 12088 alc_inithook(codec); 12089} 12090 12091/* 12092 * configuration and preset 12093 */ 12094static const char *alc269_models[ALC269_MODEL_LAST] = { 12095 [ALC269_BASIC] = "basic", 12096 [ALC269_QUANTA_FL1] = "quanta", 12097 [ALC269_ASUS_EEEPC_P703] = "eeepc-p703", 12098 [ALC269_ASUS_EEEPC_P901] = "eeepc-p901", 12099 [ALC269_FUJITSU] = "fujitsu" 12100}; 12101 12102static struct snd_pci_quirk alc269_cfg_tbl[] = { 12103 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1), 12104 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A", 12105 ALC269_ASUS_EEEPC_P703), 12106 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901", 12107 ALC269_ASUS_EEEPC_P901), 12108 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101", 12109 ALC269_ASUS_EEEPC_P901), 12110 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU), 12111 {} 12112}; 12113 12114static struct alc_config_preset alc269_presets[] = { 12115 [ALC269_BASIC] = { 12116 .mixers = { alc269_base_mixer }, 12117 .init_verbs = { alc269_init_verbs }, 12118 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 12119 .dac_nids = alc269_dac_nids, 12120 .hp_nid = 0x03, 12121 .num_channel_mode = ARRAY_SIZE(alc269_modes), 12122 .channel_mode = alc269_modes, 12123 .input_mux = &alc269_capture_source, 12124 }, 12125 [ALC269_QUANTA_FL1] = { 12126 .mixers = { alc269_quanta_fl1_mixer }, 12127 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs }, 12128 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 12129 .dac_nids = alc269_dac_nids, 12130 .hp_nid = 0x03, 12131 .num_channel_mode = ARRAY_SIZE(alc269_modes), 12132 .channel_mode = alc269_modes, 12133 .input_mux = &alc269_capture_source, 12134 .unsol_event = alc269_quanta_fl1_unsol_event, 12135 .init_hook = alc269_quanta_fl1_init_hook, 12136 }, 12137 [ALC269_ASUS_EEEPC_P703] = { 12138 .mixers = { alc269_eeepc_mixer }, 12139 .cap_mixer = alc269_epc_capture_mixer, 12140 .init_verbs = { alc269_init_verbs, 12141 alc269_eeepc_amic_init_verbs }, 12142 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 12143 .dac_nids = alc269_dac_nids, 12144 .hp_nid = 0x03, 12145 .num_channel_mode = ARRAY_SIZE(alc269_modes), 12146 .channel_mode = alc269_modes, 12147 .input_mux = &alc269_eeepc_amic_capture_source, 12148 .unsol_event = alc269_eeepc_amic_unsol_event, 12149 .init_hook = alc269_eeepc_amic_inithook, 12150 }, 12151 [ALC269_ASUS_EEEPC_P901] = { 12152 .mixers = { alc269_eeepc_mixer }, 12153 .cap_mixer = alc269_epc_capture_mixer, 12154 .init_verbs = { alc269_init_verbs, 12155 alc269_eeepc_dmic_init_verbs }, 12156 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 12157 .dac_nids = alc269_dac_nids, 12158 .hp_nid = 0x03, 12159 .num_channel_mode = ARRAY_SIZE(alc269_modes), 12160 .channel_mode = alc269_modes, 12161 .input_mux = &alc269_eeepc_dmic_capture_source, 12162 .unsol_event = alc269_eeepc_dmic_unsol_event, 12163 .init_hook = alc269_eeepc_dmic_inithook, 12164 }, 12165 [ALC269_FUJITSU] = { 12166 .mixers = { alc269_fujitsu_mixer, alc269_beep_mixer }, 12167 .cap_mixer = alc269_epc_capture_mixer, 12168 .init_verbs = { alc269_init_verbs, 12169 alc269_eeepc_dmic_init_verbs }, 12170 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 12171 .dac_nids = alc269_dac_nids, 12172 .hp_nid = 0x03, 12173 .num_channel_mode = ARRAY_SIZE(alc269_modes), 12174 .channel_mode = alc269_modes, 12175 .input_mux = &alc269_eeepc_dmic_capture_source, 12176 .unsol_event = alc269_eeepc_dmic_unsol_event, 12177 .init_hook = alc269_eeepc_dmic_inithook, 12178 }, 12179}; 12180 12181static int patch_alc269(struct hda_codec *codec) 12182{ 12183 struct alc_spec *spec; 12184 int board_config; 12185 int err; 12186 12187 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 12188 if (spec == NULL) 12189 return -ENOMEM; 12190 12191 codec->spec = spec; 12192 12193 alc_fix_pll_init(codec, 0x20, 0x04, 15); 12194 12195 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST, 12196 alc269_models, 12197 alc269_cfg_tbl); 12198 12199 if (board_config < 0) { 12200 printk(KERN_INFO "hda_codec: Unknown model for ALC269, " 12201 "trying auto-probe from BIOS...\n"); 12202 board_config = ALC269_AUTO; 12203 } 12204 12205 if (board_config == ALC269_AUTO) { 12206 /* automatic parse from the BIOS config */ 12207 err = alc269_parse_auto_config(codec); 12208 if (err < 0) { 12209 alc_free(codec); 12210 return err; 12211 } else if (!err) { 12212 printk(KERN_INFO 12213 "hda_codec: Cannot set up configuration " 12214 "from BIOS. Using base mode...\n"); 12215 board_config = ALC269_BASIC; 12216 } 12217 } 12218 12219 if (board_config != ALC269_AUTO) 12220 setup_preset(spec, &alc269_presets[board_config]); 12221 12222 spec->stream_name_analog = "ALC269 Analog"; 12223 spec->stream_analog_playback = &alc269_pcm_analog_playback; 12224 spec->stream_analog_capture = &alc269_pcm_analog_capture; 12225 12226 spec->stream_name_digital = "ALC269 Digital"; 12227 spec->stream_digital_playback = &alc269_pcm_digital_playback; 12228 spec->stream_digital_capture = &alc269_pcm_digital_capture; 12229 12230 spec->adc_nids = alc269_adc_nids; 12231 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids); 12232 spec->capsrc_nids = alc269_capsrc_nids; 12233 if (!spec->cap_mixer) 12234 set_capture_mixer(spec); 12235 12236 codec->patch_ops = alc_patch_ops; 12237 if (board_config == ALC269_AUTO) 12238 spec->init_hook = alc269_auto_init; 12239#ifdef CONFIG_SND_HDA_POWER_SAVE 12240 if (!spec->loopback.amplist) 12241 spec->loopback.amplist = alc269_loopbacks; 12242#endif 12243 12244 return 0; 12245} 12246 12247/* 12248 * ALC861 channel source setting (2/6 channel selection for 3-stack) 12249 */ 12250 12251/* 12252 * set the path ways for 2 channel output 12253 * need to set the codec line out and mic 1 pin widgets to inputs 12254 */ 12255static struct hda_verb alc861_threestack_ch2_init[] = { 12256 /* set pin widget 1Ah (line in) for input */ 12257 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 12258 /* set pin widget 18h (mic1/2) for input, for mic also enable 12259 * the vref 12260 */ 12261 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 12262 12263 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, 12264#if 0 12265 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/ 12266 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/ 12267#endif 12268 { } /* end */ 12269}; 12270/* 12271 * 6ch mode 12272 * need to set the codec line out and mic 1 pin widgets to outputs 12273 */ 12274static struct hda_verb alc861_threestack_ch6_init[] = { 12275 /* set pin widget 1Ah (line in) for output (Back Surround)*/ 12276 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 12277 /* set pin widget 18h (mic1) for output (CLFE)*/ 12278 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 12279 12280 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 }, 12281 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 }, 12282 12283 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 }, 12284#if 0 12285 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/ 12286 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/ 12287#endif 12288 { } /* end */ 12289}; 12290 12291static struct hda_channel_mode alc861_threestack_modes[2] = { 12292 { 2, alc861_threestack_ch2_init }, 12293 { 6, alc861_threestack_ch6_init }, 12294}; 12295/* Set mic1 as input and unmute the mixer */ 12296static struct hda_verb alc861_uniwill_m31_ch2_init[] = { 12297 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 12298 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/ 12299 { } /* end */ 12300}; 12301/* Set mic1 as output and mute mixer */ 12302static struct hda_verb alc861_uniwill_m31_ch4_init[] = { 12303 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 12304 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/ 12305 { } /* end */ 12306}; 12307 12308static struct hda_channel_mode alc861_uniwill_m31_modes[2] = { 12309 { 2, alc861_uniwill_m31_ch2_init }, 12310 { 4, alc861_uniwill_m31_ch4_init }, 12311}; 12312 12313/* Set mic1 and line-in as input and unmute the mixer */ 12314static struct hda_verb alc861_asus_ch2_init[] = { 12315 /* set pin widget 1Ah (line in) for input */ 12316 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 12317 /* set pin widget 18h (mic1/2) for input, for mic also enable 12318 * the vref 12319 */ 12320 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 12321 12322 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, 12323#if 0 12324 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/ 12325 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/ 12326#endif 12327 { } /* end */ 12328}; 12329/* Set mic1 nad line-in as output and mute mixer */ 12330static struct hda_verb alc861_asus_ch6_init[] = { 12331 /* set pin widget 1Ah (line in) for output (Back Surround)*/ 12332 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 12333 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */ 12334 /* set pin widget 18h (mic1) for output (CLFE)*/ 12335 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 12336 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */ 12337 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 }, 12338 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 }, 12339 12340 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 }, 12341#if 0 12342 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/ 12343 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/ 12344#endif 12345 { } /* end */ 12346}; 12347 12348static struct hda_channel_mode alc861_asus_modes[2] = { 12349 { 2, alc861_asus_ch2_init }, 12350 { 6, alc861_asus_ch6_init }, 12351}; 12352 12353/* patch-ALC861 */ 12354 12355static struct snd_kcontrol_new alc861_base_mixer[] = { 12356 /* output mixer control */ 12357 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), 12358 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), 12359 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT), 12360 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT), 12361 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), 12362 12363 /*Input mixer control */ 12364 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT), 12365 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */ 12366 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), 12367 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), 12368 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT), 12369 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT), 12370 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), 12371 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), 12372 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), 12373 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT), 12374 12375 { } /* end */ 12376}; 12377 12378static struct snd_kcontrol_new alc861_3ST_mixer[] = { 12379 /* output mixer control */ 12380 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), 12381 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), 12382 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT), 12383 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT), 12384 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */ 12385 12386 /* Input mixer control */ 12387 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT), 12388 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */ 12389 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), 12390 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), 12391 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT), 12392 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT), 12393 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), 12394 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), 12395 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), 12396 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT), 12397 12398 { 12399 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 12400 .name = "Channel Mode", 12401 .info = alc_ch_mode_info, 12402 .get = alc_ch_mode_get, 12403 .put = alc_ch_mode_put, 12404 .private_value = ARRAY_SIZE(alc861_threestack_modes), 12405 }, 12406 { } /* end */ 12407}; 12408 12409static struct snd_kcontrol_new alc861_toshiba_mixer[] = { 12410 /* output mixer control */ 12411 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT), 12412 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), 12413 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), 12414 12415 { } /* end */ 12416}; 12417 12418static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = { 12419 /* output mixer control */ 12420 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), 12421 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), 12422 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT), 12423 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT), 12424 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */ 12425 12426 /* Input mixer control */ 12427 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT), 12428 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */ 12429 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), 12430 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), 12431 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT), 12432 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT), 12433 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), 12434 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), 12435 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), 12436 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT), 12437 12438 { 12439 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 12440 .name = "Channel Mode", 12441 .info = alc_ch_mode_info, 12442 .get = alc_ch_mode_get, 12443 .put = alc_ch_mode_put, 12444 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes), 12445 }, 12446 { } /* end */ 12447}; 12448 12449static struct snd_kcontrol_new alc861_asus_mixer[] = { 12450 /* output mixer control */ 12451 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), 12452 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), 12453 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT), 12454 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT), 12455 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), 12456 12457 /* Input mixer control */ 12458 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT), 12459 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), 12460 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), 12461 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), 12462 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT), 12463 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT), 12464 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), 12465 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), 12466 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), 12467 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT), 12468 12469 { 12470 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 12471 .name = "Channel Mode", 12472 .info = alc_ch_mode_info, 12473 .get = alc_ch_mode_get, 12474 .put = alc_ch_mode_put, 12475 .private_value = ARRAY_SIZE(alc861_asus_modes), 12476 }, 12477 { } 12478}; 12479 12480/* additional mixer */ 12481static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = { 12482 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), 12483 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), 12484 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x23, 0x0, HDA_OUTPUT), 12485 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x23, 0x0, HDA_OUTPUT), 12486 { } 12487}; 12488 12489/* 12490 * generic initialization of ADC, input mixers and output mixers 12491 */ 12492static struct hda_verb alc861_base_init_verbs[] = { 12493 /* 12494 * Unmute ADC0 and set the default input to mic-in 12495 */ 12496 /* port-A for surround (rear panel) */ 12497 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 12498 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 }, 12499 /* port-B for mic-in (rear panel) with vref */ 12500 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 12501 /* port-C for line-in (rear panel) */ 12502 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 12503 /* port-D for Front */ 12504 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 12505 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 }, 12506 /* port-E for HP out (front panel) */ 12507 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, 12508 /* route front PCM to HP */ 12509 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, 12510 /* port-F for mic-in (front panel) with vref */ 12511 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 12512 /* port-G for CLFE (rear panel) */ 12513 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 12514 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 }, 12515 /* port-H for side (rear panel) */ 12516 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 12517 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 }, 12518 /* CD-in */ 12519 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 12520 /* route front mic to ADC1*/ 12521 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 12522 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12523 12524 /* Unmute DAC0~3 & spdif out*/ 12525 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 12526 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 12527 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 12528 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 12529 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 12530 12531 /* Unmute Mixer 14 (mic) 1c (Line in)*/ 12532 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12533 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12534 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12535 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12536 12537 /* Unmute Stereo Mixer 15 */ 12538 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12539 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12540 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 12541 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */ 12542 12543 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12544 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12545 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12546 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12547 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12548 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12549 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12550 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12551 /* hp used DAC 3 (Front) */ 12552 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 12553 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 12554 12555 { } 12556}; 12557 12558static struct hda_verb alc861_threestack_init_verbs[] = { 12559 /* 12560 * Unmute ADC0 and set the default input to mic-in 12561 */ 12562 /* port-A for surround (rear panel) */ 12563 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 12564 /* port-B for mic-in (rear panel) with vref */ 12565 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 12566 /* port-C for line-in (rear panel) */ 12567 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 12568 /* port-D for Front */ 12569 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 12570 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 }, 12571 /* port-E for HP out (front panel) */ 12572 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, 12573 /* route front PCM to HP */ 12574 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, 12575 /* port-F for mic-in (front panel) with vref */ 12576 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 12577 /* port-G for CLFE (rear panel) */ 12578 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 12579 /* port-H for side (rear panel) */ 12580 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 12581 /* CD-in */ 12582 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 12583 /* route front mic to ADC1*/ 12584 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 12585 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12586 /* Unmute DAC0~3 & spdif out*/ 12587 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 12588 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 12589 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 12590 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 12591 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 12592 12593 /* Unmute Mixer 14 (mic) 1c (Line in)*/ 12594 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12595 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12596 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12597 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12598 12599 /* Unmute Stereo Mixer 15 */ 12600 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12601 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12602 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 12603 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */ 12604 12605 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12606 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12607 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12608 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12609 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12610 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12611 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12612 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12613 /* hp used DAC 3 (Front) */ 12614 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 12615 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 12616 { } 12617}; 12618 12619static struct hda_verb alc861_uniwill_m31_init_verbs[] = { 12620 /* 12621 * Unmute ADC0 and set the default input to mic-in 12622 */ 12623 /* port-A for surround (rear panel) */ 12624 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 12625 /* port-B for mic-in (rear panel) with vref */ 12626 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 12627 /* port-C for line-in (rear panel) */ 12628 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 12629 /* port-D for Front */ 12630 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 12631 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 }, 12632 /* port-E for HP out (front panel) */ 12633 /* this has to be set to VREF80 */ 12634 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 12635 /* route front PCM to HP */ 12636 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, 12637 /* port-F for mic-in (front panel) with vref */ 12638 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 12639 /* port-G for CLFE (rear panel) */ 12640 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 12641 /* port-H for side (rear panel) */ 12642 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 12643 /* CD-in */ 12644 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 12645 /* route front mic to ADC1*/ 12646 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 12647 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12648 /* Unmute DAC0~3 & spdif out*/ 12649 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 12650 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 12651 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 12652 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 12653 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 12654 12655 /* Unmute Mixer 14 (mic) 1c (Line in)*/ 12656 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12657 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12658 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12659 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12660 12661 /* Unmute Stereo Mixer 15 */ 12662 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12663 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12664 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 12665 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */ 12666 12667 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12668 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12669 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12670 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12671 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12672 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12673 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12674 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12675 /* hp used DAC 3 (Front) */ 12676 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 12677 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 12678 { } 12679}; 12680 12681static struct hda_verb alc861_asus_init_verbs[] = { 12682 /* 12683 * Unmute ADC0 and set the default input to mic-in 12684 */ 12685 /* port-A for surround (rear panel) 12686 * according to codec#0 this is the HP jack 12687 */ 12688 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */ 12689 /* route front PCM to HP */ 12690 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 }, 12691 /* port-B for mic-in (rear panel) with vref */ 12692 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 12693 /* port-C for line-in (rear panel) */ 12694 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 12695 /* port-D for Front */ 12696 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 12697 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 }, 12698 /* port-E for HP out (front panel) */ 12699 /* this has to be set to VREF80 */ 12700 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 12701 /* route front PCM to HP */ 12702 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, 12703 /* port-F for mic-in (front panel) with vref */ 12704 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 12705 /* port-G for CLFE (rear panel) */ 12706 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 12707 /* port-H for side (rear panel) */ 12708 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 12709 /* CD-in */ 12710 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 12711 /* route front mic to ADC1*/ 12712 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 12713 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12714 /* Unmute DAC0~3 & spdif out*/ 12715 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 12716 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 12717 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 12718 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 12719 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 12720 /* Unmute Mixer 14 (mic) 1c (Line in)*/ 12721 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12722 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12723 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12724 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12725 12726 /* Unmute Stereo Mixer 15 */ 12727 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12728 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12729 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 12730 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */ 12731 12732 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12733 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12734 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12735 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12736 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12737 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12738 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12739 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12740 /* hp used DAC 3 (Front) */ 12741 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 12742 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 12743 { } 12744}; 12745 12746/* additional init verbs for ASUS laptops */ 12747static struct hda_verb alc861_asus_laptop_init_verbs[] = { 12748 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */ 12749 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */ 12750 { } 12751}; 12752 12753/* 12754 * generic initialization of ADC, input mixers and output mixers 12755 */ 12756static struct hda_verb alc861_auto_init_verbs[] = { 12757 /* 12758 * Unmute ADC0 and set the default input to mic-in 12759 */ 12760 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */ 12761 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12762 12763 /* Unmute DAC0~3 & spdif out*/ 12764 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 12765 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 12766 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 12767 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 12768 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 12769 12770 /* Unmute Mixer 14 (mic) 1c (Line in)*/ 12771 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12772 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12773 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12774 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12775 12776 /* Unmute Stereo Mixer 15 */ 12777 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12778 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12779 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 12780 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, 12781 12782 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12783 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12784 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12785 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12786 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12787 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12788 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12789 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12790 12791 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 12792 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 12793 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 12794 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 12795 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 12796 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 12797 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 12798 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 12799 12800 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */ 12801 12802 { } 12803}; 12804 12805static struct hda_verb alc861_toshiba_init_verbs[] = { 12806 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 12807 12808 { } 12809}; 12810 12811/* toggle speaker-output according to the hp-jack state */ 12812static void alc861_toshiba_automute(struct hda_codec *codec) 12813{ 12814 unsigned int present; 12815 12816 present = snd_hda_codec_read(codec, 0x0f, 0, 12817 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 12818 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0, 12819 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 12820 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3, 12821 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE); 12822} 12823 12824static void alc861_toshiba_unsol_event(struct hda_codec *codec, 12825 unsigned int res) 12826{ 12827 if ((res >> 26) == ALC880_HP_EVENT) 12828 alc861_toshiba_automute(codec); 12829} 12830 12831/* pcm configuration: identiacal with ALC880 */ 12832#define alc861_pcm_analog_playback alc880_pcm_analog_playback 12833#define alc861_pcm_analog_capture alc880_pcm_analog_capture 12834#define alc861_pcm_digital_playback alc880_pcm_digital_playback 12835#define alc861_pcm_digital_capture alc880_pcm_digital_capture 12836 12837 12838#define ALC861_DIGOUT_NID 0x07 12839 12840static struct hda_channel_mode alc861_8ch_modes[1] = { 12841 { 8, NULL } 12842}; 12843 12844static hda_nid_t alc861_dac_nids[4] = { 12845 /* front, surround, clfe, side */ 12846 0x03, 0x06, 0x05, 0x04 12847}; 12848 12849static hda_nid_t alc660_dac_nids[3] = { 12850 /* front, clfe, surround */ 12851 0x03, 0x05, 0x06 12852}; 12853 12854static hda_nid_t alc861_adc_nids[1] = { 12855 /* ADC0-2 */ 12856 0x08, 12857}; 12858 12859static struct hda_input_mux alc861_capture_source = { 12860 .num_items = 5, 12861 .items = { 12862 { "Mic", 0x0 }, 12863 { "Front Mic", 0x3 }, 12864 { "Line", 0x1 }, 12865 { "CD", 0x4 }, 12866 { "Mixer", 0x5 }, 12867 }, 12868}; 12869 12870/* fill in the dac_nids table from the parsed pin configuration */ 12871static int alc861_auto_fill_dac_nids(struct alc_spec *spec, 12872 const struct auto_pin_cfg *cfg) 12873{ 12874 int i; 12875 hda_nid_t nid; 12876 12877 spec->multiout.dac_nids = spec->private_dac_nids; 12878 for (i = 0; i < cfg->line_outs; i++) { 12879 nid = cfg->line_out_pins[i]; 12880 if (nid) { 12881 if (i >= ARRAY_SIZE(alc861_dac_nids)) 12882 continue; 12883 spec->multiout.dac_nids[i] = alc861_dac_nids[i]; 12884 } 12885 } 12886 spec->multiout.num_dacs = cfg->line_outs; 12887 return 0; 12888} 12889 12890/* add playback controls from the parsed DAC table */ 12891static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec, 12892 const struct auto_pin_cfg *cfg) 12893{ 12894 char name[32]; 12895 static const char *chname[4] = { 12896 "Front", "Surround", NULL /*CLFE*/, "Side" 12897 }; 12898 hda_nid_t nid; 12899 int i, idx, err; 12900 12901 for (i = 0; i < cfg->line_outs; i++) { 12902 nid = spec->multiout.dac_nids[i]; 12903 if (!nid) 12904 continue; 12905 if (nid == 0x05) { 12906 /* Center/LFE */ 12907 err = add_control(spec, ALC_CTL_BIND_MUTE, 12908 "Center Playback Switch", 12909 HDA_COMPOSE_AMP_VAL(nid, 1, 0, 12910 HDA_OUTPUT)); 12911 if (err < 0) 12912 return err; 12913 err = add_control(spec, ALC_CTL_BIND_MUTE, 12914 "LFE Playback Switch", 12915 HDA_COMPOSE_AMP_VAL(nid, 2, 0, 12916 HDA_OUTPUT)); 12917 if (err < 0) 12918 return err; 12919 } else { 12920 for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1; 12921 idx++) 12922 if (nid == alc861_dac_nids[idx]) 12923 break; 12924 sprintf(name, "%s Playback Switch", chname[idx]); 12925 err = add_control(spec, ALC_CTL_BIND_MUTE, name, 12926 HDA_COMPOSE_AMP_VAL(nid, 3, 0, 12927 HDA_OUTPUT)); 12928 if (err < 0) 12929 return err; 12930 } 12931 } 12932 return 0; 12933} 12934 12935static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin) 12936{ 12937 int err; 12938 hda_nid_t nid; 12939 12940 if (!pin) 12941 return 0; 12942 12943 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) { 12944 nid = 0x03; 12945 err = add_control(spec, ALC_CTL_WIDGET_MUTE, 12946 "Headphone Playback Switch", 12947 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); 12948 if (err < 0) 12949 return err; 12950 spec->multiout.hp_nid = nid; 12951 } 12952 return 0; 12953} 12954 12955/* create playback/capture controls for input pins */ 12956static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec, 12957 const struct auto_pin_cfg *cfg) 12958{ 12959 struct hda_input_mux *imux = &spec->private_imux; 12960 int i, err, idx, idx1; 12961 12962 for (i = 0; i < AUTO_PIN_LAST; i++) { 12963 switch (cfg->input_pins[i]) { 12964 case 0x0c: 12965 idx1 = 1; 12966 idx = 2; /* Line In */ 12967 break; 12968 case 0x0f: 12969 idx1 = 2; 12970 idx = 2; /* Line In */ 12971 break; 12972 case 0x0d: 12973 idx1 = 0; 12974 idx = 1; /* Mic In */ 12975 break; 12976 case 0x10: 12977 idx1 = 3; 12978 idx = 1; /* Mic In */ 12979 break; 12980 case 0x11: 12981 idx1 = 4; 12982 idx = 0; /* CD */ 12983 break; 12984 default: 12985 continue; 12986 } 12987 12988 err = new_analog_input(spec, cfg->input_pins[i], 12989 auto_pin_cfg_labels[i], idx, 0x15); 12990 if (err < 0) 12991 return err; 12992 12993 imux->items[imux->num_items].label = auto_pin_cfg_labels[i]; 12994 imux->items[imux->num_items].index = idx1; 12995 imux->num_items++; 12996 } 12997 return 0; 12998} 12999 13000static void alc861_auto_set_output_and_unmute(struct hda_codec *codec, 13001 hda_nid_t nid, 13002 int pin_type, int dac_idx) 13003{ 13004 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 13005 pin_type); 13006 snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE, 13007 AMP_OUT_UNMUTE); 13008} 13009 13010static void alc861_auto_init_multi_out(struct hda_codec *codec) 13011{ 13012 struct alc_spec *spec = codec->spec; 13013 int i; 13014 13015 alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b); 13016 for (i = 0; i < spec->autocfg.line_outs; i++) { 13017 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 13018 int pin_type = get_pin_type(spec->autocfg.line_out_type); 13019 if (nid) 13020 alc861_auto_set_output_and_unmute(codec, nid, pin_type, 13021 spec->multiout.dac_nids[i]); 13022 } 13023} 13024 13025static void alc861_auto_init_hp_out(struct hda_codec *codec) 13026{ 13027 struct alc_spec *spec = codec->spec; 13028 hda_nid_t pin; 13029 13030 pin = spec->autocfg.hp_pins[0]; 13031 if (pin) /* connect to front */ 13032 alc861_auto_set_output_and_unmute(codec, pin, PIN_HP, 13033 spec->multiout.dac_nids[0]); 13034 pin = spec->autocfg.speaker_pins[0]; 13035 if (pin) 13036 alc861_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0); 13037} 13038 13039static void alc861_auto_init_analog_input(struct hda_codec *codec) 13040{ 13041 struct alc_spec *spec = codec->spec; 13042 int i; 13043 13044 for (i = 0; i < AUTO_PIN_LAST; i++) { 13045 hda_nid_t nid = spec->autocfg.input_pins[i]; 13046 if (nid >= 0x0c && nid <= 0x11) { 13047 snd_hda_codec_write(codec, nid, 0, 13048 AC_VERB_SET_PIN_WIDGET_CONTROL, 13049 i <= AUTO_PIN_FRONT_MIC ? 13050 PIN_VREF80 : PIN_IN); 13051 } 13052 } 13053} 13054 13055/* parse the BIOS configuration and set up the alc_spec */ 13056/* return 1 if successful, 0 if the proper config is not found, 13057 * or a negative error code 13058 */ 13059static int alc861_parse_auto_config(struct hda_codec *codec) 13060{ 13061 struct alc_spec *spec = codec->spec; 13062 int err; 13063 static hda_nid_t alc861_ignore[] = { 0x1d, 0 }; 13064 13065 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 13066 alc861_ignore); 13067 if (err < 0) 13068 return err; 13069 if (!spec->autocfg.line_outs) 13070 return 0; /* can't find valid BIOS pin config */ 13071 13072 err = alc861_auto_fill_dac_nids(spec, &spec->autocfg); 13073 if (err < 0) 13074 return err; 13075 err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg); 13076 if (err < 0) 13077 return err; 13078 err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]); 13079 if (err < 0) 13080 return err; 13081 err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg); 13082 if (err < 0) 13083 return err; 13084 13085 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 13086 13087 if (spec->autocfg.dig_out_pin) 13088 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID; 13089 13090 if (spec->kctls.list) 13091 add_mixer(spec, spec->kctls.list); 13092 13093 add_verb(spec, alc861_auto_init_verbs); 13094 13095 spec->num_mux_defs = 1; 13096 spec->input_mux = &spec->private_imux; 13097 13098 spec->adc_nids = alc861_adc_nids; 13099 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids); 13100 set_capture_mixer(spec); 13101 13102 store_pin_configs(codec); 13103 return 1; 13104} 13105 13106/* additional initialization for auto-configuration model */ 13107static void alc861_auto_init(struct hda_codec *codec) 13108{ 13109 struct alc_spec *spec = codec->spec; 13110 alc861_auto_init_multi_out(codec); 13111 alc861_auto_init_hp_out(codec); 13112 alc861_auto_init_analog_input(codec); 13113 if (spec->unsol_event) 13114 alc_inithook(codec); 13115} 13116 13117#ifdef CONFIG_SND_HDA_POWER_SAVE 13118static struct hda_amp_list alc861_loopbacks[] = { 13119 { 0x15, HDA_INPUT, 0 }, 13120 { 0x15, HDA_INPUT, 1 }, 13121 { 0x15, HDA_INPUT, 2 }, 13122 { 0x15, HDA_INPUT, 3 }, 13123 { } /* end */ 13124}; 13125#endif 13126 13127 13128/* 13129 * configuration and preset 13130 */ 13131static const char *alc861_models[ALC861_MODEL_LAST] = { 13132 [ALC861_3ST] = "3stack", 13133 [ALC660_3ST] = "3stack-660", 13134 [ALC861_3ST_DIG] = "3stack-dig", 13135 [ALC861_6ST_DIG] = "6stack-dig", 13136 [ALC861_UNIWILL_M31] = "uniwill-m31", 13137 [ALC861_TOSHIBA] = "toshiba", 13138 [ALC861_ASUS] = "asus", 13139 [ALC861_ASUS_LAPTOP] = "asus-laptop", 13140 [ALC861_AUTO] = "auto", 13141}; 13142 13143static struct snd_pci_quirk alc861_cfg_tbl[] = { 13144 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST), 13145 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP), 13146 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP), 13147 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS), 13148 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP), 13149 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG), 13150 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA), 13151 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!) 13152 * Any other models that need this preset? 13153 */ 13154 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */ 13155 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST), 13156 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST), 13157 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31), 13158 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31), 13159 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP), 13160 /* FIXME: the below seems conflict */ 13161 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */ 13162 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST), 13163 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST), 13164 {} 13165}; 13166 13167static struct alc_config_preset alc861_presets[] = { 13168 [ALC861_3ST] = { 13169 .mixers = { alc861_3ST_mixer }, 13170 .init_verbs = { alc861_threestack_init_verbs }, 13171 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 13172 .dac_nids = alc861_dac_nids, 13173 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes), 13174 .channel_mode = alc861_threestack_modes, 13175 .need_dac_fix = 1, 13176 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 13177 .adc_nids = alc861_adc_nids, 13178 .input_mux = &alc861_capture_source, 13179 }, 13180 [ALC861_3ST_DIG] = { 13181 .mixers = { alc861_base_mixer }, 13182 .init_verbs = { alc861_threestack_init_verbs }, 13183 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 13184 .dac_nids = alc861_dac_nids, 13185 .dig_out_nid = ALC861_DIGOUT_NID, 13186 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes), 13187 .channel_mode = alc861_threestack_modes, 13188 .need_dac_fix = 1, 13189 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 13190 .adc_nids = alc861_adc_nids, 13191 .input_mux = &alc861_capture_source, 13192 }, 13193 [ALC861_6ST_DIG] = { 13194 .mixers = { alc861_base_mixer }, 13195 .init_verbs = { alc861_base_init_verbs }, 13196 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 13197 .dac_nids = alc861_dac_nids, 13198 .dig_out_nid = ALC861_DIGOUT_NID, 13199 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes), 13200 .channel_mode = alc861_8ch_modes, 13201 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 13202 .adc_nids = alc861_adc_nids, 13203 .input_mux = &alc861_capture_source, 13204 }, 13205 [ALC660_3ST] = { 13206 .mixers = { alc861_3ST_mixer }, 13207 .init_verbs = { alc861_threestack_init_verbs }, 13208 .num_dacs = ARRAY_SIZE(alc660_dac_nids), 13209 .dac_nids = alc660_dac_nids, 13210 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes), 13211 .channel_mode = alc861_threestack_modes, 13212 .need_dac_fix = 1, 13213 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 13214 .adc_nids = alc861_adc_nids, 13215 .input_mux = &alc861_capture_source, 13216 }, 13217 [ALC861_UNIWILL_M31] = { 13218 .mixers = { alc861_uniwill_m31_mixer }, 13219 .init_verbs = { alc861_uniwill_m31_init_verbs }, 13220 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 13221 .dac_nids = alc861_dac_nids, 13222 .dig_out_nid = ALC861_DIGOUT_NID, 13223 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes), 13224 .channel_mode = alc861_uniwill_m31_modes, 13225 .need_dac_fix = 1, 13226 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 13227 .adc_nids = alc861_adc_nids, 13228 .input_mux = &alc861_capture_source, 13229 }, 13230 [ALC861_TOSHIBA] = { 13231 .mixers = { alc861_toshiba_mixer }, 13232 .init_verbs = { alc861_base_init_verbs, 13233 alc861_toshiba_init_verbs }, 13234 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 13235 .dac_nids = alc861_dac_nids, 13236 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 13237 .channel_mode = alc883_3ST_2ch_modes, 13238 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 13239 .adc_nids = alc861_adc_nids, 13240 .input_mux = &alc861_capture_source, 13241 .unsol_event = alc861_toshiba_unsol_event, 13242 .init_hook = alc861_toshiba_automute, 13243 }, 13244 [ALC861_ASUS] = { 13245 .mixers = { alc861_asus_mixer }, 13246 .init_verbs = { alc861_asus_init_verbs }, 13247 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 13248 .dac_nids = alc861_dac_nids, 13249 .dig_out_nid = ALC861_DIGOUT_NID, 13250 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes), 13251 .channel_mode = alc861_asus_modes, 13252 .need_dac_fix = 1, 13253 .hp_nid = 0x06, 13254 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 13255 .adc_nids = alc861_adc_nids, 13256 .input_mux = &alc861_capture_source, 13257 }, 13258 [ALC861_ASUS_LAPTOP] = { 13259 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer }, 13260 .init_verbs = { alc861_asus_init_verbs, 13261 alc861_asus_laptop_init_verbs }, 13262 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 13263 .dac_nids = alc861_dac_nids, 13264 .dig_out_nid = ALC861_DIGOUT_NID, 13265 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 13266 .channel_mode = alc883_3ST_2ch_modes, 13267 .need_dac_fix = 1, 13268 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 13269 .adc_nids = alc861_adc_nids, 13270 .input_mux = &alc861_capture_source, 13271 }, 13272}; 13273 13274 13275static int patch_alc861(struct hda_codec *codec) 13276{ 13277 struct alc_spec *spec; 13278 int board_config; 13279 int err; 13280 13281 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 13282 if (spec == NULL) 13283 return -ENOMEM; 13284 13285 codec->spec = spec; 13286 13287 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST, 13288 alc861_models, 13289 alc861_cfg_tbl); 13290 13291 if (board_config < 0) { 13292 printk(KERN_INFO "hda_codec: Unknown model for ALC861, " 13293 "trying auto-probe from BIOS...\n"); 13294 board_config = ALC861_AUTO; 13295 } 13296 13297 if (board_config == ALC861_AUTO) { 13298 /* automatic parse from the BIOS config */ 13299 err = alc861_parse_auto_config(codec); 13300 if (err < 0) { 13301 alc_free(codec); 13302 return err; 13303 } else if (!err) { 13304 printk(KERN_INFO 13305 "hda_codec: Cannot set up configuration " 13306 "from BIOS. Using base mode...\n"); 13307 board_config = ALC861_3ST_DIG; 13308 } 13309 } 13310 13311 if (board_config != ALC861_AUTO) 13312 setup_preset(spec, &alc861_presets[board_config]); 13313 13314 spec->stream_name_analog = "ALC861 Analog"; 13315 spec->stream_analog_playback = &alc861_pcm_analog_playback; 13316 spec->stream_analog_capture = &alc861_pcm_analog_capture; 13317 13318 spec->stream_name_digital = "ALC861 Digital"; 13319 spec->stream_digital_playback = &alc861_pcm_digital_playback; 13320 spec->stream_digital_capture = &alc861_pcm_digital_capture; 13321 13322 spec->vmaster_nid = 0x03; 13323 13324 codec->patch_ops = alc_patch_ops; 13325 if (board_config == ALC861_AUTO) 13326 spec->init_hook = alc861_auto_init; 13327#ifdef CONFIG_SND_HDA_POWER_SAVE 13328 if (!spec->loopback.amplist) 13329 spec->loopback.amplist = alc861_loopbacks; 13330#endif 13331 13332 return 0; 13333} 13334 13335/* 13336 * ALC861-VD support 13337 * 13338 * Based on ALC882 13339 * 13340 * In addition, an independent DAC 13341 */ 13342#define ALC861VD_DIGOUT_NID 0x06 13343 13344static hda_nid_t alc861vd_dac_nids[4] = { 13345 /* front, surr, clfe, side surr */ 13346 0x02, 0x03, 0x04, 0x05 13347}; 13348 13349/* dac_nids for ALC660vd are in a different order - according to 13350 * Realtek's driver. 13351 * This should probably tesult in a different mixer for 6stack models 13352 * of ALC660vd codecs, but for now there is only 3stack mixer 13353 * - and it is the same as in 861vd. 13354 * adc_nids in ALC660vd are (is) the same as in 861vd 13355 */ 13356static hda_nid_t alc660vd_dac_nids[3] = { 13357 /* front, rear, clfe, rear_surr */ 13358 0x02, 0x04, 0x03 13359}; 13360 13361static hda_nid_t alc861vd_adc_nids[1] = { 13362 /* ADC0 */ 13363 0x09, 13364}; 13365 13366static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 }; 13367 13368/* input MUX */ 13369/* FIXME: should be a matrix-type input source selection */ 13370static struct hda_input_mux alc861vd_capture_source = { 13371 .num_items = 4, 13372 .items = { 13373 { "Mic", 0x0 }, 13374 { "Front Mic", 0x1 }, 13375 { "Line", 0x2 }, 13376 { "CD", 0x4 }, 13377 }, 13378}; 13379 13380static struct hda_input_mux alc861vd_dallas_capture_source = { 13381 .num_items = 2, 13382 .items = { 13383 { "Ext Mic", 0x0 }, 13384 { "Int Mic", 0x1 }, 13385 }, 13386}; 13387 13388static struct hda_input_mux alc861vd_hp_capture_source = { 13389 .num_items = 2, 13390 .items = { 13391 { "Front Mic", 0x0 }, 13392 { "ATAPI Mic", 0x1 }, 13393 }, 13394}; 13395 13396/* 13397 * 2ch mode 13398 */ 13399static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = { 13400 { 2, NULL } 13401}; 13402 13403/* 13404 * 6ch mode 13405 */ 13406static struct hda_verb alc861vd_6stack_ch6_init[] = { 13407 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 13408 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 13409 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 13410 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 13411 { } /* end */ 13412}; 13413 13414/* 13415 * 8ch mode 13416 */ 13417static struct hda_verb alc861vd_6stack_ch8_init[] = { 13418 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 13419 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 13420 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 13421 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 13422 { } /* end */ 13423}; 13424 13425static struct hda_channel_mode alc861vd_6stack_modes[2] = { 13426 { 6, alc861vd_6stack_ch6_init }, 13427 { 8, alc861vd_6stack_ch8_init }, 13428}; 13429 13430static struct snd_kcontrol_new alc861vd_chmode_mixer[] = { 13431 { 13432 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 13433 .name = "Channel Mode", 13434 .info = alc_ch_mode_info, 13435 .get = alc_ch_mode_get, 13436 .put = alc_ch_mode_put, 13437 }, 13438 { } /* end */ 13439}; 13440 13441/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 13442 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b 13443 */ 13444static struct snd_kcontrol_new alc861vd_6st_mixer[] = { 13445 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 13446 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 13447 13448 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT), 13449 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 13450 13451 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, 13452 HDA_OUTPUT), 13453 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, 13454 HDA_OUTPUT), 13455 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 13456 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 13457 13458 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT), 13459 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 13460 13461 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 13462 13463 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 13464 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 13465 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 13466 13467 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 13468 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 13469 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 13470 13471 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 13472 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 13473 13474 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 13475 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 13476 13477 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 13478 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 13479 13480 { } /* end */ 13481}; 13482 13483static struct snd_kcontrol_new alc861vd_3st_mixer[] = { 13484 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 13485 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 13486 13487 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 13488 13489 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 13490 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 13491 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 13492 13493 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 13494 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 13495 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 13496 13497 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 13498 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 13499 13500 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 13501 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 13502 13503 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 13504 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 13505 13506 { } /* end */ 13507}; 13508 13509static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = { 13510 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 13511 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/ 13512 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 13513 13514 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 13515 13516 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 13517 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 13518 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 13519 13520 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 13521 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 13522 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 13523 13524 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 13525 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 13526 13527 { } /* end */ 13528}; 13529 13530/* Pin assignment: Speaker=0x14, HP = 0x15, 13531 * Ext Mic=0x18, Int Mic = 0x19, CD = 0x1c, PC Beep = 0x1d 13532 */ 13533static struct snd_kcontrol_new alc861vd_dallas_mixer[] = { 13534 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 13535 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT), 13536 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 13537 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT), 13538 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT), 13539 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 13540 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 13541 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 13542 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 13543 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 13544 HDA_CODEC_VOLUME("PC Beep Volume", 0x0b, 0x05, HDA_INPUT), 13545 HDA_CODEC_MUTE("PC Beep Switch", 0x0b, 0x05, HDA_INPUT), 13546 { } /* end */ 13547}; 13548 13549/* Pin assignment: Speaker=0x14, Line-out = 0x15, 13550 * Front Mic=0x18, ATAPI Mic = 0x19, 13551 */ 13552static struct snd_kcontrol_new alc861vd_hp_mixer[] = { 13553 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 13554 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 13555 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 13556 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT), 13557 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 13558 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 13559 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 13560 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 13561 13562 { } /* end */ 13563}; 13564 13565/* 13566 * generic initialization of ADC, input mixers and output mixers 13567 */ 13568static struct hda_verb alc861vd_volume_init_verbs[] = { 13569 /* 13570 * Unmute ADC0 and set the default input to mic-in 13571 */ 13572 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 13573 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13574 13575 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of 13576 * the analog-loopback mixer widget 13577 */ 13578 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 13579 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 13580 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 13581 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 13582 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 13583 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 13584 13585 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */ 13586 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13587 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 13588 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 13589 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, 13590 13591 /* 13592 * Set up output mixers (0x02 - 0x05) 13593 */ 13594 /* set vol=0 to output mixers */ 13595 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 13596 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 13597 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 13598 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 13599 13600 /* set up input amps for analog loopback */ 13601 /* Amp Indices: DAC = 0, mixer = 1 */ 13602 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 13603 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 13604 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 13605 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 13606 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 13607 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 13608 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 13609 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 13610 13611 { } 13612}; 13613 13614/* 13615 * 3-stack pin configuration: 13616 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b 13617 */ 13618static struct hda_verb alc861vd_3stack_init_verbs[] = { 13619 /* 13620 * Set pin mode and muting 13621 */ 13622 /* set front pin widgets 0x14 for output */ 13623 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 13624 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 13625 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 13626 13627 /* Mic (rear) pin: input vref at 80% */ 13628 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 13629 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 13630 /* Front Mic pin: input vref at 80% */ 13631 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 13632 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 13633 /* Line In pin: input */ 13634 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 13635 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 13636 /* Line-2 In: Headphone output (output 0 - 0x0c) */ 13637 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 13638 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 13639 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 13640 /* CD pin widget for input */ 13641 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 13642 13643 { } 13644}; 13645 13646/* 13647 * 6-stack pin configuration: 13648 */ 13649static struct hda_verb alc861vd_6stack_init_verbs[] = { 13650 /* 13651 * Set pin mode and muting 13652 */ 13653 /* set front pin widgets 0x14 for output */ 13654 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 13655 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 13656 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 13657 13658 /* Rear Pin: output 1 (0x0d) */ 13659 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 13660 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 13661 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 13662 /* CLFE Pin: output 2 (0x0e) */ 13663 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 13664 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 13665 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, 13666 /* Side Pin: output 3 (0x0f) */ 13667 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 13668 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 13669 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, 13670 13671 /* Mic (rear) pin: input vref at 80% */ 13672 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 13673 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 13674 /* Front Mic pin: input vref at 80% */ 13675 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 13676 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 13677 /* Line In pin: input */ 13678 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 13679 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 13680 /* Line-2 In: Headphone output (output 0 - 0x0c) */ 13681 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 13682 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 13683 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 13684 /* CD pin widget for input */ 13685 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 13686 13687 { } 13688}; 13689 13690static struct hda_verb alc861vd_eapd_verbs[] = { 13691 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 13692 { } 13693}; 13694 13695static struct hda_verb alc660vd_eapd_verbs[] = { 13696 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 13697 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, 13698 { } 13699}; 13700 13701static struct hda_verb alc861vd_lenovo_unsol_verbs[] = { 13702 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13703 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 13704 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, 13705 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 13706 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 13707 {} 13708}; 13709 13710/* toggle speaker-output according to the hp-jack state */ 13711static void alc861vd_lenovo_hp_automute(struct hda_codec *codec) 13712{ 13713 unsigned int present; 13714 unsigned char bits; 13715 13716 present = snd_hda_codec_read(codec, 0x1b, 0, 13717 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 13718 bits = present ? HDA_AMP_MUTE : 0; 13719 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 13720 HDA_AMP_MUTE, bits); 13721} 13722 13723static void alc861vd_lenovo_mic_automute(struct hda_codec *codec) 13724{ 13725 unsigned int present; 13726 unsigned char bits; 13727 13728 present = snd_hda_codec_read(codec, 0x18, 0, 13729 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 13730 bits = present ? HDA_AMP_MUTE : 0; 13731 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, 13732 HDA_AMP_MUTE, bits); 13733} 13734 13735static void alc861vd_lenovo_automute(struct hda_codec *codec) 13736{ 13737 alc861vd_lenovo_hp_automute(codec); 13738 alc861vd_lenovo_mic_automute(codec); 13739} 13740 13741static void alc861vd_lenovo_unsol_event(struct hda_codec *codec, 13742 unsigned int res) 13743{ 13744 switch (res >> 26) { 13745 case ALC880_HP_EVENT: 13746 alc861vd_lenovo_hp_automute(codec); 13747 break; 13748 case ALC880_MIC_EVENT: 13749 alc861vd_lenovo_mic_automute(codec); 13750 break; 13751 } 13752} 13753 13754static struct hda_verb alc861vd_dallas_verbs[] = { 13755 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 13756 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 13757 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 13758 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 13759 13760 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13761 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 13762 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 13763 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 13764 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 13765 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 13766 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 13767 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 13768 13769 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 13770 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 13771 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 13772 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 13773 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 13774 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 13775 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 13776 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 13777 13778 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, 13779 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 13780 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, 13781 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 13782 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 13783 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 13784 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 13785 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 13786 13787 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13788 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 13789 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 13790 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 13791 13792 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 13793 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 13794 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 13795 13796 { } /* end */ 13797}; 13798 13799/* toggle speaker-output according to the hp-jack state */ 13800static void alc861vd_dallas_automute(struct hda_codec *codec) 13801{ 13802 unsigned int present; 13803 13804 present = snd_hda_codec_read(codec, 0x15, 0, 13805 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 13806 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 13807 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 13808} 13809 13810static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int res) 13811{ 13812 if ((res >> 26) == ALC880_HP_EVENT) 13813 alc861vd_dallas_automute(codec); 13814} 13815 13816#ifdef CONFIG_SND_HDA_POWER_SAVE 13817#define alc861vd_loopbacks alc880_loopbacks 13818#endif 13819 13820/* pcm configuration: identiacal with ALC880 */ 13821#define alc861vd_pcm_analog_playback alc880_pcm_analog_playback 13822#define alc861vd_pcm_analog_capture alc880_pcm_analog_capture 13823#define alc861vd_pcm_digital_playback alc880_pcm_digital_playback 13824#define alc861vd_pcm_digital_capture alc880_pcm_digital_capture 13825 13826/* 13827 * configuration and preset 13828 */ 13829static const char *alc861vd_models[ALC861VD_MODEL_LAST] = { 13830 [ALC660VD_3ST] = "3stack-660", 13831 [ALC660VD_3ST_DIG] = "3stack-660-digout", 13832 [ALC861VD_3ST] = "3stack", 13833 [ALC861VD_3ST_DIG] = "3stack-digout", 13834 [ALC861VD_6ST_DIG] = "6stack-digout", 13835 [ALC861VD_LENOVO] = "lenovo", 13836 [ALC861VD_DALLAS] = "dallas", 13837 [ALC861VD_HP] = "hp", 13838 [ALC861VD_AUTO] = "auto", 13839}; 13840 13841static struct snd_pci_quirk alc861vd_cfg_tbl[] = { 13842 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST), 13843 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP), 13844 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST), 13845 SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST), 13846 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC861VD_LENOVO), 13847 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG), 13848 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST), 13849 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO), 13850 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/ 13851 SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS), 13852 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO), 13853 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS), 13854 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG), 13855 SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO), 13856 SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO), 13857 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 N200", ALC861VD_LENOVO), 13858 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG), 13859 {} 13860}; 13861 13862static struct alc_config_preset alc861vd_presets[] = { 13863 [ALC660VD_3ST] = { 13864 .mixers = { alc861vd_3st_mixer }, 13865 .init_verbs = { alc861vd_volume_init_verbs, 13866 alc861vd_3stack_init_verbs }, 13867 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids), 13868 .dac_nids = alc660vd_dac_nids, 13869 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 13870 .channel_mode = alc861vd_3stack_2ch_modes, 13871 .input_mux = &alc861vd_capture_source, 13872 }, 13873 [ALC660VD_3ST_DIG] = { 13874 .mixers = { alc861vd_3st_mixer }, 13875 .init_verbs = { alc861vd_volume_init_verbs, 13876 alc861vd_3stack_init_verbs }, 13877 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids), 13878 .dac_nids = alc660vd_dac_nids, 13879 .dig_out_nid = ALC861VD_DIGOUT_NID, 13880 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 13881 .channel_mode = alc861vd_3stack_2ch_modes, 13882 .input_mux = &alc861vd_capture_source, 13883 }, 13884 [ALC861VD_3ST] = { 13885 .mixers = { alc861vd_3st_mixer }, 13886 .init_verbs = { alc861vd_volume_init_verbs, 13887 alc861vd_3stack_init_verbs }, 13888 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids), 13889 .dac_nids = alc861vd_dac_nids, 13890 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 13891 .channel_mode = alc861vd_3stack_2ch_modes, 13892 .input_mux = &alc861vd_capture_source, 13893 }, 13894 [ALC861VD_3ST_DIG] = { 13895 .mixers = { alc861vd_3st_mixer }, 13896 .init_verbs = { alc861vd_volume_init_verbs, 13897 alc861vd_3stack_init_verbs }, 13898 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids), 13899 .dac_nids = alc861vd_dac_nids, 13900 .dig_out_nid = ALC861VD_DIGOUT_NID, 13901 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 13902 .channel_mode = alc861vd_3stack_2ch_modes, 13903 .input_mux = &alc861vd_capture_source, 13904 }, 13905 [ALC861VD_6ST_DIG] = { 13906 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer }, 13907 .init_verbs = { alc861vd_volume_init_verbs, 13908 alc861vd_6stack_init_verbs }, 13909 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids), 13910 .dac_nids = alc861vd_dac_nids, 13911 .dig_out_nid = ALC861VD_DIGOUT_NID, 13912 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes), 13913 .channel_mode = alc861vd_6stack_modes, 13914 .input_mux = &alc861vd_capture_source, 13915 }, 13916 [ALC861VD_LENOVO] = { 13917 .mixers = { alc861vd_lenovo_mixer }, 13918 .init_verbs = { alc861vd_volume_init_verbs, 13919 alc861vd_3stack_init_verbs, 13920 alc861vd_eapd_verbs, 13921 alc861vd_lenovo_unsol_verbs }, 13922 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids), 13923 .dac_nids = alc660vd_dac_nids, 13924 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 13925 .channel_mode = alc861vd_3stack_2ch_modes, 13926 .input_mux = &alc861vd_capture_source, 13927 .unsol_event = alc861vd_lenovo_unsol_event, 13928 .init_hook = alc861vd_lenovo_automute, 13929 }, 13930 [ALC861VD_DALLAS] = { 13931 .mixers = { alc861vd_dallas_mixer }, 13932 .init_verbs = { alc861vd_dallas_verbs }, 13933 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids), 13934 .dac_nids = alc861vd_dac_nids, 13935 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 13936 .channel_mode = alc861vd_3stack_2ch_modes, 13937 .input_mux = &alc861vd_dallas_capture_source, 13938 .unsol_event = alc861vd_dallas_unsol_event, 13939 .init_hook = alc861vd_dallas_automute, 13940 }, 13941 [ALC861VD_HP] = { 13942 .mixers = { alc861vd_hp_mixer }, 13943 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs }, 13944 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids), 13945 .dac_nids = alc861vd_dac_nids, 13946 .dig_out_nid = ALC861VD_DIGOUT_NID, 13947 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 13948 .channel_mode = alc861vd_3stack_2ch_modes, 13949 .input_mux = &alc861vd_hp_capture_source, 13950 .unsol_event = alc861vd_dallas_unsol_event, 13951 .init_hook = alc861vd_dallas_automute, 13952 }, 13953}; 13954 13955/* 13956 * BIOS auto configuration 13957 */ 13958static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec, 13959 hda_nid_t nid, int pin_type, int dac_idx) 13960{ 13961 alc_set_pin_output(codec, nid, pin_type); 13962} 13963 13964static void alc861vd_auto_init_multi_out(struct hda_codec *codec) 13965{ 13966 struct alc_spec *spec = codec->spec; 13967 int i; 13968 13969 alc_subsystem_id(codec, 0x15, 0x1b, 0x14); 13970 for (i = 0; i <= HDA_SIDE; i++) { 13971 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 13972 int pin_type = get_pin_type(spec->autocfg.line_out_type); 13973 if (nid) 13974 alc861vd_auto_set_output_and_unmute(codec, nid, 13975 pin_type, i); 13976 } 13977} 13978 13979 13980static void alc861vd_auto_init_hp_out(struct hda_codec *codec) 13981{ 13982 struct alc_spec *spec = codec->spec; 13983 hda_nid_t pin; 13984 13985 pin = spec->autocfg.hp_pins[0]; 13986 if (pin) /* connect to front and use dac 0 */ 13987 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); 13988 pin = spec->autocfg.speaker_pins[0]; 13989 if (pin) 13990 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0); 13991} 13992 13993#define alc861vd_is_input_pin(nid) alc880_is_input_pin(nid) 13994#define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID 13995 13996static void alc861vd_auto_init_analog_input(struct hda_codec *codec) 13997{ 13998 struct alc_spec *spec = codec->spec; 13999 int i; 14000 14001 for (i = 0; i < AUTO_PIN_LAST; i++) { 14002 hda_nid_t nid = spec->autocfg.input_pins[i]; 14003 if (alc861vd_is_input_pin(nid)) { 14004 snd_hda_codec_write(codec, nid, 0, 14005 AC_VERB_SET_PIN_WIDGET_CONTROL, 14006 i <= AUTO_PIN_FRONT_MIC ? 14007 PIN_VREF80 : PIN_IN); 14008 if (nid != ALC861VD_PIN_CD_NID) 14009 snd_hda_codec_write(codec, nid, 0, 14010 AC_VERB_SET_AMP_GAIN_MUTE, 14011 AMP_OUT_MUTE); 14012 } 14013 } 14014} 14015 14016#define alc861vd_auto_init_input_src alc882_auto_init_input_src 14017 14018#define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02) 14019#define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c) 14020 14021/* add playback controls from the parsed DAC table */ 14022/* Based on ALC880 version. But ALC861VD has separate, 14023 * different NIDs for mute/unmute switch and volume control */ 14024static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec, 14025 const struct auto_pin_cfg *cfg) 14026{ 14027 char name[32]; 14028 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"}; 14029 hda_nid_t nid_v, nid_s; 14030 int i, err; 14031 14032 for (i = 0; i < cfg->line_outs; i++) { 14033 if (!spec->multiout.dac_nids[i]) 14034 continue; 14035 nid_v = alc861vd_idx_to_mixer_vol( 14036 alc880_dac_to_idx( 14037 spec->multiout.dac_nids[i])); 14038 nid_s = alc861vd_idx_to_mixer_switch( 14039 alc880_dac_to_idx( 14040 spec->multiout.dac_nids[i])); 14041 14042 if (i == 2) { 14043 /* Center/LFE */ 14044 err = add_control(spec, ALC_CTL_WIDGET_VOL, 14045 "Center Playback Volume", 14046 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0, 14047 HDA_OUTPUT)); 14048 if (err < 0) 14049 return err; 14050 err = add_control(spec, ALC_CTL_WIDGET_VOL, 14051 "LFE Playback Volume", 14052 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0, 14053 HDA_OUTPUT)); 14054 if (err < 0) 14055 return err; 14056 err = add_control(spec, ALC_CTL_BIND_MUTE, 14057 "Center Playback Switch", 14058 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2, 14059 HDA_INPUT)); 14060 if (err < 0) 14061 return err; 14062 err = add_control(spec, ALC_CTL_BIND_MUTE, 14063 "LFE Playback Switch", 14064 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2, 14065 HDA_INPUT)); 14066 if (err < 0) 14067 return err; 14068 } else { 14069 sprintf(name, "%s Playback Volume", chname[i]); 14070 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, 14071 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, 14072 HDA_OUTPUT)); 14073 if (err < 0) 14074 return err; 14075 sprintf(name, "%s Playback Switch", chname[i]); 14076 err = add_control(spec, ALC_CTL_BIND_MUTE, name, 14077 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, 14078 HDA_INPUT)); 14079 if (err < 0) 14080 return err; 14081 } 14082 } 14083 return 0; 14084} 14085 14086/* add playback controls for speaker and HP outputs */ 14087/* Based on ALC880 version. But ALC861VD has separate, 14088 * different NIDs for mute/unmute switch and volume control */ 14089static int alc861vd_auto_create_extra_out(struct alc_spec *spec, 14090 hda_nid_t pin, const char *pfx) 14091{ 14092 hda_nid_t nid_v, nid_s; 14093 int err; 14094 char name[32]; 14095 14096 if (!pin) 14097 return 0; 14098 14099 if (alc880_is_fixed_pin(pin)) { 14100 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); 14101 /* specify the DAC as the extra output */ 14102 if (!spec->multiout.hp_nid) 14103 spec->multiout.hp_nid = nid_v; 14104 else 14105 spec->multiout.extra_out_nid[0] = nid_v; 14106 /* control HP volume/switch on the output mixer amp */ 14107 nid_v = alc861vd_idx_to_mixer_vol( 14108 alc880_fixed_pin_idx(pin)); 14109 nid_s = alc861vd_idx_to_mixer_switch( 14110 alc880_fixed_pin_idx(pin)); 14111 14112 sprintf(name, "%s Playback Volume", pfx); 14113 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, 14114 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT)); 14115 if (err < 0) 14116 return err; 14117 sprintf(name, "%s Playback Switch", pfx); 14118 err = add_control(spec, ALC_CTL_BIND_MUTE, name, 14119 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT)); 14120 if (err < 0) 14121 return err; 14122 } else if (alc880_is_multi_pin(pin)) { 14123 /* set manual connection */ 14124 /* we have only a switch on HP-out PIN */ 14125 sprintf(name, "%s Playback Switch", pfx); 14126 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, 14127 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); 14128 if (err < 0) 14129 return err; 14130 } 14131 return 0; 14132} 14133 14134/* parse the BIOS configuration and set up the alc_spec 14135 * return 1 if successful, 0 if the proper config is not found, 14136 * or a negative error code 14137 * Based on ALC880 version - had to change it to override 14138 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */ 14139static int alc861vd_parse_auto_config(struct hda_codec *codec) 14140{ 14141 struct alc_spec *spec = codec->spec; 14142 int err; 14143 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 }; 14144 14145 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 14146 alc861vd_ignore); 14147 if (err < 0) 14148 return err; 14149 if (!spec->autocfg.line_outs) 14150 return 0; /* can't find valid BIOS pin config */ 14151 14152 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); 14153 if (err < 0) 14154 return err; 14155 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg); 14156 if (err < 0) 14157 return err; 14158 err = alc861vd_auto_create_extra_out(spec, 14159 spec->autocfg.speaker_pins[0], 14160 "Speaker"); 14161 if (err < 0) 14162 return err; 14163 err = alc861vd_auto_create_extra_out(spec, 14164 spec->autocfg.hp_pins[0], 14165 "Headphone"); 14166 if (err < 0) 14167 return err; 14168 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg); 14169 if (err < 0) 14170 return err; 14171 14172 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 14173 14174 if (spec->autocfg.dig_out_pin) 14175 spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID; 14176 14177 if (spec->kctls.list) 14178 add_mixer(spec, spec->kctls.list); 14179 14180 add_verb(spec, alc861vd_volume_init_verbs); 14181 14182 spec->num_mux_defs = 1; 14183 spec->input_mux = &spec->private_imux; 14184 14185 err = alc_auto_add_mic_boost(codec); 14186 if (err < 0) 14187 return err; 14188 14189 store_pin_configs(codec); 14190 return 1; 14191} 14192 14193/* additional initialization for auto-configuration model */ 14194static void alc861vd_auto_init(struct hda_codec *codec) 14195{ 14196 struct alc_spec *spec = codec->spec; 14197 alc861vd_auto_init_multi_out(codec); 14198 alc861vd_auto_init_hp_out(codec); 14199 alc861vd_auto_init_analog_input(codec); 14200 alc861vd_auto_init_input_src(codec); 14201 if (spec->unsol_event) 14202 alc_inithook(codec); 14203} 14204 14205static int patch_alc861vd(struct hda_codec *codec) 14206{ 14207 struct alc_spec *spec; 14208 int err, board_config; 14209 14210 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 14211 if (spec == NULL) 14212 return -ENOMEM; 14213 14214 codec->spec = spec; 14215 14216 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST, 14217 alc861vd_models, 14218 alc861vd_cfg_tbl); 14219 14220 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) { 14221 printk(KERN_INFO "hda_codec: Unknown model for ALC660VD/" 14222 "ALC861VD, trying auto-probe from BIOS...\n"); 14223 board_config = ALC861VD_AUTO; 14224 } 14225 14226 if (board_config == ALC861VD_AUTO) { 14227 /* automatic parse from the BIOS config */ 14228 err = alc861vd_parse_auto_config(codec); 14229 if (err < 0) { 14230 alc_free(codec); 14231 return err; 14232 } else if (!err) { 14233 printk(KERN_INFO 14234 "hda_codec: Cannot set up configuration " 14235 "from BIOS. Using base mode...\n"); 14236 board_config = ALC861VD_3ST; 14237 } 14238 } 14239 14240 if (board_config != ALC861VD_AUTO) 14241 setup_preset(spec, &alc861vd_presets[board_config]); 14242 14243 if (codec->vendor_id == 0x10ec0660) { 14244 spec->stream_name_analog = "ALC660-VD Analog"; 14245 spec->stream_name_digital = "ALC660-VD Digital"; 14246 /* always turn on EAPD */ 14247 add_verb(spec, alc660vd_eapd_verbs); 14248 } else { 14249 spec->stream_name_analog = "ALC861VD Analog"; 14250 spec->stream_name_digital = "ALC861VD Digital"; 14251 } 14252 14253 spec->stream_analog_playback = &alc861vd_pcm_analog_playback; 14254 spec->stream_analog_capture = &alc861vd_pcm_analog_capture; 14255 14256 spec->stream_digital_playback = &alc861vd_pcm_digital_playback; 14257 spec->stream_digital_capture = &alc861vd_pcm_digital_capture; 14258 14259 spec->adc_nids = alc861vd_adc_nids; 14260 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids); 14261 spec->capsrc_nids = alc861vd_capsrc_nids; 14262 spec->is_mix_capture = 1; 14263 14264 set_capture_mixer(spec); 14265 14266 spec->vmaster_nid = 0x02; 14267 14268 codec->patch_ops = alc_patch_ops; 14269 14270 if (board_config == ALC861VD_AUTO) 14271 spec->init_hook = alc861vd_auto_init; 14272#ifdef CONFIG_SND_HDA_POWER_SAVE 14273 if (!spec->loopback.amplist) 14274 spec->loopback.amplist = alc861vd_loopbacks; 14275#endif 14276 14277 return 0; 14278} 14279 14280/* 14281 * ALC662 support 14282 * 14283 * ALC662 is almost identical with ALC880 but has cleaner and more flexible 14284 * configuration. Each pin widget can choose any input DACs and a mixer. 14285 * Each ADC is connected from a mixer of all inputs. This makes possible 14286 * 6-channel independent captures. 14287 * 14288 * In addition, an independent DAC for the multi-playback (not used in this 14289 * driver yet). 14290 */ 14291#define ALC662_DIGOUT_NID 0x06 14292#define ALC662_DIGIN_NID 0x0a 14293 14294static hda_nid_t alc662_dac_nids[4] = { 14295 /* front, rear, clfe, rear_surr */ 14296 0x02, 0x03, 0x04 14297}; 14298 14299static hda_nid_t alc662_adc_nids[1] = { 14300 /* ADC1-2 */ 14301 0x09, 14302}; 14303 14304static hda_nid_t alc662_capsrc_nids[1] = { 0x22 }; 14305 14306/* input MUX */ 14307/* FIXME: should be a matrix-type input source selection */ 14308static struct hda_input_mux alc662_capture_source = { 14309 .num_items = 4, 14310 .items = { 14311 { "Mic", 0x0 }, 14312 { "Front Mic", 0x1 }, 14313 { "Line", 0x2 }, 14314 { "CD", 0x4 }, 14315 }, 14316}; 14317 14318static struct hda_input_mux alc662_lenovo_101e_capture_source = { 14319 .num_items = 2, 14320 .items = { 14321 { "Mic", 0x1 }, 14322 { "Line", 0x2 }, 14323 }, 14324}; 14325 14326static struct hda_input_mux alc662_eeepc_capture_source = { 14327 .num_items = 2, 14328 .items = { 14329 { "i-Mic", 0x1 }, 14330 { "e-Mic", 0x0 }, 14331 }, 14332}; 14333 14334static struct hda_input_mux alc663_capture_source = { 14335 .num_items = 3, 14336 .items = { 14337 { "Mic", 0x0 }, 14338 { "Front Mic", 0x1 }, 14339 { "Line", 0x2 }, 14340 }, 14341}; 14342 14343static struct hda_input_mux alc663_m51va_capture_source = { 14344 .num_items = 2, 14345 .items = { 14346 { "Ext-Mic", 0x0 }, 14347 { "D-Mic", 0x9 }, 14348 }, 14349}; 14350 14351/* 14352 * 2ch mode 14353 */ 14354static struct hda_channel_mode alc662_3ST_2ch_modes[1] = { 14355 { 2, NULL } 14356}; 14357 14358/* 14359 * 2ch mode 14360 */ 14361static struct hda_verb alc662_3ST_ch2_init[] = { 14362 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 14363 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 14364 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 14365 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 14366 { } /* end */ 14367}; 14368 14369/* 14370 * 6ch mode 14371 */ 14372static struct hda_verb alc662_3ST_ch6_init[] = { 14373 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 14374 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 14375 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, 14376 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 14377 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 14378 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 14379 { } /* end */ 14380}; 14381 14382static struct hda_channel_mode alc662_3ST_6ch_modes[2] = { 14383 { 2, alc662_3ST_ch2_init }, 14384 { 6, alc662_3ST_ch6_init }, 14385}; 14386 14387/* 14388 * 2ch mode 14389 */ 14390static struct hda_verb alc662_sixstack_ch6_init[] = { 14391 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 14392 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 14393 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 14394 { } /* end */ 14395}; 14396 14397/* 14398 * 6ch mode 14399 */ 14400static struct hda_verb alc662_sixstack_ch8_init[] = { 14401 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 14402 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 14403 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 14404 { } /* end */ 14405}; 14406 14407static struct hda_channel_mode alc662_5stack_modes[2] = { 14408 { 2, alc662_sixstack_ch6_init }, 14409 { 6, alc662_sixstack_ch8_init }, 14410}; 14411 14412/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 14413 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b 14414 */ 14415 14416static struct snd_kcontrol_new alc662_base_mixer[] = { 14417 /* output mixer control */ 14418 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), 14419 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT), 14420 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT), 14421 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT), 14422 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT), 14423 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT), 14424 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT), 14425 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT), 14426 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 14427 14428 /*Input mixer control */ 14429 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT), 14430 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT), 14431 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT), 14432 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT), 14433 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT), 14434 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT), 14435 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT), 14436 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT), 14437 { } /* end */ 14438}; 14439 14440static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = { 14441 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 14442 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT), 14443 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 14444 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 14445 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 14446 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 14447 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 14448 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 14449 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 14450 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 14451 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 14452 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 14453 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 14454 { } /* end */ 14455}; 14456 14457static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = { 14458 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 14459 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT), 14460 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT), 14461 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT), 14462 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT), 14463 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT), 14464 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT), 14465 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT), 14466 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 14467 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 14468 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 14469 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 14470 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 14471 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 14472 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 14473 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 14474 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 14475 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 14476 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 14477 { } /* end */ 14478}; 14479 14480static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = { 14481 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 14482 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT), 14483 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT), 14484 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT), 14485 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 14486 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 14487 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 14488 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 14489 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 14490 { } /* end */ 14491}; 14492 14493static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = { 14494 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 14495 14496 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT), 14497 HDA_CODEC_MUTE("Line-Out Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 14498 14499 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT), 14500 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 14501 HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 14502 14503 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT), 14504 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 14505 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 14506 { } /* end */ 14507}; 14508 14509static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = { 14510 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT), 14511 HDA_CODEC_MUTE("Line-Out Playback Switch", 0x14, 0x0, HDA_OUTPUT), 14512 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT), 14513 HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT), 14514 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT), 14515 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT), 14516 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT), 14517 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT), 14518 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 14519 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT), 14520 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 14521 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 14522 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 14523 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 14524 { } /* end */ 14525}; 14526 14527static struct hda_bind_ctls alc663_asus_bind_master_vol = { 14528 .ops = &snd_hda_bind_vol, 14529 .values = { 14530 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), 14531 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT), 14532 0 14533 }, 14534}; 14535 14536static struct hda_bind_ctls alc663_asus_one_bind_switch = { 14537 .ops = &snd_hda_bind_sw, 14538 .values = { 14539 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 14540 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT), 14541 0 14542 }, 14543}; 14544 14545static struct snd_kcontrol_new alc663_m51va_mixer[] = { 14546 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol), 14547 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch), 14548 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 14549 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 14550 { } /* end */ 14551}; 14552 14553static struct hda_bind_ctls alc663_asus_tree_bind_switch = { 14554 .ops = &snd_hda_bind_sw, 14555 .values = { 14556 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 14557 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT), 14558 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT), 14559 0 14560 }, 14561}; 14562 14563static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = { 14564 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol), 14565 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch), 14566 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 14567 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 14568 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 14569 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 14570 14571 { } /* end */ 14572}; 14573 14574static struct hda_bind_ctls alc663_asus_four_bind_switch = { 14575 .ops = &snd_hda_bind_sw, 14576 .values = { 14577 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 14578 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT), 14579 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT), 14580 0 14581 }, 14582}; 14583 14584static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = { 14585 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol), 14586 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch), 14587 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 14588 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 14589 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 14590 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 14591 { } /* end */ 14592}; 14593 14594static struct snd_kcontrol_new alc662_1bjd_mixer[] = { 14595 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 14596 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 14597 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 14598 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 14599 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 14600 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 14601 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 14602 { } /* end */ 14603}; 14604 14605static struct hda_bind_ctls alc663_asus_two_bind_master_vol = { 14606 .ops = &snd_hda_bind_vol, 14607 .values = { 14608 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), 14609 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT), 14610 0 14611 }, 14612}; 14613 14614static struct hda_bind_ctls alc663_asus_two_bind_switch = { 14615 .ops = &snd_hda_bind_sw, 14616 .values = { 14617 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 14618 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT), 14619 0 14620 }, 14621}; 14622 14623static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = { 14624 HDA_BIND_VOL("Master Playback Volume", 14625 &alc663_asus_two_bind_master_vol), 14626 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch), 14627 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 14628 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT), 14629 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 14630 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 14631 { } /* end */ 14632}; 14633 14634static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = { 14635 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol), 14636 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch), 14637 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 14638 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 14639 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 14640 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 14641 { } /* end */ 14642}; 14643 14644static struct snd_kcontrol_new alc663_g71v_mixer[] = { 14645 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 14646 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 14647 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT), 14648 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT), 14649 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT), 14650 14651 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 14652 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 14653 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 14654 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 14655 { } /* end */ 14656}; 14657 14658static struct snd_kcontrol_new alc663_g50v_mixer[] = { 14659 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 14660 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 14661 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT), 14662 14663 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 14664 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 14665 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 14666 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 14667 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 14668 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 14669 { } /* end */ 14670}; 14671 14672static struct snd_kcontrol_new alc662_chmode_mixer[] = { 14673 { 14674 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 14675 .name = "Channel Mode", 14676 .info = alc_ch_mode_info, 14677 .get = alc_ch_mode_get, 14678 .put = alc_ch_mode_put, 14679 }, 14680 { } /* end */ 14681}; 14682 14683static struct hda_verb alc662_init_verbs[] = { 14684 /* ADC: mute amp left and right */ 14685 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 14686 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 14687 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 14688 14689 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 14690 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 14691 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 14692 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 14693 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 14694 14695 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14696 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 14697 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14698 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 14699 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14700 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 14701 14702 /* Front Pin: output 0 (0x0c) */ 14703 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 14704 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 14705 14706 /* Rear Pin: output 1 (0x0d) */ 14707 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 14708 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 14709 14710 /* CLFE Pin: output 2 (0x0e) */ 14711 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 14712 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 14713 14714 /* Mic (rear) pin: input vref at 80% */ 14715 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 14716 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 14717 /* Front Mic pin: input vref at 80% */ 14718 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 14719 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 14720 /* Line In pin: input */ 14721 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14722 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 14723 /* Line-2 In: Headphone output (output 0 - 0x0c) */ 14724 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 14725 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 14726 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 14727 /* CD pin widget for input */ 14728 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14729 14730 /* FIXME: use matrix-type input source selection */ 14731 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 14732 /* Input mixer */ 14733 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14734 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 14735 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 14736 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, 14737 14738 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14739 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 14740 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 14741 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, 14742 14743 /* always trun on EAPD */ 14744 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 14745 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, 14746 14747 { } 14748}; 14749 14750static struct hda_verb alc662_sue_init_verbs[] = { 14751 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT}, 14752 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT}, 14753 {} 14754}; 14755 14756static struct hda_verb alc662_eeepc_sue_init_verbs[] = { 14757 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 14758 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 14759 {} 14760}; 14761 14762/* Set Unsolicited Event*/ 14763static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = { 14764 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 14765 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 14766 {} 14767}; 14768 14769/* 14770 * generic initialization of ADC, input mixers and output mixers 14771 */ 14772static struct hda_verb alc662_auto_init_verbs[] = { 14773 /* 14774 * Unmute ADC and set the default input to mic-in 14775 */ 14776 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 14777 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14778 14779 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 14780 * mixer widget 14781 * Note: PASD motherboards uses the Line In 2 as the input for front 14782 * panel mic (mic 2) 14783 */ 14784 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 14785 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 14786 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 14787 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 14788 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 14789 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 14790 14791 /* 14792 * Set up output mixers (0x0c - 0x0f) 14793 */ 14794 /* set vol=0 to output mixers */ 14795 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 14796 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 14797 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 14798 14799 /* set up input amps for analog loopback */ 14800 /* Amp Indices: DAC = 0, mixer = 1 */ 14801 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14802 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 14803 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14804 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 14805 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14806 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 14807 14808 14809 /* FIXME: use matrix-type input source selection */ 14810 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 14811 /* Input mixer */ 14812 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14813 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14814 { } 14815}; 14816 14817/* additional verbs for ALC663 */ 14818static struct hda_verb alc663_auto_init_verbs[] = { 14819 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14820 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 14821 { } 14822}; 14823 14824static struct hda_verb alc663_m51va_init_verbs[] = { 14825 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14826 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14827 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 14828 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 14829 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ 14830 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 14831 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)}, 14832 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 14833 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 14834 {} 14835}; 14836 14837static struct hda_verb alc663_21jd_amic_init_verbs[] = { 14838 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 14839 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 14840 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ 14841 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 14842 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 14843 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 14844 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 14845 {} 14846}; 14847 14848static struct hda_verb alc662_1bjd_amic_init_verbs[] = { 14849 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14850 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 14851 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 14852 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */ 14853 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 14854 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 14855 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 14856 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 14857 {} 14858}; 14859 14860static struct hda_verb alc663_15jd_amic_init_verbs[] = { 14861 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 14862 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 14863 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ 14864 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 14865 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 14866 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 14867 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 14868 {} 14869}; 14870 14871static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = { 14872 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14873 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 14874 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 14875 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */ 14876 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 14877 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 14878 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */ 14879 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 14880 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 14881 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 14882 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 14883 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 14884 {} 14885}; 14886 14887static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = { 14888 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14889 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 14890 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 14891 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ 14892 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 14893 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 14894 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ 14895 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 14896 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 14897 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 14898 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 14899 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 14900 {} 14901}; 14902 14903static struct hda_verb alc663_g71v_init_verbs[] = { 14904 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 14905 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */ 14906 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */ 14907 14908 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 14909 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 14910 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */ 14911 14912 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT}, 14913 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT}, 14914 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT}, 14915 {} 14916}; 14917 14918static struct hda_verb alc663_g50v_init_verbs[] = { 14919 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 14920 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 14921 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */ 14922 14923 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 14924 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 14925 {} 14926}; 14927 14928static struct hda_verb alc662_ecs_init_verbs[] = { 14929 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f}, 14930 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 14931 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 14932 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 14933 {} 14934}; 14935 14936static struct snd_kcontrol_new alc662_auto_capture_mixer[] = { 14937 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), 14938 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), 14939 { } /* end */ 14940}; 14941 14942static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec) 14943{ 14944 unsigned int present; 14945 unsigned char bits; 14946 14947 present = snd_hda_codec_read(codec, 0x14, 0, 14948 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 14949 bits = present ? HDA_AMP_MUTE : 0; 14950 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 14951 HDA_AMP_MUTE, bits); 14952} 14953 14954static void alc662_lenovo_101e_all_automute(struct hda_codec *codec) 14955{ 14956 unsigned int present; 14957 unsigned char bits; 14958 14959 present = snd_hda_codec_read(codec, 0x1b, 0, 14960 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 14961 bits = present ? HDA_AMP_MUTE : 0; 14962 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 14963 HDA_AMP_MUTE, bits); 14964 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 14965 HDA_AMP_MUTE, bits); 14966} 14967 14968static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec, 14969 unsigned int res) 14970{ 14971 if ((res >> 26) == ALC880_HP_EVENT) 14972 alc662_lenovo_101e_all_automute(codec); 14973 if ((res >> 26) == ALC880_FRONT_EVENT) 14974 alc662_lenovo_101e_ispeaker_automute(codec); 14975} 14976 14977static void alc662_eeepc_mic_automute(struct hda_codec *codec) 14978{ 14979 unsigned int present; 14980 14981 present = snd_hda_codec_read(codec, 0x18, 0, 14982 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 14983 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE, 14984 0x7000 | (0x00 << 8) | (present ? 0 : 0x80)); 14985 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE, 14986 0x7000 | (0x00 << 8) | (present ? 0 : 0x80)); 14987 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE, 14988 0x7000 | (0x01 << 8) | (present ? 0x80 : 0)); 14989 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE, 14990 0x7000 | (0x01 << 8) | (present ? 0x80 : 0)); 14991} 14992 14993/* unsolicited event for HP jack sensing */ 14994static void alc662_eeepc_unsol_event(struct hda_codec *codec, 14995 unsigned int res) 14996{ 14997 if ((res >> 26) == ALC880_HP_EVENT) 14998 alc262_hippo1_automute( codec ); 14999 15000 if ((res >> 26) == ALC880_MIC_EVENT) 15001 alc662_eeepc_mic_automute(codec); 15002} 15003 15004static void alc662_eeepc_inithook(struct hda_codec *codec) 15005{ 15006 alc262_hippo1_automute( codec ); 15007 alc662_eeepc_mic_automute(codec); 15008} 15009 15010static void alc662_eeepc_ep20_automute(struct hda_codec *codec) 15011{ 15012 unsigned int mute; 15013 unsigned int present; 15014 15015 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0); 15016 present = snd_hda_codec_read(codec, 0x14, 0, 15017 AC_VERB_GET_PIN_SENSE, 0); 15018 present = (present & 0x80000000) != 0; 15019 if (present) { 15020 /* mute internal speaker */ 15021 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0, 15022 HDA_AMP_MUTE, HDA_AMP_MUTE); 15023 } else { 15024 /* unmute internal speaker if necessary */ 15025 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0); 15026 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0, 15027 HDA_AMP_MUTE, mute); 15028 } 15029} 15030 15031/* unsolicited event for HP jack sensing */ 15032static void alc662_eeepc_ep20_unsol_event(struct hda_codec *codec, 15033 unsigned int res) 15034{ 15035 if ((res >> 26) == ALC880_HP_EVENT) 15036 alc662_eeepc_ep20_automute(codec); 15037} 15038 15039static void alc662_eeepc_ep20_inithook(struct hda_codec *codec) 15040{ 15041 alc662_eeepc_ep20_automute(codec); 15042} 15043 15044static void alc663_m51va_speaker_automute(struct hda_codec *codec) 15045{ 15046 unsigned int present; 15047 unsigned char bits; 15048 15049 present = snd_hda_codec_read(codec, 0x21, 0, 15050 AC_VERB_GET_PIN_SENSE, 0) 15051 & AC_PINSENSE_PRESENCE; 15052 bits = present ? HDA_AMP_MUTE : 0; 15053 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 15054 AMP_IN_MUTE(0), bits); 15055 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 15056 AMP_IN_MUTE(0), bits); 15057} 15058 15059static void alc663_21jd_two_speaker_automute(struct hda_codec *codec) 15060{ 15061 unsigned int present; 15062 unsigned char bits; 15063 15064 present = snd_hda_codec_read(codec, 0x21, 0, 15065 AC_VERB_GET_PIN_SENSE, 0) 15066 & AC_PINSENSE_PRESENCE; 15067 bits = present ? HDA_AMP_MUTE : 0; 15068 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 15069 AMP_IN_MUTE(0), bits); 15070 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 15071 AMP_IN_MUTE(0), bits); 15072 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0, 15073 AMP_IN_MUTE(0), bits); 15074 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1, 15075 AMP_IN_MUTE(0), bits); 15076} 15077 15078static void alc663_15jd_two_speaker_automute(struct hda_codec *codec) 15079{ 15080 unsigned int present; 15081 unsigned char bits; 15082 15083 present = snd_hda_codec_read(codec, 0x15, 0, 15084 AC_VERB_GET_PIN_SENSE, 0) 15085 & AC_PINSENSE_PRESENCE; 15086 bits = present ? HDA_AMP_MUTE : 0; 15087 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 15088 AMP_IN_MUTE(0), bits); 15089 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 15090 AMP_IN_MUTE(0), bits); 15091 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0, 15092 AMP_IN_MUTE(0), bits); 15093 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1, 15094 AMP_IN_MUTE(0), bits); 15095} 15096 15097static void alc662_f5z_speaker_automute(struct hda_codec *codec) 15098{ 15099 unsigned int present; 15100 unsigned char bits; 15101 15102 present = snd_hda_codec_read(codec, 0x1b, 0, 15103 AC_VERB_GET_PIN_SENSE, 0) 15104 & AC_PINSENSE_PRESENCE; 15105 bits = present ? 0 : PIN_OUT; 15106 snd_hda_codec_write(codec, 0x14, 0, 15107 AC_VERB_SET_PIN_WIDGET_CONTROL, bits); 15108} 15109 15110static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec) 15111{ 15112 unsigned int present1, present2; 15113 15114 present1 = snd_hda_codec_read(codec, 0x21, 0, 15115 AC_VERB_GET_PIN_SENSE, 0) 15116 & AC_PINSENSE_PRESENCE; 15117 present2 = snd_hda_codec_read(codec, 0x15, 0, 15118 AC_VERB_GET_PIN_SENSE, 0) 15119 & AC_PINSENSE_PRESENCE; 15120 15121 if (present1 || present2) { 15122 snd_hda_codec_write_cache(codec, 0x14, 0, 15123 AC_VERB_SET_PIN_WIDGET_CONTROL, 0); 15124 } else { 15125 snd_hda_codec_write_cache(codec, 0x14, 0, 15126 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); 15127 } 15128} 15129 15130static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec) 15131{ 15132 unsigned int present1, present2; 15133 15134 present1 = snd_hda_codec_read(codec, 0x1b, 0, 15135 AC_VERB_GET_PIN_SENSE, 0) 15136 & AC_PINSENSE_PRESENCE; 15137 present2 = snd_hda_codec_read(codec, 0x15, 0, 15138 AC_VERB_GET_PIN_SENSE, 0) 15139 & AC_PINSENSE_PRESENCE; 15140 15141 if (present1 || present2) { 15142 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 15143 AMP_IN_MUTE(0), AMP_IN_MUTE(0)); 15144 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 15145 AMP_IN_MUTE(0), AMP_IN_MUTE(0)); 15146 } else { 15147 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 15148 AMP_IN_MUTE(0), 0); 15149 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 15150 AMP_IN_MUTE(0), 0); 15151 } 15152} 15153 15154static void alc663_m51va_mic_automute(struct hda_codec *codec) 15155{ 15156 unsigned int present; 15157 15158 present = snd_hda_codec_read(codec, 0x18, 0, 15159 AC_VERB_GET_PIN_SENSE, 0) 15160 & AC_PINSENSE_PRESENCE; 15161 snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE, 15162 0x7000 | (0x00 << 8) | (present ? 0 : 0x80)); 15163 snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE, 15164 0x7000 | (0x00 << 8) | (present ? 0 : 0x80)); 15165 snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE, 15166 0x7000 | (0x09 << 8) | (present ? 0x80 : 0)); 15167 snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE, 15168 0x7000 | (0x09 << 8) | (present ? 0x80 : 0)); 15169} 15170 15171static void alc663_m51va_unsol_event(struct hda_codec *codec, 15172 unsigned int res) 15173{ 15174 switch (res >> 26) { 15175 case ALC880_HP_EVENT: 15176 alc663_m51va_speaker_automute(codec); 15177 break; 15178 case ALC880_MIC_EVENT: 15179 alc663_m51va_mic_automute(codec); 15180 break; 15181 } 15182} 15183 15184static void alc663_m51va_inithook(struct hda_codec *codec) 15185{ 15186 alc663_m51va_speaker_automute(codec); 15187 alc663_m51va_mic_automute(codec); 15188} 15189 15190/* ***************** Mode1 ******************************/ 15191static void alc663_mode1_unsol_event(struct hda_codec *codec, 15192 unsigned int res) 15193{ 15194 switch (res >> 26) { 15195 case ALC880_HP_EVENT: 15196 alc663_m51va_speaker_automute(codec); 15197 break; 15198 case ALC880_MIC_EVENT: 15199 alc662_eeepc_mic_automute(codec); 15200 break; 15201 } 15202} 15203 15204static void alc663_mode1_inithook(struct hda_codec *codec) 15205{ 15206 alc663_m51va_speaker_automute(codec); 15207 alc662_eeepc_mic_automute(codec); 15208} 15209/* ***************** Mode2 ******************************/ 15210static void alc662_mode2_unsol_event(struct hda_codec *codec, 15211 unsigned int res) 15212{ 15213 switch (res >> 26) { 15214 case ALC880_HP_EVENT: 15215 alc662_f5z_speaker_automute(codec); 15216 break; 15217 case ALC880_MIC_EVENT: 15218 alc662_eeepc_mic_automute(codec); 15219 break; 15220 } 15221} 15222 15223static void alc662_mode2_inithook(struct hda_codec *codec) 15224{ 15225 alc662_f5z_speaker_automute(codec); 15226 alc662_eeepc_mic_automute(codec); 15227} 15228/* ***************** Mode3 ******************************/ 15229static void alc663_mode3_unsol_event(struct hda_codec *codec, 15230 unsigned int res) 15231{ 15232 switch (res >> 26) { 15233 case ALC880_HP_EVENT: 15234 alc663_two_hp_m1_speaker_automute(codec); 15235 break; 15236 case ALC880_MIC_EVENT: 15237 alc662_eeepc_mic_automute(codec); 15238 break; 15239 } 15240} 15241 15242static void alc663_mode3_inithook(struct hda_codec *codec) 15243{ 15244 alc663_two_hp_m1_speaker_automute(codec); 15245 alc662_eeepc_mic_automute(codec); 15246} 15247/* ***************** Mode4 ******************************/ 15248static void alc663_mode4_unsol_event(struct hda_codec *codec, 15249 unsigned int res) 15250{ 15251 switch (res >> 26) { 15252 case ALC880_HP_EVENT: 15253 alc663_21jd_two_speaker_automute(codec); 15254 break; 15255 case ALC880_MIC_EVENT: 15256 alc662_eeepc_mic_automute(codec); 15257 break; 15258 } 15259} 15260 15261static void alc663_mode4_inithook(struct hda_codec *codec) 15262{ 15263 alc663_21jd_two_speaker_automute(codec); 15264 alc662_eeepc_mic_automute(codec); 15265} 15266/* ***************** Mode5 ******************************/ 15267static void alc663_mode5_unsol_event(struct hda_codec *codec, 15268 unsigned int res) 15269{ 15270 switch (res >> 26) { 15271 case ALC880_HP_EVENT: 15272 alc663_15jd_two_speaker_automute(codec); 15273 break; 15274 case ALC880_MIC_EVENT: 15275 alc662_eeepc_mic_automute(codec); 15276 break; 15277 } 15278} 15279 15280static void alc663_mode5_inithook(struct hda_codec *codec) 15281{ 15282 alc663_15jd_two_speaker_automute(codec); 15283 alc662_eeepc_mic_automute(codec); 15284} 15285/* ***************** Mode6 ******************************/ 15286static void alc663_mode6_unsol_event(struct hda_codec *codec, 15287 unsigned int res) 15288{ 15289 switch (res >> 26) { 15290 case ALC880_HP_EVENT: 15291 alc663_two_hp_m2_speaker_automute(codec); 15292 break; 15293 case ALC880_MIC_EVENT: 15294 alc662_eeepc_mic_automute(codec); 15295 break; 15296 } 15297} 15298 15299static void alc663_mode6_inithook(struct hda_codec *codec) 15300{ 15301 alc663_two_hp_m2_speaker_automute(codec); 15302 alc662_eeepc_mic_automute(codec); 15303} 15304 15305static void alc663_g71v_hp_automute(struct hda_codec *codec) 15306{ 15307 unsigned int present; 15308 unsigned char bits; 15309 15310 present = snd_hda_codec_read(codec, 0x21, 0, 15311 AC_VERB_GET_PIN_SENSE, 0) 15312 & AC_PINSENSE_PRESENCE; 15313 bits = present ? HDA_AMP_MUTE : 0; 15314 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 15315 HDA_AMP_MUTE, bits); 15316 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 15317 HDA_AMP_MUTE, bits); 15318} 15319 15320static void alc663_g71v_front_automute(struct hda_codec *codec) 15321{ 15322 unsigned int present; 15323 unsigned char bits; 15324 15325 present = snd_hda_codec_read(codec, 0x15, 0, 15326 AC_VERB_GET_PIN_SENSE, 0) 15327 & AC_PINSENSE_PRESENCE; 15328 bits = present ? HDA_AMP_MUTE : 0; 15329 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 15330 HDA_AMP_MUTE, bits); 15331} 15332 15333static void alc663_g71v_unsol_event(struct hda_codec *codec, 15334 unsigned int res) 15335{ 15336 switch (res >> 26) { 15337 case ALC880_HP_EVENT: 15338 alc663_g71v_hp_automute(codec); 15339 break; 15340 case ALC880_FRONT_EVENT: 15341 alc663_g71v_front_automute(codec); 15342 break; 15343 case ALC880_MIC_EVENT: 15344 alc662_eeepc_mic_automute(codec); 15345 break; 15346 } 15347} 15348 15349static void alc663_g71v_inithook(struct hda_codec *codec) 15350{ 15351 alc663_g71v_front_automute(codec); 15352 alc663_g71v_hp_automute(codec); 15353 alc662_eeepc_mic_automute(codec); 15354} 15355 15356static void alc663_g50v_unsol_event(struct hda_codec *codec, 15357 unsigned int res) 15358{ 15359 switch (res >> 26) { 15360 case ALC880_HP_EVENT: 15361 alc663_m51va_speaker_automute(codec); 15362 break; 15363 case ALC880_MIC_EVENT: 15364 alc662_eeepc_mic_automute(codec); 15365 break; 15366 } 15367} 15368 15369static void alc663_g50v_inithook(struct hda_codec *codec) 15370{ 15371 alc663_m51va_speaker_automute(codec); 15372 alc662_eeepc_mic_automute(codec); 15373} 15374 15375/* bind hp and internal speaker mute (with plug check) */ 15376static int alc662_ecs_master_sw_put(struct snd_kcontrol *kcontrol, 15377 struct snd_ctl_elem_value *ucontrol) 15378{ 15379 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 15380 long *valp = ucontrol->value.integer.value; 15381 int change; 15382 15383 change = snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0, 15384 HDA_AMP_MUTE, 15385 valp[0] ? 0 : HDA_AMP_MUTE); 15386 change |= snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0, 15387 HDA_AMP_MUTE, 15388 valp[1] ? 0 : HDA_AMP_MUTE); 15389 if (change) 15390 alc262_hippo1_automute(codec); 15391 return change; 15392} 15393 15394static struct snd_kcontrol_new alc662_ecs_mixer[] = { 15395 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT), 15396 { 15397 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 15398 .name = "Master Playback Switch", 15399 .info = snd_hda_mixer_amp_switch_info, 15400 .get = snd_hda_mixer_amp_switch_get, 15401 .put = alc662_ecs_master_sw_put, 15402 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT), 15403 }, 15404 15405 HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT), 15406 HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT), 15407 HDA_CODEC_MUTE("e-Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT), 15408 15409 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT), 15410 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 15411 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 15412 { } /* end */ 15413}; 15414 15415#ifdef CONFIG_SND_HDA_POWER_SAVE 15416#define alc662_loopbacks alc880_loopbacks 15417#endif 15418 15419 15420/* pcm configuration: identiacal with ALC880 */ 15421#define alc662_pcm_analog_playback alc880_pcm_analog_playback 15422#define alc662_pcm_analog_capture alc880_pcm_analog_capture 15423#define alc662_pcm_digital_playback alc880_pcm_digital_playback 15424#define alc662_pcm_digital_capture alc880_pcm_digital_capture 15425 15426/* 15427 * configuration and preset 15428 */ 15429static const char *alc662_models[ALC662_MODEL_LAST] = { 15430 [ALC662_3ST_2ch_DIG] = "3stack-dig", 15431 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig", 15432 [ALC662_3ST_6ch] = "3stack-6ch", 15433 [ALC662_5ST_DIG] = "6stack-dig", 15434 [ALC662_LENOVO_101E] = "lenovo-101e", 15435 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701", 15436 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20", 15437 [ALC662_ECS] = "ecs", 15438 [ALC663_ASUS_M51VA] = "m51va", 15439 [ALC663_ASUS_G71V] = "g71v", 15440 [ALC663_ASUS_H13] = "h13", 15441 [ALC663_ASUS_G50V] = "g50v", 15442 [ALC663_ASUS_MODE1] = "asus-mode1", 15443 [ALC662_ASUS_MODE2] = "asus-mode2", 15444 [ALC663_ASUS_MODE3] = "asus-mode3", 15445 [ALC663_ASUS_MODE4] = "asus-mode4", 15446 [ALC663_ASUS_MODE5] = "asus-mode5", 15447 [ALC663_ASUS_MODE6] = "asus-mode6", 15448 [ALC662_AUTO] = "auto", 15449}; 15450 15451static struct snd_pci_quirk alc662_cfg_tbl[] = { 15452 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA), 15453 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V), 15454 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG), 15455 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701), 15456 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20), 15457 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1), 15458 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1), 15459 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1), 15460 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1), 15461 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1), 15462 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1), 15463 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1), 15464 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1), 15465 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1), 15466 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1), 15467 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2), 15468 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2), 15469 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2), 15470 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2), 15471 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2), 15472 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2), 15473 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2), 15474 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2), 15475 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2), 15476 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2), 15477 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2), 15478 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2), 15479 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3), 15480 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3), 15481 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3), 15482 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3), 15483 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3), 15484 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4), 15485 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5), 15486 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6), 15487 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6), 15488 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6), 15489 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K", 15490 ALC662_3ST_6ch_DIG), 15491 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E), 15492 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS), 15493 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS), 15494 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L", 15495 ALC662_3ST_6ch_DIG), 15496 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG), 15497 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0", 15498 ALC662_3ST_6ch_DIG), 15499 SND_PCI_QUIRK(0x1854, 0x2000, "ASUS H13-2000", ALC663_ASUS_H13), 15500 SND_PCI_QUIRK(0x1854, 0x2001, "ASUS H13-2001", ALC663_ASUS_H13), 15501 SND_PCI_QUIRK(0x1854, 0x2002, "ASUS H13-2002", ALC663_ASUS_H13), 15502 {} 15503}; 15504 15505static struct alc_config_preset alc662_presets[] = { 15506 [ALC662_3ST_2ch_DIG] = { 15507 .mixers = { alc662_3ST_2ch_mixer }, 15508 .init_verbs = { alc662_init_verbs }, 15509 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 15510 .dac_nids = alc662_dac_nids, 15511 .dig_out_nid = ALC662_DIGOUT_NID, 15512 .dig_in_nid = ALC662_DIGIN_NID, 15513 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 15514 .channel_mode = alc662_3ST_2ch_modes, 15515 .input_mux = &alc662_capture_source, 15516 }, 15517 [ALC662_3ST_6ch_DIG] = { 15518 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer }, 15519 .init_verbs = { alc662_init_verbs }, 15520 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 15521 .dac_nids = alc662_dac_nids, 15522 .dig_out_nid = ALC662_DIGOUT_NID, 15523 .dig_in_nid = ALC662_DIGIN_NID, 15524 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), 15525 .channel_mode = alc662_3ST_6ch_modes, 15526 .need_dac_fix = 1, 15527 .input_mux = &alc662_capture_source, 15528 }, 15529 [ALC662_3ST_6ch] = { 15530 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer }, 15531 .init_verbs = { alc662_init_verbs }, 15532 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 15533 .dac_nids = alc662_dac_nids, 15534 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), 15535 .channel_mode = alc662_3ST_6ch_modes, 15536 .need_dac_fix = 1, 15537 .input_mux = &alc662_capture_source, 15538 }, 15539 [ALC662_5ST_DIG] = { 15540 .mixers = { alc662_base_mixer, alc662_chmode_mixer }, 15541 .init_verbs = { alc662_init_verbs }, 15542 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 15543 .dac_nids = alc662_dac_nids, 15544 .dig_out_nid = ALC662_DIGOUT_NID, 15545 .dig_in_nid = ALC662_DIGIN_NID, 15546 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes), 15547 .channel_mode = alc662_5stack_modes, 15548 .input_mux = &alc662_capture_source, 15549 }, 15550 [ALC662_LENOVO_101E] = { 15551 .mixers = { alc662_lenovo_101e_mixer }, 15552 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs }, 15553 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 15554 .dac_nids = alc662_dac_nids, 15555 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 15556 .channel_mode = alc662_3ST_2ch_modes, 15557 .input_mux = &alc662_lenovo_101e_capture_source, 15558 .unsol_event = alc662_lenovo_101e_unsol_event, 15559 .init_hook = alc662_lenovo_101e_all_automute, 15560 }, 15561 [ALC662_ASUS_EEEPC_P701] = { 15562 .mixers = { alc662_eeepc_p701_mixer }, 15563 .init_verbs = { alc662_init_verbs, 15564 alc662_eeepc_sue_init_verbs }, 15565 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 15566 .dac_nids = alc662_dac_nids, 15567 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 15568 .channel_mode = alc662_3ST_2ch_modes, 15569 .input_mux = &alc662_eeepc_capture_source, 15570 .unsol_event = alc662_eeepc_unsol_event, 15571 .init_hook = alc662_eeepc_inithook, 15572 }, 15573 [ALC662_ASUS_EEEPC_EP20] = { 15574 .mixers = { alc662_eeepc_ep20_mixer, 15575 alc662_chmode_mixer }, 15576 .init_verbs = { alc662_init_verbs, 15577 alc662_eeepc_ep20_sue_init_verbs }, 15578 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 15579 .dac_nids = alc662_dac_nids, 15580 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), 15581 .channel_mode = alc662_3ST_6ch_modes, 15582 .input_mux = &alc662_lenovo_101e_capture_source, 15583 .unsol_event = alc662_eeepc_ep20_unsol_event, 15584 .init_hook = alc662_eeepc_ep20_inithook, 15585 }, 15586 [ALC662_ECS] = { 15587 .mixers = { alc662_ecs_mixer }, 15588 .init_verbs = { alc662_init_verbs, 15589 alc662_ecs_init_verbs }, 15590 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 15591 .dac_nids = alc662_dac_nids, 15592 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 15593 .channel_mode = alc662_3ST_2ch_modes, 15594 .input_mux = &alc662_eeepc_capture_source, 15595 .unsol_event = alc662_eeepc_unsol_event, 15596 .init_hook = alc662_eeepc_inithook, 15597 }, 15598 [ALC663_ASUS_M51VA] = { 15599 .mixers = { alc663_m51va_mixer }, 15600 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs }, 15601 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 15602 .dac_nids = alc662_dac_nids, 15603 .dig_out_nid = ALC662_DIGOUT_NID, 15604 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 15605 .channel_mode = alc662_3ST_2ch_modes, 15606 .input_mux = &alc663_m51va_capture_source, 15607 .unsol_event = alc663_m51va_unsol_event, 15608 .init_hook = alc663_m51va_inithook, 15609 }, 15610 [ALC663_ASUS_G71V] = { 15611 .mixers = { alc663_g71v_mixer }, 15612 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs }, 15613 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 15614 .dac_nids = alc662_dac_nids, 15615 .dig_out_nid = ALC662_DIGOUT_NID, 15616 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 15617 .channel_mode = alc662_3ST_2ch_modes, 15618 .input_mux = &alc662_eeepc_capture_source, 15619 .unsol_event = alc663_g71v_unsol_event, 15620 .init_hook = alc663_g71v_inithook, 15621 }, 15622 [ALC663_ASUS_H13] = { 15623 .mixers = { alc663_m51va_mixer }, 15624 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs }, 15625 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 15626 .dac_nids = alc662_dac_nids, 15627 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 15628 .channel_mode = alc662_3ST_2ch_modes, 15629 .input_mux = &alc663_m51va_capture_source, 15630 .unsol_event = alc663_m51va_unsol_event, 15631 .init_hook = alc663_m51va_inithook, 15632 }, 15633 [ALC663_ASUS_G50V] = { 15634 .mixers = { alc663_g50v_mixer }, 15635 .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs }, 15636 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 15637 .dac_nids = alc662_dac_nids, 15638 .dig_out_nid = ALC662_DIGOUT_NID, 15639 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), 15640 .channel_mode = alc662_3ST_6ch_modes, 15641 .input_mux = &alc663_capture_source, 15642 .unsol_event = alc663_g50v_unsol_event, 15643 .init_hook = alc663_g50v_inithook, 15644 }, 15645 [ALC663_ASUS_MODE1] = { 15646 .mixers = { alc663_m51va_mixer }, 15647 .cap_mixer = alc662_auto_capture_mixer, 15648 .init_verbs = { alc662_init_verbs, 15649 alc663_21jd_amic_init_verbs }, 15650 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 15651 .hp_nid = 0x03, 15652 .dac_nids = alc662_dac_nids, 15653 .dig_out_nid = ALC662_DIGOUT_NID, 15654 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 15655 .channel_mode = alc662_3ST_2ch_modes, 15656 .input_mux = &alc662_eeepc_capture_source, 15657 .unsol_event = alc663_mode1_unsol_event, 15658 .init_hook = alc663_mode1_inithook, 15659 }, 15660 [ALC662_ASUS_MODE2] = { 15661 .mixers = { alc662_1bjd_mixer }, 15662 .cap_mixer = alc662_auto_capture_mixer, 15663 .init_verbs = { alc662_init_verbs, 15664 alc662_1bjd_amic_init_verbs }, 15665 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 15666 .dac_nids = alc662_dac_nids, 15667 .dig_out_nid = ALC662_DIGOUT_NID, 15668 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 15669 .channel_mode = alc662_3ST_2ch_modes, 15670 .input_mux = &alc662_eeepc_capture_source, 15671 .unsol_event = alc662_mode2_unsol_event, 15672 .init_hook = alc662_mode2_inithook, 15673 }, 15674 [ALC663_ASUS_MODE3] = { 15675 .mixers = { alc663_two_hp_m1_mixer }, 15676 .cap_mixer = alc662_auto_capture_mixer, 15677 .init_verbs = { alc662_init_verbs, 15678 alc663_two_hp_amic_m1_init_verbs }, 15679 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 15680 .hp_nid = 0x03, 15681 .dac_nids = alc662_dac_nids, 15682 .dig_out_nid = ALC662_DIGOUT_NID, 15683 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 15684 .channel_mode = alc662_3ST_2ch_modes, 15685 .input_mux = &alc662_eeepc_capture_source, 15686 .unsol_event = alc663_mode3_unsol_event, 15687 .init_hook = alc663_mode3_inithook, 15688 }, 15689 [ALC663_ASUS_MODE4] = { 15690 .mixers = { alc663_asus_21jd_clfe_mixer }, 15691 .cap_mixer = alc662_auto_capture_mixer, 15692 .init_verbs = { alc662_init_verbs, 15693 alc663_21jd_amic_init_verbs}, 15694 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 15695 .hp_nid = 0x03, 15696 .dac_nids = alc662_dac_nids, 15697 .dig_out_nid = ALC662_DIGOUT_NID, 15698 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 15699 .channel_mode = alc662_3ST_2ch_modes, 15700 .input_mux = &alc662_eeepc_capture_source, 15701 .unsol_event = alc663_mode4_unsol_event, 15702 .init_hook = alc663_mode4_inithook, 15703 }, 15704 [ALC663_ASUS_MODE5] = { 15705 .mixers = { alc663_asus_15jd_clfe_mixer }, 15706 .cap_mixer = alc662_auto_capture_mixer, 15707 .init_verbs = { alc662_init_verbs, 15708 alc663_15jd_amic_init_verbs }, 15709 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 15710 .hp_nid = 0x03, 15711 .dac_nids = alc662_dac_nids, 15712 .dig_out_nid = ALC662_DIGOUT_NID, 15713 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 15714 .channel_mode = alc662_3ST_2ch_modes, 15715 .input_mux = &alc662_eeepc_capture_source, 15716 .unsol_event = alc663_mode5_unsol_event, 15717 .init_hook = alc663_mode5_inithook, 15718 }, 15719 [ALC663_ASUS_MODE6] = { 15720 .mixers = { alc663_two_hp_m2_mixer }, 15721 .cap_mixer = alc662_auto_capture_mixer, 15722 .init_verbs = { alc662_init_verbs, 15723 alc663_two_hp_amic_m2_init_verbs }, 15724 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 15725 .hp_nid = 0x03, 15726 .dac_nids = alc662_dac_nids, 15727 .dig_out_nid = ALC662_DIGOUT_NID, 15728 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 15729 .channel_mode = alc662_3ST_2ch_modes, 15730 .input_mux = &alc662_eeepc_capture_source, 15731 .unsol_event = alc663_mode6_unsol_event, 15732 .init_hook = alc663_mode6_inithook, 15733 }, 15734}; 15735 15736 15737/* 15738 * BIOS auto configuration 15739 */ 15740 15741/* add playback controls from the parsed DAC table */ 15742static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec, 15743 const struct auto_pin_cfg *cfg) 15744{ 15745 char name[32]; 15746 static const char *chname[4] = { 15747 "Front", "Surround", NULL /*CLFE*/, "Side" 15748 }; 15749 hda_nid_t nid; 15750 int i, err; 15751 15752 for (i = 0; i < cfg->line_outs; i++) { 15753 if (!spec->multiout.dac_nids[i]) 15754 continue; 15755 nid = alc880_idx_to_dac(i); 15756 if (i == 2) { 15757 /* Center/LFE */ 15758 err = add_control(spec, ALC_CTL_WIDGET_VOL, 15759 "Center Playback Volume", 15760 HDA_COMPOSE_AMP_VAL(nid, 1, 0, 15761 HDA_OUTPUT)); 15762 if (err < 0) 15763 return err; 15764 err = add_control(spec, ALC_CTL_WIDGET_VOL, 15765 "LFE Playback Volume", 15766 HDA_COMPOSE_AMP_VAL(nid, 2, 0, 15767 HDA_OUTPUT)); 15768 if (err < 0) 15769 return err; 15770 err = add_control(spec, ALC_CTL_WIDGET_MUTE, 15771 "Center Playback Switch", 15772 HDA_COMPOSE_AMP_VAL(0x0e, 1, 0, 15773 HDA_INPUT)); 15774 if (err < 0) 15775 return err; 15776 err = add_control(spec, ALC_CTL_WIDGET_MUTE, 15777 "LFE Playback Switch", 15778 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, 15779 HDA_INPUT)); 15780 if (err < 0) 15781 return err; 15782 } else { 15783 sprintf(name, "%s Playback Volume", chname[i]); 15784 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, 15785 HDA_COMPOSE_AMP_VAL(nid, 3, 0, 15786 HDA_OUTPUT)); 15787 if (err < 0) 15788 return err; 15789 sprintf(name, "%s Playback Switch", chname[i]); 15790 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, 15791 HDA_COMPOSE_AMP_VAL(alc880_idx_to_mixer(i), 15792 3, 0, HDA_INPUT)); 15793 if (err < 0) 15794 return err; 15795 } 15796 } 15797 return 0; 15798} 15799 15800/* add playback controls for speaker and HP outputs */ 15801static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin, 15802 const char *pfx) 15803{ 15804 hda_nid_t nid; 15805 int err; 15806 char name[32]; 15807 15808 if (!pin) 15809 return 0; 15810 15811 if (pin == 0x17) { 15812 /* ALC663 has a mono output pin on 0x17 */ 15813 sprintf(name, "%s Playback Switch", pfx); 15814 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, 15815 HDA_COMPOSE_AMP_VAL(pin, 2, 0, HDA_OUTPUT)); 15816 return err; 15817 } 15818 15819 if (alc880_is_fixed_pin(pin)) { 15820 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); 15821 /* printk("DAC nid=%x\n",nid); */ 15822 /* specify the DAC as the extra output */ 15823 if (!spec->multiout.hp_nid) 15824 spec->multiout.hp_nid = nid; 15825 else 15826 spec->multiout.extra_out_nid[0] = nid; 15827 /* control HP volume/switch on the output mixer amp */ 15828 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); 15829 sprintf(name, "%s Playback Volume", pfx); 15830 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, 15831 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); 15832 if (err < 0) 15833 return err; 15834 sprintf(name, "%s Playback Switch", pfx); 15835 err = add_control(spec, ALC_CTL_BIND_MUTE, name, 15836 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT)); 15837 if (err < 0) 15838 return err; 15839 } else if (alc880_is_multi_pin(pin)) { 15840 /* set manual connection */ 15841 /* we have only a switch on HP-out PIN */ 15842 sprintf(name, "%s Playback Switch", pfx); 15843 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, 15844 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); 15845 if (err < 0) 15846 return err; 15847 } 15848 return 0; 15849} 15850 15851/* create playback/capture controls for input pins */ 15852static int alc662_auto_create_analog_input_ctls(struct alc_spec *spec, 15853 const struct auto_pin_cfg *cfg) 15854{ 15855 struct hda_input_mux *imux = &spec->private_imux; 15856 int i, err, idx; 15857 15858 for (i = 0; i < AUTO_PIN_LAST; i++) { 15859 if (alc880_is_input_pin(cfg->input_pins[i])) { 15860 idx = alc880_input_pin_idx(cfg->input_pins[i]); 15861 err = new_analog_input(spec, cfg->input_pins[i], 15862 auto_pin_cfg_labels[i], 15863 idx, 0x0b); 15864 if (err < 0) 15865 return err; 15866 imux->items[imux->num_items].label = 15867 auto_pin_cfg_labels[i]; 15868 imux->items[imux->num_items].index = 15869 alc880_input_pin_idx(cfg->input_pins[i]); 15870 imux->num_items++; 15871 } 15872 } 15873 return 0; 15874} 15875 15876static void alc662_auto_set_output_and_unmute(struct hda_codec *codec, 15877 hda_nid_t nid, int pin_type, 15878 int dac_idx) 15879{ 15880 alc_set_pin_output(codec, nid, pin_type); 15881 /* need the manual connection? */ 15882 if (alc880_is_multi_pin(nid)) { 15883 struct alc_spec *spec = codec->spec; 15884 int idx = alc880_multi_pin_idx(nid); 15885 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0, 15886 AC_VERB_SET_CONNECT_SEL, 15887 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx])); 15888 } 15889} 15890 15891static void alc662_auto_init_multi_out(struct hda_codec *codec) 15892{ 15893 struct alc_spec *spec = codec->spec; 15894 int i; 15895 15896 alc_subsystem_id(codec, 0x15, 0x1b, 0x14); 15897 for (i = 0; i <= HDA_SIDE; i++) { 15898 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 15899 int pin_type = get_pin_type(spec->autocfg.line_out_type); 15900 if (nid) 15901 alc662_auto_set_output_and_unmute(codec, nid, pin_type, 15902 i); 15903 } 15904} 15905 15906static void alc662_auto_init_hp_out(struct hda_codec *codec) 15907{ 15908 struct alc_spec *spec = codec->spec; 15909 hda_nid_t pin; 15910 15911 pin = spec->autocfg.hp_pins[0]; 15912 if (pin) /* connect to front */ 15913 /* use dac 0 */ 15914 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); 15915 pin = spec->autocfg.speaker_pins[0]; 15916 if (pin) 15917 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0); 15918} 15919 15920#define alc662_is_input_pin(nid) alc880_is_input_pin(nid) 15921#define ALC662_PIN_CD_NID ALC880_PIN_CD_NID 15922 15923static void alc662_auto_init_analog_input(struct hda_codec *codec) 15924{ 15925 struct alc_spec *spec = codec->spec; 15926 int i; 15927 15928 for (i = 0; i < AUTO_PIN_LAST; i++) { 15929 hda_nid_t nid = spec->autocfg.input_pins[i]; 15930 if (alc662_is_input_pin(nid)) { 15931 snd_hda_codec_write(codec, nid, 0, 15932 AC_VERB_SET_PIN_WIDGET_CONTROL, 15933 (i <= AUTO_PIN_FRONT_MIC ? 15934 PIN_VREF80 : PIN_IN)); 15935 if (nid != ALC662_PIN_CD_NID) 15936 snd_hda_codec_write(codec, nid, 0, 15937 AC_VERB_SET_AMP_GAIN_MUTE, 15938 AMP_OUT_MUTE); 15939 } 15940 } 15941} 15942 15943#define alc662_auto_init_input_src alc882_auto_init_input_src 15944 15945static int alc662_parse_auto_config(struct hda_codec *codec) 15946{ 15947 struct alc_spec *spec = codec->spec; 15948 int err; 15949 static hda_nid_t alc662_ignore[] = { 0x1d, 0 }; 15950 15951 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 15952 alc662_ignore); 15953 if (err < 0) 15954 return err; 15955 if (!spec->autocfg.line_outs) 15956 return 0; /* can't find valid BIOS pin config */ 15957 15958 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); 15959 if (err < 0) 15960 return err; 15961 err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg); 15962 if (err < 0) 15963 return err; 15964 err = alc662_auto_create_extra_out(spec, 15965 spec->autocfg.speaker_pins[0], 15966 "Speaker"); 15967 if (err < 0) 15968 return err; 15969 err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0], 15970 "Headphone"); 15971 if (err < 0) 15972 return err; 15973 err = alc662_auto_create_analog_input_ctls(spec, &spec->autocfg); 15974 if (err < 0) 15975 return err; 15976 15977 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 15978 15979 if (spec->autocfg.dig_out_pin) 15980 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID; 15981 15982 if (spec->kctls.list) 15983 add_mixer(spec, spec->kctls.list); 15984 15985 spec->num_mux_defs = 1; 15986 spec->input_mux = &spec->private_imux; 15987 15988 add_verb(spec, alc662_auto_init_verbs); 15989 if (codec->vendor_id == 0x10ec0663) 15990 add_verb(spec, alc663_auto_init_verbs); 15991 15992 err = alc_auto_add_mic_boost(codec); 15993 if (err < 0) 15994 return err; 15995 15996 store_pin_configs(codec); 15997 return 1; 15998} 15999 16000/* additional initialization for auto-configuration model */ 16001static void alc662_auto_init(struct hda_codec *codec) 16002{ 16003 struct alc_spec *spec = codec->spec; 16004 alc662_auto_init_multi_out(codec); 16005 alc662_auto_init_hp_out(codec); 16006 alc662_auto_init_analog_input(codec); 16007 alc662_auto_init_input_src(codec); 16008 if (spec->unsol_event) 16009 alc_inithook(codec); 16010} 16011 16012static int patch_alc662(struct hda_codec *codec) 16013{ 16014 struct alc_spec *spec; 16015 int err, board_config; 16016 16017 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 16018 if (!spec) 16019 return -ENOMEM; 16020 16021 codec->spec = spec; 16022 16023 alc_fix_pll_init(codec, 0x20, 0x04, 15); 16024 16025 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST, 16026 alc662_models, 16027 alc662_cfg_tbl); 16028 if (board_config < 0) { 16029 printk(KERN_INFO "hda_codec: Unknown model for ALC662, " 16030 "trying auto-probe from BIOS...\n"); 16031 board_config = ALC662_AUTO; 16032 } 16033 16034 if (board_config == ALC662_AUTO) { 16035 /* automatic parse from the BIOS config */ 16036 err = alc662_parse_auto_config(codec); 16037 if (err < 0) { 16038 alc_free(codec); 16039 return err; 16040 } else if (!err) { 16041 printk(KERN_INFO 16042 "hda_codec: Cannot set up configuration " 16043 "from BIOS. Using base mode...\n"); 16044 board_config = ALC662_3ST_2ch_DIG; 16045 } 16046 } 16047 16048 if (board_config != ALC662_AUTO) 16049 setup_preset(spec, &alc662_presets[board_config]); 16050 16051 if (codec->vendor_id == 0x10ec0663) { 16052 spec->stream_name_analog = "ALC663 Analog"; 16053 spec->stream_name_digital = "ALC663 Digital"; 16054 } else if (codec->vendor_id == 0x10ec0272) { 16055 spec->stream_name_analog = "ALC272 Analog"; 16056 spec->stream_name_digital = "ALC272 Digital"; 16057 } else { 16058 spec->stream_name_analog = "ALC662 Analog"; 16059 spec->stream_name_digital = "ALC662 Digital"; 16060 } 16061 16062 spec->stream_analog_playback = &alc662_pcm_analog_playback; 16063 spec->stream_analog_capture = &alc662_pcm_analog_capture; 16064 16065 spec->stream_digital_playback = &alc662_pcm_digital_playback; 16066 spec->stream_digital_capture = &alc662_pcm_digital_capture; 16067 16068 spec->adc_nids = alc662_adc_nids; 16069 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids); 16070 spec->capsrc_nids = alc662_capsrc_nids; 16071 spec->is_mix_capture = 1; 16072 16073 if (!spec->cap_mixer) 16074 set_capture_mixer(spec); 16075 16076 spec->vmaster_nid = 0x02; 16077 16078 codec->patch_ops = alc_patch_ops; 16079 if (board_config == ALC662_AUTO) 16080 spec->init_hook = alc662_auto_init; 16081#ifdef CONFIG_SND_HDA_POWER_SAVE 16082 if (!spec->loopback.amplist) 16083 spec->loopback.amplist = alc662_loopbacks; 16084#endif 16085 16086 return 0; 16087} 16088 16089/* 16090 * patch entries 16091 */ 16092struct hda_codec_preset snd_hda_preset_realtek[] = { 16093 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 }, 16094 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 }, 16095 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 }, 16096 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 }, 16097 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 }, 16098 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 }, 16099 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660", 16100 .patch = patch_alc861 }, 16101 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd }, 16102 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 }, 16103 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd }, 16104 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2", 16105 .patch = patch_alc883 }, 16106 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1", 16107 .patch = patch_alc662 }, 16108 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 }, 16109 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 }, 16110 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 }, 16111 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 }, 16112 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A", 16113 .patch = patch_alc882 }, /* should be patch_alc883() in future */ 16114 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A", 16115 .patch = patch_alc882 }, /* should be patch_alc883() in future */ 16116 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 }, 16117 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc883 }, 16118 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 }, 16119 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200", 16120 .patch = patch_alc883 }, 16121 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc883 }, 16122 {} /* terminator */ 16123}; 16124