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 <sound/driver.h> 27 #include <linux/init.h> 28 #include <linux/delay.h> 29 #include <linux/slab.h> 30 #include <linux/pci.h> 31 #include <sound/core.h> 32 #include "hda_codec.h" 33 #include "hda_local.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 */ 41 enum { 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 #ifdef CONFIG_SND_DEBUG 64 ALC880_TEST, 65 #endif 66 ALC880_AUTO, 67 ALC880_MODEL_LAST /* last tag */ 68 }; 69 70 /* ALC260 models */ 71 enum { 72 ALC260_BASIC, 73 ALC260_HP, 74 ALC260_HP_3013, 75 ALC260_FUJITSU_S702X, 76 ALC260_ACER, 77 ALC260_WILL, 78 ALC260_REPLACER_672V, 79 #ifdef CONFIG_SND_DEBUG 80 ALC260_TEST, 81 #endif 82 ALC260_AUTO, 83 ALC260_MODEL_LAST /* last tag */ 84 }; 85 86 /* ALC262 models */ 87 enum { 88 ALC262_BASIC, 89 ALC262_HIPPO, 90 ALC262_HIPPO_1, 91 ALC262_FUJITSU, 92 ALC262_HP_BPC, 93 ALC262_HP_BPC_D7000_WL, 94 ALC262_HP_BPC_D7000_WF, 95 ALC262_BENQ_ED8, 96 ALC262_SONY_ASSAMD, 97 ALC262_BENQ_T31, 98 ALC262_AUTO, 99 ALC262_MODEL_LAST /* last tag */ 100 }; 101 102 /* ALC268 models */ 103 enum { 104 ALC268_3ST, 105 ALC268_TOSHIBA, 106 ALC268_ACER, 107 ALC268_AUTO, 108 ALC268_MODEL_LAST /* last tag */ 109 }; 110 111 /* ALC861 models */ 112 enum { 113 ALC861_3ST, 114 ALC660_3ST, 115 ALC861_3ST_DIG, 116 ALC861_6ST_DIG, 117 ALC861_UNIWILL_M31, 118 ALC861_TOSHIBA, 119 ALC861_ASUS, 120 ALC861_ASUS_LAPTOP, 121 ALC861_AUTO, 122 ALC861_MODEL_LAST, 123 }; 124 125 /* ALC861-VD models */ 126 enum { 127 ALC660VD_3ST, 128 ALC660VD_3ST_DIG, 129 ALC861VD_3ST, 130 ALC861VD_3ST_DIG, 131 ALC861VD_6ST_DIG, 132 ALC861VD_LENOVO, 133 ALC861VD_DALLAS, 134 ALC861VD_HP, 135 ALC861VD_AUTO, 136 ALC861VD_MODEL_LAST, 137 }; 138 139 /* ALC662 models */ 140 enum { 141 ALC662_3ST_2ch_DIG, 142 ALC662_3ST_6ch_DIG, 143 ALC662_3ST_6ch, 144 ALC662_5ST_DIG, 145 ALC662_LENOVO_101E, 146 ALC662_ASUS_EEEPC_P701, 147 ALC662_AUTO, 148 ALC662_MODEL_LAST, 149 }; 150 151 /* ALC882 models */ 152 enum { 153 ALC882_3ST_DIG, 154 ALC882_6ST_DIG, 155 ALC882_ARIMA, 156 ALC882_W2JC, 157 ALC882_TARGA, 158 ALC882_ASUS_A7J, 159 ALC882_ASUS_A7M, 160 ALC885_MACPRO, 161 ALC885_MBP3, 162 ALC885_IMAC24, 163 ALC882_AUTO, 164 ALC882_MODEL_LAST, 165 }; 166 167 /* ALC883 models */ 168 enum { 169 ALC883_3ST_2ch_DIG, 170 ALC883_3ST_6ch_DIG, 171 ALC883_3ST_6ch, 172 ALC883_6ST_DIG, 173 ALC883_TARGA_DIG, 174 ALC883_TARGA_2ch_DIG, 175 ALC883_ACER, 176 ALC883_ACER_ASPIRE, 177 ALC883_MEDION, 178 ALC883_MEDION_MD2, 179 ALC883_LAPTOP_EAPD, 180 ALC883_LENOVO_101E_2ch, 181 ALC883_LENOVO_NB0763, 182 ALC888_LENOVO_MS7195_DIG, 183 ALC883_HAIER_W66, 184 ALC888_6ST_HP, 185 ALC888_3ST_HP, 186 ALC883_AUTO, 187 ALC883_MODEL_LAST, 188 }; 189 190 /* for GPIO Poll */ 191 #define GPIO_MASK 0x03 192 193 struct alc_spec { 194 /* codec parameterization */ 195 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */ 196 unsigned int num_mixers; 197 198 const struct hda_verb *init_verbs[5]; /* initialization verbs 199 * don't forget NULL 200 * termination! 201 */ 202 unsigned int num_init_verbs; 203 204 char *stream_name_analog; /* analog PCM stream */ 205 struct hda_pcm_stream *stream_analog_playback; 206 struct hda_pcm_stream *stream_analog_capture; 207 208 char *stream_name_digital; /* digital PCM stream */ 209 struct hda_pcm_stream *stream_digital_playback; 210 struct hda_pcm_stream *stream_digital_capture; 211 212 /* playback */ 213 struct hda_multi_out multiout; /* playback set-up 214 * max_channels, dacs must be set 215 * dig_out_nid and hp_nid are optional 216 */ 217 218 /* capture */ 219 unsigned int num_adc_nids; 220 hda_nid_t *adc_nids; 221 hda_nid_t dig_in_nid; /* digital-in NID; optional */ 222 223 /* capture source */ 224 unsigned int num_mux_defs; 225 const struct hda_input_mux *input_mux; 226 unsigned int cur_mux[3]; 227 228 /* channel model */ 229 const struct hda_channel_mode *channel_mode; 230 int num_channel_mode; 231 int need_dac_fix; 232 233 /* PCM information */ 234 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */ 235 236 /* dynamic controls, init_verbs and input_mux */ 237 struct auto_pin_cfg autocfg; 238 unsigned int num_kctl_alloc, num_kctl_used; 239 struct snd_kcontrol_new *kctl_alloc; 240 struct hda_input_mux private_imux; 241 hda_nid_t private_dac_nids[5]; 242 243 /* hooks */ 244 void (*init_hook)(struct hda_codec *codec); 245 void (*unsol_event)(struct hda_codec *codec, unsigned int res); 246 247 /* for pin sensing */ 248 unsigned int sense_updated: 1; 249 unsigned int jack_present: 1; 250 251 #ifdef CONFIG_SND_HDA_POWER_SAVE 252 struct hda_loopback_check loopback; 253 #endif 254 }; 255 256 /* 257 * configuration template - to be copied to the spec instance 258 */ 259 struct alc_config_preset { 260 struct snd_kcontrol_new *mixers[5]; /* should be identical size 261 * with spec 262 */ 263 const struct hda_verb *init_verbs[5]; 264 unsigned int num_dacs; 265 hda_nid_t *dac_nids; 266 hda_nid_t dig_out_nid; /* optional */ 267 hda_nid_t hp_nid; /* optional */ 268 unsigned int num_adc_nids; 269 hda_nid_t *adc_nids; 270 hda_nid_t dig_in_nid; 271 unsigned int num_channel_mode; 272 const struct hda_channel_mode *channel_mode; 273 int need_dac_fix; 274 unsigned int num_mux_defs; 275 const struct hda_input_mux *input_mux; 276 void (*unsol_event)(struct hda_codec *, unsigned int); 277 void (*init_hook)(struct hda_codec *); 278 #ifdef CONFIG_SND_HDA_POWER_SAVE 279 struct hda_amp_list *loopbacks; 280 #endif 281 }; 282 283 284 /* 285 * input MUX handling 286 */ 287 static int alc_mux_enum_info(struct snd_kcontrol *kcontrol, 288 struct snd_ctl_elem_info *uinfo) 289 { 290 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 291 struct alc_spec *spec = codec->spec; 292 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id); 293 if (mux_idx >= spec->num_mux_defs) 294 mux_idx = 0; 295 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo); 296 } 297 298 static int alc_mux_enum_get(struct snd_kcontrol *kcontrol, 299 struct snd_ctl_elem_value *ucontrol) 300 { 301 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 302 struct alc_spec *spec = codec->spec; 303 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 304 305 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx]; 306 return 0; 307 } 308 309 static int alc_mux_enum_put(struct snd_kcontrol *kcontrol, 310 struct snd_ctl_elem_value *ucontrol) 311 { 312 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 313 struct alc_spec *spec = codec->spec; 314 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 315 unsigned int mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx; 316 return snd_hda_input_mux_put(codec, &spec->input_mux[mux_idx], ucontrol, 317 spec->adc_nids[adc_idx], 318 &spec->cur_mux[adc_idx]); 319 } 320 321 322 /* 323 * channel mode setting 324 */ 325 static int alc_ch_mode_info(struct snd_kcontrol *kcontrol, 326 struct snd_ctl_elem_info *uinfo) 327 { 328 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 329 struct alc_spec *spec = codec->spec; 330 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode, 331 spec->num_channel_mode); 332 } 333 334 static int alc_ch_mode_get(struct snd_kcontrol *kcontrol, 335 struct snd_ctl_elem_value *ucontrol) 336 { 337 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 338 struct alc_spec *spec = codec->spec; 339 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode, 340 spec->num_channel_mode, 341 spec->multiout.max_channels); 342 } 343 344 static int alc_ch_mode_put(struct snd_kcontrol *kcontrol, 345 struct snd_ctl_elem_value *ucontrol) 346 { 347 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 348 struct alc_spec *spec = codec->spec; 349 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode, 350 spec->num_channel_mode, 351 &spec->multiout.max_channels); 352 if (err >= 0 && spec->need_dac_fix) 353 spec->multiout.num_dacs = spec->multiout.max_channels / 2; 354 return err; 355 } 356 357 /* 358 * Control the mode of pin widget settings via the mixer. "pc" is used 359 * instead of "%" to avoid consequences of accidently treating the % as 360 * being part of a format specifier. Maximum allowed length of a value is 361 * 63 characters plus NULL terminator. 362 * 363 * Note: some retasking pin complexes seem to ignore requests for input 364 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these 365 * are requested. Therefore order this list so that this behaviour will not 366 * cause problems when mixer clients move through the enum sequentially. 367 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of 368 * March 2006. 369 */ 370 static char *alc_pin_mode_names[] = { 371 "Mic 50pc bias", "Mic 80pc bias", 372 "Line in", "Line out", "Headphone out", 373 }; 374 static unsigned char alc_pin_mode_values[] = { 375 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP, 376 }; 377 /* The control can present all 5 options, or it can limit the options based 378 * in the pin being assumed to be exclusively an input or an output pin. In 379 * addition, "input" pins may or may not process the mic bias option 380 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to 381 * accept requests for bias as of chip versions up to March 2006) and/or 382 * wiring in the computer. 383 */ 384 #define ALC_PIN_DIR_IN 0x00 385 #define ALC_PIN_DIR_OUT 0x01 386 #define ALC_PIN_DIR_INOUT 0x02 387 #define ALC_PIN_DIR_IN_NOMICBIAS 0x03 388 #define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04 389 390 /* Info about the pin modes supported by the different pin direction modes. 391 * For each direction the minimum and maximum values are given. 392 */ 393 static signed char alc_pin_mode_dir_info[5][2] = { 394 { 0, 2 }, /* ALC_PIN_DIR_IN */ 395 { 3, 4 }, /* ALC_PIN_DIR_OUT */ 396 { 0, 4 }, /* ALC_PIN_DIR_INOUT */ 397 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */ 398 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */ 399 }; 400 #define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0]) 401 #define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1]) 402 #define alc_pin_mode_n_items(_dir) \ 403 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1) 404 405 static int alc_pin_mode_info(struct snd_kcontrol *kcontrol, 406 struct snd_ctl_elem_info *uinfo) 407 { 408 unsigned int item_num = uinfo->value.enumerated.item; 409 unsigned char dir = (kcontrol->private_value >> 16) & 0xff; 410 411 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 412 uinfo->count = 1; 413 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir); 414 415 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir)) 416 item_num = alc_pin_mode_min(dir); 417 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]); 418 return 0; 419 } 420 421 static int alc_pin_mode_get(struct snd_kcontrol *kcontrol, 422 struct snd_ctl_elem_value *ucontrol) 423 { 424 unsigned int i; 425 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 426 hda_nid_t nid = kcontrol->private_value & 0xffff; 427 unsigned char dir = (kcontrol->private_value >> 16) & 0xff; 428 long *valp = ucontrol->value.integer.value; 429 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0, 430 AC_VERB_GET_PIN_WIDGET_CONTROL, 431 0x00); 432 433 /* Find enumerated value for current pinctl setting */ 434 i = alc_pin_mode_min(dir); 435 while (alc_pin_mode_values[i] != pinctl && i <= alc_pin_mode_max(dir)) 436 i++; 437 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir); 438 return 0; 439 } 440 441 static int alc_pin_mode_put(struct snd_kcontrol *kcontrol, 442 struct snd_ctl_elem_value *ucontrol) 443 { 444 signed int change; 445 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 446 hda_nid_t nid = kcontrol->private_value & 0xffff; 447 unsigned char dir = (kcontrol->private_value >> 16) & 0xff; 448 long val = *ucontrol->value.integer.value; 449 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0, 450 AC_VERB_GET_PIN_WIDGET_CONTROL, 451 0x00); 452 453 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir)) 454 val = alc_pin_mode_min(dir); 455 456 change = pinctl != alc_pin_mode_values[val]; 457 if (change) { 458 /* Set pin mode to that requested */ 459 snd_hda_codec_write_cache(codec, nid, 0, 460 AC_VERB_SET_PIN_WIDGET_CONTROL, 461 alc_pin_mode_values[val]); 462 463 /* Also enable the retasking pin's input/output as required 464 * for the requested pin mode. Enum values of 2 or less are 465 * input modes. 466 * 467 * Dynamically switching the input/output buffers probably 468 * reduces noise slightly (particularly on input) so we'll 469 * do it. However, having both input and output buffers 470 * enabled simultaneously doesn't seem to be problematic if 471 * this turns out to be necessary in the future. 472 */ 473 if (val <= 2) { 474 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, 475 HDA_AMP_MUTE, HDA_AMP_MUTE); 476 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0, 477 HDA_AMP_MUTE, 0); 478 } else { 479 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0, 480 HDA_AMP_MUTE, HDA_AMP_MUTE); 481 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, 482 HDA_AMP_MUTE, 0); 483 } 484 } 485 return change; 486 } 487 488 #define ALC_PIN_MODE(xname, nid, dir) \ 489 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 490 .info = alc_pin_mode_info, \ 491 .get = alc_pin_mode_get, \ 492 .put = alc_pin_mode_put, \ 493 .private_value = nid | (dir<<16) } 494 495 /* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged 496 * together using a mask with more than one bit set. This control is 497 * currently used only by the ALC260 test model. At this stage they are not 498 * needed for any "production" models. 499 */ 500 #ifdef CONFIG_SND_DEBUG 501 #define alc_gpio_data_info snd_ctl_boolean_mono_info 502 503 static int alc_gpio_data_get(struct snd_kcontrol *kcontrol, 504 struct snd_ctl_elem_value *ucontrol) 505 { 506 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 507 hda_nid_t nid = kcontrol->private_value & 0xffff; 508 unsigned char mask = (kcontrol->private_value >> 16) & 0xff; 509 long *valp = ucontrol->value.integer.value; 510 unsigned int val = snd_hda_codec_read(codec, nid, 0, 511 AC_VERB_GET_GPIO_DATA, 0x00); 512 513 *valp = (val & mask) != 0; 514 return 0; 515 } 516 static int alc_gpio_data_put(struct snd_kcontrol *kcontrol, 517 struct snd_ctl_elem_value *ucontrol) 518 { 519 signed int change; 520 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 521 hda_nid_t nid = kcontrol->private_value & 0xffff; 522 unsigned char mask = (kcontrol->private_value >> 16) & 0xff; 523 long val = *ucontrol->value.integer.value; 524 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0, 525 AC_VERB_GET_GPIO_DATA, 526 0x00); 527 528 /* Set/unset the masked GPIO bit(s) as needed */ 529 change = (val == 0 ? 0 : mask) != (gpio_data & mask); 530 if (val == 0) 531 gpio_data &= ~mask; 532 else 533 gpio_data |= mask; 534 snd_hda_codec_write_cache(codec, nid, 0, 535 AC_VERB_SET_GPIO_DATA, gpio_data); 536 537 return change; 538 } 539 #define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \ 540 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 541 .info = alc_gpio_data_info, \ 542 .get = alc_gpio_data_get, \ 543 .put = alc_gpio_data_put, \ 544 .private_value = nid | (mask<<16) } 545 #endif /* CONFIG_SND_DEBUG */ 546 547 /* A switch control to allow the enabling of the digital IO pins on the 548 * ALC260. This is incredibly simplistic; the intention of this control is 549 * to provide something in the test model allowing digital outputs to be 550 * identified if present. If models are found which can utilise these 551 * outputs a more complete mixer control can be devised for those models if 552 * necessary. 553 */ 554 #ifdef CONFIG_SND_DEBUG 555 #define alc_spdif_ctrl_info snd_ctl_boolean_mono_info 556 557 static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol, 558 struct snd_ctl_elem_value *ucontrol) 559 { 560 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 561 hda_nid_t nid = kcontrol->private_value & 0xffff; 562 unsigned char mask = (kcontrol->private_value >> 16) & 0xff; 563 long *valp = ucontrol->value.integer.value; 564 unsigned int val = snd_hda_codec_read(codec, nid, 0, 565 AC_VERB_GET_DIGI_CONVERT, 0x00); 566 567 *valp = (val & mask) != 0; 568 return 0; 569 } 570 static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol, 571 struct snd_ctl_elem_value *ucontrol) 572 { 573 signed int change; 574 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 575 hda_nid_t nid = kcontrol->private_value & 0xffff; 576 unsigned char mask = (kcontrol->private_value >> 16) & 0xff; 577 long val = *ucontrol->value.integer.value; 578 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0, 579 AC_VERB_GET_DIGI_CONVERT, 580 0x00); 581 582 /* Set/unset the masked control bit(s) as needed */ 583 change = (val == 0 ? 0 : mask) != (ctrl_data & mask); 584 if (val==0) 585 ctrl_data &= ~mask; 586 else 587 ctrl_data |= mask; 588 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, 589 ctrl_data); 590 591 return change; 592 } 593 #define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \ 594 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 595 .info = alc_spdif_ctrl_info, \ 596 .get = alc_spdif_ctrl_get, \ 597 .put = alc_spdif_ctrl_put, \ 598 .private_value = nid | (mask<<16) } 599 #endif /* CONFIG_SND_DEBUG */ 600 601 /* 602 * set up from the preset table 603 */ 604 static void setup_preset(struct alc_spec *spec, 605 const struct alc_config_preset *preset) 606 { 607 int i; 608 609 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++) 610 spec->mixers[spec->num_mixers++] = preset->mixers[i]; 611 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i]; 612 i++) 613 spec->init_verbs[spec->num_init_verbs++] = 614 preset->init_verbs[i]; 615 616 spec->channel_mode = preset->channel_mode; 617 spec->num_channel_mode = preset->num_channel_mode; 618 spec->need_dac_fix = preset->need_dac_fix; 619 620 spec->multiout.max_channels = spec->channel_mode[0].channels; 621 622 spec->multiout.num_dacs = preset->num_dacs; 623 spec->multiout.dac_nids = preset->dac_nids; 624 spec->multiout.dig_out_nid = preset->dig_out_nid; 625 spec->multiout.hp_nid = preset->hp_nid; 626 627 spec->num_mux_defs = preset->num_mux_defs; 628 if (!spec->num_mux_defs) 629 spec->num_mux_defs = 1; 630 spec->input_mux = preset->input_mux; 631 632 spec->num_adc_nids = preset->num_adc_nids; 633 spec->adc_nids = preset->adc_nids; 634 spec->dig_in_nid = preset->dig_in_nid; 635 636 spec->unsol_event = preset->unsol_event; 637 spec->init_hook = preset->init_hook; 638 #ifdef CONFIG_SND_HDA_POWER_SAVE 639 spec->loopback.amplist = preset->loopbacks; 640 #endif 641 } 642 643 /* Enable GPIO mask and set output */ 644 static struct hda_verb alc_gpio1_init_verbs[] = { 645 {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, 646 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, 647 {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, 648 { } 649 }; 650 651 static struct hda_verb alc_gpio2_init_verbs[] = { 652 {0x01, AC_VERB_SET_GPIO_MASK, 0x02}, 653 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02}, 654 {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, 655 { } 656 }; 657 658 static struct hda_verb alc_gpio3_init_verbs[] = { 659 {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, 660 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03}, 661 {0x01, AC_VERB_SET_GPIO_DATA, 0x03}, 662 { } 663 }; 664 665 static void alc_sku_automute(struct hda_codec *codec) 666 { 667 struct alc_spec *spec = codec->spec; 668 unsigned int mute; 669 unsigned int present; 670 unsigned int hp_nid = spec->autocfg.hp_pins[0]; 671 unsigned int sp_nid = spec->autocfg.speaker_pins[0]; 672 673 /* need to execute and sync at first */ 674 snd_hda_codec_read(codec, hp_nid, 0, AC_VERB_SET_PIN_SENSE, 0); 675 present = snd_hda_codec_read(codec, hp_nid, 0, 676 AC_VERB_GET_PIN_SENSE, 0); 677 spec->jack_present = (present & 0x80000000) != 0; 678 if (spec->jack_present) { 679 /* mute internal speaker */ 680 snd_hda_codec_amp_stereo(codec, sp_nid, HDA_OUTPUT, 0, 681 HDA_AMP_MUTE, HDA_AMP_MUTE); 682 } else { 683 /* unmute internal speaker if necessary */ 684 mute = snd_hda_codec_amp_read(codec, hp_nid, 0, HDA_OUTPUT, 0); 685 snd_hda_codec_amp_stereo(codec, sp_nid, HDA_OUTPUT, 0, 686 HDA_AMP_MUTE, mute); 687 } 688 } 689 690 /* unsolicited event for HP jack sensing */ 691 static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res) 692 { 693 if (codec->vendor_id == 0x10ec0880) 694 res >>= 28; 695 else 696 res >>= 26; 697 if (res != ALC880_HP_EVENT) 698 return; 699 700 alc_sku_automute(codec); 701 } 702 703 /* 32-bit subsystem ID for BIOS loading in HD Audio codec. 704 * 31 ~ 16 : Manufacture ID 705 * 15 ~ 8 : SKU ID 706 * 7 ~ 0 : Assembly ID 707 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36 708 */ 709 static void alc_subsystem_id(struct hda_codec *codec, 710 unsigned int porta, unsigned int porte, 711 unsigned int portd) 712 { 713 unsigned int ass, tmp, i; 714 unsigned nid; 715 struct alc_spec *spec = codec->spec; 716 717 ass = codec->subsystem_id & 0xffff; 718 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1)) 719 goto do_sku; 720 721 /* 722 * 31~30 : port conetcivity 723 * 29~21 : reserve 724 * 20 : PCBEEP input 725 * 19~16 : Check sum (15:1) 726 * 15~1 : Custom 727 * 0 : override 728 */ 729 nid = 0x1d; 730 if (codec->vendor_id == 0x10ec0260) 731 nid = 0x17; 732 ass = snd_hda_codec_read(codec, nid, 0, 733 AC_VERB_GET_CONFIG_DEFAULT, 0); 734 if (!(ass & 1) && !(ass & 0x100000)) 735 return; 736 if ((ass >> 30) != 1) /* no physical connection */ 737 return; 738 739 /* check sum */ 740 tmp = 0; 741 for (i = 1; i < 16; i++) { 742 if ((ass >> i) && 1) 743 tmp++; 744 } 745 if (((ass >> 16) & 0xf) != tmp) 746 return; 747 do_sku: 748 /* 749 * 0 : override 750 * 1 : Swap Jack 751 * 2 : 0 --> Desktop, 1 --> Laptop 752 * 3~5 : External Amplifier control 753 * 7~6 : Reserved 754 */ 755 tmp = (ass & 0x38) >> 3; /* external Amp control */ 756 switch (tmp) { 757 case 1: 758 snd_hda_sequence_write(codec, alc_gpio1_init_verbs); 759 break; 760 case 3: 761 snd_hda_sequence_write(codec, alc_gpio2_init_verbs); 762 break; 763 case 7: 764 snd_hda_sequence_write(codec, alc_gpio3_init_verbs); 765 break; 766 case 5: /* set EAPD output high */ 767 switch (codec->vendor_id) { 768 case 0x10ec0260: 769 snd_hda_codec_write(codec, 0x0f, 0, 770 AC_VERB_SET_EAPD_BTLENABLE, 2); 771 snd_hda_codec_write(codec, 0x10, 0, 772 AC_VERB_SET_EAPD_BTLENABLE, 2); 773 break; 774 case 0x10ec0262: 775 case 0x10ec0267: 776 case 0x10ec0268: 777 case 0x10ec0269: 778 case 0x10ec0862: 779 case 0x10ec0662: 780 snd_hda_codec_write(codec, 0x14, 0, 781 AC_VERB_SET_EAPD_BTLENABLE, 2); 782 snd_hda_codec_write(codec, 0x15, 0, 783 AC_VERB_SET_EAPD_BTLENABLE, 2); 784 break; 785 } 786 switch (codec->vendor_id) { 787 case 0x10ec0260: 788 snd_hda_codec_write(codec, 0x1a, 0, 789 AC_VERB_SET_COEF_INDEX, 7); 790 tmp = snd_hda_codec_read(codec, 0x1a, 0, 791 AC_VERB_GET_PROC_COEF, 0); 792 snd_hda_codec_write(codec, 0x1a, 0, 793 AC_VERB_SET_COEF_INDEX, 7); 794 snd_hda_codec_write(codec, 0x1a, 0, 795 AC_VERB_SET_PROC_COEF, 796 tmp | 0x2010); 797 break; 798 case 0x10ec0262: 799 case 0x10ec0880: 800 case 0x10ec0882: 801 case 0x10ec0883: 802 case 0x10ec0885: 803 case 0x10ec0888: 804 snd_hda_codec_write(codec, 0x20, 0, 805 AC_VERB_SET_COEF_INDEX, 7); 806 tmp = snd_hda_codec_read(codec, 0x20, 0, 807 AC_VERB_GET_PROC_COEF, 0); 808 snd_hda_codec_write(codec, 0x20, 0, 809 AC_VERB_SET_COEF_INDEX, 7); 810 snd_hda_codec_write(codec, 0x20, 0, 811 AC_VERB_SET_PROC_COEF, 812 tmp | 0x2010); 813 break; 814 case 0x10ec0267: 815 case 0x10ec0268: 816 snd_hda_codec_write(codec, 0x20, 0, 817 AC_VERB_SET_COEF_INDEX, 7); 818 tmp = snd_hda_codec_read(codec, 0x20, 0, 819 AC_VERB_GET_PROC_COEF, 0); 820 snd_hda_codec_write(codec, 0x20, 0, 821 AC_VERB_SET_COEF_INDEX, 7); 822 snd_hda_codec_write(codec, 0x20, 0, 823 AC_VERB_SET_PROC_COEF, 824 tmp | 0x3000); 825 break; 826 } 827 default: 828 break; 829 } 830 831 /* is laptop and enable the function "Mute internal speaker 832 * when the external headphone out jack is plugged" 833 */ 834 if (!(ass & 0x4) || !(ass & 0x8000)) 835 return; 836 /* 837 * 10~8 : Jack location 838 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered 839 * 14~13: Resvered 840 * 15 : 1 --> enable the function "Mute internal speaker 841 * when the external headphone out jack is plugged" 842 */ 843 if (!spec->autocfg.speaker_pins[0]) { 844 if (spec->multiout.dac_nids[0]) 845 spec->autocfg.speaker_pins[0] = 846 spec->multiout.dac_nids[0]; 847 else 848 return; 849 } 850 851 if (!spec->autocfg.hp_pins[0]) { 852 tmp = (ass >> 11) & 0x3; /* HP to chassis */ 853 if (tmp == 0) 854 spec->autocfg.hp_pins[0] = porta; 855 else if (tmp == 1) 856 spec->autocfg.hp_pins[0] = porte; 857 else if (tmp == 2) 858 spec->autocfg.hp_pins[0] = portd; 859 else 860 return; 861 } 862 863 snd_hda_codec_write(codec, spec->autocfg.hp_pins[0], 0, 864 AC_VERB_SET_UNSOLICITED_ENABLE, 865 AC_USRSP_EN | ALC880_HP_EVENT); 866 spec->unsol_event = alc_sku_unsol_event; 867 spec->init_hook = alc_sku_automute; 868 } 869 870 /* 871 * Fix-up pin default configurations 872 */ 873 874 struct alc_pincfg { 875 hda_nid_t nid; 876 u32 val; 877 }; 878 879 static void alc_fix_pincfg(struct hda_codec *codec, 880 const struct snd_pci_quirk *quirk, 881 const struct alc_pincfg **pinfix) 882 { 883 const struct alc_pincfg *cfg; 884 885 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk); 886 if (!quirk) 887 return; 888 889 cfg = pinfix[quirk->value]; 890 for (; cfg->nid; cfg++) { 891 int i; 892 u32 val = cfg->val; 893 for (i = 0; i < 4; i++) { 894 snd_hda_codec_write(codec, cfg->nid, 0, 895 AC_VERB_SET_CONFIG_DEFAULT_BYTES_0 + i, 896 val & 0xff); 897 val >>= 8; 898 } 899 } 900 } 901 902 /* 903 * ALC880 3-stack model 904 * 905 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e) 906 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18, 907 * F-Mic = 0x1b, HP = 0x19 908 */ 909 910 static hda_nid_t alc880_dac_nids[4] = { 911 /* front, rear, clfe, rear_surr */ 912 0x02, 0x05, 0x04, 0x03 913 }; 914 915 static hda_nid_t alc880_adc_nids[3] = { 916 /* ADC0-2 */ 917 0x07, 0x08, 0x09, 918 }; 919 920 /* The datasheet says the node 0x07 is connected from inputs, 921 * but it shows zero connection in the real implementation on some devices. 922 * Note: this is a 915GAV bug, fixed on 915GLV 923 */ 924 static hda_nid_t alc880_adc_nids_alt[2] = { 925 /* ADC1-2 */ 926 0x08, 0x09, 927 }; 928 929 #define ALC880_DIGOUT_NID 0x06 930 #define ALC880_DIGIN_NID 0x0a 931 932 static struct hda_input_mux alc880_capture_source = { 933 .num_items = 4, 934 .items = { 935 { "Mic", 0x0 }, 936 { "Front Mic", 0x3 }, 937 { "Line", 0x2 }, 938 { "CD", 0x4 }, 939 }, 940 }; 941 942 /* channel source setting (2/6 channel selection for 3-stack) */ 943 /* 2ch mode */ 944 static struct hda_verb alc880_threestack_ch2_init[] = { 945 /* set line-in to input, mute it */ 946 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 947 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 948 /* set mic-in to input vref 80%, mute it */ 949 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 950 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 951 { } /* end */ 952 }; 953 954 /* 6ch mode */ 955 static struct hda_verb alc880_threestack_ch6_init[] = { 956 /* set line-in to output, unmute it */ 957 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 958 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 959 /* set mic-in to output, unmute it */ 960 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 961 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 962 { } /* end */ 963 }; 964 965 static struct hda_channel_mode alc880_threestack_modes[2] = { 966 { 2, alc880_threestack_ch2_init }, 967 { 6, alc880_threestack_ch6_init }, 968 }; 969 970 static struct snd_kcontrol_new alc880_three_stack_mixer[] = { 971 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 972 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 973 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 974 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT), 975 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 976 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 977 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 978 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 979 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 980 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 981 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 982 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 983 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 984 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 985 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT), 986 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT), 987 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 988 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 989 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT), 990 { 991 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 992 .name = "Channel Mode", 993 .info = alc_ch_mode_info, 994 .get = alc_ch_mode_get, 995 .put = alc_ch_mode_put, 996 }, 997 { } /* end */ 998 }; 999 1000 /* capture mixer elements */ 1001 static struct snd_kcontrol_new alc880_capture_mixer[] = { 1002 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT), 1003 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT), 1004 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT), 1005 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT), 1006 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT), 1007 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT), 1008 { 1009 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1010 /* The multiple "Capture Source" controls confuse alsamixer 1011 * So call somewhat different.. 1012 * FIXME: the controls appear in the "playback" view! 1013 */ 1014 /* .name = "Capture Source", */ 1015 .name = "Input Source", 1016 .count = 3, 1017 .info = alc_mux_enum_info, 1018 .get = alc_mux_enum_get, 1019 .put = alc_mux_enum_put, 1020 }, 1021 { } /* end */ 1022 }; 1023 1024 /* capture mixer elements (in case NID 0x07 not available) */ 1025 static struct snd_kcontrol_new alc880_capture_alt_mixer[] = { 1026 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 1027 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 1028 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), 1029 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), 1030 { 1031 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1032 /* The multiple "Capture Source" controls confuse alsamixer 1033 * So call somewhat different.. 1034 * FIXME: the controls appear in the "playback" view! 1035 */ 1036 /* .name = "Capture Source", */ 1037 .name = "Input Source", 1038 .count = 2, 1039 .info = alc_mux_enum_info, 1040 .get = alc_mux_enum_get, 1041 .put = alc_mux_enum_put, 1042 }, 1043 { } /* end */ 1044 }; 1045 1046 1047 1048 /* 1049 * ALC880 5-stack model 1050 * 1051 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d), 1052 * Side = 0x02 (0xd) 1053 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16 1054 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19 1055 */ 1056 1057 /* additional mixers to alc880_three_stack_mixer */ 1058 static struct snd_kcontrol_new alc880_five_stack_mixer[] = { 1059 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 1060 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT), 1061 { } /* end */ 1062 }; 1063 1064 /* channel source setting (6/8 channel selection for 5-stack) */ 1065 /* 6ch mode */ 1066 static struct hda_verb alc880_fivestack_ch6_init[] = { 1067 /* set line-in to input, mute it */ 1068 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 1069 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 1070 { } /* end */ 1071 }; 1072 1073 /* 8ch mode */ 1074 static struct hda_verb alc880_fivestack_ch8_init[] = { 1075 /* set line-in to output, unmute it */ 1076 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 1077 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 1078 { } /* end */ 1079 }; 1080 1081 static struct hda_channel_mode alc880_fivestack_modes[2] = { 1082 { 6, alc880_fivestack_ch6_init }, 1083 { 8, alc880_fivestack_ch8_init }, 1084 }; 1085 1086 1087 /* 1088 * ALC880 6-stack model 1089 * 1090 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e), 1091 * Side = 0x05 (0x0f) 1092 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17, 1093 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b 1094 */ 1095 1096 static hda_nid_t alc880_6st_dac_nids[4] = { 1097 /* front, rear, clfe, rear_surr */ 1098 0x02, 0x03, 0x04, 0x05 1099 }; 1100 1101 static struct hda_input_mux alc880_6stack_capture_source = { 1102 .num_items = 4, 1103 .items = { 1104 { "Mic", 0x0 }, 1105 { "Front Mic", 0x1 }, 1106 { "Line", 0x2 }, 1107 { "CD", 0x4 }, 1108 }, 1109 }; 1110 1111 /* fixed 8-channels */ 1112 static struct hda_channel_mode alc880_sixstack_modes[1] = { 1113 { 8, NULL }, 1114 }; 1115 1116 static struct snd_kcontrol_new alc880_six_stack_mixer[] = { 1117 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 1118 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 1119 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 1120 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 1121 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 1122 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 1123 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 1124 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 1125 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 1126 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 1127 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 1128 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 1129 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 1130 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 1131 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 1132 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 1133 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 1134 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 1135 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 1136 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 1137 { 1138 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1139 .name = "Channel Mode", 1140 .info = alc_ch_mode_info, 1141 .get = alc_ch_mode_get, 1142 .put = alc_ch_mode_put, 1143 }, 1144 { } /* end */ 1145 }; 1146 1147 1148 /* 1149 * ALC880 W810 model 1150 * 1151 * W810 has rear IO for: 1152 * Front (DAC 02) 1153 * Surround (DAC 03) 1154 * Center/LFE (DAC 04) 1155 * Digital out (06) 1156 * 1157 * The system also has a pair of internal speakers, and a headphone jack. 1158 * These are both connected to Line2 on the codec, hence to DAC 02. 1159 * 1160 * There is a variable resistor to control the speaker or headphone 1161 * volume. This is a hardware-only device without a software API. 1162 * 1163 * Plugging headphones in will disable the internal speakers. This is 1164 * implemented in hardware, not via the driver using jack sense. In 1165 * a similar fashion, plugging into the rear socket marked "front" will 1166 * disable both the speakers and headphones. 1167 * 1168 * For input, there's a microphone jack, and an "audio in" jack. 1169 * These may not do anything useful with this driver yet, because I 1170 * haven't setup any initialization verbs for these yet... 1171 */ 1172 1173 static hda_nid_t alc880_w810_dac_nids[3] = { 1174 /* front, rear/surround, clfe */ 1175 0x02, 0x03, 0x04 1176 }; 1177 1178 /* fixed 6 channels */ 1179 static struct hda_channel_mode alc880_w810_modes[1] = { 1180 { 6, NULL } 1181 }; 1182 1183 /* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */ 1184 static struct snd_kcontrol_new alc880_w810_base_mixer[] = { 1185 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 1186 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 1187 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 1188 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 1189 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 1190 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 1191 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 1192 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 1193 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 1194 { } /* end */ 1195 }; 1196 1197 1198 /* 1199 * Z710V model 1200 * 1201 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d) 1202 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?), 1203 * Line = 0x1a 1204 */ 1205 1206 static hda_nid_t alc880_z71v_dac_nids[1] = { 1207 0x02 1208 }; 1209 #define ALC880_Z71V_HP_DAC 0x03 1210 1211 /* fixed 2 channels */ 1212 static struct hda_channel_mode alc880_2_jack_modes[1] = { 1213 { 2, NULL } 1214 }; 1215 1216 static struct snd_kcontrol_new alc880_z71v_mixer[] = { 1217 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 1218 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 1219 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 1220 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT), 1221 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 1222 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 1223 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 1224 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 1225 { } /* end */ 1226 }; 1227 1228 1229 /* FIXME! */ 1230 /* 1231 * ALC880 F1734 model 1232 * 1233 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d) 1234 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18 1235 */ 1236 1237 static hda_nid_t alc880_f1734_dac_nids[1] = { 1238 0x03 1239 }; 1240 #define ALC880_F1734_HP_DAC 0x02 1241 1242 static struct snd_kcontrol_new alc880_f1734_mixer[] = { 1243 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 1244 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), 1245 HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 1246 HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 1247 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 1248 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 1249 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 1250 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 1251 { } /* end */ 1252 }; 1253 1254 1255 /* FIXME! */ 1256 /* 1257 * ALC880 ASUS model 1258 * 1259 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e) 1260 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16, 1261 * Mic = 0x18, Line = 0x1a 1262 */ 1263 1264 #define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */ 1265 #define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */ 1266 1267 static struct snd_kcontrol_new alc880_asus_mixer[] = { 1268 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 1269 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 1270 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 1271 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 1272 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 1273 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 1274 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 1275 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 1276 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 1277 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 1278 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 1279 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 1280 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 1281 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 1282 { 1283 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1284 .name = "Channel Mode", 1285 .info = alc_ch_mode_info, 1286 .get = alc_ch_mode_get, 1287 .put = alc_ch_mode_put, 1288 }, 1289 { } /* end */ 1290 }; 1291 1292 /* FIXME! */ 1293 /* 1294 * ALC880 ASUS W1V model 1295 * 1296 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e) 1297 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16, 1298 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b 1299 */ 1300 1301 /* additional mixers to alc880_asus_mixer */ 1302 static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = { 1303 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT), 1304 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT), 1305 { } /* end */ 1306 }; 1307 1308 /* additional mixers to alc880_asus_mixer */ 1309 static struct snd_kcontrol_new alc880_pcbeep_mixer[] = { 1310 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 1311 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 1312 { } /* end */ 1313 }; 1314 1315 /* TCL S700 */ 1316 static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = { 1317 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 1318 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 1319 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 1320 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT), 1321 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT), 1322 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT), 1323 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT), 1324 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 1325 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 1326 { 1327 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1328 /* The multiple "Capture Source" controls confuse alsamixer 1329 * So call somewhat different.. 1330 * FIXME: the controls appear in the "playback" view! 1331 */ 1332 /* .name = "Capture Source", */ 1333 .name = "Input Source", 1334 .count = 1, 1335 .info = alc_mux_enum_info, 1336 .get = alc_mux_enum_get, 1337 .put = alc_mux_enum_put, 1338 }, 1339 { } /* end */ 1340 }; 1341 1342 /* Uniwill */ 1343 static struct snd_kcontrol_new alc880_uniwill_mixer[] = { 1344 HDA_CODEC_VOLUME("HPhone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 1345 HDA_BIND_MUTE("HPhone Playback Switch", 0x0c, 2, HDA_INPUT), 1346 HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 1347 HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT), 1348 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 1349 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 1350 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 1351 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 1352 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 1353 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 1354 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 1355 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 1356 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 1357 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 1358 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 1359 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 1360 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 1361 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 1362 { 1363 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1364 .name = "Channel Mode", 1365 .info = alc_ch_mode_info, 1366 .get = alc_ch_mode_get, 1367 .put = alc_ch_mode_put, 1368 }, 1369 { } /* end */ 1370 }; 1371 1372 static struct snd_kcontrol_new alc880_fujitsu_mixer[] = { 1373 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 1374 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), 1375 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 1376 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 1377 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 1378 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 1379 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 1380 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 1381 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 1382 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 1383 { } /* end */ 1384 }; 1385 1386 static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = { 1387 HDA_CODEC_VOLUME("HPhone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 1388 HDA_BIND_MUTE("HPhone Playback Switch", 0x0c, 2, HDA_INPUT), 1389 HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 1390 HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT), 1391 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 1392 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 1393 { } /* end */ 1394 }; 1395 1396 /* 1397 * build control elements 1398 */ 1399 static int alc_build_controls(struct hda_codec *codec) 1400 { 1401 struct alc_spec *spec = codec->spec; 1402 int err; 1403 int i; 1404 1405 for (i = 0; i < spec->num_mixers; i++) { 1406 err = snd_hda_add_new_ctls(codec, spec->mixers[i]); 1407 if (err < 0) 1408 return err; 1409 } 1410 1411 if (spec->multiout.dig_out_nid) { 1412 err = snd_hda_create_spdif_out_ctls(codec, 1413 spec->multiout.dig_out_nid); 1414 if (err < 0) 1415 return err; 1416 } 1417 if (spec->dig_in_nid) { 1418 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid); 1419 if (err < 0) 1420 return err; 1421 } 1422 return 0; 1423 } 1424 1425 1426 /* 1427 * initialize the codec volumes, etc 1428 */ 1429 1430 /* 1431 * generic initialization of ADC, input mixers and output mixers 1432 */ 1433 static struct hda_verb alc880_volume_init_verbs[] = { 1434 /* 1435 * Unmute ADC0-2 and set the default input to mic-in 1436 */ 1437 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 1438 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1439 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 1440 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1441 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 1442 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1443 1444 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 1445 * mixer widget 1446 * Note: PASD motherboards uses the Line In 2 as the input for front 1447 * panel mic (mic 2) 1448 */ 1449 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 1450 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 1451 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 1452 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 1453 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 1454 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 1455 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, 1456 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, 1457 1458 /* 1459 * Set up output mixers (0x0c - 0x0f) 1460 */ 1461 /* set vol=0 to output mixers */ 1462 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 1463 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 1464 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 1465 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 1466 /* set up input amps for analog loopback */ 1467 /* Amp Indices: DAC = 0, mixer = 1 */ 1468 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 1469 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 1470 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 1471 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 1472 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 1473 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 1474 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 1475 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 1476 1477 { } 1478 }; 1479 1480 /* 1481 * 3-stack pin configuration: 1482 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b 1483 */ 1484 static struct hda_verb alc880_pin_3stack_init_verbs[] = { 1485 /* 1486 * preset connection lists of input pins 1487 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround 1488 */ 1489 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ 1490 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 1491 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */ 1492 1493 /* 1494 * Set pin mode and muting 1495 */ 1496 /* set front pin widgets 0x14 for output */ 1497 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1498 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1499 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 1500 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1501 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1502 /* Mic2 (as headphone out) for HP output */ 1503 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1504 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1505 /* Line In pin widget for input */ 1506 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1507 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1508 /* Line2 (as front mic) pin widget for input and vref at 80% */ 1509 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1510 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1511 /* CD pin widget for input */ 1512 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1513 1514 { } 1515 }; 1516 1517 /* 1518 * 5-stack pin configuration: 1519 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19, 1520 * line-in/side = 0x1a, f-mic = 0x1b 1521 */ 1522 static struct hda_verb alc880_pin_5stack_init_verbs[] = { 1523 /* 1524 * preset connection lists of input pins 1525 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround 1526 */ 1527 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 1528 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */ 1529 1530 /* 1531 * Set pin mode and muting 1532 */ 1533 /* set pin widgets 0x14-0x17 for output */ 1534 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1535 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1536 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1537 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1538 /* unmute pins for output (no gain on this amp) */ 1539 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1540 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1541 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1542 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1543 1544 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 1545 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1546 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1547 /* Mic2 (as headphone out) for HP output */ 1548 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1549 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1550 /* Line In pin widget for input */ 1551 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1552 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1553 /* Line2 (as front mic) pin widget for input and vref at 80% */ 1554 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1555 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1556 /* CD pin widget for input */ 1557 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1558 1559 { } 1560 }; 1561 1562 /* 1563 * W810 pin configuration: 1564 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b 1565 */ 1566 static struct hda_verb alc880_pin_w810_init_verbs[] = { 1567 /* hphone/speaker input selector: front DAC */ 1568 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0}, 1569 1570 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1571 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1572 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1573 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1574 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1575 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1576 1577 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1578 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1579 1580 { } 1581 }; 1582 1583 /* 1584 * Z71V pin configuration: 1585 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?) 1586 */ 1587 static struct hda_verb alc880_pin_z71v_init_verbs[] = { 1588 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1589 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1590 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1591 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1592 1593 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1594 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1595 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1596 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1597 1598 { } 1599 }; 1600 1601 /* 1602 * 6-stack pin configuration: 1603 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18, 1604 * f-mic = 0x19, line = 0x1a, HP = 0x1b 1605 */ 1606 static struct hda_verb alc880_pin_6stack_init_verbs[] = { 1607 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 1608 1609 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1610 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1611 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1612 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1613 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1614 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1615 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1616 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1617 1618 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1619 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1620 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1621 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1622 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1623 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1624 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1625 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1626 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1627 1628 { } 1629 }; 1630 1631 /* 1632 * Uniwill pin configuration: 1633 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19, 1634 * line = 0x1a 1635 */ 1636 static struct hda_verb alc880_uniwill_init_verbs[] = { 1637 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 1638 1639 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1640 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1641 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1642 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1643 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1644 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1645 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1646 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1647 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 1648 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 1649 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 1650 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 1651 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 1652 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 1653 1654 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1655 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1656 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1657 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1658 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1659 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1660 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */ 1661 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */ 1662 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1663 1664 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 1665 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 1666 1667 { } 1668 }; 1669 1670 /* 1671 * Uniwill P53 1672 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x19, 1673 */ 1674 static struct hda_verb alc880_uniwill_p53_init_verbs[] = { 1675 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 1676 1677 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1678 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1679 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1680 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1681 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1682 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1683 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 1684 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 1685 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 1686 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 1687 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 1688 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 1689 1690 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1691 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1692 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1693 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1694 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1695 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1696 1697 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 1698 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT}, 1699 1700 { } 1701 }; 1702 1703 static struct hda_verb alc880_beep_init_verbs[] = { 1704 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) }, 1705 { } 1706 }; 1707 1708 /* toggle speaker-output according to the hp-jack state */ 1709 static void alc880_uniwill_hp_automute(struct hda_codec *codec) 1710 { 1711 unsigned int present; 1712 unsigned char bits; 1713 1714 present = snd_hda_codec_read(codec, 0x14, 0, 1715 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 1716 bits = present ? HDA_AMP_MUTE : 0; 1717 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 1718 HDA_AMP_MUTE, bits); 1719 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0, 1720 HDA_AMP_MUTE, bits); 1721 } 1722 1723 /* auto-toggle front mic */ 1724 static void alc880_uniwill_mic_automute(struct hda_codec *codec) 1725 { 1726 unsigned int present; 1727 unsigned char bits; 1728 1729 present = snd_hda_codec_read(codec, 0x18, 0, 1730 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 1731 bits = present ? HDA_AMP_MUTE : 0; 1732 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits); 1733 } 1734 1735 static void alc880_uniwill_automute(struct hda_codec *codec) 1736 { 1737 alc880_uniwill_hp_automute(codec); 1738 alc880_uniwill_mic_automute(codec); 1739 } 1740 1741 static void alc880_uniwill_unsol_event(struct hda_codec *codec, 1742 unsigned int res) 1743 { 1744 /* Looks like the unsol event is incompatible with the standard 1745 * definition. 4bit tag is placed at 28 bit! 1746 */ 1747 switch (res >> 28) { 1748 case ALC880_HP_EVENT: 1749 alc880_uniwill_hp_automute(codec); 1750 break; 1751 case ALC880_MIC_EVENT: 1752 alc880_uniwill_mic_automute(codec); 1753 break; 1754 } 1755 } 1756 1757 static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec) 1758 { 1759 unsigned int present; 1760 unsigned char bits; 1761 1762 present = snd_hda_codec_read(codec, 0x14, 0, 1763 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 1764 bits = present ? HDA_AMP_MUTE : 0; 1765 snd_hda_codec_amp_stereo(codec, 0x15, HDA_INPUT, 0, HDA_AMP_MUTE, bits); 1766 } 1767 1768 static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec) 1769 { 1770 unsigned int present; 1771 1772 present = snd_hda_codec_read(codec, 0x21, 0, 1773 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0); 1774 present &= HDA_AMP_VOLMASK; 1775 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0, 1776 HDA_AMP_VOLMASK, present); 1777 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0, 1778 HDA_AMP_VOLMASK, present); 1779 } 1780 1781 static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec, 1782 unsigned int res) 1783 { 1784 /* Looks like the unsol event is incompatible with the standard 1785 * definition. 4bit tag is placed at 28 bit! 1786 */ 1787 if ((res >> 28) == ALC880_HP_EVENT) 1788 alc880_uniwill_p53_hp_automute(codec); 1789 if ((res >> 28) == ALC880_DCVOL_EVENT) 1790 alc880_uniwill_p53_dcvol_automute(codec); 1791 } 1792 1793 /* FIXME! */ 1794 /* 1795 * F1734 pin configuration: 1796 * HP = 0x14, speaker-out = 0x15, mic = 0x18 1797 */ 1798 static struct hda_verb alc880_pin_f1734_init_verbs[] = { 1799 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, 1800 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, 1801 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, 1802 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, 1803 1804 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1805 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1806 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1807 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1808 1809 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1810 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1811 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1812 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1813 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1814 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1815 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1816 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1817 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1818 1819 { } 1820 }; 1821 1822 /* FIXME! */ 1823 /* 1824 * ASUS pin configuration: 1825 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a 1826 */ 1827 static struct hda_verb alc880_pin_asus_init_verbs[] = { 1828 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, 1829 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, 1830 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, 1831 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, 1832 1833 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1834 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1835 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1836 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1837 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1838 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1839 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1840 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1841 1842 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1843 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1844 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1845 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1846 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1847 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1848 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1849 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1850 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1851 1852 { } 1853 }; 1854 1855 /* Enable GPIO mask and set output */ 1856 #define alc880_gpio1_init_verbs alc_gpio1_init_verbs 1857 #define alc880_gpio2_init_verbs alc_gpio2_init_verbs 1858 1859 /* Clevo m520g init */ 1860 static struct hda_verb alc880_pin_clevo_init_verbs[] = { 1861 /* headphone output */ 1862 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01}, 1863 /* line-out */ 1864 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1865 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1866 /* Line-in */ 1867 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1868 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1869 /* CD */ 1870 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1871 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1872 /* Mic1 (rear panel) */ 1873 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1874 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1875 /* Mic2 (front panel) */ 1876 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1877 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1878 /* headphone */ 1879 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1880 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1881 /* change to EAPD mode */ 1882 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 1883 {0x20, AC_VERB_SET_PROC_COEF, 0x3060}, 1884 1885 { } 1886 }; 1887 1888 static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = { 1889 /* change to EAPD mode */ 1890 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 1891 {0x20, AC_VERB_SET_PROC_COEF, 0x3060}, 1892 1893 /* Headphone output */ 1894 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1895 /* Front output*/ 1896 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1897 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 1898 1899 /* Line In pin widget for input */ 1900 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1901 /* CD pin widget for input */ 1902 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1903 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 1904 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1905 1906 /* change to EAPD mode */ 1907 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 1908 {0x20, AC_VERB_SET_PROC_COEF, 0x3070}, 1909 1910 { } 1911 }; 1912 1913 /* 1914 * LG m1 express dual 1915 * 1916 * Pin assignment: 1917 * Rear Line-In/Out (blue): 0x14 1918 * Build-in Mic-In: 0x15 1919 * Speaker-out: 0x17 1920 * HP-Out (green): 0x1b 1921 * Mic-In/Out (red): 0x19 1922 * SPDIF-Out: 0x1e 1923 */ 1924 1925 /* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */ 1926 static hda_nid_t alc880_lg_dac_nids[3] = { 1927 0x05, 0x02, 0x03 1928 }; 1929 1930 /* seems analog CD is not working */ 1931 static struct hda_input_mux alc880_lg_capture_source = { 1932 .num_items = 3, 1933 .items = { 1934 { "Mic", 0x1 }, 1935 { "Line", 0x5 }, 1936 { "Internal Mic", 0x6 }, 1937 }, 1938 }; 1939 1940 /* 2,4,6 channel modes */ 1941 static struct hda_verb alc880_lg_ch2_init[] = { 1942 /* set line-in and mic-in to input */ 1943 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 1944 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 1945 { } 1946 }; 1947 1948 static struct hda_verb alc880_lg_ch4_init[] = { 1949 /* set line-in to out and mic-in to input */ 1950 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, 1951 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 1952 { } 1953 }; 1954 1955 static struct hda_verb alc880_lg_ch6_init[] = { 1956 /* set line-in and mic-in to output */ 1957 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, 1958 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, 1959 { } 1960 }; 1961 1962 static struct hda_channel_mode alc880_lg_ch_modes[3] = { 1963 { 2, alc880_lg_ch2_init }, 1964 { 4, alc880_lg_ch4_init }, 1965 { 6, alc880_lg_ch6_init }, 1966 }; 1967 1968 static struct snd_kcontrol_new alc880_lg_mixer[] = { 1969 /* FIXME: it's not really "master" but front channels */ 1970 HDA_CODEC_VOLUME("Master Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 1971 HDA_BIND_MUTE("Master Playback Switch", 0x0f, 2, HDA_INPUT), 1972 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 1973 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT), 1974 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT), 1975 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT), 1976 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT), 1977 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT), 1978 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 1979 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 1980 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT), 1981 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT), 1982 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT), 1983 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT), 1984 { 1985 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1986 .name = "Channel Mode", 1987 .info = alc_ch_mode_info, 1988 .get = alc_ch_mode_get, 1989 .put = alc_ch_mode_put, 1990 }, 1991 { } /* end */ 1992 }; 1993 1994 static struct hda_verb alc880_lg_init_verbs[] = { 1995 /* set capture source to mic-in */ 1996 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 1997 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 1998 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 1999 /* mute all amp mixer inputs */ 2000 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)}, 2001 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, 2002 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, 2003 /* line-in to input */ 2004 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2005 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2006 /* built-in mic */ 2007 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2008 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2009 /* speaker-out */ 2010 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 2011 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2012 /* mic-in to input */ 2013 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01}, 2014 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2015 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2016 /* HP-out */ 2017 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03}, 2018 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 2019 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2020 /* jack sense */ 2021 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1}, 2022 { } 2023 }; 2024 2025 /* toggle speaker-output according to the hp-jack state */ 2026 static void alc880_lg_automute(struct hda_codec *codec) 2027 { 2028 unsigned int present; 2029 unsigned char bits; 2030 2031 present = snd_hda_codec_read(codec, 0x1b, 0, 2032 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 2033 bits = present ? HDA_AMP_MUTE : 0; 2034 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0, 2035 HDA_AMP_MUTE, bits); 2036 } 2037 2038 static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res) 2039 { 2040 /* Looks like the unsol event is incompatible with the standard 2041 * definition. 4bit tag is placed at 28 bit! 2042 */ 2043 if ((res >> 28) == 0x01) 2044 alc880_lg_automute(codec); 2045 } 2046 2047 /* 2048 * LG LW20 2049 * 2050 * Pin assignment: 2051 * Speaker-out: 0x14 2052 * Mic-In: 0x18 2053 * Built-in Mic-In: 0x19 2054 * Line-In: 0x1b 2055 * HP-Out: 0x1a 2056 * SPDIF-Out: 0x1e 2057 */ 2058 2059 static struct hda_input_mux alc880_lg_lw_capture_source = { 2060 .num_items = 3, 2061 .items = { 2062 { "Mic", 0x0 }, 2063 { "Internal Mic", 0x1 }, 2064 { "Line In", 0x2 }, 2065 }, 2066 }; 2067 2068 #define alc880_lg_lw_modes alc880_threestack_modes 2069 2070 static struct snd_kcontrol_new alc880_lg_lw_mixer[] = { 2071 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2072 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 2073 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 2074 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT), 2075 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 2076 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 2077 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 2078 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 2079 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 2080 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 2081 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 2082 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 2083 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 2084 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 2085 { 2086 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2087 .name = "Channel Mode", 2088 .info = alc_ch_mode_info, 2089 .get = alc_ch_mode_get, 2090 .put = alc_ch_mode_put, 2091 }, 2092 { } /* end */ 2093 }; 2094 2095 static struct hda_verb alc880_lg_lw_init_verbs[] = { 2096 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 2097 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ 2098 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */ 2099 2100 /* set capture source to mic-in */ 2101 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 2102 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 2103 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 2104 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, 2105 /* speaker-out */ 2106 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 2107 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2108 /* HP-out */ 2109 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 2110 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2111 /* mic-in to input */ 2112 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2113 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2114 /* built-in mic */ 2115 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2116 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2117 /* jack sense */ 2118 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1}, 2119 { } 2120 }; 2121 2122 /* toggle speaker-output according to the hp-jack state */ 2123 static void alc880_lg_lw_automute(struct hda_codec *codec) 2124 { 2125 unsigned int present; 2126 unsigned char bits; 2127 2128 present = snd_hda_codec_read(codec, 0x1b, 0, 2129 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 2130 bits = present ? HDA_AMP_MUTE : 0; 2131 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 2132 HDA_AMP_MUTE, bits); 2133 } 2134 2135 static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res) 2136 { 2137 /* Looks like the unsol event is incompatible with the standard 2138 * definition. 4bit tag is placed at 28 bit! 2139 */ 2140 if ((res >> 28) == 0x01) 2141 alc880_lg_lw_automute(codec); 2142 } 2143 2144 #ifdef CONFIG_SND_HDA_POWER_SAVE 2145 static struct hda_amp_list alc880_loopbacks[] = { 2146 { 0x0b, HDA_INPUT, 0 }, 2147 { 0x0b, HDA_INPUT, 1 }, 2148 { 0x0b, HDA_INPUT, 2 }, 2149 { 0x0b, HDA_INPUT, 3 }, 2150 { 0x0b, HDA_INPUT, 4 }, 2151 { } /* end */ 2152 }; 2153 2154 static struct hda_amp_list alc880_lg_loopbacks[] = { 2155 { 0x0b, HDA_INPUT, 1 }, 2156 { 0x0b, HDA_INPUT, 6 }, 2157 { 0x0b, HDA_INPUT, 7 }, 2158 { } /* end */ 2159 }; 2160 #endif 2161 2162 /* 2163 * Common callbacks 2164 */ 2165 2166 static int alc_init(struct hda_codec *codec) 2167 { 2168 struct alc_spec *spec = codec->spec; 2169 unsigned int i; 2170 2171 for (i = 0; i < spec->num_init_verbs; i++) 2172 snd_hda_sequence_write(codec, spec->init_verbs[i]); 2173 2174 if (spec->init_hook) 2175 spec->init_hook(codec); 2176 2177 return 0; 2178 } 2179 2180 static void alc_unsol_event(struct hda_codec *codec, unsigned int res) 2181 { 2182 struct alc_spec *spec = codec->spec; 2183 2184 if (spec->unsol_event) 2185 spec->unsol_event(codec, res); 2186 } 2187 2188 #ifdef CONFIG_SND_HDA_POWER_SAVE 2189 static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid) 2190 { 2191 struct alc_spec *spec = codec->spec; 2192 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid); 2193 } 2194 #endif 2195 2196 /* 2197 * Analog playback callbacks 2198 */ 2199 static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo, 2200 struct hda_codec *codec, 2201 struct snd_pcm_substream *substream) 2202 { 2203 struct alc_spec *spec = codec->spec; 2204 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream); 2205 } 2206 2207 static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo, 2208 struct hda_codec *codec, 2209 unsigned int stream_tag, 2210 unsigned int format, 2211 struct snd_pcm_substream *substream) 2212 { 2213 struct alc_spec *spec = codec->spec; 2214 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, 2215 stream_tag, format, substream); 2216 } 2217 2218 static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, 2219 struct hda_codec *codec, 2220 struct snd_pcm_substream *substream) 2221 { 2222 struct alc_spec *spec = codec->spec; 2223 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); 2224 } 2225 2226 /* 2227 * Digital out 2228 */ 2229 static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo, 2230 struct hda_codec *codec, 2231 struct snd_pcm_substream *substream) 2232 { 2233 struct alc_spec *spec = codec->spec; 2234 return snd_hda_multi_out_dig_open(codec, &spec->multiout); 2235 } 2236 2237 static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, 2238 struct hda_codec *codec, 2239 unsigned int stream_tag, 2240 unsigned int format, 2241 struct snd_pcm_substream *substream) 2242 { 2243 struct alc_spec *spec = codec->spec; 2244 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, 2245 stream_tag, format, substream); 2246 } 2247 2248 static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, 2249 struct hda_codec *codec, 2250 struct snd_pcm_substream *substream) 2251 { 2252 struct alc_spec *spec = codec->spec; 2253 return snd_hda_multi_out_dig_close(codec, &spec->multiout); 2254 } 2255 2256 /* 2257 * Analog capture 2258 */ 2259 static int alc880_capture_pcm_prepare(struct hda_pcm_stream *hinfo, 2260 struct hda_codec *codec, 2261 unsigned int stream_tag, 2262 unsigned int format, 2263 struct snd_pcm_substream *substream) 2264 { 2265 struct alc_spec *spec = codec->spec; 2266 2267 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number], 2268 stream_tag, 0, format); 2269 return 0; 2270 } 2271 2272 static int alc880_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, 2273 struct hda_codec *codec, 2274 struct snd_pcm_substream *substream) 2275 { 2276 struct alc_spec *spec = codec->spec; 2277 2278 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number], 2279 0, 0, 0); 2280 return 0; 2281 } 2282 2283 2284 /* 2285 */ 2286 static struct hda_pcm_stream alc880_pcm_analog_playback = { 2287 .substreams = 1, 2288 .channels_min = 2, 2289 .channels_max = 8, 2290 /* NID is set in alc_build_pcms */ 2291 .ops = { 2292 .open = alc880_playback_pcm_open, 2293 .prepare = alc880_playback_pcm_prepare, 2294 .cleanup = alc880_playback_pcm_cleanup 2295 }, 2296 }; 2297 2298 static struct hda_pcm_stream alc880_pcm_analog_capture = { 2299 .substreams = 2, 2300 .channels_min = 2, 2301 .channels_max = 2, 2302 /* NID is set in alc_build_pcms */ 2303 .ops = { 2304 .prepare = alc880_capture_pcm_prepare, 2305 .cleanup = alc880_capture_pcm_cleanup 2306 }, 2307 }; 2308 2309 static struct hda_pcm_stream alc880_pcm_digital_playback = { 2310 .substreams = 1, 2311 .channels_min = 2, 2312 .channels_max = 2, 2313 /* NID is set in alc_build_pcms */ 2314 .ops = { 2315 .open = alc880_dig_playback_pcm_open, 2316 .close = alc880_dig_playback_pcm_close, 2317 .prepare = alc880_dig_playback_pcm_prepare 2318 }, 2319 }; 2320 2321 static struct hda_pcm_stream alc880_pcm_digital_capture = { 2322 .substreams = 1, 2323 .channels_min = 2, 2324 .channels_max = 2, 2325 /* NID is set in alc_build_pcms */ 2326 }; 2327 2328 /* Used by alc_build_pcms to flag that a PCM has no playback stream */ 2329 static struct hda_pcm_stream alc_pcm_null_playback = { 2330 .substreams = 0, 2331 .channels_min = 0, 2332 .channels_max = 0, 2333 }; 2334 2335 static int alc_build_pcms(struct hda_codec *codec) 2336 { 2337 struct alc_spec *spec = codec->spec; 2338 struct hda_pcm *info = spec->pcm_rec; 2339 int i; 2340 2341 codec->num_pcms = 1; 2342 codec->pcm_info = info; 2343 2344 info->name = spec->stream_name_analog; 2345 if (spec->stream_analog_playback) { 2346 snd_assert(spec->multiout.dac_nids, return -EINVAL); 2347 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback); 2348 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0]; 2349 } 2350 if (spec->stream_analog_capture) { 2351 snd_assert(spec->adc_nids, return -EINVAL); 2352 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture); 2353 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0]; 2354 } 2355 2356 if (spec->channel_mode) { 2357 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0; 2358 for (i = 0; i < spec->num_channel_mode; i++) { 2359 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) { 2360 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels; 2361 } 2362 } 2363 } 2364 2365 /* SPDIF for stream index #1 */ 2366 if (spec->multiout.dig_out_nid || spec->dig_in_nid) { 2367 codec->num_pcms = 2; 2368 info = spec->pcm_rec + 1; 2369 info->name = spec->stream_name_digital; 2370 if (spec->multiout.dig_out_nid && 2371 spec->stream_digital_playback) { 2372 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback); 2373 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid; 2374 } 2375 if (spec->dig_in_nid && 2376 spec->stream_digital_capture) { 2377 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture); 2378 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid; 2379 } 2380 } 2381 2382 /* If the use of more than one ADC is requested for the current 2383 * model, configure a second analog capture-only PCM. 2384 */ 2385 /* Additional Analaog capture for index #2 */ 2386 if (spec->num_adc_nids > 1 && spec->stream_analog_capture && 2387 spec->adc_nids) { 2388 codec->num_pcms = 3; 2389 info = spec->pcm_rec + 2; 2390 info->name = spec->stream_name_analog; 2391 /* No playback stream for second PCM */ 2392 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = alc_pcm_null_playback; 2393 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0; 2394 if (spec->stream_analog_capture) { 2395 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture); 2396 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[1]; 2397 } 2398 } 2399 2400 return 0; 2401 } 2402 2403 static void alc_free(struct hda_codec *codec) 2404 { 2405 struct alc_spec *spec = codec->spec; 2406 unsigned int i; 2407 2408 if (!spec) 2409 return; 2410 2411 if (spec->kctl_alloc) { 2412 for (i = 0; i < spec->num_kctl_used; i++) 2413 kfree(spec->kctl_alloc[i].name); 2414 kfree(spec->kctl_alloc); 2415 } 2416 kfree(spec); 2417 } 2418 2419 /* 2420 */ 2421 static struct hda_codec_ops alc_patch_ops = { 2422 .build_controls = alc_build_controls, 2423 .build_pcms = alc_build_pcms, 2424 .init = alc_init, 2425 .free = alc_free, 2426 .unsol_event = alc_unsol_event, 2427 #ifdef CONFIG_SND_HDA_POWER_SAVE 2428 .check_power_status = alc_check_power_status, 2429 #endif 2430 }; 2431 2432 2433 /* 2434 * Test configuration for debugging 2435 * 2436 * Almost all inputs/outputs are enabled. I/O pins can be configured via 2437 * enum controls. 2438 */ 2439 #ifdef CONFIG_SND_DEBUG 2440 static hda_nid_t alc880_test_dac_nids[4] = { 2441 0x02, 0x03, 0x04, 0x05 2442 }; 2443 2444 static struct hda_input_mux alc880_test_capture_source = { 2445 .num_items = 7, 2446 .items = { 2447 { "In-1", 0x0 }, 2448 { "In-2", 0x1 }, 2449 { "In-3", 0x2 }, 2450 { "In-4", 0x3 }, 2451 { "CD", 0x4 }, 2452 { "Front", 0x5 }, 2453 { "Surround", 0x6 }, 2454 }, 2455 }; 2456 2457 static struct hda_channel_mode alc880_test_modes[4] = { 2458 { 2, NULL }, 2459 { 4, NULL }, 2460 { 6, NULL }, 2461 { 8, NULL }, 2462 }; 2463 2464 static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol, 2465 struct snd_ctl_elem_info *uinfo) 2466 { 2467 static char *texts[] = { 2468 "N/A", "Line Out", "HP Out", 2469 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%" 2470 }; 2471 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 2472 uinfo->count = 1; 2473 uinfo->value.enumerated.items = 8; 2474 if (uinfo->value.enumerated.item >= 8) 2475 uinfo->value.enumerated.item = 7; 2476 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); 2477 return 0; 2478 } 2479 2480 static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol, 2481 struct snd_ctl_elem_value *ucontrol) 2482 { 2483 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2484 hda_nid_t nid = (hda_nid_t)kcontrol->private_value; 2485 unsigned int pin_ctl, item = 0; 2486 2487 pin_ctl = snd_hda_codec_read(codec, nid, 0, 2488 AC_VERB_GET_PIN_WIDGET_CONTROL, 0); 2489 if (pin_ctl & AC_PINCTL_OUT_EN) { 2490 if (pin_ctl & AC_PINCTL_HP_EN) 2491 item = 2; 2492 else 2493 item = 1; 2494 } else if (pin_ctl & AC_PINCTL_IN_EN) { 2495 switch (pin_ctl & AC_PINCTL_VREFEN) { 2496 case AC_PINCTL_VREF_HIZ: item = 3; break; 2497 case AC_PINCTL_VREF_50: item = 4; break; 2498 case AC_PINCTL_VREF_GRD: item = 5; break; 2499 case AC_PINCTL_VREF_80: item = 6; break; 2500 case AC_PINCTL_VREF_100: item = 7; break; 2501 } 2502 } 2503 ucontrol->value.enumerated.item[0] = item; 2504 return 0; 2505 } 2506 2507 static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol, 2508 struct snd_ctl_elem_value *ucontrol) 2509 { 2510 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2511 hda_nid_t nid = (hda_nid_t)kcontrol->private_value; 2512 static unsigned int ctls[] = { 2513 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN, 2514 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ, 2515 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50, 2516 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD, 2517 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80, 2518 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100, 2519 }; 2520 unsigned int old_ctl, new_ctl; 2521 2522 old_ctl = snd_hda_codec_read(codec, nid, 0, 2523 AC_VERB_GET_PIN_WIDGET_CONTROL, 0); 2524 new_ctl = ctls[ucontrol->value.enumerated.item[0]]; 2525 if (old_ctl != new_ctl) { 2526 int val; 2527 snd_hda_codec_write_cache(codec, nid, 0, 2528 AC_VERB_SET_PIN_WIDGET_CONTROL, 2529 new_ctl); 2530 val = ucontrol->value.enumerated.item[0] >= 3 ? 2531 HDA_AMP_MUTE : 0; 2532 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, 2533 HDA_AMP_MUTE, val); 2534 return 1; 2535 } 2536 return 0; 2537 } 2538 2539 static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol, 2540 struct snd_ctl_elem_info *uinfo) 2541 { 2542 static char *texts[] = { 2543 "Front", "Surround", "CLFE", "Side" 2544 }; 2545 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 2546 uinfo->count = 1; 2547 uinfo->value.enumerated.items = 4; 2548 if (uinfo->value.enumerated.item >= 4) 2549 uinfo->value.enumerated.item = 3; 2550 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); 2551 return 0; 2552 } 2553 2554 static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol, 2555 struct snd_ctl_elem_value *ucontrol) 2556 { 2557 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2558 hda_nid_t nid = (hda_nid_t)kcontrol->private_value; 2559 unsigned int sel; 2560 2561 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0); 2562 ucontrol->value.enumerated.item[0] = sel & 3; 2563 return 0; 2564 } 2565 2566 static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol, 2567 struct snd_ctl_elem_value *ucontrol) 2568 { 2569 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2570 hda_nid_t nid = (hda_nid_t)kcontrol->private_value; 2571 unsigned int sel; 2572 2573 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3; 2574 if (ucontrol->value.enumerated.item[0] != sel) { 2575 sel = ucontrol->value.enumerated.item[0] & 3; 2576 snd_hda_codec_write_cache(codec, nid, 0, 2577 AC_VERB_SET_CONNECT_SEL, sel); 2578 return 1; 2579 } 2580 return 0; 2581 } 2582 2583 #define PIN_CTL_TEST(xname,nid) { \ 2584 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 2585 .name = xname, \ 2586 .info = alc_test_pin_ctl_info, \ 2587 .get = alc_test_pin_ctl_get, \ 2588 .put = alc_test_pin_ctl_put, \ 2589 .private_value = nid \ 2590 } 2591 2592 #define PIN_SRC_TEST(xname,nid) { \ 2593 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 2594 .name = xname, \ 2595 .info = alc_test_pin_src_info, \ 2596 .get = alc_test_pin_src_get, \ 2597 .put = alc_test_pin_src_put, \ 2598 .private_value = nid \ 2599 } 2600 2601 static struct snd_kcontrol_new alc880_test_mixer[] = { 2602 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2603 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2604 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT), 2605 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 2606 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 2607 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 2608 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT), 2609 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 2610 PIN_CTL_TEST("Front Pin Mode", 0x14), 2611 PIN_CTL_TEST("Surround Pin Mode", 0x15), 2612 PIN_CTL_TEST("CLFE Pin Mode", 0x16), 2613 PIN_CTL_TEST("Side Pin Mode", 0x17), 2614 PIN_CTL_TEST("In-1 Pin Mode", 0x18), 2615 PIN_CTL_TEST("In-2 Pin Mode", 0x19), 2616 PIN_CTL_TEST("In-3 Pin Mode", 0x1a), 2617 PIN_CTL_TEST("In-4 Pin Mode", 0x1b), 2618 PIN_SRC_TEST("In-1 Pin Source", 0x18), 2619 PIN_SRC_TEST("In-2 Pin Source", 0x19), 2620 PIN_SRC_TEST("In-3 Pin Source", 0x1a), 2621 PIN_SRC_TEST("In-4 Pin Source", 0x1b), 2622 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT), 2623 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT), 2624 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT), 2625 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT), 2626 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT), 2627 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT), 2628 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT), 2629 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT), 2630 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT), 2631 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT), 2632 { 2633 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2634 .name = "Channel Mode", 2635 .info = alc_ch_mode_info, 2636 .get = alc_ch_mode_get, 2637 .put = alc_ch_mode_put, 2638 }, 2639 { } /* end */ 2640 }; 2641 2642 static struct hda_verb alc880_test_init_verbs[] = { 2643 /* Unmute inputs of 0x0c - 0x0f */ 2644 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 2645 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 2646 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 2647 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 2648 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 2649 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 2650 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 2651 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 2652 /* Vol output for 0x0c-0x0f */ 2653 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 2654 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 2655 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 2656 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 2657 /* Set output pins 0x14-0x17 */ 2658 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2659 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2660 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2661 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2662 /* Unmute output pins 0x14-0x17 */ 2663 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2664 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2665 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2666 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2667 /* Set input pins 0x18-0x1c */ 2668 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2669 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2670 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2671 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2672 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2673 /* Mute input pins 0x18-0x1b */ 2674 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2675 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2676 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2677 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2678 /* ADC set up */ 2679 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 2680 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 2681 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 2682 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 2683 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 2684 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 2685 /* Analog input/passthru */ 2686 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 2687 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 2688 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 2689 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 2690 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 2691 { } 2692 }; 2693 #endif 2694 2695 /* 2696 */ 2697 2698 static const char *alc880_models[ALC880_MODEL_LAST] = { 2699 [ALC880_3ST] = "3stack", 2700 [ALC880_TCL_S700] = "tcl", 2701 [ALC880_3ST_DIG] = "3stack-digout", 2702 [ALC880_CLEVO] = "clevo", 2703 [ALC880_5ST] = "5stack", 2704 [ALC880_5ST_DIG] = "5stack-digout", 2705 [ALC880_W810] = "w810", 2706 [ALC880_Z71V] = "z71v", 2707 [ALC880_6ST] = "6stack", 2708 [ALC880_6ST_DIG] = "6stack-digout", 2709 [ALC880_ASUS] = "asus", 2710 [ALC880_ASUS_W1V] = "asus-w1v", 2711 [ALC880_ASUS_DIG] = "asus-dig", 2712 [ALC880_ASUS_DIG2] = "asus-dig2", 2713 [ALC880_UNIWILL_DIG] = "uniwill", 2714 [ALC880_UNIWILL_P53] = "uniwill-p53", 2715 [ALC880_FUJITSU] = "fujitsu", 2716 [ALC880_F1734] = "F1734", 2717 [ALC880_LG] = "lg", 2718 [ALC880_LG_LW] = "lg-lw", 2719 #ifdef CONFIG_SND_DEBUG 2720 [ALC880_TEST] = "test", 2721 #endif 2722 [ALC880_AUTO] = "auto", 2723 }; 2724 2725 static struct snd_pci_quirk alc880_cfg_tbl[] = { 2726 /* Broken BIOS configuration */ 2727 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), 2728 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG), 2729 2730 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG), 2731 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST), 2732 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810), 2733 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG), 2734 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG), 2735 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG), 2736 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG), 2737 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG), 2738 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST), 2739 2740 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG), 2741 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST), 2742 2743 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V), 2744 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG), 2745 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG), 2746 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG), 2747 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG), 2748 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG), 2749 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V), 2750 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */ 2751 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG), 2752 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG), 2753 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS", ALC880_ASUS), 2754 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG), 2755 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST), 2756 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST), 2757 SND_PCI_QUIRK(0x1043, 0, "ASUS", ALC880_ASUS), 2758 2759 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST), 2760 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST), 2761 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST), 2762 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST), 2763 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST), 2764 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO), 2765 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO), 2766 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG), 2767 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810), 2768 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG), 2769 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700), 2770 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG), 2771 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG), 2772 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG), 2773 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG), 2774 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG), 2775 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG), 2776 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2), 2777 2778 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG), 2779 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL), 2780 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53), 2781 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734), 2782 2783 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG), 2784 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL), 2785 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734), 2786 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU), 2787 2788 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG), 2789 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG), 2790 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW), 2791 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW), 2792 2793 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG), 2794 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG), 2795 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG), 2796 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG), 2797 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG), 2798 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG), 2799 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG), 2800 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG), 2801 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG), 2802 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG), 2803 SND_PCI_QUIRK(0x8086, 0, "Intel mobo", ALC880_3ST), 2804 2805 {} 2806 }; 2807 2808 /* 2809 * ALC880 codec presets 2810 */ 2811 static struct alc_config_preset alc880_presets[] = { 2812 [ALC880_3ST] = { 2813 .mixers = { alc880_three_stack_mixer }, 2814 .init_verbs = { alc880_volume_init_verbs, 2815 alc880_pin_3stack_init_verbs }, 2816 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 2817 .dac_nids = alc880_dac_nids, 2818 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), 2819 .channel_mode = alc880_threestack_modes, 2820 .need_dac_fix = 1, 2821 .input_mux = &alc880_capture_source, 2822 }, 2823 [ALC880_3ST_DIG] = { 2824 .mixers = { alc880_three_stack_mixer }, 2825 .init_verbs = { alc880_volume_init_verbs, 2826 alc880_pin_3stack_init_verbs }, 2827 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 2828 .dac_nids = alc880_dac_nids, 2829 .dig_out_nid = ALC880_DIGOUT_NID, 2830 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), 2831 .channel_mode = alc880_threestack_modes, 2832 .need_dac_fix = 1, 2833 .input_mux = &alc880_capture_source, 2834 }, 2835 [ALC880_TCL_S700] = { 2836 .mixers = { alc880_tcl_s700_mixer }, 2837 .init_verbs = { alc880_volume_init_verbs, 2838 alc880_pin_tcl_S700_init_verbs, 2839 alc880_gpio2_init_verbs }, 2840 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 2841 .dac_nids = alc880_dac_nids, 2842 .hp_nid = 0x03, 2843 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), 2844 .channel_mode = alc880_2_jack_modes, 2845 .input_mux = &alc880_capture_source, 2846 }, 2847 [ALC880_5ST] = { 2848 .mixers = { alc880_three_stack_mixer, 2849 alc880_five_stack_mixer}, 2850 .init_verbs = { alc880_volume_init_verbs, 2851 alc880_pin_5stack_init_verbs }, 2852 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 2853 .dac_nids = alc880_dac_nids, 2854 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes), 2855 .channel_mode = alc880_fivestack_modes, 2856 .input_mux = &alc880_capture_source, 2857 }, 2858 [ALC880_5ST_DIG] = { 2859 .mixers = { alc880_three_stack_mixer, 2860 alc880_five_stack_mixer }, 2861 .init_verbs = { alc880_volume_init_verbs, 2862 alc880_pin_5stack_init_verbs }, 2863 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 2864 .dac_nids = alc880_dac_nids, 2865 .dig_out_nid = ALC880_DIGOUT_NID, 2866 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes), 2867 .channel_mode = alc880_fivestack_modes, 2868 .input_mux = &alc880_capture_source, 2869 }, 2870 [ALC880_6ST] = { 2871 .mixers = { alc880_six_stack_mixer }, 2872 .init_verbs = { alc880_volume_init_verbs, 2873 alc880_pin_6stack_init_verbs }, 2874 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids), 2875 .dac_nids = alc880_6st_dac_nids, 2876 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes), 2877 .channel_mode = alc880_sixstack_modes, 2878 .input_mux = &alc880_6stack_capture_source, 2879 }, 2880 [ALC880_6ST_DIG] = { 2881 .mixers = { alc880_six_stack_mixer }, 2882 .init_verbs = { alc880_volume_init_verbs, 2883 alc880_pin_6stack_init_verbs }, 2884 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids), 2885 .dac_nids = alc880_6st_dac_nids, 2886 .dig_out_nid = ALC880_DIGOUT_NID, 2887 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes), 2888 .channel_mode = alc880_sixstack_modes, 2889 .input_mux = &alc880_6stack_capture_source, 2890 }, 2891 [ALC880_W810] = { 2892 .mixers = { alc880_w810_base_mixer }, 2893 .init_verbs = { alc880_volume_init_verbs, 2894 alc880_pin_w810_init_verbs, 2895 alc880_gpio2_init_verbs }, 2896 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids), 2897 .dac_nids = alc880_w810_dac_nids, 2898 .dig_out_nid = ALC880_DIGOUT_NID, 2899 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes), 2900 .channel_mode = alc880_w810_modes, 2901 .input_mux = &alc880_capture_source, 2902 }, 2903 [ALC880_Z71V] = { 2904 .mixers = { alc880_z71v_mixer }, 2905 .init_verbs = { alc880_volume_init_verbs, 2906 alc880_pin_z71v_init_verbs }, 2907 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids), 2908 .dac_nids = alc880_z71v_dac_nids, 2909 .dig_out_nid = ALC880_DIGOUT_NID, 2910 .hp_nid = 0x03, 2911 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), 2912 .channel_mode = alc880_2_jack_modes, 2913 .input_mux = &alc880_capture_source, 2914 }, 2915 [ALC880_F1734] = { 2916 .mixers = { alc880_f1734_mixer }, 2917 .init_verbs = { alc880_volume_init_verbs, 2918 alc880_pin_f1734_init_verbs }, 2919 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids), 2920 .dac_nids = alc880_f1734_dac_nids, 2921 .hp_nid = 0x02, 2922 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), 2923 .channel_mode = alc880_2_jack_modes, 2924 .input_mux = &alc880_capture_source, 2925 }, 2926 [ALC880_ASUS] = { 2927 .mixers = { alc880_asus_mixer }, 2928 .init_verbs = { alc880_volume_init_verbs, 2929 alc880_pin_asus_init_verbs, 2930 alc880_gpio1_init_verbs }, 2931 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 2932 .dac_nids = alc880_asus_dac_nids, 2933 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), 2934 .channel_mode = alc880_asus_modes, 2935 .need_dac_fix = 1, 2936 .input_mux = &alc880_capture_source, 2937 }, 2938 [ALC880_ASUS_DIG] = { 2939 .mixers = { alc880_asus_mixer }, 2940 .init_verbs = { alc880_volume_init_verbs, 2941 alc880_pin_asus_init_verbs, 2942 alc880_gpio1_init_verbs }, 2943 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 2944 .dac_nids = alc880_asus_dac_nids, 2945 .dig_out_nid = ALC880_DIGOUT_NID, 2946 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), 2947 .channel_mode = alc880_asus_modes, 2948 .need_dac_fix = 1, 2949 .input_mux = &alc880_capture_source, 2950 }, 2951 [ALC880_ASUS_DIG2] = { 2952 .mixers = { alc880_asus_mixer }, 2953 .init_verbs = { alc880_volume_init_verbs, 2954 alc880_pin_asus_init_verbs, 2955 alc880_gpio2_init_verbs }, /* use GPIO2 */ 2956 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 2957 .dac_nids = alc880_asus_dac_nids, 2958 .dig_out_nid = ALC880_DIGOUT_NID, 2959 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), 2960 .channel_mode = alc880_asus_modes, 2961 .need_dac_fix = 1, 2962 .input_mux = &alc880_capture_source, 2963 }, 2964 [ALC880_ASUS_W1V] = { 2965 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer }, 2966 .init_verbs = { alc880_volume_init_verbs, 2967 alc880_pin_asus_init_verbs, 2968 alc880_gpio1_init_verbs }, 2969 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 2970 .dac_nids = alc880_asus_dac_nids, 2971 .dig_out_nid = ALC880_DIGOUT_NID, 2972 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), 2973 .channel_mode = alc880_asus_modes, 2974 .need_dac_fix = 1, 2975 .input_mux = &alc880_capture_source, 2976 }, 2977 [ALC880_UNIWILL_DIG] = { 2978 .mixers = { alc880_asus_mixer, alc880_pcbeep_mixer }, 2979 .init_verbs = { alc880_volume_init_verbs, 2980 alc880_pin_asus_init_verbs }, 2981 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 2982 .dac_nids = alc880_asus_dac_nids, 2983 .dig_out_nid = ALC880_DIGOUT_NID, 2984 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), 2985 .channel_mode = alc880_asus_modes, 2986 .need_dac_fix = 1, 2987 .input_mux = &alc880_capture_source, 2988 }, 2989 [ALC880_UNIWILL] = { 2990 .mixers = { alc880_uniwill_mixer }, 2991 .init_verbs = { alc880_volume_init_verbs, 2992 alc880_uniwill_init_verbs }, 2993 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 2994 .dac_nids = alc880_asus_dac_nids, 2995 .dig_out_nid = ALC880_DIGOUT_NID, 2996 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), 2997 .channel_mode = alc880_threestack_modes, 2998 .need_dac_fix = 1, 2999 .input_mux = &alc880_capture_source, 3000 .unsol_event = alc880_uniwill_unsol_event, 3001 .init_hook = alc880_uniwill_automute, 3002 }, 3003 [ALC880_UNIWILL_P53] = { 3004 .mixers = { alc880_uniwill_p53_mixer }, 3005 .init_verbs = { alc880_volume_init_verbs, 3006 alc880_uniwill_p53_init_verbs }, 3007 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 3008 .dac_nids = alc880_asus_dac_nids, 3009 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes), 3010 .channel_mode = alc880_threestack_modes, 3011 .input_mux = &alc880_capture_source, 3012 .unsol_event = alc880_uniwill_p53_unsol_event, 3013 .init_hook = alc880_uniwill_p53_hp_automute, 3014 }, 3015 [ALC880_FUJITSU] = { 3016 .mixers = { alc880_fujitsu_mixer, 3017 alc880_pcbeep_mixer, }, 3018 .init_verbs = { alc880_volume_init_verbs, 3019 alc880_uniwill_p53_init_verbs, 3020 alc880_beep_init_verbs }, 3021 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 3022 .dac_nids = alc880_dac_nids, 3023 .dig_out_nid = ALC880_DIGOUT_NID, 3024 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), 3025 .channel_mode = alc880_2_jack_modes, 3026 .input_mux = &alc880_capture_source, 3027 .unsol_event = alc880_uniwill_p53_unsol_event, 3028 .init_hook = alc880_uniwill_p53_hp_automute, 3029 }, 3030 [ALC880_CLEVO] = { 3031 .mixers = { alc880_three_stack_mixer }, 3032 .init_verbs = { alc880_volume_init_verbs, 3033 alc880_pin_clevo_init_verbs }, 3034 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 3035 .dac_nids = alc880_dac_nids, 3036 .hp_nid = 0x03, 3037 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), 3038 .channel_mode = alc880_threestack_modes, 3039 .need_dac_fix = 1, 3040 .input_mux = &alc880_capture_source, 3041 }, 3042 [ALC880_LG] = { 3043 .mixers = { alc880_lg_mixer }, 3044 .init_verbs = { alc880_volume_init_verbs, 3045 alc880_lg_init_verbs }, 3046 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids), 3047 .dac_nids = alc880_lg_dac_nids, 3048 .dig_out_nid = ALC880_DIGOUT_NID, 3049 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes), 3050 .channel_mode = alc880_lg_ch_modes, 3051 .need_dac_fix = 1, 3052 .input_mux = &alc880_lg_capture_source, 3053 .unsol_event = alc880_lg_unsol_event, 3054 .init_hook = alc880_lg_automute, 3055 #ifdef CONFIG_SND_HDA_POWER_SAVE 3056 .loopbacks = alc880_lg_loopbacks, 3057 #endif 3058 }, 3059 [ALC880_LG_LW] = { 3060 .mixers = { alc880_lg_lw_mixer }, 3061 .init_verbs = { alc880_volume_init_verbs, 3062 alc880_lg_lw_init_verbs }, 3063 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 3064 .dac_nids = alc880_dac_nids, 3065 .dig_out_nid = ALC880_DIGOUT_NID, 3066 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes), 3067 .channel_mode = alc880_lg_lw_modes, 3068 .input_mux = &alc880_lg_lw_capture_source, 3069 .unsol_event = alc880_lg_lw_unsol_event, 3070 .init_hook = alc880_lg_lw_automute, 3071 }, 3072 #ifdef CONFIG_SND_DEBUG 3073 [ALC880_TEST] = { 3074 .mixers = { alc880_test_mixer }, 3075 .init_verbs = { alc880_test_init_verbs }, 3076 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids), 3077 .dac_nids = alc880_test_dac_nids, 3078 .dig_out_nid = ALC880_DIGOUT_NID, 3079 .num_channel_mode = ARRAY_SIZE(alc880_test_modes), 3080 .channel_mode = alc880_test_modes, 3081 .input_mux = &alc880_test_capture_source, 3082 }, 3083 #endif 3084 }; 3085 3086 /* 3087 * Automatic parse of I/O pins from the BIOS configuration 3088 */ 3089 3090 #define NUM_CONTROL_ALLOC 32 3091 #define NUM_VERB_ALLOC 32 3092 3093 enum { 3094 ALC_CTL_WIDGET_VOL, 3095 ALC_CTL_WIDGET_MUTE, 3096 ALC_CTL_BIND_MUTE, 3097 }; 3098 static struct snd_kcontrol_new alc880_control_templates[] = { 3099 HDA_CODEC_VOLUME(NULL, 0, 0, 0), 3100 HDA_CODEC_MUTE(NULL, 0, 0, 0), 3101 HDA_BIND_MUTE(NULL, 0, 0, 0), 3102 }; 3103 3104 /* add dynamic controls */ 3105 static int add_control(struct alc_spec *spec, int type, const char *name, 3106 unsigned long val) 3107 { 3108 struct snd_kcontrol_new *knew; 3109 3110 if (spec->num_kctl_used >= spec->num_kctl_alloc) { 3111 int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC; 3112 3113 /* array + terminator */ 3114 knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL); 3115 if (!knew) 3116 return -ENOMEM; 3117 if (spec->kctl_alloc) { 3118 memcpy(knew, spec->kctl_alloc, 3119 sizeof(*knew) * spec->num_kctl_alloc); 3120 kfree(spec->kctl_alloc); 3121 } 3122 spec->kctl_alloc = knew; 3123 spec->num_kctl_alloc = num; 3124 } 3125 3126 knew = &spec->kctl_alloc[spec->num_kctl_used]; 3127 *knew = alc880_control_templates[type]; 3128 knew->name = kstrdup(name, GFP_KERNEL); 3129 if (!knew->name) 3130 return -ENOMEM; 3131 knew->private_value = val; 3132 spec->num_kctl_used++; 3133 return 0; 3134 } 3135 3136 #define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17) 3137 #define alc880_fixed_pin_idx(nid) ((nid) - 0x14) 3138 #define alc880_is_multi_pin(nid) ((nid) >= 0x18) 3139 #define alc880_multi_pin_idx(nid) ((nid) - 0x18) 3140 #define alc880_is_input_pin(nid) ((nid) >= 0x18) 3141 #define alc880_input_pin_idx(nid) ((nid) - 0x18) 3142 #define alc880_idx_to_dac(nid) ((nid) + 0x02) 3143 #define alc880_dac_to_idx(nid) ((nid) - 0x02) 3144 #define alc880_idx_to_mixer(nid) ((nid) + 0x0c) 3145 #define alc880_idx_to_selector(nid) ((nid) + 0x10) 3146 #define ALC880_PIN_CD_NID 0x1c 3147 3148 /* fill in the dac_nids table from the parsed pin configuration */ 3149 static int alc880_auto_fill_dac_nids(struct alc_spec *spec, 3150 const struct auto_pin_cfg *cfg) 3151 { 3152 hda_nid_t nid; 3153 int assigned[4]; 3154 int i, j; 3155 3156 memset(assigned, 0, sizeof(assigned)); 3157 spec->multiout.dac_nids = spec->private_dac_nids; 3158 3159 /* check the pins hardwired to audio widget */ 3160 for (i = 0; i < cfg->line_outs; i++) { 3161 nid = cfg->line_out_pins[i]; 3162 if (alc880_is_fixed_pin(nid)) { 3163 int idx = alc880_fixed_pin_idx(nid); 3164 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx); 3165 assigned[idx] = 1; 3166 } 3167 } 3168 /* left pins can be connect to any audio widget */ 3169 for (i = 0; i < cfg->line_outs; i++) { 3170 nid = cfg->line_out_pins[i]; 3171 if (alc880_is_fixed_pin(nid)) 3172 continue; 3173 /* search for an empty channel */ 3174 for (j = 0; j < cfg->line_outs; j++) { 3175 if (!assigned[j]) { 3176 spec->multiout.dac_nids[i] = 3177 alc880_idx_to_dac(j); 3178 assigned[j] = 1; 3179 break; 3180 } 3181 } 3182 } 3183 spec->multiout.num_dacs = cfg->line_outs; 3184 return 0; 3185 } 3186 3187 /* add playback controls from the parsed DAC table */ 3188 static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec, 3189 const struct auto_pin_cfg *cfg) 3190 { 3191 char name[32]; 3192 static const char *chname[4] = { 3193 "Front", "Surround", NULL /*CLFE*/, "Side" 3194 }; 3195 hda_nid_t nid; 3196 int i, err; 3197 3198 for (i = 0; i < cfg->line_outs; i++) { 3199 if (!spec->multiout.dac_nids[i]) 3200 continue; 3201 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i])); 3202 if (i == 2) { 3203 /* Center/LFE */ 3204 err = add_control(spec, ALC_CTL_WIDGET_VOL, 3205 "Center Playback Volume", 3206 HDA_COMPOSE_AMP_VAL(nid, 1, 0, 3207 HDA_OUTPUT)); 3208 if (err < 0) 3209 return err; 3210 err = add_control(spec, ALC_CTL_WIDGET_VOL, 3211 "LFE Playback Volume", 3212 HDA_COMPOSE_AMP_VAL(nid, 2, 0, 3213 HDA_OUTPUT)); 3214 if (err < 0) 3215 return err; 3216 err = add_control(spec, ALC_CTL_BIND_MUTE, 3217 "Center Playback Switch", 3218 HDA_COMPOSE_AMP_VAL(nid, 1, 2, 3219 HDA_INPUT)); 3220 if (err < 0) 3221 return err; 3222 err = add_control(spec, ALC_CTL_BIND_MUTE, 3223 "LFE Playback Switch", 3224 HDA_COMPOSE_AMP_VAL(nid, 2, 2, 3225 HDA_INPUT)); 3226 if (err < 0) 3227 return err; 3228 } else { 3229 sprintf(name, "%s Playback Volume", chname[i]); 3230 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, 3231 HDA_COMPOSE_AMP_VAL(nid, 3, 0, 3232 HDA_OUTPUT)); 3233 if (err < 0) 3234 return err; 3235 sprintf(name, "%s Playback Switch", chname[i]); 3236 err = add_control(spec, ALC_CTL_BIND_MUTE, name, 3237 HDA_COMPOSE_AMP_VAL(nid, 3, 2, 3238 HDA_INPUT)); 3239 if (err < 0) 3240 return err; 3241 } 3242 } 3243 return 0; 3244 } 3245 3246 /* add playback controls for speaker and HP outputs */ 3247 static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin, 3248 const char *pfx) 3249 { 3250 hda_nid_t nid; 3251 int err; 3252 char name[32]; 3253 3254 if (!pin) 3255 return 0; 3256 3257 if (alc880_is_fixed_pin(pin)) { 3258 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); 3259 /* specify the DAC as the extra output */ 3260 if (!spec->multiout.hp_nid) 3261 spec->multiout.hp_nid = nid; 3262 else 3263 spec->multiout.extra_out_nid[0] = nid; 3264 /* control HP volume/switch on the output mixer amp */ 3265 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin)); 3266 sprintf(name, "%s Playback Volume", pfx); 3267 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, 3268 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); 3269 if (err < 0) 3270 return err; 3271 sprintf(name, "%s Playback Switch", pfx); 3272 err = add_control(spec, ALC_CTL_BIND_MUTE, name, 3273 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT)); 3274 if (err < 0) 3275 return err; 3276 } else if (alc880_is_multi_pin(pin)) { 3277 /* set manual connection */ 3278 /* we have only a switch on HP-out PIN */ 3279 sprintf(name, "%s Playback Switch", pfx); 3280 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, 3281 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); 3282 if (err < 0) 3283 return err; 3284 } 3285 return 0; 3286 } 3287 3288 /* create input playback/capture controls for the given pin */ 3289 static int new_analog_input(struct alc_spec *spec, hda_nid_t pin, 3290 const char *ctlname, 3291 int idx, hda_nid_t mix_nid) 3292 { 3293 char name[32]; 3294 int err; 3295 3296 sprintf(name, "%s Playback Volume", ctlname); 3297 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, 3298 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT)); 3299 if (err < 0) 3300 return err; 3301 sprintf(name, "%s Playback Switch", ctlname); 3302 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, 3303 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT)); 3304 if (err < 0) 3305 return err; 3306 return 0; 3307 } 3308 3309 /* create playback/capture controls for input pins */ 3310 static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec, 3311 const struct auto_pin_cfg *cfg) 3312 { 3313 struct hda_input_mux *imux = &spec->private_imux; 3314 int i, err, idx; 3315 3316 for (i = 0; i < AUTO_PIN_LAST; i++) { 3317 if (alc880_is_input_pin(cfg->input_pins[i])) { 3318 idx = alc880_input_pin_idx(cfg->input_pins[i]); 3319 err = new_analog_input(spec, cfg->input_pins[i], 3320 auto_pin_cfg_labels[i], 3321 idx, 0x0b); 3322 if (err < 0) 3323 return err; 3324 imux->items[imux->num_items].label = 3325 auto_pin_cfg_labels[i]; 3326 imux->items[imux->num_items].index = 3327 alc880_input_pin_idx(cfg->input_pins[i]); 3328 imux->num_items++; 3329 } 3330 } 3331 return 0; 3332 } 3333 3334 static void alc880_auto_set_output_and_unmute(struct hda_codec *codec, 3335 hda_nid_t nid, int pin_type, 3336 int dac_idx) 3337 { 3338 /* set as output */ 3339 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 3340 pin_type); 3341 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, 3342 AMP_OUT_UNMUTE); 3343 /* need the manual connection? */ 3344 if (alc880_is_multi_pin(nid)) { 3345 struct alc_spec *spec = codec->spec; 3346 int idx = alc880_multi_pin_idx(nid); 3347 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0, 3348 AC_VERB_SET_CONNECT_SEL, 3349 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx])); 3350 } 3351 } 3352 3353 static int get_pin_type(int line_out_type) 3354 { 3355 if (line_out_type == AUTO_PIN_HP_OUT) 3356 return PIN_HP; 3357 else 3358 return PIN_OUT; 3359 } 3360 3361 static void alc880_auto_init_multi_out(struct hda_codec *codec) 3362 { 3363 struct alc_spec *spec = codec->spec; 3364 int i; 3365 3366 alc_subsystem_id(codec, 0x15, 0x1b, 0x14); 3367 for (i = 0; i < spec->autocfg.line_outs; i++) { 3368 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 3369 int pin_type = get_pin_type(spec->autocfg.line_out_type); 3370 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i); 3371 } 3372 } 3373 3374 static void alc880_auto_init_extra_out(struct hda_codec *codec) 3375 { 3376 struct alc_spec *spec = codec->spec; 3377 hda_nid_t pin; 3378 3379 pin = spec->autocfg.speaker_pins[0]; 3380 if (pin) /* connect to front */ 3381 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0); 3382 pin = spec->autocfg.hp_pins[0]; 3383 if (pin) /* connect to front */ 3384 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); 3385 } 3386 3387 static void alc880_auto_init_analog_input(struct hda_codec *codec) 3388 { 3389 struct alc_spec *spec = codec->spec; 3390 int i; 3391 3392 for (i = 0; i < AUTO_PIN_LAST; i++) { 3393 hda_nid_t nid = spec->autocfg.input_pins[i]; 3394 if (alc880_is_input_pin(nid)) { 3395 snd_hda_codec_write(codec, nid, 0, 3396 AC_VERB_SET_PIN_WIDGET_CONTROL, 3397 i <= AUTO_PIN_FRONT_MIC ? 3398 PIN_VREF80 : PIN_IN); 3399 if (nid != ALC880_PIN_CD_NID) 3400 snd_hda_codec_write(codec, nid, 0, 3401 AC_VERB_SET_AMP_GAIN_MUTE, 3402 AMP_OUT_MUTE); 3403 } 3404 } 3405 } 3406 3407 /* parse the BIOS configuration and set up the alc_spec */ 3408 /* return 1 if successful, 0 if the proper config is not found, 3409 * or a negative error code 3410 */ 3411 static int alc880_parse_auto_config(struct hda_codec *codec) 3412 { 3413 struct alc_spec *spec = codec->spec; 3414 int err; 3415 static hda_nid_t alc880_ignore[] = { 0x1d, 0 }; 3416 3417 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 3418 alc880_ignore); 3419 if (err < 0) 3420 return err; 3421 if (!spec->autocfg.line_outs) 3422 return 0; /* can't find valid BIOS pin config */ 3423 3424 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); 3425 if (err < 0) 3426 return err; 3427 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg); 3428 if (err < 0) 3429 return err; 3430 err = alc880_auto_create_extra_out(spec, 3431 spec->autocfg.speaker_pins[0], 3432 "Speaker"); 3433 if (err < 0) 3434 return err; 3435 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0], 3436 "Headphone"); 3437 if (err < 0) 3438 return err; 3439 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg); 3440 if (err < 0) 3441 return err; 3442 3443 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 3444 3445 if (spec->autocfg.dig_out_pin) 3446 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID; 3447 if (spec->autocfg.dig_in_pin) 3448 spec->dig_in_nid = ALC880_DIGIN_NID; 3449 3450 if (spec->kctl_alloc) 3451 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 3452 3453 spec->init_verbs[spec->num_init_verbs++] = alc880_volume_init_verbs; 3454 3455 spec->num_mux_defs = 1; 3456 spec->input_mux = &spec->private_imux; 3457 3458 return 1; 3459 } 3460 3461 /* additional initialization for auto-configuration model */ 3462 static void alc880_auto_init(struct hda_codec *codec) 3463 { 3464 alc880_auto_init_multi_out(codec); 3465 alc880_auto_init_extra_out(codec); 3466 alc880_auto_init_analog_input(codec); 3467 } 3468 3469 /* 3470 * OK, here we have finally the patch for ALC880 3471 */ 3472 3473 static int patch_alc880(struct hda_codec *codec) 3474 { 3475 struct alc_spec *spec; 3476 int board_config; 3477 int err; 3478 3479 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 3480 if (spec == NULL) 3481 return -ENOMEM; 3482 3483 codec->spec = spec; 3484 3485 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST, 3486 alc880_models, 3487 alc880_cfg_tbl); 3488 if (board_config < 0) { 3489 printk(KERN_INFO "hda_codec: Unknown model for ALC880, " 3490 "trying auto-probe from BIOS...\n"); 3491 board_config = ALC880_AUTO; 3492 } 3493 3494 if (board_config == ALC880_AUTO) { 3495 /* automatic parse from the BIOS config */ 3496 err = alc880_parse_auto_config(codec); 3497 if (err < 0) { 3498 alc_free(codec); 3499 return err; 3500 } else if (!err) { 3501 printk(KERN_INFO 3502 "hda_codec: Cannot set up configuration " 3503 "from BIOS. Using 3-stack mode...\n"); 3504 board_config = ALC880_3ST; 3505 } 3506 } 3507 3508 if (board_config != ALC880_AUTO) 3509 setup_preset(spec, &alc880_presets[board_config]); 3510 3511 spec->stream_name_analog = "ALC880 Analog"; 3512 spec->stream_analog_playback = &alc880_pcm_analog_playback; 3513 spec->stream_analog_capture = &alc880_pcm_analog_capture; 3514 3515 spec->stream_name_digital = "ALC880 Digital"; 3516 spec->stream_digital_playback = &alc880_pcm_digital_playback; 3517 spec->stream_digital_capture = &alc880_pcm_digital_capture; 3518 3519 if (!spec->adc_nids && spec->input_mux) { 3520 /* check whether NID 0x07 is valid */ 3521 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]); 3522 /* get type */ 3523 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; 3524 if (wcap != AC_WID_AUD_IN) { 3525 spec->adc_nids = alc880_adc_nids_alt; 3526 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt); 3527 spec->mixers[spec->num_mixers] = 3528 alc880_capture_alt_mixer; 3529 spec->num_mixers++; 3530 } else { 3531 spec->adc_nids = alc880_adc_nids; 3532 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids); 3533 spec->mixers[spec->num_mixers] = alc880_capture_mixer; 3534 spec->num_mixers++; 3535 } 3536 } 3537 3538 codec->patch_ops = alc_patch_ops; 3539 if (board_config == ALC880_AUTO) 3540 spec->init_hook = alc880_auto_init; 3541 #ifdef CONFIG_SND_HDA_POWER_SAVE 3542 if (!spec->loopback.amplist) 3543 spec->loopback.amplist = alc880_loopbacks; 3544 #endif 3545 3546 return 0; 3547 } 3548 3549 3550 /* 3551 * ALC260 support 3552 */ 3553 3554 static hda_nid_t alc260_dac_nids[1] = { 3555 /* front */ 3556 0x02, 3557 }; 3558 3559 static hda_nid_t alc260_adc_nids[1] = { 3560 /* ADC0 */ 3561 0x04, 3562 }; 3563 3564 static hda_nid_t alc260_adc_nids_alt[1] = { 3565 /* ADC1 */ 3566 0x05, 3567 }; 3568 3569 static hda_nid_t alc260_hp_adc_nids[2] = { 3570 /* ADC1, 0 */ 3571 0x05, 0x04 3572 }; 3573 3574 /* NIDs used when simultaneous access to both ADCs makes sense. Note that 3575 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC. 3576 */ 3577 static hda_nid_t alc260_dual_adc_nids[2] = { 3578 /* ADC0, ADC1 */ 3579 0x04, 0x05 3580 }; 3581 3582 #define ALC260_DIGOUT_NID 0x03 3583 #define ALC260_DIGIN_NID 0x06 3584 3585 static struct hda_input_mux alc260_capture_source = { 3586 .num_items = 4, 3587 .items = { 3588 { "Mic", 0x0 }, 3589 { "Front Mic", 0x1 }, 3590 { "Line", 0x2 }, 3591 { "CD", 0x4 }, 3592 }, 3593 }; 3594 3595 /* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack, 3596 * headphone jack and the internal CD lines since these are the only pins at 3597 * which audio can appear. For flexibility, also allow the option of 3598 * recording the mixer output on the second ADC (ADC0 doesn't have a 3599 * connection to the mixer output). 3600 */ 3601 static struct hda_input_mux alc260_fujitsu_capture_sources[2] = { 3602 { 3603 .num_items = 3, 3604 .items = { 3605 { "Mic/Line", 0x0 }, 3606 { "CD", 0x4 }, 3607 { "Headphone", 0x2 }, 3608 }, 3609 }, 3610 { 3611 .num_items = 4, 3612 .items = { 3613 { "Mic/Line", 0x0 }, 3614 { "CD", 0x4 }, 3615 { "Headphone", 0x2 }, 3616 { "Mixer", 0x5 }, 3617 }, 3618 }, 3619 3620 }; 3621 3622 /* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to 3623 * the Fujitsu S702x, but jacks are marked differently. 3624 */ 3625 static struct hda_input_mux alc260_acer_capture_sources[2] = { 3626 { 3627 .num_items = 4, 3628 .items = { 3629 { "Mic", 0x0 }, 3630 { "Line", 0x2 }, 3631 { "CD", 0x4 }, 3632 { "Headphone", 0x5 }, 3633 }, 3634 }, 3635 { 3636 .num_items = 5, 3637 .items = { 3638 { "Mic", 0x0 }, 3639 { "Line", 0x2 }, 3640 { "CD", 0x4 }, 3641 { "Headphone", 0x6 }, 3642 { "Mixer", 0x5 }, 3643 }, 3644 }, 3645 }; 3646 /* 3647 * This is just place-holder, so there's something for alc_build_pcms to look 3648 * at when it calculates the maximum number of channels. ALC260 has no mixer 3649 * element which allows changing the channel mode, so the verb list is 3650 * never used. 3651 */ 3652 static struct hda_channel_mode alc260_modes[1] = { 3653 { 2, NULL }, 3654 }; 3655 3656 3657 /* Mixer combinations 3658 * 3659 * basic: base_output + input + pc_beep + capture 3660 * HP: base_output + input + capture_alt 3661 * HP_3013: hp_3013 + input + capture 3662 * fujitsu: fujitsu + capture 3663 * acer: acer + capture 3664 */ 3665 3666 static struct snd_kcontrol_new alc260_base_output_mixer[] = { 3667 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT), 3668 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT), 3669 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT), 3670 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT), 3671 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), 3672 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT), 3673 { } /* end */ 3674 }; 3675 3676 static struct snd_kcontrol_new alc260_input_mixer[] = { 3677 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), 3678 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), 3679 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), 3680 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT), 3681 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), 3682 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT), 3683 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT), 3684 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT), 3685 { } /* end */ 3686 }; 3687 3688 static struct snd_kcontrol_new alc260_pc_beep_mixer[] = { 3689 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT), 3690 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT), 3691 { } /* end */ 3692 }; 3693 3694 static struct snd_kcontrol_new alc260_hp_3013_mixer[] = { 3695 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT), 3696 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT), 3697 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT), 3698 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT), 3699 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT), 3700 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 3701 HDA_CODEC_VOLUME_MONO("iSpeaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), 3702 HDA_CODEC_MUTE_MONO("iSpeaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT), 3703 { } /* end */ 3704 }; 3705 3706 /* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12, 3707 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10. 3708 */ 3709 static struct snd_kcontrol_new alc260_fujitsu_mixer[] = { 3710 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT), 3711 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT), 3712 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT), 3713 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), 3714 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), 3715 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT), 3716 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT), 3717 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN), 3718 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT), 3719 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT), 3720 HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT), 3721 HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x09, 2, HDA_INPUT), 3722 { } /* end */ 3723 }; 3724 3725 /* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current 3726 * versions of the ALC260 don't act on requests to enable mic bias from NID 3727 * 0x0f (used to drive the headphone jack in these laptops). The ALC260 3728 * datasheet doesn't mention this restriction. At this stage it's not clear 3729 * whether this behaviour is intentional or is a hardware bug in chip 3730 * revisions available in early 2006. Therefore for now allow the 3731 * "Headphone Jack Mode" control to span all choices, but if it turns out 3732 * that the lack of mic bias for this NID is intentional we could change the 3733 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS. 3734 * 3735 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006 3736 * don't appear to make the mic bias available from the "line" jack, even 3737 * though the NID used for this jack (0x14) can supply it. The theory is 3738 * that perhaps Acer have included blocking capacitors between the ALC260 3739 * and the output jack. If this turns out to be the case for all such 3740 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT 3741 * to ALC_PIN_DIR_INOUT_NOMICBIAS. 3742 * 3743 * The C20x Tablet series have a mono internal speaker which is controlled 3744 * via the chip's Mono sum widget and pin complex, so include the necessary 3745 * controls for such models. On models without a "mono speaker" the control 3746 * won't do anything. 3747 */ 3748 static struct snd_kcontrol_new alc260_acer_mixer[] = { 3749 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), 3750 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT), 3751 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT), 3752 HDA_CODEC_VOLUME_MONO("Mono Speaker Playback Volume", 0x0a, 1, 0x0, 3753 HDA_OUTPUT), 3754 HDA_BIND_MUTE_MONO("Mono Speaker Playback Switch", 0x0a, 1, 2, 3755 HDA_INPUT), 3756 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), 3757 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), 3758 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), 3759 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT), 3760 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN), 3761 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), 3762 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT), 3763 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT), 3764 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT), 3765 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT), 3766 { } /* end */ 3767 }; 3768 3769 /* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12, 3770 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17. 3771 */ 3772 static struct snd_kcontrol_new alc260_will_mixer[] = { 3773 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), 3774 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT), 3775 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), 3776 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT), 3777 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN), 3778 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), 3779 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT), 3780 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT), 3781 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), 3782 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), 3783 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT), 3784 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT), 3785 { } /* end */ 3786 }; 3787 3788 /* Replacer 672V ALC260 pin usage: Mic jack = 0x12, 3789 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f. 3790 */ 3791 static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = { 3792 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), 3793 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT), 3794 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), 3795 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT), 3796 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN), 3797 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT), 3798 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT), 3799 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), 3800 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT), 3801 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT), 3802 { } /* end */ 3803 }; 3804 3805 /* capture mixer elements */ 3806 static struct snd_kcontrol_new alc260_capture_mixer[] = { 3807 HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT), 3808 HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT), 3809 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x05, 0x0, HDA_INPUT), 3810 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x05, 0x0, HDA_INPUT), 3811 { 3812 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 3813 /* The multiple "Capture Source" controls confuse alsamixer 3814 * So call somewhat different.. 3815 * FIXME: the controls appear in the "playback" view! 3816 */ 3817 /* .name = "Capture Source", */ 3818 .name = "Input Source", 3819 .count = 2, 3820 .info = alc_mux_enum_info, 3821 .get = alc_mux_enum_get, 3822 .put = alc_mux_enum_put, 3823 }, 3824 { } /* end */ 3825 }; 3826 3827 static struct snd_kcontrol_new alc260_capture_alt_mixer[] = { 3828 HDA_CODEC_VOLUME("Capture Volume", 0x05, 0x0, HDA_INPUT), 3829 HDA_CODEC_MUTE("Capture Switch", 0x05, 0x0, HDA_INPUT), 3830 { 3831 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 3832 /* The multiple "Capture Source" controls confuse alsamixer 3833 * So call somewhat different.. 3834 * FIXME: the controls appear in the "playback" view! 3835 */ 3836 /* .name = "Capture Source", */ 3837 .name = "Input Source", 3838 .count = 1, 3839 .info = alc_mux_enum_info, 3840 .get = alc_mux_enum_get, 3841 .put = alc_mux_enum_put, 3842 }, 3843 { } /* end */ 3844 }; 3845 3846 /* 3847 * initialization verbs 3848 */ 3849 static struct hda_verb alc260_init_verbs[] = { 3850 /* Line In pin widget for input */ 3851 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3852 /* CD pin widget for input */ 3853 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3854 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 3855 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3856 /* Mic2 (front panel) pin widget for input and vref at 80% */ 3857 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3858 /* LINE-2 is used for line-out in rear */ 3859 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3860 /* select line-out */ 3861 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00}, 3862 /* LINE-OUT pin */ 3863 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3864 /* enable HP */ 3865 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3866 /* enable Mono */ 3867 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3868 /* mute capture amp left and right */ 3869 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3870 /* set connection select to line in (default select for this ADC) */ 3871 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02}, 3872 /* mute capture amp left and right */ 3873 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3874 /* set connection select to line in (default select for this ADC) */ 3875 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02}, 3876 /* set vol=0 Line-Out mixer amp left and right */ 3877 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3878 /* unmute pin widget amp left and right (no gain on this amp) */ 3879 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3880 /* set vol=0 HP mixer amp left and right */ 3881 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3882 /* unmute pin widget amp left and right (no gain on this amp) */ 3883 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3884 /* set vol=0 Mono mixer amp left and right */ 3885 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3886 /* unmute pin widget amp left and right (no gain on this amp) */ 3887 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3888 /* unmute LINE-2 out pin */ 3889 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3890 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & 3891 * Line In 2 = 0x03 3892 */ 3893 /* mute analog inputs */ 3894 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3895 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 3896 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 3897 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 3898 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 3899 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */ 3900 /* mute Front out path */ 3901 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3902 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 3903 /* mute Headphone out path */ 3904 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3905 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 3906 /* mute Mono out path */ 3907 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3908 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 3909 { } 3910 }; 3911 3912 #if 0 /* should be identical with alc260_init_verbs? */ 3913 static struct hda_verb alc260_hp_init_verbs[] = { 3914 /* Headphone and output */ 3915 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 3916 /* mono output */ 3917 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 3918 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 3919 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 3920 /* Mic2 (front panel) pin widget for input and vref at 80% */ 3921 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 3922 /* Line In pin widget for input */ 3923 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 3924 /* Line-2 pin widget for output */ 3925 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 3926 /* CD pin widget for input */ 3927 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 3928 /* unmute amp left and right */ 3929 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000}, 3930 /* set connection select to line in (default select for this ADC) */ 3931 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02}, 3932 /* unmute Line-Out mixer amp left and right (volume = 0) */ 3933 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 3934 /* mute pin widget amp left and right (no gain on this amp) */ 3935 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 3936 /* unmute HP mixer amp left and right (volume = 0) */ 3937 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 3938 /* mute pin widget amp left and right (no gain on this amp) */ 3939 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 3940 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & 3941 * Line In 2 = 0x03 3942 */ 3943 /* mute analog inputs */ 3944 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3945 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 3946 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 3947 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 3948 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 3949 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */ 3950 /* Unmute Front out path */ 3951 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 3952 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 3953 /* Unmute Headphone out path */ 3954 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 3955 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 3956 /* Unmute Mono out path */ 3957 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 3958 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 3959 { } 3960 }; 3961 #endif 3962 3963 static struct hda_verb alc260_hp_3013_init_verbs[] = { 3964 /* Line out and output */ 3965 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 3966 /* mono output */ 3967 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 3968 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 3969 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 3970 /* Mic2 (front panel) pin widget for input and vref at 80% */ 3971 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 3972 /* Line In pin widget for input */ 3973 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 3974 /* Headphone pin widget for output */ 3975 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 3976 /* CD pin widget for input */ 3977 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 3978 /* unmute amp left and right */ 3979 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000}, 3980 /* set connection select to line in (default select for this ADC) */ 3981 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02}, 3982 /* unmute Line-Out mixer amp left and right (volume = 0) */ 3983 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 3984 /* mute pin widget amp left and right (no gain on this amp) */ 3985 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 3986 /* unmute HP mixer amp left and right (volume = 0) */ 3987 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 3988 /* mute pin widget amp left and right (no gain on this amp) */ 3989 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 3990 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & 3991 * Line In 2 = 0x03 3992 */ 3993 /* mute analog inputs */ 3994 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3995 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 3996 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 3997 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 3998 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 3999 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */ 4000 /* Unmute Front out path */ 4001 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 4002 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 4003 /* Unmute Headphone out path */ 4004 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 4005 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 4006 /* Unmute Mono out path */ 4007 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 4008 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 4009 { } 4010 }; 4011 4012 /* Initialisation sequence for ALC260 as configured in Fujitsu S702x 4013 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD 4014 * audio = 0x16, internal speaker = 0x10. 4015 */ 4016 static struct hda_verb alc260_fujitsu_init_verbs[] = { 4017 /* Disable all GPIOs */ 4018 {0x01, AC_VERB_SET_GPIO_MASK, 0}, 4019 /* Internal speaker is connected to headphone pin */ 4020 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 4021 /* Headphone/Line-out jack connects to Line1 pin; make it an output */ 4022 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4023 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */ 4024 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 4025 /* Ensure all other unused pins are disabled and muted. */ 4026 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 4027 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4028 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 4029 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4030 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 4031 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4032 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 4033 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4034 4035 /* Disable digital (SPDIF) pins */ 4036 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0}, 4037 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0}, 4038 4039 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus 4040 * when acting as an output. 4041 */ 4042 {0x0d, AC_VERB_SET_CONNECT_SEL, 0}, 4043 4044 /* Start with output sum widgets muted and their output gains at min */ 4045 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4046 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4047 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4048 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4049 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4050 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4051 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4052 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4053 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4054 4055 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */ 4056 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4057 /* Unmute Line1 pin widget output buffer since it starts as an output. 4058 * If the pin mode is changed by the user the pin mode control will 4059 * take care of enabling the pin's input/output buffers as needed. 4060 * Therefore there's no need to enable the input buffer at this 4061 * stage. 4062 */ 4063 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4064 /* Unmute input buffer of pin widget used for Line-in (no equiv 4065 * mixer ctrl) 4066 */ 4067 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4068 4069 /* Mute capture amp left and right */ 4070 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4071 /* Set ADC connection select to match default mixer setting - line 4072 * in (on mic1 pin) 4073 */ 4074 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, 4075 4076 /* Do the same for the second ADC: mute capture input amp and 4077 * set ADC connection to line in (on mic1 pin) 4078 */ 4079 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4080 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, 4081 4082 /* Mute all inputs to mixer widget (even unconnected ones) */ 4083 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */ 4084 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */ 4085 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */ 4086 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */ 4087 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */ 4088 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */ 4089 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */ 4090 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */ 4091 4092 { } 4093 }; 4094 4095 /* Initialisation sequence for ALC260 as configured in Acer TravelMate and 4096 * similar laptops (adapted from Fujitsu init verbs). 4097 */ 4098 static struct hda_verb alc260_acer_init_verbs[] = { 4099 /* On TravelMate laptops, GPIO 0 enables the internal speaker and 4100 * the headphone jack. Turn this on and rely on the standard mute 4101 * methods whenever the user wants to turn these outputs off. 4102 */ 4103 {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, 4104 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, 4105 {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, 4106 /* Internal speaker/Headphone jack is connected to Line-out pin */ 4107 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 4108 /* Internal microphone/Mic jack is connected to Mic1 pin */ 4109 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, 4110 /* Line In jack is connected to Line1 pin */ 4111 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 4112 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */ 4113 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 4114 /* Ensure all other unused pins are disabled and muted. */ 4115 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 4116 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4117 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 4118 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4119 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 4120 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4121 /* Disable digital (SPDIF) pins */ 4122 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0}, 4123 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0}, 4124 4125 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum 4126 * bus when acting as outputs. 4127 */ 4128 {0x0b, AC_VERB_SET_CONNECT_SEL, 0}, 4129 {0x0d, AC_VERB_SET_CONNECT_SEL, 0}, 4130 4131 /* Start with output sum widgets muted and their output gains at min */ 4132 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4133 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4134 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4135 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4136 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4137 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4138 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4139 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4140 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4141 4142 /* Unmute Line-out pin widget amp left and right 4143 * (no equiv mixer ctrl) 4144 */ 4145 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4146 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */ 4147 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4148 /* Unmute Mic1 and Line1 pin widget input buffers since they start as 4149 * inputs. If the pin mode is changed by the user the pin mode control 4150 * will take care of enabling the pin's input/output buffers as needed. 4151 * Therefore there's no need to enable the input buffer at this 4152 * stage. 4153 */ 4154 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4155 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4156 4157 /* Mute capture amp left and right */ 4158 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4159 /* Set ADC connection select to match default mixer setting - mic 4160 * (on mic1 pin) 4161 */ 4162 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, 4163 4164 /* Do similar with the second ADC: mute capture input amp and 4165 * set ADC connection to mic to match ALSA's default state. 4166 */ 4167 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4168 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, 4169 4170 /* Mute all inputs to mixer widget (even unconnected ones) */ 4171 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */ 4172 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */ 4173 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */ 4174 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */ 4175 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */ 4176 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */ 4177 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */ 4178 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */ 4179 4180 { } 4181 }; 4182 4183 static struct hda_verb alc260_will_verbs[] = { 4184 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 4185 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00}, 4186 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00}, 4187 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02}, 4188 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07}, 4189 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040}, 4190 {} 4191 }; 4192 4193 static struct hda_verb alc260_replacer_672v_verbs[] = { 4194 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02}, 4195 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07}, 4196 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050}, 4197 4198 {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, 4199 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, 4200 {0x01, AC_VERB_SET_GPIO_DATA, 0x00}, 4201 4202 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 4203 {} 4204 }; 4205 4206 /* toggle speaker-output according to the hp-jack state */ 4207 static void alc260_replacer_672v_automute(struct hda_codec *codec) 4208 { 4209 unsigned int present; 4210 4211 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */ 4212 present = snd_hda_codec_read(codec, 0x0f, 0, 4213 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 4214 if (present) { 4215 snd_hda_codec_write_cache(codec, 0x01, 0, 4216 AC_VERB_SET_GPIO_DATA, 1); 4217 snd_hda_codec_write_cache(codec, 0x0f, 0, 4218 AC_VERB_SET_PIN_WIDGET_CONTROL, 4219 PIN_HP); 4220 } else { 4221 snd_hda_codec_write_cache(codec, 0x01, 0, 4222 AC_VERB_SET_GPIO_DATA, 0); 4223 snd_hda_codec_write_cache(codec, 0x0f, 0, 4224 AC_VERB_SET_PIN_WIDGET_CONTROL, 4225 PIN_OUT); 4226 } 4227 } 4228 4229 static void alc260_replacer_672v_unsol_event(struct hda_codec *codec, 4230 unsigned int res) 4231 { 4232 if ((res >> 26) == ALC880_HP_EVENT) 4233 alc260_replacer_672v_automute(codec); 4234 } 4235 4236 /* Test configuration for debugging, modelled after the ALC880 test 4237 * configuration. 4238 */ 4239 #ifdef CONFIG_SND_DEBUG 4240 static hda_nid_t alc260_test_dac_nids[1] = { 4241 0x02, 4242 }; 4243 static hda_nid_t alc260_test_adc_nids[2] = { 4244 0x04, 0x05, 4245 }; 4246 /* For testing the ALC260, each input MUX needs its own definition since 4247 * the signal assignments are different. This assumes that the first ADC 4248 * is NID 0x04. 4249 */ 4250 static struct hda_input_mux alc260_test_capture_sources[2] = { 4251 { 4252 .num_items = 7, 4253 .items = { 4254 { "MIC1 pin", 0x0 }, 4255 { "MIC2 pin", 0x1 }, 4256 { "LINE1 pin", 0x2 }, 4257 { "LINE2 pin", 0x3 }, 4258 { "CD pin", 0x4 }, 4259 { "LINE-OUT pin", 0x5 }, 4260 { "HP-OUT pin", 0x6 }, 4261 }, 4262 }, 4263 { 4264 .num_items = 8, 4265 .items = { 4266 { "MIC1 pin", 0x0 }, 4267 { "MIC2 pin", 0x1 }, 4268 { "LINE1 pin", 0x2 }, 4269 { "LINE2 pin", 0x3 }, 4270 { "CD pin", 0x4 }, 4271 { "Mixer", 0x5 }, 4272 { "LINE-OUT pin", 0x6 }, 4273 { "HP-OUT pin", 0x7 }, 4274 }, 4275 }, 4276 }; 4277 static struct snd_kcontrol_new alc260_test_mixer[] = { 4278 /* Output driver widgets */ 4279 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), 4280 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT), 4281 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT), 4282 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT), 4283 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT), 4284 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT), 4285 4286 /* Modes for retasking pin widgets 4287 * Note: the ALC260 doesn't seem to act on requests to enable mic 4288 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't 4289 * mention this restriction. At this stage it's not clear whether 4290 * this behaviour is intentional or is a hardware bug in chip 4291 * revisions available at least up until early 2006. Therefore for 4292 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all 4293 * choices, but if it turns out that the lack of mic bias for these 4294 * NIDs is intentional we could change their modes from 4295 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS. 4296 */ 4297 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT), 4298 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT), 4299 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT), 4300 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT), 4301 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT), 4302 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT), 4303 4304 /* Loopback mixer controls */ 4305 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT), 4306 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT), 4307 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT), 4308 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT), 4309 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT), 4310 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT), 4311 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT), 4312 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT), 4313 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), 4314 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), 4315 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT), 4316 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT), 4317 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT), 4318 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT), 4319 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT), 4320 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT), 4321 4322 /* Controls for GPIO pins, assuming they are configured as outputs */ 4323 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01), 4324 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02), 4325 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04), 4326 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08), 4327 4328 /* Switches to allow the digital IO pins to be enabled. The datasheet 4329 * is ambigious as to which NID is which; testing on laptops which 4330 * make this output available should provide clarification. 4331 */ 4332 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01), 4333 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01), 4334 4335 { } /* end */ 4336 }; 4337 static struct hda_verb alc260_test_init_verbs[] = { 4338 /* Enable all GPIOs as outputs with an initial value of 0 */ 4339 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f}, 4340 {0x01, AC_VERB_SET_GPIO_DATA, 0x00}, 4341 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f}, 4342 4343 /* Enable retasking pins as output, initially without power amp */ 4344 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4345 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4346 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4347 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4348 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4349 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4350 4351 /* Disable digital (SPDIF) pins initially, but users can enable 4352 * them via a mixer switch. In the case of SPDIF-out, this initverb 4353 * payload also sets the generation to 0, output to be in "consumer" 4354 * PCM format, copyright asserted, no pre-emphasis and no validity 4355 * control. 4356 */ 4357 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0}, 4358 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0}, 4359 4360 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the 4361 * OUT1 sum bus when acting as an output. 4362 */ 4363 {0x0b, AC_VERB_SET_CONNECT_SEL, 0}, 4364 {0x0c, AC_VERB_SET_CONNECT_SEL, 0}, 4365 {0x0d, AC_VERB_SET_CONNECT_SEL, 0}, 4366 {0x0e, AC_VERB_SET_CONNECT_SEL, 0}, 4367 4368 /* Start with output sum widgets muted and their output gains at min */ 4369 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4370 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4371 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4372 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4373 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4374 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4375 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4376 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4377 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4378 4379 /* Unmute retasking pin widget output buffers since the default 4380 * state appears to be output. As the pin mode is changed by the 4381 * user the pin mode control will take care of enabling the pin's 4382 * input/output buffers as needed. 4383 */ 4384 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4385 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4386 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4387 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4388 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4389 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4390 /* Also unmute the mono-out pin widget */ 4391 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4392 4393 /* Mute capture amp left and right */ 4394 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4395 /* Set ADC connection select to match default mixer setting (mic1 4396 * pin) 4397 */ 4398 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, 4399 4400 /* Do the same for the second ADC: mute capture input amp and 4401 * set ADC connection to mic1 pin 4402 */ 4403 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4404 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, 4405 4406 /* Mute all inputs to mixer widget (even unconnected ones) */ 4407 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */ 4408 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */ 4409 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */ 4410 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */ 4411 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */ 4412 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */ 4413 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */ 4414 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */ 4415 4416 { } 4417 }; 4418 #endif 4419 4420 static struct hda_pcm_stream alc260_pcm_analog_playback = { 4421 .substreams = 1, 4422 .channels_min = 2, 4423 .channels_max = 2, 4424 }; 4425 4426 static struct hda_pcm_stream alc260_pcm_analog_capture = { 4427 .substreams = 1, 4428 .channels_min = 2, 4429 .channels_max = 2, 4430 }; 4431 4432 #define alc260_pcm_digital_playback alc880_pcm_digital_playback 4433 #define alc260_pcm_digital_capture alc880_pcm_digital_capture 4434 4435 /* 4436 * for BIOS auto-configuration 4437 */ 4438 4439 static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid, 4440 const char *pfx) 4441 { 4442 hda_nid_t nid_vol; 4443 unsigned long vol_val, sw_val; 4444 char name[32]; 4445 int err; 4446 4447 if (nid >= 0x0f && nid < 0x11) { 4448 nid_vol = nid - 0x7; 4449 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT); 4450 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT); 4451 } else if (nid == 0x11) { 4452 nid_vol = nid - 0x7; 4453 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT); 4454 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT); 4455 } else if (nid >= 0x12 && nid <= 0x15) { 4456 nid_vol = 0x08; 4457 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT); 4458 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT); 4459 } else 4460 return 0; /* N/A */ 4461 4462 snprintf(name, sizeof(name), "%s Playback Volume", pfx); 4463 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val); 4464 if (err < 0) 4465 return err; 4466 snprintf(name, sizeof(name), "%s Playback Switch", pfx); 4467 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val); 4468 if (err < 0) 4469 return err; 4470 return 1; 4471 } 4472 4473 /* add playback controls from the parsed DAC table */ 4474 static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec, 4475 const struct auto_pin_cfg *cfg) 4476 { 4477 hda_nid_t nid; 4478 int err; 4479 4480 spec->multiout.num_dacs = 1; 4481 spec->multiout.dac_nids = spec->private_dac_nids; 4482 spec->multiout.dac_nids[0] = 0x02; 4483 4484 nid = cfg->line_out_pins[0]; 4485 if (nid) { 4486 err = alc260_add_playback_controls(spec, nid, "Front"); 4487 if (err < 0) 4488 return err; 4489 } 4490 4491 nid = cfg->speaker_pins[0]; 4492 if (nid) { 4493 err = alc260_add_playback_controls(spec, nid, "Speaker"); 4494 if (err < 0) 4495 return err; 4496 } 4497 4498 nid = cfg->hp_pins[0]; 4499 if (nid) { 4500 err = alc260_add_playback_controls(spec, nid, "Headphone"); 4501 if (err < 0) 4502 return err; 4503 } 4504 return 0; 4505 } 4506 4507 /* create playback/capture controls for input pins */ 4508 static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec, 4509 const struct auto_pin_cfg *cfg) 4510 { 4511 struct hda_input_mux *imux = &spec->private_imux; 4512 int i, err, idx; 4513 4514 for (i = 0; i < AUTO_PIN_LAST; i++) { 4515 if (cfg->input_pins[i] >= 0x12) { 4516 idx = cfg->input_pins[i] - 0x12; 4517 err = new_analog_input(spec, cfg->input_pins[i], 4518 auto_pin_cfg_labels[i], idx, 4519 0x07); 4520 if (err < 0) 4521 return err; 4522 imux->items[imux->num_items].label = 4523 auto_pin_cfg_labels[i]; 4524 imux->items[imux->num_items].index = idx; 4525 imux->num_items++; 4526 } 4527 if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){ 4528 idx = cfg->input_pins[i] - 0x09; 4529 err = new_analog_input(spec, cfg->input_pins[i], 4530 auto_pin_cfg_labels[i], idx, 4531 0x07); 4532 if (err < 0) 4533 return err; 4534 imux->items[imux->num_items].label = 4535 auto_pin_cfg_labels[i]; 4536 imux->items[imux->num_items].index = idx; 4537 imux->num_items++; 4538 } 4539 } 4540 return 0; 4541 } 4542 4543 static void alc260_auto_set_output_and_unmute(struct hda_codec *codec, 4544 hda_nid_t nid, int pin_type, 4545 int sel_idx) 4546 { 4547 /* set as output */ 4548 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 4549 pin_type); 4550 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, 4551 AMP_OUT_UNMUTE); 4552 /* need the manual connection? */ 4553 if (nid >= 0x12) { 4554 int idx = nid - 0x12; 4555 snd_hda_codec_write(codec, idx + 0x0b, 0, 4556 AC_VERB_SET_CONNECT_SEL, sel_idx); 4557 } 4558 } 4559 4560 static void alc260_auto_init_multi_out(struct hda_codec *codec) 4561 { 4562 struct alc_spec *spec = codec->spec; 4563 hda_nid_t nid; 4564 4565 alc_subsystem_id(codec, 0x10, 0x15, 0x0f); 4566 nid = spec->autocfg.line_out_pins[0]; 4567 if (nid) { 4568 int pin_type = get_pin_type(spec->autocfg.line_out_type); 4569 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0); 4570 } 4571 4572 nid = spec->autocfg.speaker_pins[0]; 4573 if (nid) 4574 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0); 4575 4576 nid = spec->autocfg.hp_pins[0]; 4577 if (nid) 4578 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0); 4579 } 4580 4581 #define ALC260_PIN_CD_NID 0x16 4582 static void alc260_auto_init_analog_input(struct hda_codec *codec) 4583 { 4584 struct alc_spec *spec = codec->spec; 4585 int i; 4586 4587 for (i = 0; i < AUTO_PIN_LAST; i++) { 4588 hda_nid_t nid = spec->autocfg.input_pins[i]; 4589 if (nid >= 0x12) { 4590 snd_hda_codec_write(codec, nid, 0, 4591 AC_VERB_SET_PIN_WIDGET_CONTROL, 4592 i <= AUTO_PIN_FRONT_MIC ? 4593 PIN_VREF80 : PIN_IN); 4594 if (nid != ALC260_PIN_CD_NID) 4595 snd_hda_codec_write(codec, nid, 0, 4596 AC_VERB_SET_AMP_GAIN_MUTE, 4597 AMP_OUT_MUTE); 4598 } 4599 } 4600 } 4601 4602 /* 4603 * generic initialization of ADC, input mixers and output mixers 4604 */ 4605 static struct hda_verb alc260_volume_init_verbs[] = { 4606 /* 4607 * Unmute ADC0-1 and set the default input to mic-in 4608 */ 4609 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, 4610 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4611 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, 4612 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4613 4614 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 4615 * mixer widget 4616 * Note: PASD motherboards uses the Line In 2 as the input for 4617 * front panel mic (mic 2) 4618 */ 4619 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 4620 /* mute analog inputs */ 4621 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4622 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4623 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 4624 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 4625 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 4626 4627 /* 4628 * Set up output mixers (0x08 - 0x0a) 4629 */ 4630 /* set vol=0 to output mixers */ 4631 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4632 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4633 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4634 /* set up input amps for analog loopback */ 4635 /* Amp Indices: DAC = 0, mixer = 1 */ 4636 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4637 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4638 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4639 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4640 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4641 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4642 4643 { } 4644 }; 4645 4646 static int alc260_parse_auto_config(struct hda_codec *codec) 4647 { 4648 struct alc_spec *spec = codec->spec; 4649 unsigned int wcap; 4650 int err; 4651 static hda_nid_t alc260_ignore[] = { 0x17, 0 }; 4652 4653 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 4654 alc260_ignore); 4655 if (err < 0) 4656 return err; 4657 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg); 4658 if (err < 0) 4659 return err; 4660 if (!spec->kctl_alloc) 4661 return 0; /* can't find valid BIOS pin config */ 4662 err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg); 4663 if (err < 0) 4664 return err; 4665 4666 spec->multiout.max_channels = 2; 4667 4668 if (spec->autocfg.dig_out_pin) 4669 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID; 4670 if (spec->kctl_alloc) 4671 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 4672 4673 spec->init_verbs[spec->num_init_verbs++] = alc260_volume_init_verbs; 4674 4675 spec->num_mux_defs = 1; 4676 spec->input_mux = &spec->private_imux; 4677 4678 /* check whether NID 0x04 is valid */ 4679 wcap = get_wcaps(codec, 0x04); 4680 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */ 4681 if (wcap != AC_WID_AUD_IN) { 4682 spec->adc_nids = alc260_adc_nids_alt; 4683 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt); 4684 spec->mixers[spec->num_mixers] = alc260_capture_alt_mixer; 4685 } else { 4686 spec->adc_nids = alc260_adc_nids; 4687 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids); 4688 spec->mixers[spec->num_mixers] = alc260_capture_mixer; 4689 } 4690 spec->num_mixers++; 4691 4692 return 1; 4693 } 4694 4695 /* additional initialization for auto-configuration model */ 4696 static void alc260_auto_init(struct hda_codec *codec) 4697 { 4698 alc260_auto_init_multi_out(codec); 4699 alc260_auto_init_analog_input(codec); 4700 } 4701 4702 #ifdef CONFIG_SND_HDA_POWER_SAVE 4703 static struct hda_amp_list alc260_loopbacks[] = { 4704 { 0x07, HDA_INPUT, 0 }, 4705 { 0x07, HDA_INPUT, 1 }, 4706 { 0x07, HDA_INPUT, 2 }, 4707 { 0x07, HDA_INPUT, 3 }, 4708 { 0x07, HDA_INPUT, 4 }, 4709 { } /* end */ 4710 }; 4711 #endif 4712 4713 /* 4714 * ALC260 configurations 4715 */ 4716 static const char *alc260_models[ALC260_MODEL_LAST] = { 4717 [ALC260_BASIC] = "basic", 4718 [ALC260_HP] = "hp", 4719 [ALC260_HP_3013] = "hp-3013", 4720 [ALC260_FUJITSU_S702X] = "fujitsu", 4721 [ALC260_ACER] = "acer", 4722 [ALC260_WILL] = "will", 4723 [ALC260_REPLACER_672V] = "replacer", 4724 #ifdef CONFIG_SND_DEBUG 4725 [ALC260_TEST] = "test", 4726 #endif 4727 [ALC260_AUTO] = "auto", 4728 }; 4729 4730 static struct snd_pci_quirk alc260_cfg_tbl[] = { 4731 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER), 4732 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER), 4733 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013), 4734 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013), 4735 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013), 4736 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP), 4737 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_3013), 4738 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013), 4739 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP), 4740 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP), 4741 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP), 4742 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC), 4743 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC), 4744 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC), 4745 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X), 4746 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC), 4747 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL), 4748 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V), 4749 {} 4750 }; 4751 4752 static struct alc_config_preset alc260_presets[] = { 4753 [ALC260_BASIC] = { 4754 .mixers = { alc260_base_output_mixer, 4755 alc260_input_mixer, 4756 alc260_pc_beep_mixer, 4757 alc260_capture_mixer }, 4758 .init_verbs = { alc260_init_verbs }, 4759 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 4760 .dac_nids = alc260_dac_nids, 4761 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids), 4762 .adc_nids = alc260_adc_nids, 4763 .num_channel_mode = ARRAY_SIZE(alc260_modes), 4764 .channel_mode = alc260_modes, 4765 .input_mux = &alc260_capture_source, 4766 }, 4767 [ALC260_HP] = { 4768 .mixers = { alc260_base_output_mixer, 4769 alc260_input_mixer, 4770 alc260_capture_alt_mixer }, 4771 .init_verbs = { alc260_init_verbs }, 4772 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 4773 .dac_nids = alc260_dac_nids, 4774 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids), 4775 .adc_nids = alc260_hp_adc_nids, 4776 .num_channel_mode = ARRAY_SIZE(alc260_modes), 4777 .channel_mode = alc260_modes, 4778 .input_mux = &alc260_capture_source, 4779 }, 4780 [ALC260_HP_3013] = { 4781 .mixers = { alc260_hp_3013_mixer, 4782 alc260_input_mixer, 4783 alc260_capture_alt_mixer }, 4784 .init_verbs = { alc260_hp_3013_init_verbs }, 4785 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 4786 .dac_nids = alc260_dac_nids, 4787 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids), 4788 .adc_nids = alc260_hp_adc_nids, 4789 .num_channel_mode = ARRAY_SIZE(alc260_modes), 4790 .channel_mode = alc260_modes, 4791 .input_mux = &alc260_capture_source, 4792 }, 4793 [ALC260_FUJITSU_S702X] = { 4794 .mixers = { alc260_fujitsu_mixer, 4795 alc260_capture_mixer }, 4796 .init_verbs = { alc260_fujitsu_init_verbs }, 4797 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 4798 .dac_nids = alc260_dac_nids, 4799 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids), 4800 .adc_nids = alc260_dual_adc_nids, 4801 .num_channel_mode = ARRAY_SIZE(alc260_modes), 4802 .channel_mode = alc260_modes, 4803 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources), 4804 .input_mux = alc260_fujitsu_capture_sources, 4805 }, 4806 [ALC260_ACER] = { 4807 .mixers = { alc260_acer_mixer, 4808 alc260_capture_mixer }, 4809 .init_verbs = { alc260_acer_init_verbs }, 4810 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 4811 .dac_nids = alc260_dac_nids, 4812 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids), 4813 .adc_nids = alc260_dual_adc_nids, 4814 .num_channel_mode = ARRAY_SIZE(alc260_modes), 4815 .channel_mode = alc260_modes, 4816 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources), 4817 .input_mux = alc260_acer_capture_sources, 4818 }, 4819 [ALC260_WILL] = { 4820 .mixers = { alc260_will_mixer, 4821 alc260_capture_mixer }, 4822 .init_verbs = { alc260_init_verbs, alc260_will_verbs }, 4823 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 4824 .dac_nids = alc260_dac_nids, 4825 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids), 4826 .adc_nids = alc260_adc_nids, 4827 .dig_out_nid = ALC260_DIGOUT_NID, 4828 .num_channel_mode = ARRAY_SIZE(alc260_modes), 4829 .channel_mode = alc260_modes, 4830 .input_mux = &alc260_capture_source, 4831 }, 4832 [ALC260_REPLACER_672V] = { 4833 .mixers = { alc260_replacer_672v_mixer, 4834 alc260_capture_mixer }, 4835 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs }, 4836 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 4837 .dac_nids = alc260_dac_nids, 4838 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids), 4839 .adc_nids = alc260_adc_nids, 4840 .dig_out_nid = ALC260_DIGOUT_NID, 4841 .num_channel_mode = ARRAY_SIZE(alc260_modes), 4842 .channel_mode = alc260_modes, 4843 .input_mux = &alc260_capture_source, 4844 .unsol_event = alc260_replacer_672v_unsol_event, 4845 .init_hook = alc260_replacer_672v_automute, 4846 }, 4847 #ifdef CONFIG_SND_DEBUG 4848 [ALC260_TEST] = { 4849 .mixers = { alc260_test_mixer, 4850 alc260_capture_mixer }, 4851 .init_verbs = { alc260_test_init_verbs }, 4852 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids), 4853 .dac_nids = alc260_test_dac_nids, 4854 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids), 4855 .adc_nids = alc260_test_adc_nids, 4856 .num_channel_mode = ARRAY_SIZE(alc260_modes), 4857 .channel_mode = alc260_modes, 4858 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources), 4859 .input_mux = alc260_test_capture_sources, 4860 }, 4861 #endif 4862 }; 4863 4864 static int patch_alc260(struct hda_codec *codec) 4865 { 4866 struct alc_spec *spec; 4867 int err, board_config; 4868 4869 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 4870 if (spec == NULL) 4871 return -ENOMEM; 4872 4873 codec->spec = spec; 4874 4875 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST, 4876 alc260_models, 4877 alc260_cfg_tbl); 4878 if (board_config < 0) { 4879 snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, " 4880 "trying auto-probe from BIOS...\n"); 4881 board_config = ALC260_AUTO; 4882 } 4883 4884 if (board_config == ALC260_AUTO) { 4885 /* automatic parse from the BIOS config */ 4886 err = alc260_parse_auto_config(codec); 4887 if (err < 0) { 4888 alc_free(codec); 4889 return err; 4890 } else if (!err) { 4891 printk(KERN_INFO 4892 "hda_codec: Cannot set up configuration " 4893 "from BIOS. Using base mode...\n"); 4894 board_config = ALC260_BASIC; 4895 } 4896 } 4897 4898 if (board_config != ALC260_AUTO) 4899 setup_preset(spec, &alc260_presets[board_config]); 4900 4901 spec->stream_name_analog = "ALC260 Analog"; 4902 spec->stream_analog_playback = &alc260_pcm_analog_playback; 4903 spec->stream_analog_capture = &alc260_pcm_analog_capture; 4904 4905 spec->stream_name_digital = "ALC260 Digital"; 4906 spec->stream_digital_playback = &alc260_pcm_digital_playback; 4907 spec->stream_digital_capture = &alc260_pcm_digital_capture; 4908 4909 codec->patch_ops = alc_patch_ops; 4910 if (board_config == ALC260_AUTO) 4911 spec->init_hook = alc260_auto_init; 4912 #ifdef CONFIG_SND_HDA_POWER_SAVE 4913 if (!spec->loopback.amplist) 4914 spec->loopback.amplist = alc260_loopbacks; 4915 #endif 4916 4917 return 0; 4918 } 4919 4920 4921 /* 4922 * ALC882 support 4923 * 4924 * ALC882 is almost identical with ALC880 but has cleaner and more flexible 4925 * configuration. Each pin widget can choose any input DACs and a mixer. 4926 * Each ADC is connected from a mixer of all inputs. This makes possible 4927 * 6-channel independent captures. 4928 * 4929 * In addition, an independent DAC for the multi-playback (not used in this 4930 * driver yet). 4931 */ 4932 #define ALC882_DIGOUT_NID 0x06 4933 #define ALC882_DIGIN_NID 0x0a 4934 4935 static struct hda_channel_mode alc882_ch_modes[1] = { 4936 { 8, NULL } 4937 }; 4938 4939 static hda_nid_t alc882_dac_nids[4] = { 4940 /* front, rear, clfe, rear_surr */ 4941 0x02, 0x03, 0x04, 0x05 4942 }; 4943 4944 /* identical with ALC880 */ 4945 #define alc882_adc_nids alc880_adc_nids 4946 #define alc882_adc_nids_alt alc880_adc_nids_alt 4947 4948 /* input MUX */ 4949 /* FIXME: should be a matrix-type input source selection */ 4950 4951 static struct hda_input_mux alc882_capture_source = { 4952 .num_items = 4, 4953 .items = { 4954 { "Mic", 0x0 }, 4955 { "Front Mic", 0x1 }, 4956 { "Line", 0x2 }, 4957 { "CD", 0x4 }, 4958 }, 4959 }; 4960 #define alc882_mux_enum_info alc_mux_enum_info 4961 #define alc882_mux_enum_get alc_mux_enum_get 4962 4963 static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol, 4964 struct snd_ctl_elem_value *ucontrol) 4965 { 4966 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 4967 struct alc_spec *spec = codec->spec; 4968 const struct hda_input_mux *imux = spec->input_mux; 4969 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 4970 static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 }; 4971 hda_nid_t nid = capture_mixers[adc_idx]; 4972 unsigned int *cur_val = &spec->cur_mux[adc_idx]; 4973 unsigned int i, idx; 4974 4975 idx = ucontrol->value.enumerated.item[0]; 4976 if (idx >= imux->num_items) 4977 idx = imux->num_items - 1; 4978 if (*cur_val == idx) 4979 return 0; 4980 for (i = 0; i < imux->num_items; i++) { 4981 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE; 4982 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 4983 imux->items[i].index, 4984 HDA_AMP_MUTE, v); 4985 } 4986 *cur_val = idx; 4987 return 1; 4988 } 4989 4990 /* 4991 * 2ch mode 4992 */ 4993 static struct hda_verb alc882_3ST_ch2_init[] = { 4994 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 4995 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 4996 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 4997 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 4998 { } /* end */ 4999 }; 5000 5001 /* 5002 * 6ch mode 5003 */ 5004 static struct hda_verb alc882_3ST_ch6_init[] = { 5005 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 5006 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 5007 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, 5008 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 5009 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 5010 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 5011 { } /* end */ 5012 }; 5013 5014 static struct hda_channel_mode alc882_3ST_6ch_modes[2] = { 5015 { 2, alc882_3ST_ch2_init }, 5016 { 6, alc882_3ST_ch6_init }, 5017 }; 5018 5019 /* 5020 * 6ch mode 5021 */ 5022 static struct hda_verb alc882_sixstack_ch6_init[] = { 5023 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 5024 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 5025 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 5026 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 5027 { } /* end */ 5028 }; 5029 5030 /* 5031 * 8ch mode 5032 */ 5033 static struct hda_verb alc882_sixstack_ch8_init[] = { 5034 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 5035 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 5036 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 5037 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 5038 { } /* end */ 5039 }; 5040 5041 static struct hda_channel_mode alc882_sixstack_modes[2] = { 5042 { 6, alc882_sixstack_ch6_init }, 5043 { 8, alc882_sixstack_ch8_init }, 5044 }; 5045 5046 /* 5047 * macbook pro ALC885 can switch LineIn to LineOut without loosing Mic 5048 */ 5049 5050 /* 5051 * 2ch mode 5052 */ 5053 static struct hda_verb alc885_mbp_ch2_init[] = { 5054 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 5055 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5056 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 5057 { } /* end */ 5058 }; 5059 5060 /* 5061 * 6ch mode 5062 */ 5063 static struct hda_verb alc885_mbp_ch6_init[] = { 5064 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 5065 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5066 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 5067 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5068 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 5069 { } /* end */ 5070 }; 5071 5072 static struct hda_channel_mode alc885_mbp_6ch_modes[2] = { 5073 { 2, alc885_mbp_ch2_init }, 5074 { 6, alc885_mbp_ch6_init }, 5075 }; 5076 5077 5078 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 5079 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b 5080 */ 5081 static struct snd_kcontrol_new alc882_base_mixer[] = { 5082 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 5083 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 5084 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 5085 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 5086 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 5087 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 5088 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 5089 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 5090 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 5091 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 5092 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 5093 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 5094 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 5095 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 5096 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 5097 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 5098 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 5099 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 5100 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 5101 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 5102 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 5103 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 5104 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 5105 { } /* end */ 5106 }; 5107 5108 static struct snd_kcontrol_new alc885_mbp3_mixer[] = { 5109 HDA_CODEC_VOLUME("Master Volume", 0x0c, 0x00, HDA_OUTPUT), 5110 HDA_BIND_MUTE ("Master Switch", 0x0c, 0x02, HDA_INPUT), 5111 HDA_CODEC_MUTE ("Speaker Switch", 0x14, 0x00, HDA_OUTPUT), 5112 HDA_CODEC_VOLUME("Line Out Volume", 0x0d,0x00, HDA_OUTPUT), 5113 HDA_CODEC_VOLUME("Line In Playback Volume", 0x0b, 0x02, HDA_INPUT), 5114 HDA_CODEC_MUTE ("Line In Playback Switch", 0x0b, 0x02, HDA_INPUT), 5115 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT), 5116 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT), 5117 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0x00, HDA_INPUT), 5118 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT), 5119 { } /* end */ 5120 }; 5121 static struct snd_kcontrol_new alc882_w2jc_mixer[] = { 5122 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 5123 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 5124 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 5125 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 5126 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 5127 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 5128 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 5129 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 5130 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 5131 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 5132 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 5133 { } /* end */ 5134 }; 5135 5136 static struct snd_kcontrol_new alc882_targa_mixer[] = { 5137 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 5138 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 5139 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 5140 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 5141 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 5142 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 5143 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 5144 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 5145 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 5146 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 5147 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 5148 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 5149 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 5150 { } /* end */ 5151 }; 5152 5153 /* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ??? 5154 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c 5155 */ 5156 static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = { 5157 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 5158 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 5159 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 5160 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT), 5161 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 5162 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 5163 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 5164 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 5165 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT), 5166 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT), 5167 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 5168 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 5169 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 5170 { } /* end */ 5171 }; 5172 5173 static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = { 5174 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 5175 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 5176 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 5177 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 5178 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 5179 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 5180 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 5181 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 5182 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 5183 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 5184 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 5185 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 5186 { } /* end */ 5187 }; 5188 5189 static struct snd_kcontrol_new alc882_chmode_mixer[] = { 5190 { 5191 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 5192 .name = "Channel Mode", 5193 .info = alc_ch_mode_info, 5194 .get = alc_ch_mode_get, 5195 .put = alc_ch_mode_put, 5196 }, 5197 { } /* end */ 5198 }; 5199 5200 static struct hda_verb alc882_init_verbs[] = { 5201 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 5202 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5203 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5204 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 5205 /* Rear mixer */ 5206 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5207 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5208 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 5209 /* CLFE mixer */ 5210 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5211 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5212 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 5213 /* Side mixer */ 5214 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5215 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5216 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 5217 5218 /* Front Pin: output 0 (0x0c) */ 5219 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5220 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5221 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 5222 /* Rear Pin: output 1 (0x0d) */ 5223 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5224 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5225 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 5226 /* CLFE Pin: output 2 (0x0e) */ 5227 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5228 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5229 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, 5230 /* Side Pin: output 3 (0x0f) */ 5231 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5232 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5233 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, 5234 /* Mic (rear) pin: input vref at 80% */ 5235 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 5236 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 5237 /* Front Mic pin: input vref at 80% */ 5238 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 5239 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 5240 /* Line In pin: input */ 5241 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 5242 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 5243 /* Line-2 In: Headphone output (output 0 - 0x0c) */ 5244 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 5245 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5246 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 5247 /* CD pin widget for input */ 5248 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 5249 5250 /* FIXME: use matrix-type input source selection */ 5251 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 5252 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 5253 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5254 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 5255 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 5256 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 5257 /* Input mixer2 */ 5258 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5259 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 5260 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 5261 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 5262 /* Input mixer3 */ 5263 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5264 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 5265 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 5266 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 5267 /* ADC1: mute amp left and right */ 5268 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5269 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 5270 /* ADC2: mute amp left and right */ 5271 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5272 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 5273 /* ADC3: mute amp left and right */ 5274 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5275 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 5276 5277 { } 5278 }; 5279 5280 static struct hda_verb alc882_eapd_verbs[] = { 5281 /* change to EAPD mode */ 5282 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 5283 {0x20, AC_VERB_SET_PROC_COEF, 0x3060}, 5284 { } 5285 }; 5286 5287 /* Mac Pro test */ 5288 static struct snd_kcontrol_new alc882_macpro_mixer[] = { 5289 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 5290 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 5291 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT), 5292 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT), 5293 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT), 5294 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT), 5295 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT), 5296 { } /* end */ 5297 }; 5298 5299 static struct hda_verb alc882_macpro_init_verbs[] = { 5300 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 5301 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5302 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5303 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 5304 /* Front Pin: output 0 (0x0c) */ 5305 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5306 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5307 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 5308 /* Front Mic pin: input vref at 80% */ 5309 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 5310 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 5311 /* Speaker: output */ 5312 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5313 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5314 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04}, 5315 /* Headphone output (output 0 - 0x0c) */ 5316 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 5317 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5318 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00}, 5319 5320 /* FIXME: use matrix-type input source selection */ 5321 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 5322 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 5323 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5324 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 5325 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 5326 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 5327 /* Input mixer2 */ 5328 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5329 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 5330 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 5331 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 5332 /* Input mixer3 */ 5333 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5334 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 5335 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 5336 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 5337 /* ADC1: mute amp left and right */ 5338 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5339 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 5340 /* ADC2: mute amp left and right */ 5341 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5342 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 5343 /* ADC3: mute amp left and right */ 5344 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5345 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 5346 5347 { } 5348 }; 5349 5350 /* Macbook Pro rev3 */ 5351 static struct hda_verb alc885_mbp3_init_verbs[] = { 5352 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 5353 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5354 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5355 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 5356 /* Rear mixer */ 5357 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5358 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5359 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 5360 /* Front Pin: output 0 (0x0c) */ 5361 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5362 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5363 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 5364 /* HP Pin: output 0 (0x0d) */ 5365 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, 5366 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 5367 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 5368 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 5369 /* Mic (rear) pin: input vref at 80% */ 5370 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 5371 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 5372 /* Front Mic pin: input vref at 80% */ 5373 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 5374 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 5375 /* Line In pin: use output 1 when in LineOut mode */ 5376 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 5377 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 5378 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, 5379 5380 /* FIXME: use matrix-type input source selection */ 5381 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 5382 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 5383 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5384 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 5385 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 5386 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 5387 /* Input mixer2 */ 5388 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5389 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 5390 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 5391 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 5392 /* Input mixer3 */ 5393 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5394 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 5395 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 5396 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 5397 /* ADC1: mute amp left and right */ 5398 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5399 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 5400 /* ADC2: mute amp left and right */ 5401 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5402 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 5403 /* ADC3: mute amp left and right */ 5404 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5405 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 5406 5407 { } 5408 }; 5409 5410 /* iMac 24 mixer. */ 5411 static struct snd_kcontrol_new alc885_imac24_mixer[] = { 5412 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 5413 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT), 5414 { } /* end */ 5415 }; 5416 5417 /* iMac 24 init verbs. */ 5418 static struct hda_verb alc885_imac24_init_verbs[] = { 5419 /* Internal speakers: output 0 (0x0c) */ 5420 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5421 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5422 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00}, 5423 /* Internal speakers: output 0 (0x0c) */ 5424 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5425 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5426 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00}, 5427 /* Headphone: output 0 (0x0c) */ 5428 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 5429 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5430 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 5431 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 5432 /* Front Mic: input vref at 80% */ 5433 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 5434 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 5435 { } 5436 }; 5437 5438 /* Toggle speaker-output according to the hp-jack state */ 5439 static void alc885_imac24_automute(struct hda_codec *codec) 5440 { 5441 unsigned int present; 5442 5443 present = snd_hda_codec_read(codec, 0x14, 0, 5444 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 5445 snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0, 5446 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 5447 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0, 5448 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 5449 } 5450 5451 /* Processes unsolicited events. */ 5452 static void alc885_imac24_unsol_event(struct hda_codec *codec, 5453 unsigned int res) 5454 { 5455 /* Headphone insertion or removal. */ 5456 if ((res >> 26) == ALC880_HP_EVENT) 5457 alc885_imac24_automute(codec); 5458 } 5459 5460 static void alc885_mbp3_automute(struct hda_codec *codec) 5461 { 5462 unsigned int present; 5463 5464 present = snd_hda_codec_read(codec, 0x15, 0, 5465 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 5466 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 5467 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 5468 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 5469 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE); 5470 5471 } 5472 static void alc885_mbp3_unsol_event(struct hda_codec *codec, 5473 unsigned int res) 5474 { 5475 /* Headphone insertion or removal. */ 5476 if ((res >> 26) == ALC880_HP_EVENT) 5477 alc885_mbp3_automute(codec); 5478 } 5479 5480 5481 static struct hda_verb alc882_targa_verbs[] = { 5482 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5483 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 5484 5485 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 5486 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5487 5488 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ 5489 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */ 5490 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 5491 5492 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 5493 {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, 5494 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03}, 5495 {0x01, AC_VERB_SET_GPIO_DATA, 0x03}, 5496 { } /* end */ 5497 }; 5498 5499 /* toggle speaker-output according to the hp-jack state */ 5500 static void alc882_targa_automute(struct hda_codec *codec) 5501 { 5502 unsigned int present; 5503 5504 present = snd_hda_codec_read(codec, 0x14, 0, 5505 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 5506 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0, 5507 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 5508 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA, 5509 present ? 1 : 3); 5510 } 5511 5512 static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res) 5513 { 5514 /* Looks like the unsol event is incompatible with the standard 5515 * definition. 4bit tag is placed at 26 bit! 5516 */ 5517 if (((res >> 26) == ALC880_HP_EVENT)) { 5518 alc882_targa_automute(codec); 5519 } 5520 } 5521 5522 static struct hda_verb alc882_asus_a7j_verbs[] = { 5523 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5524 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 5525 5526 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 5527 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5528 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5529 5530 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */ 5531 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 5532 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */ 5533 5534 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ 5535 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */ 5536 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 5537 { } /* end */ 5538 }; 5539 5540 static struct hda_verb alc882_asus_a7m_verbs[] = { 5541 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5542 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 5543 5544 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 5545 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5546 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5547 5548 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */ 5549 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 5550 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */ 5551 5552 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ 5553 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */ 5554 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 5555 { } /* end */ 5556 }; 5557 5558 static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted) 5559 { 5560 unsigned int gpiostate, gpiomask, gpiodir; 5561 5562 gpiostate = snd_hda_codec_read(codec, codec->afg, 0, 5563 AC_VERB_GET_GPIO_DATA, 0); 5564 5565 if (!muted) 5566 gpiostate |= (1 << pin); 5567 else 5568 gpiostate &= ~(1 << pin); 5569 5570 gpiomask = snd_hda_codec_read(codec, codec->afg, 0, 5571 AC_VERB_GET_GPIO_MASK, 0); 5572 gpiomask |= (1 << pin); 5573 5574 gpiodir = snd_hda_codec_read(codec, codec->afg, 0, 5575 AC_VERB_GET_GPIO_DIRECTION, 0); 5576 gpiodir |= (1 << pin); 5577 5578 5579 snd_hda_codec_write(codec, codec->afg, 0, 5580 AC_VERB_SET_GPIO_MASK, gpiomask); 5581 snd_hda_codec_write(codec, codec->afg, 0, 5582 AC_VERB_SET_GPIO_DIRECTION, gpiodir); 5583 5584 msleep(1); 5585 5586 snd_hda_codec_write(codec, codec->afg, 0, 5587 AC_VERB_SET_GPIO_DATA, gpiostate); 5588 } 5589 5590 /* set up GPIO at initialization */ 5591 static void alc885_macpro_init_hook(struct hda_codec *codec) 5592 { 5593 alc882_gpio_mute(codec, 0, 0); 5594 alc882_gpio_mute(codec, 1, 0); 5595 } 5596 5597 /* set up GPIO and update auto-muting at initialization */ 5598 static void alc885_imac24_init_hook(struct hda_codec *codec) 5599 { 5600 alc885_macpro_init_hook(codec); 5601 alc885_imac24_automute(codec); 5602 } 5603 5604 /* 5605 * generic initialization of ADC, input mixers and output mixers 5606 */ 5607 static struct hda_verb alc882_auto_init_verbs[] = { 5608 /* 5609 * Unmute ADC0-2 and set the default input to mic-in 5610 */ 5611 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 5612 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5613 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 5614 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5615 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 5616 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5617 5618 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 5619 * mixer widget 5620 * Note: PASD motherboards uses the Line In 2 as the input for 5621 * front panel mic (mic 2) 5622 */ 5623 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 5624 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5625 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 5626 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 5627 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 5628 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 5629 5630 /* 5631 * Set up output mixers (0x0c - 0x0f) 5632 */ 5633 /* set vol=0 to output mixers */ 5634 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5635 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5636 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5637 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5638 /* set up input amps for analog loopback */ 5639 /* Amp Indices: DAC = 0, mixer = 1 */ 5640 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5641 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 5642 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5643 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 5644 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5645 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 5646 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5647 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 5648 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5649 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 5650 5651 /* FIXME: use matrix-type input source selection */ 5652 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 5653 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 5654 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 5655 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 5656 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 5657 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 5658 /* Input mixer2 */ 5659 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 5660 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 5661 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 5662 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 5663 /* Input mixer3 */ 5664 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 5665 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 5666 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 5667 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 5668 5669 { } 5670 }; 5671 5672 /* capture mixer elements */ 5673 static struct snd_kcontrol_new alc882_capture_alt_mixer[] = { 5674 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 5675 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 5676 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), 5677 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), 5678 { 5679 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 5680 /* The multiple "Capture Source" controls confuse alsamixer 5681 * So call somewhat different.. 5682 * FIXME: the controls appear in the "playback" view! 5683 */ 5684 /* .name = "Capture Source", */ 5685 .name = "Input Source", 5686 .count = 2, 5687 .info = alc882_mux_enum_info, 5688 .get = alc882_mux_enum_get, 5689 .put = alc882_mux_enum_put, 5690 }, 5691 { } /* end */ 5692 }; 5693 5694 static struct snd_kcontrol_new alc882_capture_mixer[] = { 5695 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT), 5696 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT), 5697 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT), 5698 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT), 5699 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT), 5700 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT), 5701 { 5702 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 5703 /* The multiple "Capture Source" controls confuse alsamixer 5704 * So call somewhat different.. 5705 * FIXME: the controls appear in the "playback" view! 5706 */ 5707 /* .name = "Capture Source", */ 5708 .name = "Input Source", 5709 .count = 3, 5710 .info = alc882_mux_enum_info, 5711 .get = alc882_mux_enum_get, 5712 .put = alc882_mux_enum_put, 5713 }, 5714 { } /* end */ 5715 }; 5716 5717 #ifdef CONFIG_SND_HDA_POWER_SAVE 5718 #define alc882_loopbacks alc880_loopbacks 5719 #endif 5720 5721 /* pcm configuration: identiacal with ALC880 */ 5722 #define alc882_pcm_analog_playback alc880_pcm_analog_playback 5723 #define alc882_pcm_analog_capture alc880_pcm_analog_capture 5724 #define alc882_pcm_digital_playback alc880_pcm_digital_playback 5725 #define alc882_pcm_digital_capture alc880_pcm_digital_capture 5726 5727 /* 5728 * configuration and preset 5729 */ 5730 static const char *alc882_models[ALC882_MODEL_LAST] = { 5731 [ALC882_3ST_DIG] = "3stack-dig", 5732 [ALC882_6ST_DIG] = "6stack-dig", 5733 [ALC882_ARIMA] = "arima", 5734 [ALC882_W2JC] = "w2jc", 5735 [ALC882_TARGA] = "targa", 5736 [ALC882_ASUS_A7J] = "asus-a7j", 5737 [ALC882_ASUS_A7M] = "asus-a7m", 5738 [ALC885_MACPRO] = "macpro", 5739 [ALC885_MBP3] = "mbp3", 5740 [ALC885_IMAC24] = "imac24", 5741 [ALC882_AUTO] = "auto", 5742 }; 5743 5744 static struct snd_pci_quirk alc882_cfg_tbl[] = { 5745 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG), 5746 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG), 5747 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG), 5748 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */ 5749 SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), 5750 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J), 5751 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J), 5752 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M), 5753 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG), 5754 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG), 5755 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC), 5756 {} 5757 }; 5758 5759 static struct alc_config_preset alc882_presets[] = { 5760 [ALC882_3ST_DIG] = { 5761 .mixers = { alc882_base_mixer }, 5762 .init_verbs = { alc882_init_verbs }, 5763 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 5764 .dac_nids = alc882_dac_nids, 5765 .dig_out_nid = ALC882_DIGOUT_NID, 5766 .dig_in_nid = ALC882_DIGIN_NID, 5767 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes), 5768 .channel_mode = alc882_ch_modes, 5769 .need_dac_fix = 1, 5770 .input_mux = &alc882_capture_source, 5771 }, 5772 [ALC882_6ST_DIG] = { 5773 .mixers = { alc882_base_mixer, alc882_chmode_mixer }, 5774 .init_verbs = { alc882_init_verbs }, 5775 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 5776 .dac_nids = alc882_dac_nids, 5777 .dig_out_nid = ALC882_DIGOUT_NID, 5778 .dig_in_nid = ALC882_DIGIN_NID, 5779 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes), 5780 .channel_mode = alc882_sixstack_modes, 5781 .input_mux = &alc882_capture_source, 5782 }, 5783 [ALC882_ARIMA] = { 5784 .mixers = { alc882_base_mixer, alc882_chmode_mixer }, 5785 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs }, 5786 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 5787 .dac_nids = alc882_dac_nids, 5788 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes), 5789 .channel_mode = alc882_sixstack_modes, 5790 .input_mux = &alc882_capture_source, 5791 }, 5792 [ALC882_W2JC] = { 5793 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer }, 5794 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs, 5795 alc880_gpio1_init_verbs }, 5796 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 5797 .dac_nids = alc882_dac_nids, 5798 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), 5799 .channel_mode = alc880_threestack_modes, 5800 .need_dac_fix = 1, 5801 .input_mux = &alc882_capture_source, 5802 .dig_out_nid = ALC882_DIGOUT_NID, 5803 }, 5804 [ALC885_MBP3] = { 5805 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer }, 5806 .init_verbs = { alc885_mbp3_init_verbs, 5807 alc880_gpio1_init_verbs }, 5808 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 5809 .dac_nids = alc882_dac_nids, 5810 .channel_mode = alc885_mbp_6ch_modes, 5811 .num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes), 5812 .input_mux = &alc882_capture_source, 5813 .dig_out_nid = ALC882_DIGOUT_NID, 5814 .dig_in_nid = ALC882_DIGIN_NID, 5815 .unsol_event = alc885_mbp3_unsol_event, 5816 .init_hook = alc885_mbp3_automute, 5817 }, 5818 [ALC885_MACPRO] = { 5819 .mixers = { alc882_macpro_mixer }, 5820 .init_verbs = { alc882_macpro_init_verbs }, 5821 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 5822 .dac_nids = alc882_dac_nids, 5823 .dig_out_nid = ALC882_DIGOUT_NID, 5824 .dig_in_nid = ALC882_DIGIN_NID, 5825 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes), 5826 .channel_mode = alc882_ch_modes, 5827 .input_mux = &alc882_capture_source, 5828 .init_hook = alc885_macpro_init_hook, 5829 }, 5830 [ALC885_IMAC24] = { 5831 .mixers = { alc885_imac24_mixer }, 5832 .init_verbs = { alc885_imac24_init_verbs }, 5833 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 5834 .dac_nids = alc882_dac_nids, 5835 .dig_out_nid = ALC882_DIGOUT_NID, 5836 .dig_in_nid = ALC882_DIGIN_NID, 5837 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes), 5838 .channel_mode = alc882_ch_modes, 5839 .input_mux = &alc882_capture_source, 5840 .unsol_event = alc885_imac24_unsol_event, 5841 .init_hook = alc885_imac24_init_hook, 5842 }, 5843 [ALC882_TARGA] = { 5844 .mixers = { alc882_targa_mixer, alc882_chmode_mixer, 5845 alc882_capture_mixer }, 5846 .init_verbs = { alc882_init_verbs, alc882_targa_verbs}, 5847 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 5848 .dac_nids = alc882_dac_nids, 5849 .dig_out_nid = ALC882_DIGOUT_NID, 5850 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids), 5851 .adc_nids = alc882_adc_nids, 5852 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes), 5853 .channel_mode = alc882_3ST_6ch_modes, 5854 .need_dac_fix = 1, 5855 .input_mux = &alc882_capture_source, 5856 .unsol_event = alc882_targa_unsol_event, 5857 .init_hook = alc882_targa_automute, 5858 }, 5859 [ALC882_ASUS_A7J] = { 5860 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer, 5861 alc882_capture_mixer }, 5862 .init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs}, 5863 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 5864 .dac_nids = alc882_dac_nids, 5865 .dig_out_nid = ALC882_DIGOUT_NID, 5866 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids), 5867 .adc_nids = alc882_adc_nids, 5868 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes), 5869 .channel_mode = alc882_3ST_6ch_modes, 5870 .need_dac_fix = 1, 5871 .input_mux = &alc882_capture_source, 5872 }, 5873 [ALC882_ASUS_A7M] = { 5874 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer }, 5875 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs, 5876 alc880_gpio1_init_verbs, 5877 alc882_asus_a7m_verbs }, 5878 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 5879 .dac_nids = alc882_dac_nids, 5880 .dig_out_nid = ALC882_DIGOUT_NID, 5881 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), 5882 .channel_mode = alc880_threestack_modes, 5883 .need_dac_fix = 1, 5884 .input_mux = &alc882_capture_source, 5885 }, 5886 }; 5887 5888 5889 /* 5890 * Pin config fixes 5891 */ 5892 enum { 5893 PINFIX_ABIT_AW9D_MAX 5894 }; 5895 5896 static struct alc_pincfg alc882_abit_aw9d_pinfix[] = { 5897 { 0x15, 0x01080104 }, /* side */ 5898 { 0x16, 0x01011012 }, /* rear */ 5899 { 0x17, 0x01016011 }, /* clfe */ 5900 { } 5901 }; 5902 5903 static const struct alc_pincfg *alc882_pin_fixes[] = { 5904 [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix, 5905 }; 5906 5907 static struct snd_pci_quirk alc882_pinfix_tbl[] = { 5908 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX), 5909 {} 5910 }; 5911 5912 /* 5913 * BIOS auto configuration 5914 */ 5915 static void alc882_auto_set_output_and_unmute(struct hda_codec *codec, 5916 hda_nid_t nid, int pin_type, 5917 int dac_idx) 5918 { 5919 /* set as output */ 5920 struct alc_spec *spec = codec->spec; 5921 int idx; 5922 5923 if (spec->multiout.dac_nids[dac_idx] == 0x25) 5924 idx = 4; 5925 else 5926 idx = spec->multiout.dac_nids[dac_idx] - 2; 5927 5928 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 5929 pin_type); 5930 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, 5931 AMP_OUT_UNMUTE); 5932 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx); 5933 5934 } 5935 5936 static void alc882_auto_init_multi_out(struct hda_codec *codec) 5937 { 5938 struct alc_spec *spec = codec->spec; 5939 int i; 5940 5941 alc_subsystem_id(codec, 0x15, 0x1b, 0x14); 5942 for (i = 0; i <= HDA_SIDE; i++) { 5943 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 5944 int pin_type = get_pin_type(spec->autocfg.line_out_type); 5945 if (nid) 5946 alc882_auto_set_output_and_unmute(codec, nid, pin_type, 5947 i); 5948 } 5949 } 5950 5951 static void alc882_auto_init_hp_out(struct hda_codec *codec) 5952 { 5953 struct alc_spec *spec = codec->spec; 5954 hda_nid_t pin; 5955 5956 pin = spec->autocfg.hp_pins[0]; 5957 if (pin) /* connect to front */ 5958 /* use dac 0 */ 5959 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); 5960 } 5961 5962 #define alc882_is_input_pin(nid) alc880_is_input_pin(nid) 5963 #define ALC882_PIN_CD_NID ALC880_PIN_CD_NID 5964 5965 static void alc882_auto_init_analog_input(struct hda_codec *codec) 5966 { 5967 struct alc_spec *spec = codec->spec; 5968 int i; 5969 5970 for (i = 0; i < AUTO_PIN_LAST; i++) { 5971 hda_nid_t nid = spec->autocfg.input_pins[i]; 5972 if (alc882_is_input_pin(nid)) { 5973 snd_hda_codec_write(codec, nid, 0, 5974 AC_VERB_SET_PIN_WIDGET_CONTROL, 5975 i <= AUTO_PIN_FRONT_MIC ? 5976 PIN_VREF80 : PIN_IN); 5977 if (nid != ALC882_PIN_CD_NID) 5978 snd_hda_codec_write(codec, nid, 0, 5979 AC_VERB_SET_AMP_GAIN_MUTE, 5980 AMP_OUT_MUTE); 5981 } 5982 } 5983 } 5984 5985 /* add mic boosts if needed */ 5986 static int alc_auto_add_mic_boost(struct hda_codec *codec) 5987 { 5988 struct alc_spec *spec = codec->spec; 5989 int err; 5990 hda_nid_t nid; 5991 5992 nid = spec->autocfg.input_pins[AUTO_PIN_MIC]; 5993 if (nid) { 5994 err = add_control(spec, ALC_CTL_WIDGET_VOL, 5995 "Mic Boost", 5996 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT)); 5997 if (err < 0) 5998 return err; 5999 } 6000 nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC]; 6001 if (nid) { 6002 err = add_control(spec, ALC_CTL_WIDGET_VOL, 6003 "Front Mic Boost", 6004 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT)); 6005 if (err < 0) 6006 return err; 6007 } 6008 return 0; 6009 } 6010 6011 /* almost identical with ALC880 parser... */ 6012 static int alc882_parse_auto_config(struct hda_codec *codec) 6013 { 6014 struct alc_spec *spec = codec->spec; 6015 int err = alc880_parse_auto_config(codec); 6016 6017 if (err < 0) 6018 return err; 6019 else if (!err) 6020 return 0; /* no config found */ 6021 6022 err = alc_auto_add_mic_boost(codec); 6023 if (err < 0) 6024 return err; 6025 6026 /* hack - override the init verbs */ 6027 spec->init_verbs[0] = alc882_auto_init_verbs; 6028 6029 return 1; /* config found */ 6030 } 6031 6032 /* additional initialization for auto-configuration model */ 6033 static void alc882_auto_init(struct hda_codec *codec) 6034 { 6035 alc882_auto_init_multi_out(codec); 6036 alc882_auto_init_hp_out(codec); 6037 alc882_auto_init_analog_input(codec); 6038 } 6039 6040 static int patch_alc882(struct hda_codec *codec) 6041 { 6042 struct alc_spec *spec; 6043 int err, board_config; 6044 6045 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 6046 if (spec == NULL) 6047 return -ENOMEM; 6048 6049 codec->spec = spec; 6050 6051 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST, 6052 alc882_models, 6053 alc882_cfg_tbl); 6054 6055 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) { 6056 /* Pick up systems that don't supply PCI SSID */ 6057 switch (codec->subsystem_id) { 6058 case 0x106b0c00: /* Mac Pro */ 6059 board_config = ALC885_MACPRO; 6060 break; 6061 case 0x106b1000: /* iMac 24 */ 6062 board_config = ALC885_IMAC24; 6063 break; 6064 case 0x106b2c00: /* Macbook Pro rev3 */ 6065 board_config = ALC885_MBP3; 6066 break; 6067 default: 6068 printk(KERN_INFO "hda_codec: Unknown model for ALC882, " 6069 "trying auto-probe from BIOS...\n"); 6070 board_config = ALC882_AUTO; 6071 } 6072 } 6073 6074 alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes); 6075 6076 if (board_config == ALC882_AUTO) { 6077 /* automatic parse from the BIOS config */ 6078 err = alc882_parse_auto_config(codec); 6079 if (err < 0) { 6080 alc_free(codec); 6081 return err; 6082 } else if (!err) { 6083 printk(KERN_INFO 6084 "hda_codec: Cannot set up configuration " 6085 "from BIOS. Using base mode...\n"); 6086 board_config = ALC882_3ST_DIG; 6087 } 6088 } 6089 6090 if (board_config != ALC882_AUTO) 6091 setup_preset(spec, &alc882_presets[board_config]); 6092 6093 spec->stream_name_analog = "ALC882 Analog"; 6094 spec->stream_analog_playback = &alc882_pcm_analog_playback; 6095 spec->stream_analog_capture = &alc882_pcm_analog_capture; 6096 6097 spec->stream_name_digital = "ALC882 Digital"; 6098 spec->stream_digital_playback = &alc882_pcm_digital_playback; 6099 spec->stream_digital_capture = &alc882_pcm_digital_capture; 6100 6101 if (!spec->adc_nids && spec->input_mux) { 6102 /* check whether NID 0x07 is valid */ 6103 unsigned int wcap = get_wcaps(codec, 0x07); 6104 /* get type */ 6105 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; 6106 if (wcap != AC_WID_AUD_IN) { 6107 spec->adc_nids = alc882_adc_nids_alt; 6108 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt); 6109 spec->mixers[spec->num_mixers] = 6110 alc882_capture_alt_mixer; 6111 spec->num_mixers++; 6112 } else { 6113 spec->adc_nids = alc882_adc_nids; 6114 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids); 6115 spec->mixers[spec->num_mixers] = alc882_capture_mixer; 6116 spec->num_mixers++; 6117 } 6118 } 6119 6120 codec->patch_ops = alc_patch_ops; 6121 if (board_config == ALC882_AUTO) 6122 spec->init_hook = alc882_auto_init; 6123 #ifdef CONFIG_SND_HDA_POWER_SAVE 6124 if (!spec->loopback.amplist) 6125 spec->loopback.amplist = alc882_loopbacks; 6126 #endif 6127 6128 return 0; 6129 } 6130 6131 /* 6132 * ALC883 support 6133 * 6134 * ALC883 is almost identical with ALC880 but has cleaner and more flexible 6135 * configuration. Each pin widget can choose any input DACs and a mixer. 6136 * Each ADC is connected from a mixer of all inputs. This makes possible 6137 * 6-channel independent captures. 6138 * 6139 * In addition, an independent DAC for the multi-playback (not used in this 6140 * driver yet). 6141 */ 6142 #define ALC883_DIGOUT_NID 0x06 6143 #define ALC883_DIGIN_NID 0x0a 6144 6145 static hda_nid_t alc883_dac_nids[4] = { 6146 /* front, rear, clfe, rear_surr */ 6147 0x02, 0x04, 0x03, 0x05 6148 }; 6149 6150 static hda_nid_t alc883_adc_nids[2] = { 6151 /* ADC1-2 */ 6152 0x08, 0x09, 6153 }; 6154 6155 /* input MUX */ 6156 /* FIXME: should be a matrix-type input source selection */ 6157 6158 static struct hda_input_mux alc883_capture_source = { 6159 .num_items = 4, 6160 .items = { 6161 { "Mic", 0x0 }, 6162 { "Front Mic", 0x1 }, 6163 { "Line", 0x2 }, 6164 { "CD", 0x4 }, 6165 }, 6166 }; 6167 6168 static struct hda_input_mux alc883_lenovo_101e_capture_source = { 6169 .num_items = 2, 6170 .items = { 6171 { "Mic", 0x1 }, 6172 { "Line", 0x2 }, 6173 }, 6174 }; 6175 6176 static struct hda_input_mux alc883_lenovo_nb0763_capture_source = { 6177 .num_items = 4, 6178 .items = { 6179 { "Mic", 0x0 }, 6180 { "iMic", 0x1 }, 6181 { "Line", 0x2 }, 6182 { "CD", 0x4 }, 6183 }, 6184 }; 6185 6186 #define alc883_mux_enum_info alc_mux_enum_info 6187 #define alc883_mux_enum_get alc_mux_enum_get 6188 6189 static int alc883_mux_enum_put(struct snd_kcontrol *kcontrol, 6190 struct snd_ctl_elem_value *ucontrol) 6191 { 6192 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 6193 struct alc_spec *spec = codec->spec; 6194 const struct hda_input_mux *imux = spec->input_mux; 6195 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 6196 static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 }; 6197 hda_nid_t nid = capture_mixers[adc_idx]; 6198 unsigned int *cur_val = &spec->cur_mux[adc_idx]; 6199 unsigned int i, idx; 6200 6201 idx = ucontrol->value.enumerated.item[0]; 6202 if (idx >= imux->num_items) 6203 idx = imux->num_items - 1; 6204 if (*cur_val == idx) 6205 return 0; 6206 for (i = 0; i < imux->num_items; i++) { 6207 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE; 6208 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 6209 imux->items[i].index, 6210 HDA_AMP_MUTE, v); 6211 } 6212 *cur_val = idx; 6213 return 1; 6214 } 6215 6216 /* 6217 * 2ch mode 6218 */ 6219 static struct hda_channel_mode alc883_3ST_2ch_modes[1] = { 6220 { 2, NULL } 6221 }; 6222 6223 /* 6224 * 2ch mode 6225 */ 6226 static struct hda_verb alc883_3ST_ch2_init[] = { 6227 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 6228 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 6229 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 6230 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 6231 { } /* end */ 6232 }; 6233 6234 /* 6235 * 4ch mode 6236 */ 6237 static struct hda_verb alc883_3ST_ch4_init[] = { 6238 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 6239 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 6240 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 6241 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 6242 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 6243 { } /* end */ 6244 }; 6245 6246 /* 6247 * 6ch mode 6248 */ 6249 static struct hda_verb alc883_3ST_ch6_init[] = { 6250 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 6251 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 6252 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, 6253 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 6254 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 6255 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 6256 { } /* end */ 6257 }; 6258 6259 static struct hda_channel_mode alc883_3ST_6ch_modes[3] = { 6260 { 2, alc883_3ST_ch2_init }, 6261 { 4, alc883_3ST_ch4_init }, 6262 { 6, alc883_3ST_ch6_init }, 6263 }; 6264 6265 /* 6266 * 6ch mode 6267 */ 6268 static struct hda_verb alc883_sixstack_ch6_init[] = { 6269 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 6270 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 6271 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 6272 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 6273 { } /* end */ 6274 }; 6275 6276 /* 6277 * 8ch mode 6278 */ 6279 static struct hda_verb alc883_sixstack_ch8_init[] = { 6280 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 6281 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 6282 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 6283 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 6284 { } /* end */ 6285 }; 6286 6287 static struct hda_channel_mode alc883_sixstack_modes[2] = { 6288 { 6, alc883_sixstack_ch6_init }, 6289 { 8, alc883_sixstack_ch8_init }, 6290 }; 6291 6292 static struct hda_verb alc883_medion_eapd_verbs[] = { 6293 /* eanable EAPD on medion laptop */ 6294 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 6295 {0x20, AC_VERB_SET_PROC_COEF, 0x3070}, 6296 { } 6297 }; 6298 6299 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 6300 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b 6301 */ 6302 6303 static struct snd_kcontrol_new alc883_base_mixer[] = { 6304 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 6305 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 6306 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 6307 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 6308 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 6309 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 6310 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 6311 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 6312 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 6313 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 6314 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 6315 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 6316 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 6317 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 6318 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 6319 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 6320 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 6321 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 6322 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 6323 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 6324 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 6325 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 6326 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 6327 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 6328 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 6329 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), 6330 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), 6331 { 6332 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 6333 /* .name = "Capture Source", */ 6334 .name = "Input Source", 6335 .count = 2, 6336 .info = alc883_mux_enum_info, 6337 .get = alc883_mux_enum_get, 6338 .put = alc883_mux_enum_put, 6339 }, 6340 { } /* end */ 6341 }; 6342 6343 static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = { 6344 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 6345 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 6346 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 6347 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 6348 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 6349 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 6350 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 6351 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 6352 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 6353 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 6354 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 6355 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 6356 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 6357 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 6358 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 6359 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 6360 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 6361 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), 6362 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), 6363 { 6364 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 6365 /* .name = "Capture Source", */ 6366 .name = "Input Source", 6367 .count = 2, 6368 .info = alc883_mux_enum_info, 6369 .get = alc883_mux_enum_get, 6370 .put = alc883_mux_enum_put, 6371 }, 6372 { } /* end */ 6373 }; 6374 6375 static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = { 6376 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 6377 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 6378 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 6379 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 6380 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 6381 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 6382 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 6383 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 6384 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 6385 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 6386 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 6387 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 6388 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 6389 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 6390 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 6391 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 6392 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 6393 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 6394 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 6395 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 6396 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 6397 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 6398 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 6399 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), 6400 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), 6401 { 6402 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 6403 /* .name = "Capture Source", */ 6404 .name = "Input Source", 6405 .count = 2, 6406 .info = alc883_mux_enum_info, 6407 .get = alc883_mux_enum_get, 6408 .put = alc883_mux_enum_put, 6409 }, 6410 { } /* end */ 6411 }; 6412 6413 static struct snd_kcontrol_new alc883_fivestack_mixer[] = { 6414 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 6415 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 6416 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 6417 HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT), 6418 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 6419 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 6420 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x16, 1, 0x0, HDA_OUTPUT), 6421 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT), 6422 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 6423 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 6424 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 6425 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 6426 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 6427 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 6428 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 6429 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 6430 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 6431 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 6432 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 6433 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 6434 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 6435 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 6436 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 6437 6438 { 6439 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 6440 /* .name = "Capture Source", */ 6441 .name = "Input Source", 6442 .count = 1, 6443 .info = alc883_mux_enum_info, 6444 .get = alc883_mux_enum_get, 6445 .put = alc883_mux_enum_put, 6446 }, 6447 { } /* end */ 6448 }; 6449 6450 static struct snd_kcontrol_new alc883_tagra_mixer[] = { 6451 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 6452 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 6453 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 6454 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 6455 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 6456 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 6457 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 6458 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 6459 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 6460 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 6461 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 6462 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 6463 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 6464 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 6465 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 6466 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 6467 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 6468 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 6469 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), 6470 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), 6471 { 6472 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 6473 /* .name = "Capture Source", */ 6474 .name = "Input Source", 6475 .count = 2, 6476 .info = alc883_mux_enum_info, 6477 .get = alc883_mux_enum_get, 6478 .put = alc883_mux_enum_put, 6479 }, 6480 { } /* end */ 6481 }; 6482 6483 static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = { 6484 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 6485 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 6486 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 6487 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 6488 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 6489 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 6490 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 6491 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 6492 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 6493 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 6494 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), 6495 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), 6496 { 6497 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 6498 /* .name = "Capture Source", */ 6499 .name = "Input Source", 6500 .count = 2, 6501 .info = alc883_mux_enum_info, 6502 .get = alc883_mux_enum_get, 6503 .put = alc883_mux_enum_put, 6504 }, 6505 { } /* end */ 6506 }; 6507 6508 static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = { 6509 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 6510 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 6511 HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 6512 HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT), 6513 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 6514 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 6515 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 6516 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 6517 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 6518 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 6519 { 6520 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 6521 /* .name = "Capture Source", */ 6522 .name = "Input Source", 6523 .count = 1, 6524 .info = alc883_mux_enum_info, 6525 .get = alc883_mux_enum_get, 6526 .put = alc883_mux_enum_put, 6527 }, 6528 { } /* end */ 6529 }; 6530 6531 static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = { 6532 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 6533 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT), 6534 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 6535 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 6536 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 6537 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 6538 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 6539 HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT), 6540 HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT), 6541 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 6542 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 6543 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), 6544 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), 6545 { 6546 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 6547 /* .name = "Capture Source", */ 6548 .name = "Input Source", 6549 .count = 2, 6550 .info = alc883_mux_enum_info, 6551 .get = alc883_mux_enum_get, 6552 .put = alc883_mux_enum_put, 6553 }, 6554 { } /* end */ 6555 }; 6556 6557 static struct snd_kcontrol_new alc883_medion_md2_mixer[] = { 6558 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 6559 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 6560 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT), 6561 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 6562 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 6563 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 6564 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 6565 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 6566 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 6567 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 6568 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 6569 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), 6570 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), 6571 { 6572 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 6573 /* .name = "Capture Source", */ 6574 .name = "Input Source", 6575 .count = 2, 6576 .info = alc883_mux_enum_info, 6577 .get = alc883_mux_enum_get, 6578 .put = alc883_mux_enum_put, 6579 }, 6580 { } /* end */ 6581 }; 6582 6583 static struct snd_kcontrol_new alc888_6st_hp_mixer[] = { 6584 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 6585 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 6586 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT), 6587 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT), 6588 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT), 6589 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT), 6590 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT), 6591 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT), 6592 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 6593 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 6594 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 6595 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 6596 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 6597 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 6598 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 6599 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 6600 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 6601 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 6602 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 6603 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 6604 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 6605 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 6606 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 6607 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 6608 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 6609 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), 6610 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), 6611 { 6612 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 6613 /* .name = "Capture Source", */ 6614 .name = "Input Source", 6615 .count = 2, 6616 .info = alc883_mux_enum_info, 6617 .get = alc883_mux_enum_get, 6618 .put = alc883_mux_enum_put, 6619 }, 6620 { } /* end */ 6621 }; 6622 6623 static struct snd_kcontrol_new alc888_3st_hp_mixer[] = { 6624 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 6625 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 6626 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT), 6627 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT), 6628 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT), 6629 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT), 6630 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT), 6631 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT), 6632 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 6633 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 6634 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 6635 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 6636 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 6637 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 6638 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 6639 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 6640 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 6641 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 6642 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 6643 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 6644 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 6645 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 6646 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 6647 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), 6648 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), 6649 { 6650 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 6651 /* .name = "Capture Source", */ 6652 .name = "Input Source", 6653 .count = 2, 6654 .info = alc883_mux_enum_info, 6655 .get = alc883_mux_enum_get, 6656 .put = alc883_mux_enum_put, 6657 }, 6658 { } /* end */ 6659 }; 6660 6661 static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = { 6662 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 6663 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 6664 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 6665 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 6666 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 6667 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 6668 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 6669 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 6670 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 6671 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 6672 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), 6673 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), 6674 { 6675 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 6676 /* .name = "Capture Source", */ 6677 .name = "Input Source", 6678 .count = 2, 6679 .info = alc883_mux_enum_info, 6680 .get = alc883_mux_enum_get, 6681 .put = alc883_mux_enum_put, 6682 }, 6683 { } /* end */ 6684 }; 6685 6686 static struct snd_kcontrol_new alc883_chmode_mixer[] = { 6687 { 6688 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 6689 .name = "Channel Mode", 6690 .info = alc_ch_mode_info, 6691 .get = alc_ch_mode_get, 6692 .put = alc_ch_mode_put, 6693 }, 6694 { } /* end */ 6695 }; 6696 6697 static struct hda_verb alc883_init_verbs[] = { 6698 /* ADC1: mute amp left and right */ 6699 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6700 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 6701 /* ADC2: mute amp left and right */ 6702 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6703 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 6704 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 6705 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6706 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6707 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6708 /* Rear mixer */ 6709 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6710 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6711 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6712 /* CLFE mixer */ 6713 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6714 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6715 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6716 /* Side mixer */ 6717 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6718 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6719 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6720 6721 /* mute analog input loopbacks */ 6722 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6723 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6724 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 6725 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 6726 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 6727 6728 /* Front Pin: output 0 (0x0c) */ 6729 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6730 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6731 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 6732 /* Rear Pin: output 1 (0x0d) */ 6733 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6734 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6735 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 6736 /* CLFE Pin: output 2 (0x0e) */ 6737 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6738 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6739 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, 6740 /* Side Pin: output 3 (0x0f) */ 6741 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6742 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6743 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, 6744 /* Mic (rear) pin: input vref at 80% */ 6745 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 6746 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 6747 /* Front Mic pin: input vref at 80% */ 6748 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 6749 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 6750 /* Line In pin: input */ 6751 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 6752 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 6753 /* Line-2 In: Headphone output (output 0 - 0x0c) */ 6754 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6755 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6756 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 6757 /* CD pin widget for input */ 6758 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 6759 6760 /* FIXME: use matrix-type input source selection */ 6761 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 6762 /* Input mixer2 */ 6763 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6764 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 6765 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 6766 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, 6767 /* Input mixer3 */ 6768 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6769 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 6770 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 6771 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, 6772 { } 6773 }; 6774 6775 static struct hda_verb alc883_tagra_verbs[] = { 6776 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6777 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 6778 6779 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6780 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6781 6782 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ 6783 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */ 6784 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 6785 6786 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 6787 {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, 6788 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03}, 6789 {0x01, AC_VERB_SET_GPIO_DATA, 0x03}, 6790 6791 { } /* end */ 6792 }; 6793 6794 static struct hda_verb alc883_lenovo_101e_verbs[] = { 6795 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 6796 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN}, 6797 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN}, 6798 { } /* end */ 6799 }; 6800 6801 static struct hda_verb alc883_lenovo_nb0763_verbs[] = { 6802 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 6803 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6804 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 6805 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6806 { } /* end */ 6807 }; 6808 6809 static struct hda_verb alc888_lenovo_ms7195_verbs[] = { 6810 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6811 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 6812 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 6813 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN}, 6814 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 6815 { } /* end */ 6816 }; 6817 6818 static struct hda_verb alc883_haier_w66_verbs[] = { 6819 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6820 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 6821 6822 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6823 6824 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 6825 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6826 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 6827 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6828 { } /* end */ 6829 }; 6830 6831 static struct hda_verb alc888_6st_hp_verbs[] = { 6832 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */ 6833 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Rear : output 2 (0x0e) */ 6834 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* CLFE : output 1 (0x0d) */ 6835 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, /* Side : output 3 (0x0f) */ 6836 { } 6837 }; 6838 6839 static struct hda_verb alc888_3st_hp_verbs[] = { 6840 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */ 6841 {0x18, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */ 6842 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */ 6843 { } 6844 }; 6845 6846 static struct hda_verb alc888_3st_hp_2ch_init[] = { 6847 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 6848 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 6849 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 6850 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 6851 { } 6852 }; 6853 6854 static struct hda_verb alc888_3st_hp_6ch_init[] = { 6855 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 6856 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 6857 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 6858 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 6859 { } 6860 }; 6861 6862 static struct hda_channel_mode alc888_3st_hp_modes[2] = { 6863 { 2, alc888_3st_hp_2ch_init }, 6864 { 6, alc888_3st_hp_6ch_init }, 6865 }; 6866 6867 /* toggle front-jack and RCA according to the hp-jack state */ 6868 static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec) 6869 { 6870 unsigned int present; 6871 6872 present = snd_hda_codec_read(codec, 0x1b, 0, 6873 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 6874 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 6875 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 6876 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 6877 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 6878 } 6879 6880 /* toggle RCA according to the front-jack state */ 6881 static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec) 6882 { 6883 unsigned int present; 6884 6885 present = snd_hda_codec_read(codec, 0x14, 0, 6886 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 6887 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 6888 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 6889 } 6890 6891 static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec, 6892 unsigned int res) 6893 { 6894 if ((res >> 26) == ALC880_HP_EVENT) 6895 alc888_lenovo_ms7195_front_automute(codec); 6896 if ((res >> 26) == ALC880_FRONT_EVENT) 6897 alc888_lenovo_ms7195_rca_automute(codec); 6898 } 6899 6900 static struct hda_verb alc883_medion_md2_verbs[] = { 6901 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6902 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 6903 6904 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6905 6906 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 6907 { } /* end */ 6908 }; 6909 6910 /* toggle speaker-output according to the hp-jack state */ 6911 static void alc883_medion_md2_automute(struct hda_codec *codec) 6912 { 6913 unsigned int present; 6914 6915 present = snd_hda_codec_read(codec, 0x14, 0, 6916 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 6917 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 6918 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 6919 } 6920 6921 static void alc883_medion_md2_unsol_event(struct hda_codec *codec, 6922 unsigned int res) 6923 { 6924 if ((res >> 26) == ALC880_HP_EVENT) 6925 alc883_medion_md2_automute(codec); 6926 } 6927 6928 /* toggle speaker-output according to the hp-jack state */ 6929 static void alc883_tagra_automute(struct hda_codec *codec) 6930 { 6931 unsigned int present; 6932 unsigned char bits; 6933 6934 present = snd_hda_codec_read(codec, 0x14, 0, 6935 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 6936 bits = present ? HDA_AMP_MUTE : 0; 6937 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0, 6938 HDA_AMP_MUTE, bits); 6939 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA, 6940 present ? 1 : 3); 6941 } 6942 6943 static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res) 6944 { 6945 if ((res >> 26) == ALC880_HP_EVENT) 6946 alc883_tagra_automute(codec); 6947 } 6948 6949 static void alc883_haier_w66_automute(struct hda_codec *codec) 6950 { 6951 unsigned int present; 6952 unsigned char bits; 6953 6954 present = snd_hda_codec_read(codec, 0x1b, 0, 6955 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 6956 bits = present ? 0x80 : 0; 6957 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 6958 0x80, bits); 6959 } 6960 6961 static void alc883_haier_w66_unsol_event(struct hda_codec *codec, 6962 unsigned int res) 6963 { 6964 if ((res >> 26) == ALC880_HP_EVENT) 6965 alc883_haier_w66_automute(codec); 6966 } 6967 6968 static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec) 6969 { 6970 unsigned int present; 6971 unsigned char bits; 6972 6973 present = snd_hda_codec_read(codec, 0x14, 0, 6974 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 6975 bits = present ? HDA_AMP_MUTE : 0; 6976 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 6977 HDA_AMP_MUTE, bits); 6978 } 6979 6980 static void alc883_lenovo_101e_all_automute(struct hda_codec *codec) 6981 { 6982 unsigned int present; 6983 unsigned char bits; 6984 6985 present = snd_hda_codec_read(codec, 0x1b, 0, 6986 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 6987 bits = present ? HDA_AMP_MUTE : 0; 6988 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 6989 HDA_AMP_MUTE, bits); 6990 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 6991 HDA_AMP_MUTE, bits); 6992 } 6993 6994 static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec, 6995 unsigned int res) 6996 { 6997 if ((res >> 26) == ALC880_HP_EVENT) 6998 alc883_lenovo_101e_all_automute(codec); 6999 if ((res >> 26) == ALC880_FRONT_EVENT) 7000 alc883_lenovo_101e_ispeaker_automute(codec); 7001 } 7002 7003 /* toggle speaker-output according to the hp-jack state */ 7004 static void alc883_acer_aspire_automute(struct hda_codec *codec) 7005 { 7006 unsigned int present; 7007 7008 present = snd_hda_codec_read(codec, 0x14, 0, 7009 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 7010 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 7011 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 7012 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0, 7013 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 7014 } 7015 7016 static void alc883_acer_aspire_unsol_event(struct hda_codec *codec, 7017 unsigned int res) 7018 { 7019 if ((res >> 26) == ALC880_HP_EVENT) 7020 alc883_acer_aspire_automute(codec); 7021 } 7022 7023 static struct hda_verb alc883_acer_eapd_verbs[] = { 7024 /* HP Pin: output 0 (0x0c) */ 7025 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 7026 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7027 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 7028 /* Front Pin: output 0 (0x0c) */ 7029 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 7030 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 7031 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 7032 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, 7033 /* eanable EAPD on medion laptop */ 7034 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 7035 {0x20, AC_VERB_SET_PROC_COEF, 0x3050}, 7036 /* enable unsolicited event */ 7037 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 7038 { } 7039 }; 7040 7041 /* 7042 * generic initialization of ADC, input mixers and output mixers 7043 */ 7044 static struct hda_verb alc883_auto_init_verbs[] = { 7045 /* 7046 * Unmute ADC0-2 and set the default input to mic-in 7047 */ 7048 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 7049 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7050 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 7051 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7052 7053 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 7054 * mixer widget 7055 * Note: PASD motherboards uses the Line In 2 as the input for 7056 * front panel mic (mic 2) 7057 */ 7058 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 7059 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7060 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7061 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 7062 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 7063 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 7064 7065 /* 7066 * Set up output mixers (0x0c - 0x0f) 7067 */ 7068 /* set vol=0 to output mixers */ 7069 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 7070 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 7071 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 7072 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 7073 /* set up input amps for analog loopback */ 7074 /* Amp Indices: DAC = 0, mixer = 1 */ 7075 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7076 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 7077 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7078 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 7079 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7080 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 7081 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7082 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 7083 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7084 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 7085 7086 /* FIXME: use matrix-type input source selection */ 7087 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 7088 /* Input mixer1 */ 7089 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7090 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 7091 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 7092 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */ 7093 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, 7094 /* Input mixer2 */ 7095 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7096 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 7097 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 7098 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */ 7099 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, 7100 7101 { } 7102 }; 7103 7104 /* capture mixer elements */ 7105 static struct snd_kcontrol_new alc883_capture_mixer[] = { 7106 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 7107 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 7108 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), 7109 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), 7110 { 7111 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 7112 /* The multiple "Capture Source" controls confuse alsamixer 7113 * So call somewhat different.. 7114 * FIXME: the controls appear in the "playback" view! 7115 */ 7116 /* .name = "Capture Source", */ 7117 .name = "Input Source", 7118 .count = 2, 7119 .info = alc882_mux_enum_info, 7120 .get = alc882_mux_enum_get, 7121 .put = alc882_mux_enum_put, 7122 }, 7123 { } /* end */ 7124 }; 7125 7126 #ifdef CONFIG_SND_HDA_POWER_SAVE 7127 #define alc883_loopbacks alc880_loopbacks 7128 #endif 7129 7130 /* pcm configuration: identiacal with ALC880 */ 7131 #define alc883_pcm_analog_playback alc880_pcm_analog_playback 7132 #define alc883_pcm_analog_capture alc880_pcm_analog_capture 7133 #define alc883_pcm_digital_playback alc880_pcm_digital_playback 7134 #define alc883_pcm_digital_capture alc880_pcm_digital_capture 7135 7136 /* 7137 * configuration and preset 7138 */ 7139 static const char *alc883_models[ALC883_MODEL_LAST] = { 7140 [ALC883_3ST_2ch_DIG] = "3stack-dig", 7141 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig", 7142 [ALC883_3ST_6ch] = "3stack-6ch", 7143 [ALC883_6ST_DIG] = "6stack-dig", 7144 [ALC883_TARGA_DIG] = "targa-dig", 7145 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig", 7146 [ALC883_ACER] = "acer", 7147 [ALC883_ACER_ASPIRE] = "acer-aspire", 7148 [ALC883_MEDION] = "medion", 7149 [ALC883_MEDION_MD2] = "medion-md2", 7150 [ALC883_LAPTOP_EAPD] = "laptop-eapd", 7151 [ALC883_LENOVO_101E_2ch] = "lenovo-101e", 7152 [ALC883_LENOVO_NB0763] = "lenovo-nb0763", 7153 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig", 7154 [ALC883_HAIER_W66] = "haier-w66", 7155 [ALC888_6ST_HP] = "6stack-hp", 7156 [ALC888_3ST_HP] = "3stack-hp", 7157 [ALC883_AUTO] = "auto", 7158 }; 7159 7160 static struct snd_pci_quirk alc883_cfg_tbl[] = { 7161 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG), 7162 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG), 7163 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch), 7164 SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD), 7165 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG), 7166 SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG), 7167 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG), 7168 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG), 7169 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG), 7170 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG), 7171 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG), 7172 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG), 7173 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG), 7174 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG), 7175 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG), 7176 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG), 7177 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG), 7178 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG), 7179 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG), 7180 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG), 7181 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG), 7182 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG), 7183 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG), 7184 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG), 7185 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE), 7186 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE), 7187 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE), 7188 SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER), 7189 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch), 7190 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION), 7191 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD), 7192 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch), 7193 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch), 7194 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763), 7195 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763), 7196 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC888_6ST_HP), 7197 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP), 7198 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP), 7199 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2), 7200 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66), 7201 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763), 7202 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG), 7203 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG), 7204 {} 7205 }; 7206 7207 static struct alc_config_preset alc883_presets[] = { 7208 [ALC883_3ST_2ch_DIG] = { 7209 .mixers = { alc883_3ST_2ch_mixer }, 7210 .init_verbs = { alc883_init_verbs }, 7211 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 7212 .dac_nids = alc883_dac_nids, 7213 .dig_out_nid = ALC883_DIGOUT_NID, 7214 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 7215 .adc_nids = alc883_adc_nids, 7216 .dig_in_nid = ALC883_DIGIN_NID, 7217 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 7218 .channel_mode = alc883_3ST_2ch_modes, 7219 .input_mux = &alc883_capture_source, 7220 }, 7221 [ALC883_3ST_6ch_DIG] = { 7222 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, 7223 .init_verbs = { alc883_init_verbs }, 7224 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 7225 .dac_nids = alc883_dac_nids, 7226 .dig_out_nid = ALC883_DIGOUT_NID, 7227 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 7228 .adc_nids = alc883_adc_nids, 7229 .dig_in_nid = ALC883_DIGIN_NID, 7230 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 7231 .channel_mode = alc883_3ST_6ch_modes, 7232 .need_dac_fix = 1, 7233 .input_mux = &alc883_capture_source, 7234 }, 7235 [ALC883_3ST_6ch] = { 7236 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, 7237 .init_verbs = { alc883_init_verbs }, 7238 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 7239 .dac_nids = alc883_dac_nids, 7240 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 7241 .adc_nids = alc883_adc_nids, 7242 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 7243 .channel_mode = alc883_3ST_6ch_modes, 7244 .need_dac_fix = 1, 7245 .input_mux = &alc883_capture_source, 7246 }, 7247 [ALC883_6ST_DIG] = { 7248 .mixers = { alc883_base_mixer, alc883_chmode_mixer }, 7249 .init_verbs = { alc883_init_verbs }, 7250 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 7251 .dac_nids = alc883_dac_nids, 7252 .dig_out_nid = ALC883_DIGOUT_NID, 7253 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 7254 .adc_nids = alc883_adc_nids, 7255 .dig_in_nid = ALC883_DIGIN_NID, 7256 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), 7257 .channel_mode = alc883_sixstack_modes, 7258 .input_mux = &alc883_capture_source, 7259 }, 7260 [ALC883_TARGA_DIG] = { 7261 .mixers = { alc883_tagra_mixer, alc883_chmode_mixer }, 7262 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs}, 7263 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 7264 .dac_nids = alc883_dac_nids, 7265 .dig_out_nid = ALC883_DIGOUT_NID, 7266 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 7267 .adc_nids = alc883_adc_nids, 7268 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 7269 .channel_mode = alc883_3ST_6ch_modes, 7270 .need_dac_fix = 1, 7271 .input_mux = &alc883_capture_source, 7272 .unsol_event = alc883_tagra_unsol_event, 7273 .init_hook = alc883_tagra_automute, 7274 }, 7275 [ALC883_TARGA_2ch_DIG] = { 7276 .mixers = { alc883_tagra_2ch_mixer}, 7277 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs}, 7278 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 7279 .dac_nids = alc883_dac_nids, 7280 .dig_out_nid = ALC883_DIGOUT_NID, 7281 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 7282 .adc_nids = alc883_adc_nids, 7283 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 7284 .channel_mode = alc883_3ST_2ch_modes, 7285 .input_mux = &alc883_capture_source, 7286 .unsol_event = alc883_tagra_unsol_event, 7287 .init_hook = alc883_tagra_automute, 7288 }, 7289 [ALC883_ACER] = { 7290 .mixers = { alc883_base_mixer }, 7291 /* On TravelMate laptops, GPIO 0 enables the internal speaker 7292 * and the headphone jack. Turn this on and rely on the 7293 * standard mute methods whenever the user wants to turn 7294 * these outputs off. 7295 */ 7296 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs }, 7297 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 7298 .dac_nids = alc883_dac_nids, 7299 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 7300 .adc_nids = alc883_adc_nids, 7301 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 7302 .channel_mode = alc883_3ST_2ch_modes, 7303 .input_mux = &alc883_capture_source, 7304 }, 7305 [ALC883_ACER_ASPIRE] = { 7306 .mixers = { alc883_acer_aspire_mixer }, 7307 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs }, 7308 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 7309 .dac_nids = alc883_dac_nids, 7310 .dig_out_nid = ALC883_DIGOUT_NID, 7311 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 7312 .adc_nids = alc883_adc_nids, 7313 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 7314 .channel_mode = alc883_3ST_2ch_modes, 7315 .input_mux = &alc883_capture_source, 7316 .unsol_event = alc883_acer_aspire_unsol_event, 7317 .init_hook = alc883_acer_aspire_automute, 7318 }, 7319 [ALC883_MEDION] = { 7320 .mixers = { alc883_fivestack_mixer, 7321 alc883_chmode_mixer }, 7322 .init_verbs = { alc883_init_verbs, 7323 alc883_medion_eapd_verbs }, 7324 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 7325 .dac_nids = alc883_dac_nids, 7326 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 7327 .adc_nids = alc883_adc_nids, 7328 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), 7329 .channel_mode = alc883_sixstack_modes, 7330 .input_mux = &alc883_capture_source, 7331 }, 7332 [ALC883_MEDION_MD2] = { 7333 .mixers = { alc883_medion_md2_mixer}, 7334 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs}, 7335 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 7336 .dac_nids = alc883_dac_nids, 7337 .dig_out_nid = ALC883_DIGOUT_NID, 7338 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 7339 .adc_nids = alc883_adc_nids, 7340 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 7341 .channel_mode = alc883_3ST_2ch_modes, 7342 .input_mux = &alc883_capture_source, 7343 .unsol_event = alc883_medion_md2_unsol_event, 7344 .init_hook = alc883_medion_md2_automute, 7345 }, 7346 [ALC883_LAPTOP_EAPD] = { 7347 .mixers = { alc883_base_mixer }, 7348 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs }, 7349 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 7350 .dac_nids = alc883_dac_nids, 7351 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 7352 .adc_nids = alc883_adc_nids, 7353 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 7354 .channel_mode = alc883_3ST_2ch_modes, 7355 .input_mux = &alc883_capture_source, 7356 }, 7357 [ALC883_LENOVO_101E_2ch] = { 7358 .mixers = { alc883_lenovo_101e_2ch_mixer}, 7359 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs}, 7360 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 7361 .dac_nids = alc883_dac_nids, 7362 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 7363 .adc_nids = alc883_adc_nids, 7364 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 7365 .channel_mode = alc883_3ST_2ch_modes, 7366 .input_mux = &alc883_lenovo_101e_capture_source, 7367 .unsol_event = alc883_lenovo_101e_unsol_event, 7368 .init_hook = alc883_lenovo_101e_all_automute, 7369 }, 7370 [ALC883_LENOVO_NB0763] = { 7371 .mixers = { alc883_lenovo_nb0763_mixer }, 7372 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs}, 7373 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 7374 .dac_nids = alc883_dac_nids, 7375 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 7376 .adc_nids = alc883_adc_nids, 7377 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 7378 .channel_mode = alc883_3ST_2ch_modes, 7379 .need_dac_fix = 1, 7380 .input_mux = &alc883_lenovo_nb0763_capture_source, 7381 .unsol_event = alc883_medion_md2_unsol_event, 7382 .init_hook = alc883_medion_md2_automute, 7383 }, 7384 [ALC888_LENOVO_MS7195_DIG] = { 7385 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, 7386 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs}, 7387 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 7388 .dac_nids = alc883_dac_nids, 7389 .dig_out_nid = ALC883_DIGOUT_NID, 7390 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 7391 .adc_nids = alc883_adc_nids, 7392 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 7393 .channel_mode = alc883_3ST_6ch_modes, 7394 .need_dac_fix = 1, 7395 .input_mux = &alc883_capture_source, 7396 .unsol_event = alc883_lenovo_ms7195_unsol_event, 7397 .init_hook = alc888_lenovo_ms7195_front_automute, 7398 }, 7399 [ALC883_HAIER_W66] = { 7400 .mixers = { alc883_tagra_2ch_mixer}, 7401 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs}, 7402 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 7403 .dac_nids = alc883_dac_nids, 7404 .dig_out_nid = ALC883_DIGOUT_NID, 7405 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 7406 .adc_nids = alc883_adc_nids, 7407 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 7408 .channel_mode = alc883_3ST_2ch_modes, 7409 .input_mux = &alc883_capture_source, 7410 .unsol_event = alc883_haier_w66_unsol_event, 7411 .init_hook = alc883_haier_w66_automute, 7412 }, 7413 [ALC888_6ST_HP] = { 7414 .mixers = { alc888_6st_hp_mixer, alc883_chmode_mixer }, 7415 .init_verbs = { alc883_init_verbs, alc888_6st_hp_verbs }, 7416 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 7417 .dac_nids = alc883_dac_nids, 7418 .dig_out_nid = ALC883_DIGOUT_NID, 7419 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 7420 .adc_nids = alc883_adc_nids, 7421 .dig_in_nid = ALC883_DIGIN_NID, 7422 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), 7423 .channel_mode = alc883_sixstack_modes, 7424 .input_mux = &alc883_capture_source, 7425 }, 7426 [ALC888_3ST_HP] = { 7427 .mixers = { alc888_3st_hp_mixer, alc883_chmode_mixer }, 7428 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs }, 7429 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 7430 .dac_nids = alc883_dac_nids, 7431 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 7432 .adc_nids = alc883_adc_nids, 7433 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes), 7434 .channel_mode = alc888_3st_hp_modes, 7435 .need_dac_fix = 1, 7436 .input_mux = &alc883_capture_source, 7437 }, 7438 }; 7439 7440 7441 /* 7442 * BIOS auto configuration 7443 */ 7444 static void alc883_auto_set_output_and_unmute(struct hda_codec *codec, 7445 hda_nid_t nid, int pin_type, 7446 int dac_idx) 7447 { 7448 /* set as output */ 7449 struct alc_spec *spec = codec->spec; 7450 int idx; 7451 7452 if (spec->multiout.dac_nids[dac_idx] == 0x25) 7453 idx = 4; 7454 else 7455 idx = spec->multiout.dac_nids[dac_idx] - 2; 7456 7457 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 7458 pin_type); 7459 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, 7460 AMP_OUT_UNMUTE); 7461 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx); 7462 7463 } 7464 7465 static void alc883_auto_init_multi_out(struct hda_codec *codec) 7466 { 7467 struct alc_spec *spec = codec->spec; 7468 int i; 7469 7470 alc_subsystem_id(codec, 0x15, 0x1b, 0x14); 7471 for (i = 0; i <= HDA_SIDE; i++) { 7472 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 7473 int pin_type = get_pin_type(spec->autocfg.line_out_type); 7474 if (nid) 7475 alc883_auto_set_output_and_unmute(codec, nid, pin_type, 7476 i); 7477 } 7478 } 7479 7480 static void alc883_auto_init_hp_out(struct hda_codec *codec) 7481 { 7482 struct alc_spec *spec = codec->spec; 7483 hda_nid_t pin; 7484 7485 pin = spec->autocfg.hp_pins[0]; 7486 if (pin) /* connect to front */ 7487 /* use dac 0 */ 7488 alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); 7489 } 7490 7491 #define alc883_is_input_pin(nid) alc880_is_input_pin(nid) 7492 #define ALC883_PIN_CD_NID ALC880_PIN_CD_NID 7493 7494 static void alc883_auto_init_analog_input(struct hda_codec *codec) 7495 { 7496 struct alc_spec *spec = codec->spec; 7497 int i; 7498 7499 for (i = 0; i < AUTO_PIN_LAST; i++) { 7500 hda_nid_t nid = spec->autocfg.input_pins[i]; 7501 if (alc883_is_input_pin(nid)) { 7502 snd_hda_codec_write(codec, nid, 0, 7503 AC_VERB_SET_PIN_WIDGET_CONTROL, 7504 (i <= AUTO_PIN_FRONT_MIC ? 7505 PIN_VREF80 : PIN_IN)); 7506 if (nid != ALC883_PIN_CD_NID) 7507 snd_hda_codec_write(codec, nid, 0, 7508 AC_VERB_SET_AMP_GAIN_MUTE, 7509 AMP_OUT_MUTE); 7510 } 7511 } 7512 } 7513 7514 /* almost identical with ALC880 parser... */ 7515 static int alc883_parse_auto_config(struct hda_codec *codec) 7516 { 7517 struct alc_spec *spec = codec->spec; 7518 int err = alc880_parse_auto_config(codec); 7519 7520 if (err < 0) 7521 return err; 7522 else if (!err) 7523 return 0; /* no config found */ 7524 7525 err = alc_auto_add_mic_boost(codec); 7526 if (err < 0) 7527 return err; 7528 7529 /* hack - override the init verbs */ 7530 spec->init_verbs[0] = alc883_auto_init_verbs; 7531 spec->mixers[spec->num_mixers] = alc883_capture_mixer; 7532 spec->num_mixers++; 7533 7534 return 1; /* config found */ 7535 } 7536 7537 /* additional initialization for auto-configuration model */ 7538 static void alc883_auto_init(struct hda_codec *codec) 7539 { 7540 alc883_auto_init_multi_out(codec); 7541 alc883_auto_init_hp_out(codec); 7542 alc883_auto_init_analog_input(codec); 7543 } 7544 7545 static int patch_alc883(struct hda_codec *codec) 7546 { 7547 struct alc_spec *spec; 7548 int err, board_config; 7549 7550 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 7551 if (spec == NULL) 7552 return -ENOMEM; 7553 7554 codec->spec = spec; 7555 7556 board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST, 7557 alc883_models, 7558 alc883_cfg_tbl); 7559 if (board_config < 0) { 7560 printk(KERN_INFO "hda_codec: Unknown model for ALC883, " 7561 "trying auto-probe from BIOS...\n"); 7562 board_config = ALC883_AUTO; 7563 } 7564 7565 if (board_config == ALC883_AUTO) { 7566 /* automatic parse from the BIOS config */ 7567 err = alc883_parse_auto_config(codec); 7568 if (err < 0) { 7569 alc_free(codec); 7570 return err; 7571 } else if (!err) { 7572 printk(KERN_INFO 7573 "hda_codec: Cannot set up configuration " 7574 "from BIOS. Using base mode...\n"); 7575 board_config = ALC883_3ST_2ch_DIG; 7576 } 7577 } 7578 7579 if (board_config != ALC883_AUTO) 7580 setup_preset(spec, &alc883_presets[board_config]); 7581 7582 spec->stream_name_analog = "ALC883 Analog"; 7583 spec->stream_analog_playback = &alc883_pcm_analog_playback; 7584 spec->stream_analog_capture = &alc883_pcm_analog_capture; 7585 7586 spec->stream_name_digital = "ALC883 Digital"; 7587 spec->stream_digital_playback = &alc883_pcm_digital_playback; 7588 spec->stream_digital_capture = &alc883_pcm_digital_capture; 7589 7590 if (!spec->adc_nids && spec->input_mux) { 7591 spec->adc_nids = alc883_adc_nids; 7592 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids); 7593 } 7594 7595 codec->patch_ops = alc_patch_ops; 7596 if (board_config == ALC883_AUTO) 7597 spec->init_hook = alc883_auto_init; 7598 #ifdef CONFIG_SND_HDA_POWER_SAVE 7599 if (!spec->loopback.amplist) 7600 spec->loopback.amplist = alc883_loopbacks; 7601 #endif 7602 7603 return 0; 7604 } 7605 7606 /* 7607 * ALC262 support 7608 */ 7609 7610 #define ALC262_DIGOUT_NID ALC880_DIGOUT_NID 7611 #define ALC262_DIGIN_NID ALC880_DIGIN_NID 7612 7613 #define alc262_dac_nids alc260_dac_nids 7614 #define alc262_adc_nids alc882_adc_nids 7615 #define alc262_adc_nids_alt alc882_adc_nids_alt 7616 7617 #define alc262_modes alc260_modes 7618 #define alc262_capture_source alc882_capture_source 7619 7620 static struct snd_kcontrol_new alc262_base_mixer[] = { 7621 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7622 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 7623 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 7624 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 7625 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 7626 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 7627 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7628 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7629 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 7630 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 7631 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 7632 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 7633 /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT), 7634 HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */ 7635 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT), 7636 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 7637 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 7638 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT), 7639 { } /* end */ 7640 }; 7641 7642 static struct snd_kcontrol_new alc262_hippo1_mixer[] = { 7643 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7644 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 7645 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 7646 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 7647 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 7648 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 7649 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7650 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7651 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 7652 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 7653 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 7654 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 7655 /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT), 7656 HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */ 7657 /*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/ 7658 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 7659 { } /* end */ 7660 }; 7661 7662 static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = { 7663 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7664 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT), 7665 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 7666 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 7667 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT), 7668 7669 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7670 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7671 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 7672 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 7673 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 7674 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 7675 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 7676 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 7677 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 7678 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 7679 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT), 7680 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), 7681 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT), 7682 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT), 7683 { } /* end */ 7684 }; 7685 7686 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = { 7687 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7688 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 7689 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 7690 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 7691 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 7692 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT), 7693 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT), 7694 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT), 7695 HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT), 7696 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT), 7697 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT), 7698 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 7699 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 7700 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT), 7701 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), 7702 { } /* end */ 7703 }; 7704 7705 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = { 7706 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7707 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7708 HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT), 7709 { } /* end */ 7710 }; 7711 7712 /* bind hp and internal speaker mute (with plug check) */ 7713 static int alc262_sony_master_sw_put(struct snd_kcontrol *kcontrol, 7714 struct snd_ctl_elem_value *ucontrol) 7715 { 7716 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 7717 long *valp = ucontrol->value.integer.value; 7718 int change; 7719 7720 /* change hp mute */ 7721 change = snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0, 7722 HDA_AMP_MUTE, 7723 valp[0] ? 0 : HDA_AMP_MUTE); 7724 change |= snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0, 7725 HDA_AMP_MUTE, 7726 valp[1] ? 0 : HDA_AMP_MUTE); 7727 if (change) { 7728 /* change speaker according to HP jack state */ 7729 struct alc_spec *spec = codec->spec; 7730 unsigned int mute; 7731 if (spec->jack_present) 7732 mute = HDA_AMP_MUTE; 7733 else 7734 mute = snd_hda_codec_amp_read(codec, 0x15, 0, 7735 HDA_OUTPUT, 0); 7736 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 7737 HDA_AMP_MUTE, mute); 7738 } 7739 return change; 7740 } 7741 7742 static struct snd_kcontrol_new alc262_sony_mixer[] = { 7743 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7744 { 7745 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 7746 .name = "Master Playback Switch", 7747 .info = snd_hda_mixer_amp_switch_info, 7748 .get = snd_hda_mixer_amp_switch_get, 7749 .put = alc262_sony_master_sw_put, 7750 .private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT), 7751 }, 7752 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7753 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7754 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 7755 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 7756 { } /* end */ 7757 }; 7758 7759 static struct snd_kcontrol_new alc262_benq_t31_mixer[] = { 7760 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7761 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 7762 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 7763 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7764 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7765 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 7766 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 7767 { } /* end */ 7768 }; 7769 7770 #define alc262_capture_mixer alc882_capture_mixer 7771 #define alc262_capture_alt_mixer alc882_capture_alt_mixer 7772 7773 /* 7774 * generic initialization of ADC, input mixers and output mixers 7775 */ 7776 static struct hda_verb alc262_init_verbs[] = { 7777 /* 7778 * Unmute ADC0-2 and set the default input to mic-in 7779 */ 7780 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 7781 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7782 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 7783 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7784 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 7785 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7786 7787 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 7788 * mixer widget 7789 * Note: PASD motherboards uses the Line In 2 as the input for 7790 * front panel mic (mic 2) 7791 */ 7792 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 7793 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7794 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7795 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 7796 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 7797 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 7798 7799 /* 7800 * Set up output mixers (0x0c - 0x0e) 7801 */ 7802 /* set vol=0 to output mixers */ 7803 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 7804 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 7805 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 7806 /* set up input amps for analog loopback */ 7807 /* Amp Indices: DAC = 0, mixer = 1 */ 7808 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7809 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 7810 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7811 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 7812 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7813 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 7814 7815 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 7816 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 7817 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 7818 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 7819 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 7820 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 7821 7822 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 7823 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 7824 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 7825 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 7826 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 7827 7828 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 7829 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 7830 7831 /* FIXME: use matrix-type input source selection */ 7832 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 7833 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 7834 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 7835 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 7836 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 7837 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 7838 /* Input mixer2 */ 7839 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 7840 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 7841 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 7842 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 7843 /* Input mixer3 */ 7844 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 7845 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 7846 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 7847 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 7848 7849 { } 7850 }; 7851 7852 static struct hda_verb alc262_hippo_unsol_verbs[] = { 7853 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 7854 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 7855 {} 7856 }; 7857 7858 static struct hda_verb alc262_hippo1_unsol_verbs[] = { 7859 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 7860 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 7861 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 7862 7863 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 7864 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 7865 {} 7866 }; 7867 7868 static struct hda_verb alc262_sony_unsol_verbs[] = { 7869 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 7870 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 7871 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic 7872 7873 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 7874 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 7875 }; 7876 7877 /* mute/unmute internal speaker according to the hp jack and mute state */ 7878 static void alc262_hippo_automute(struct hda_codec *codec) 7879 { 7880 struct alc_spec *spec = codec->spec; 7881 unsigned int mute; 7882 unsigned int present; 7883 7884 /* need to execute and sync at first */ 7885 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0); 7886 present = snd_hda_codec_read(codec, 0x15, 0, 7887 AC_VERB_GET_PIN_SENSE, 0); 7888 spec->jack_present = (present & 0x80000000) != 0; 7889 if (spec->jack_present) { 7890 /* mute internal speaker */ 7891 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 7892 HDA_AMP_MUTE, HDA_AMP_MUTE); 7893 } else { 7894 /* unmute internal speaker if necessary */ 7895 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0); 7896 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 7897 HDA_AMP_MUTE, mute); 7898 } 7899 } 7900 7901 /* unsolicited event for HP jack sensing */ 7902 static void alc262_hippo_unsol_event(struct hda_codec *codec, 7903 unsigned int res) 7904 { 7905 if ((res >> 26) != ALC880_HP_EVENT) 7906 return; 7907 alc262_hippo_automute(codec); 7908 } 7909 7910 static void alc262_hippo1_automute(struct hda_codec *codec) 7911 { 7912 unsigned int mute; 7913 unsigned int present; 7914 7915 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0); 7916 present = snd_hda_codec_read(codec, 0x1b, 0, 7917 AC_VERB_GET_PIN_SENSE, 0); 7918 present = (present & 0x80000000) != 0; 7919 if (present) { 7920 /* mute internal speaker */ 7921 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 7922 HDA_AMP_MUTE, HDA_AMP_MUTE); 7923 } else { 7924 /* unmute internal speaker if necessary */ 7925 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0); 7926 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 7927 HDA_AMP_MUTE, mute); 7928 } 7929 } 7930 7931 /* unsolicited event for HP jack sensing */ 7932 static void alc262_hippo1_unsol_event(struct hda_codec *codec, 7933 unsigned int res) 7934 { 7935 if ((res >> 26) != ALC880_HP_EVENT) 7936 return; 7937 alc262_hippo1_automute(codec); 7938 } 7939 7940 /* 7941 * fujitsu model 7942 * 0x14 = headphone/spdif-out, 0x15 = internal speaker 7943 */ 7944 7945 #define ALC_HP_EVENT 0x37 7946 7947 static struct hda_verb alc262_fujitsu_unsol_verbs[] = { 7948 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, 7949 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 7950 {} 7951 }; 7952 7953 static struct hda_input_mux alc262_fujitsu_capture_source = { 7954 .num_items = 3, 7955 .items = { 7956 { "Mic", 0x0 }, 7957 { "Int Mic", 0x1 }, 7958 { "CD", 0x4 }, 7959 }, 7960 }; 7961 7962 static struct hda_input_mux alc262_HP_capture_source = { 7963 .num_items = 5, 7964 .items = { 7965 { "Mic", 0x0 }, 7966 { "Front Mic", 0x1 }, 7967 { "Line", 0x2 }, 7968 { "CD", 0x4 }, 7969 { "AUX IN", 0x6 }, 7970 }, 7971 }; 7972 7973 static struct hda_input_mux alc262_HP_D7000_capture_source = { 7974 .num_items = 4, 7975 .items = { 7976 { "Mic", 0x0 }, 7977 { "Front Mic", 0x2 }, 7978 { "Line", 0x1 }, 7979 { "CD", 0x4 }, 7980 }, 7981 }; 7982 7983 /* mute/unmute internal speaker according to the hp jack and mute state */ 7984 static void alc262_fujitsu_automute(struct hda_codec *codec, int force) 7985 { 7986 struct alc_spec *spec = codec->spec; 7987 unsigned int mute; 7988 7989 if (force || !spec->sense_updated) { 7990 unsigned int present; 7991 /* need to execute and sync at first */ 7992 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0); 7993 present = snd_hda_codec_read(codec, 0x14, 0, 7994 AC_VERB_GET_PIN_SENSE, 0); 7995 spec->jack_present = (present & 0x80000000) != 0; 7996 spec->sense_updated = 1; 7997 } 7998 if (spec->jack_present) { 7999 /* mute internal speaker */ 8000 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 8001 HDA_AMP_MUTE, HDA_AMP_MUTE); 8002 } else { 8003 /* unmute internal speaker if necessary */ 8004 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0); 8005 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 8006 HDA_AMP_MUTE, mute); 8007 } 8008 } 8009 8010 /* unsolicited event for HP jack sensing */ 8011 static void alc262_fujitsu_unsol_event(struct hda_codec *codec, 8012 unsigned int res) 8013 { 8014 if ((res >> 26) != ALC_HP_EVENT) 8015 return; 8016 alc262_fujitsu_automute(codec, 1); 8017 } 8018 8019 /* bind volumes of both NID 0x0c and 0x0d */ 8020 static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = { 8021 .ops = &snd_hda_bind_vol, 8022 .values = { 8023 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT), 8024 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT), 8025 0 8026 }, 8027 }; 8028 8029 /* bind hp and internal speaker mute (with plug check) */ 8030 static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol, 8031 struct snd_ctl_elem_value *ucontrol) 8032 { 8033 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 8034 long *valp = ucontrol->value.integer.value; 8035 int change; 8036 8037 change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0, 8038 HDA_AMP_MUTE, 8039 valp[0] ? 0 : HDA_AMP_MUTE); 8040 change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0, 8041 HDA_AMP_MUTE, 8042 valp[1] ? 0 : HDA_AMP_MUTE); 8043 if (change) 8044 alc262_fujitsu_automute(codec, 0); 8045 return change; 8046 } 8047 8048 static struct snd_kcontrol_new alc262_fujitsu_mixer[] = { 8049 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol), 8050 { 8051 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 8052 .name = "Master Playback Switch", 8053 .info = snd_hda_mixer_amp_switch_info, 8054 .get = snd_hda_mixer_amp_switch_get, 8055 .put = alc262_fujitsu_master_sw_put, 8056 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 8057 }, 8058 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 8059 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 8060 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8061 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8062 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8063 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 8064 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8065 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8066 { } /* end */ 8067 }; 8068 8069 /* additional init verbs for Benq laptops */ 8070 static struct hda_verb alc262_EAPD_verbs[] = { 8071 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 8072 {0x20, AC_VERB_SET_PROC_COEF, 0x3070}, 8073 {} 8074 }; 8075 8076 static struct hda_verb alc262_benq_t31_EAPD_verbs[] = { 8077 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 8078 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 8079 8080 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 8081 {0x20, AC_VERB_SET_PROC_COEF, 0x3050}, 8082 {} 8083 }; 8084 8085 /* add playback controls from the parsed DAC table */ 8086 static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, 8087 const struct auto_pin_cfg *cfg) 8088 { 8089 hda_nid_t nid; 8090 int err; 8091 8092 spec->multiout.num_dacs = 1; /* only use one dac */ 8093 spec->multiout.dac_nids = spec->private_dac_nids; 8094 spec->multiout.dac_nids[0] = 2; 8095 8096 nid = cfg->line_out_pins[0]; 8097 if (nid) { 8098 err = add_control(spec, ALC_CTL_WIDGET_VOL, 8099 "Front Playback Volume", 8100 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT)); 8101 if (err < 0) 8102 return err; 8103 err = add_control(spec, ALC_CTL_WIDGET_MUTE, 8104 "Front Playback Switch", 8105 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); 8106 if (err < 0) 8107 return err; 8108 } 8109 8110 nid = cfg->speaker_pins[0]; 8111 if (nid) { 8112 if (nid == 0x16) { 8113 err = add_control(spec, ALC_CTL_WIDGET_VOL, 8114 "Speaker Playback Volume", 8115 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, 8116 HDA_OUTPUT)); 8117 if (err < 0) 8118 return err; 8119 err = add_control(spec, ALC_CTL_WIDGET_MUTE, 8120 "Speaker Playback Switch", 8121 HDA_COMPOSE_AMP_VAL(nid, 2, 0, 8122 HDA_OUTPUT)); 8123 if (err < 0) 8124 return err; 8125 } else { 8126 err = add_control(spec, ALC_CTL_WIDGET_MUTE, 8127 "Speaker Playback Switch", 8128 HDA_COMPOSE_AMP_VAL(nid, 3, 0, 8129 HDA_OUTPUT)); 8130 if (err < 0) 8131 return err; 8132 } 8133 } 8134 nid = cfg->hp_pins[0]; 8135 if (nid) { 8136 /* spec->multiout.hp_nid = 2; */ 8137 if (nid == 0x16) { 8138 err = add_control(spec, ALC_CTL_WIDGET_VOL, 8139 "Headphone Playback Volume", 8140 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, 8141 HDA_OUTPUT)); 8142 if (err < 0) 8143 return err; 8144 err = add_control(spec, ALC_CTL_WIDGET_MUTE, 8145 "Headphone Playback Switch", 8146 HDA_COMPOSE_AMP_VAL(nid, 2, 0, 8147 HDA_OUTPUT)); 8148 if (err < 0) 8149 return err; 8150 } else { 8151 err = add_control(spec, ALC_CTL_WIDGET_MUTE, 8152 "Headphone Playback Switch", 8153 HDA_COMPOSE_AMP_VAL(nid, 3, 0, 8154 HDA_OUTPUT)); 8155 if (err < 0) 8156 return err; 8157 } 8158 } 8159 return 0; 8160 } 8161 8162 /* identical with ALC880 */ 8163 #define alc262_auto_create_analog_input_ctls \ 8164 alc880_auto_create_analog_input_ctls 8165 8166 /* 8167 * generic initialization of ADC, input mixers and output mixers 8168 */ 8169 static struct hda_verb alc262_volume_init_verbs[] = { 8170 /* 8171 * Unmute ADC0-2 and set the default input to mic-in 8172 */ 8173 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 8174 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8175 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 8176 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8177 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 8178 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8179 8180 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 8181 * mixer widget 8182 * Note: PASD motherboards uses the Line In 2 as the input for 8183 * front panel mic (mic 2) 8184 */ 8185 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 8186 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8187 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8188 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 8189 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8190 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8191 8192 /* 8193 * Set up output mixers (0x0c - 0x0f) 8194 */ 8195 /* set vol=0 to output mixers */ 8196 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8197 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8198 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8199 8200 /* set up input amps for analog loopback */ 8201 /* Amp Indices: DAC = 0, mixer = 1 */ 8202 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8203 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8204 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8205 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8206 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8207 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8208 8209 /* FIXME: use matrix-type input source selection */ 8210 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 8211 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 8212 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 8213 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 8214 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 8215 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 8216 /* Input mixer2 */ 8217 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 8218 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 8219 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 8220 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 8221 /* Input mixer3 */ 8222 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 8223 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 8224 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 8225 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 8226 8227 { } 8228 }; 8229 8230 static struct hda_verb alc262_HP_BPC_init_verbs[] = { 8231 /* 8232 * Unmute ADC0-2 and set the default input to mic-in 8233 */ 8234 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 8235 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8236 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 8237 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8238 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 8239 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8240 8241 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 8242 * mixer widget 8243 * Note: PASD motherboards uses the Line In 2 as the input for 8244 * front panel mic (mic 2) 8245 */ 8246 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 8247 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8248 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8249 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 8250 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8251 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8252 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, 8253 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, 8254 8255 /* 8256 * Set up output mixers (0x0c - 0x0e) 8257 */ 8258 /* set vol=0 to output mixers */ 8259 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8260 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8261 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8262 8263 /* set up input amps for analog loopback */ 8264 /* Amp Indices: DAC = 0, mixer = 1 */ 8265 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8266 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8267 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8268 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8269 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8270 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8271 8272 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 8273 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 8274 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 8275 8276 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 8277 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 8278 8279 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 8280 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 8281 8282 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 8283 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 8284 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 8285 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 8286 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 8287 8288 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, 8289 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 8290 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 8291 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, 8292 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 8293 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 8294 8295 8296 /* FIXME: use matrix-type input source selection */ 8297 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 8298 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 8299 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 8300 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, 8301 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, 8302 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, 8303 /* Input mixer2 */ 8304 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 8305 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, 8306 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, 8307 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, 8308 /* Input mixer3 */ 8309 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 8310 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, 8311 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, 8312 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, 8313 8314 { } 8315 }; 8316 8317 static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = { 8318 /* 8319 * Unmute ADC0-2 and set the default input to mic-in 8320 */ 8321 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 8322 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8323 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 8324 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8325 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 8326 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8327 8328 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 8329 * mixer widget 8330 * Note: PASD motherboards uses the Line In 2 as the input for front 8331 * panel mic (mic 2) 8332 */ 8333 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 8334 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8335 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8336 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 8337 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8338 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8339 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, 8340 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, 8341 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, 8342 /* 8343 * Set up output mixers (0x0c - 0x0e) 8344 */ 8345 /* set vol=0 to output mixers */ 8346 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8347 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8348 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8349 8350 /* set up input amps for analog loopback */ 8351 /* Amp Indices: DAC = 0, mixer = 1 */ 8352 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8353 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8354 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8355 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8356 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8357 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8358 8359 8360 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */ 8361 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */ 8362 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */ 8363 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */ 8364 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */ 8365 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */ 8366 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */ 8367 8368 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 8369 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 8370 8371 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 8372 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 8373 8374 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */ 8375 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 8376 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 8377 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, 8378 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 8379 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 8380 8381 /* FIXME: use matrix-type input source selection */ 8382 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 8383 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 8384 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/ 8385 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/ 8386 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/ 8387 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/ 8388 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/ 8389 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */ 8390 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/ 8391 /* Input mixer2 */ 8392 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 8393 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 8394 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, 8395 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, 8396 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, 8397 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */ 8398 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, 8399 /* Input mixer3 */ 8400 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 8401 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 8402 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, 8403 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, 8404 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, 8405 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */ 8406 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, 8407 8408 { } 8409 }; 8410 8411 #ifdef CONFIG_SND_HDA_POWER_SAVE 8412 #define alc262_loopbacks alc880_loopbacks 8413 #endif 8414 8415 /* pcm configuration: identiacal with ALC880 */ 8416 #define alc262_pcm_analog_playback alc880_pcm_analog_playback 8417 #define alc262_pcm_analog_capture alc880_pcm_analog_capture 8418 #define alc262_pcm_digital_playback alc880_pcm_digital_playback 8419 #define alc262_pcm_digital_capture alc880_pcm_digital_capture 8420 8421 /* 8422 * BIOS auto configuration 8423 */ 8424 static int alc262_parse_auto_config(struct hda_codec *codec) 8425 { 8426 struct alc_spec *spec = codec->spec; 8427 int err; 8428 static hda_nid_t alc262_ignore[] = { 0x1d, 0 }; 8429 8430 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 8431 alc262_ignore); 8432 if (err < 0) 8433 return err; 8434 if (!spec->autocfg.line_outs) 8435 return 0; /* can't find valid BIOS pin config */ 8436 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg); 8437 if (err < 0) 8438 return err; 8439 err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg); 8440 if (err < 0) 8441 return err; 8442 8443 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 8444 8445 if (spec->autocfg.dig_out_pin) 8446 spec->multiout.dig_out_nid = ALC262_DIGOUT_NID; 8447 if (spec->autocfg.dig_in_pin) 8448 spec->dig_in_nid = ALC262_DIGIN_NID; 8449 8450 if (spec->kctl_alloc) 8451 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 8452 8453 spec->init_verbs[spec->num_init_verbs++] = alc262_volume_init_verbs; 8454 spec->num_mux_defs = 1; 8455 spec->input_mux = &spec->private_imux; 8456 8457 err = alc_auto_add_mic_boost(codec); 8458 if (err < 0) 8459 return err; 8460 8461 return 1; 8462 } 8463 8464 #define alc262_auto_init_multi_out alc882_auto_init_multi_out 8465 #define alc262_auto_init_hp_out alc882_auto_init_hp_out 8466 #define alc262_auto_init_analog_input alc882_auto_init_analog_input 8467 8468 8469 /* init callback for auto-configuration model -- overriding the default init */ 8470 static void alc262_auto_init(struct hda_codec *codec) 8471 { 8472 alc262_auto_init_multi_out(codec); 8473 alc262_auto_init_hp_out(codec); 8474 alc262_auto_init_analog_input(codec); 8475 } 8476 8477 /* 8478 * configuration and preset 8479 */ 8480 static const char *alc262_models[ALC262_MODEL_LAST] = { 8481 [ALC262_BASIC] = "basic", 8482 [ALC262_HIPPO] = "hippo", 8483 [ALC262_HIPPO_1] = "hippo_1", 8484 [ALC262_FUJITSU] = "fujitsu", 8485 [ALC262_HP_BPC] = "hp-bpc", 8486 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000", 8487 [ALC262_BENQ_ED8] = "benq", 8488 [ALC262_BENQ_T31] = "benq-t31", 8489 [ALC262_SONY_ASSAMD] = "sony-assamd", 8490 [ALC262_AUTO] = "auto", 8491 }; 8492 8493 static struct snd_pci_quirk alc262_cfg_tbl[] = { 8494 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO), 8495 SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC), 8496 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC), 8497 SND_PCI_QUIRK(0x103c, 0x12ff, "HP xw4550", ALC262_HP_BPC), 8498 SND_PCI_QUIRK(0x103c, 0x1308, "HP xw4600", ALC262_HP_BPC), 8499 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC), 8500 SND_PCI_QUIRK(0x103c, 0x1307, "HP xw6600", ALC262_HP_BPC), 8501 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC), 8502 SND_PCI_QUIRK(0x103c, 0x1306, "HP xw8600", ALC262_HP_BPC), 8503 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL), 8504 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL), 8505 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL), 8506 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL), 8507 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF), 8508 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF), 8509 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF), 8510 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF), 8511 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO), 8512 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU), 8513 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1), 8514 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8), 8515 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31), 8516 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD), 8517 SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD), 8518 SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD), 8519 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD), 8520 {} 8521 }; 8522 8523 static struct alc_config_preset alc262_presets[] = { 8524 [ALC262_BASIC] = { 8525 .mixers = { alc262_base_mixer }, 8526 .init_verbs = { alc262_init_verbs }, 8527 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 8528 .dac_nids = alc262_dac_nids, 8529 .hp_nid = 0x03, 8530 .num_channel_mode = ARRAY_SIZE(alc262_modes), 8531 .channel_mode = alc262_modes, 8532 .input_mux = &alc262_capture_source, 8533 }, 8534 [ALC262_HIPPO] = { 8535 .mixers = { alc262_base_mixer }, 8536 .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs}, 8537 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 8538 .dac_nids = alc262_dac_nids, 8539 .hp_nid = 0x03, 8540 .dig_out_nid = ALC262_DIGOUT_NID, 8541 .num_channel_mode = ARRAY_SIZE(alc262_modes), 8542 .channel_mode = alc262_modes, 8543 .input_mux = &alc262_capture_source, 8544 .unsol_event = alc262_hippo_unsol_event, 8545 .init_hook = alc262_hippo_automute, 8546 }, 8547 [ALC262_HIPPO_1] = { 8548 .mixers = { alc262_hippo1_mixer }, 8549 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs}, 8550 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 8551 .dac_nids = alc262_dac_nids, 8552 .hp_nid = 0x02, 8553 .dig_out_nid = ALC262_DIGOUT_NID, 8554 .num_channel_mode = ARRAY_SIZE(alc262_modes), 8555 .channel_mode = alc262_modes, 8556 .input_mux = &alc262_capture_source, 8557 .unsol_event = alc262_hippo1_unsol_event, 8558 .init_hook = alc262_hippo1_automute, 8559 }, 8560 [ALC262_FUJITSU] = { 8561 .mixers = { alc262_fujitsu_mixer }, 8562 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs, 8563 alc262_fujitsu_unsol_verbs }, 8564 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 8565 .dac_nids = alc262_dac_nids, 8566 .hp_nid = 0x03, 8567 .dig_out_nid = ALC262_DIGOUT_NID, 8568 .num_channel_mode = ARRAY_SIZE(alc262_modes), 8569 .channel_mode = alc262_modes, 8570 .input_mux = &alc262_fujitsu_capture_source, 8571 .unsol_event = alc262_fujitsu_unsol_event, 8572 }, 8573 [ALC262_HP_BPC] = { 8574 .mixers = { alc262_HP_BPC_mixer }, 8575 .init_verbs = { alc262_HP_BPC_init_verbs }, 8576 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 8577 .dac_nids = alc262_dac_nids, 8578 .hp_nid = 0x03, 8579 .num_channel_mode = ARRAY_SIZE(alc262_modes), 8580 .channel_mode = alc262_modes, 8581 .input_mux = &alc262_HP_capture_source, 8582 }, 8583 [ALC262_HP_BPC_D7000_WF] = { 8584 .mixers = { alc262_HP_BPC_WildWest_mixer }, 8585 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs }, 8586 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 8587 .dac_nids = alc262_dac_nids, 8588 .hp_nid = 0x03, 8589 .num_channel_mode = ARRAY_SIZE(alc262_modes), 8590 .channel_mode = alc262_modes, 8591 .input_mux = &alc262_HP_D7000_capture_source, 8592 }, 8593 [ALC262_HP_BPC_D7000_WL] = { 8594 .mixers = { alc262_HP_BPC_WildWest_mixer, 8595 alc262_HP_BPC_WildWest_option_mixer }, 8596 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs }, 8597 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 8598 .dac_nids = alc262_dac_nids, 8599 .hp_nid = 0x03, 8600 .num_channel_mode = ARRAY_SIZE(alc262_modes), 8601 .channel_mode = alc262_modes, 8602 .input_mux = &alc262_HP_D7000_capture_source, 8603 }, 8604 [ALC262_BENQ_ED8] = { 8605 .mixers = { alc262_base_mixer }, 8606 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs }, 8607 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 8608 .dac_nids = alc262_dac_nids, 8609 .hp_nid = 0x03, 8610 .num_channel_mode = ARRAY_SIZE(alc262_modes), 8611 .channel_mode = alc262_modes, 8612 .input_mux = &alc262_capture_source, 8613 }, 8614 [ALC262_SONY_ASSAMD] = { 8615 .mixers = { alc262_sony_mixer }, 8616 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs}, 8617 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 8618 .dac_nids = alc262_dac_nids, 8619 .hp_nid = 0x02, 8620 .num_channel_mode = ARRAY_SIZE(alc262_modes), 8621 .channel_mode = alc262_modes, 8622 .input_mux = &alc262_capture_source, 8623 .unsol_event = alc262_hippo_unsol_event, 8624 .init_hook = alc262_hippo_automute, 8625 }, 8626 [ALC262_BENQ_T31] = { 8627 .mixers = { alc262_benq_t31_mixer }, 8628 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs }, 8629 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 8630 .dac_nids = alc262_dac_nids, 8631 .hp_nid = 0x03, 8632 .num_channel_mode = ARRAY_SIZE(alc262_modes), 8633 .channel_mode = alc262_modes, 8634 .input_mux = &alc262_capture_source, 8635 .unsol_event = alc262_hippo_unsol_event, 8636 .init_hook = alc262_hippo_automute, 8637 }, 8638 }; 8639 8640 static int patch_alc262(struct hda_codec *codec) 8641 { 8642 struct alc_spec *spec; 8643 int board_config; 8644 int err; 8645 8646 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 8647 if (spec == NULL) 8648 return -ENOMEM; 8649 8650 codec->spec = spec; 8651 #if 0 8652 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is 8653 * under-run 8654 */ 8655 { 8656 int tmp; 8657 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7); 8658 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0); 8659 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7); 8660 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80); 8661 } 8662 #endif 8663 8664 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST, 8665 alc262_models, 8666 alc262_cfg_tbl); 8667 8668 if (board_config < 0) { 8669 printk(KERN_INFO "hda_codec: Unknown model for ALC262, " 8670 "trying auto-probe from BIOS...\n"); 8671 board_config = ALC262_AUTO; 8672 } 8673 8674 if (board_config == ALC262_AUTO) { 8675 /* automatic parse from the BIOS config */ 8676 err = alc262_parse_auto_config(codec); 8677 if (err < 0) { 8678 alc_free(codec); 8679 return err; 8680 } else if (!err) { 8681 printk(KERN_INFO 8682 "hda_codec: Cannot set up configuration " 8683 "from BIOS. Using base mode...\n"); 8684 board_config = ALC262_BASIC; 8685 } 8686 } 8687 8688 if (board_config != ALC262_AUTO) 8689 setup_preset(spec, &alc262_presets[board_config]); 8690 8691 spec->stream_name_analog = "ALC262 Analog"; 8692 spec->stream_analog_playback = &alc262_pcm_analog_playback; 8693 spec->stream_analog_capture = &alc262_pcm_analog_capture; 8694 8695 spec->stream_name_digital = "ALC262 Digital"; 8696 spec->stream_digital_playback = &alc262_pcm_digital_playback; 8697 spec->stream_digital_capture = &alc262_pcm_digital_capture; 8698 8699 if (!spec->adc_nids && spec->input_mux) { 8700 /* check whether NID 0x07 is valid */ 8701 unsigned int wcap = get_wcaps(codec, 0x07); 8702 8703 /* get type */ 8704 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; 8705 if (wcap != AC_WID_AUD_IN) { 8706 spec->adc_nids = alc262_adc_nids_alt; 8707 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt); 8708 spec->mixers[spec->num_mixers] = 8709 alc262_capture_alt_mixer; 8710 spec->num_mixers++; 8711 } else { 8712 spec->adc_nids = alc262_adc_nids; 8713 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids); 8714 spec->mixers[spec->num_mixers] = alc262_capture_mixer; 8715 spec->num_mixers++; 8716 } 8717 } 8718 8719 codec->patch_ops = alc_patch_ops; 8720 if (board_config == ALC262_AUTO) 8721 spec->init_hook = alc262_auto_init; 8722 #ifdef CONFIG_SND_HDA_POWER_SAVE 8723 if (!spec->loopback.amplist) 8724 spec->loopback.amplist = alc262_loopbacks; 8725 #endif 8726 8727 return 0; 8728 } 8729 8730 /* 8731 * ALC268 channel source setting (2 channel) 8732 */ 8733 #define ALC268_DIGOUT_NID ALC880_DIGOUT_NID 8734 #define alc268_modes alc260_modes 8735 8736 static hda_nid_t alc268_dac_nids[2] = { 8737 /* front, hp */ 8738 0x02, 0x03 8739 }; 8740 8741 static hda_nid_t alc268_adc_nids[2] = { 8742 /* ADC0-1 */ 8743 0x08, 0x07 8744 }; 8745 8746 static hda_nid_t alc268_adc_nids_alt[1] = { 8747 /* ADC0 */ 8748 0x08 8749 }; 8750 8751 static struct snd_kcontrol_new alc268_base_mixer[] = { 8752 /* output mixer control */ 8753 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), 8754 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 8755 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT), 8756 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 8757 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8758 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 8759 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT), 8760 { } 8761 }; 8762 8763 static struct hda_verb alc268_eapd_verbs[] = { 8764 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 8765 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, 8766 { } 8767 }; 8768 8769 /* Toshiba specific */ 8770 #define alc268_toshiba_automute alc262_hippo_automute 8771 8772 static struct hda_verb alc268_toshiba_verbs[] = { 8773 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 8774 { } /* end */ 8775 }; 8776 8777 /* Acer specific */ 8778 /* bind volumes of both NID 0x02 and 0x03 */ 8779 static struct hda_bind_ctls alc268_acer_bind_master_vol = { 8780 .ops = &snd_hda_bind_vol, 8781 .values = { 8782 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), 8783 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT), 8784 0 8785 }, 8786 }; 8787 8788 /* mute/unmute internal speaker according to the hp jack and mute state */ 8789 static void alc268_acer_automute(struct hda_codec *codec, int force) 8790 { 8791 struct alc_spec *spec = codec->spec; 8792 unsigned int mute; 8793 8794 if (force || !spec->sense_updated) { 8795 unsigned int present; 8796 present = snd_hda_codec_read(codec, 0x14, 0, 8797 AC_VERB_GET_PIN_SENSE, 0); 8798 spec->jack_present = (present & 0x80000000) != 0; 8799 spec->sense_updated = 1; 8800 } 8801 if (spec->jack_present) 8802 mute = HDA_AMP_MUTE; /* mute internal speaker */ 8803 else /* unmute internal speaker if necessary */ 8804 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0); 8805 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 8806 HDA_AMP_MUTE, mute); 8807 } 8808 8809 8810 /* bind hp and internal speaker mute (with plug check) */ 8811 static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol, 8812 struct snd_ctl_elem_value *ucontrol) 8813 { 8814 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 8815 long *valp = ucontrol->value.integer.value; 8816 int change; 8817 8818 change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0, 8819 HDA_AMP_MUTE, 8820 valp[0] ? 0 : HDA_AMP_MUTE); 8821 change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0, 8822 HDA_AMP_MUTE, 8823 valp[1] ? 0 : HDA_AMP_MUTE); 8824 if (change) 8825 alc268_acer_automute(codec, 0); 8826 return change; 8827 } 8828 8829 static struct snd_kcontrol_new alc268_acer_mixer[] = { 8830 /* output mixer control */ 8831 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), 8832 { 8833 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 8834 .name = "Master Playback Switch", 8835 .info = snd_hda_mixer_amp_switch_info, 8836 .get = snd_hda_mixer_amp_switch_get, 8837 .put = alc268_acer_master_sw_put, 8838 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 8839 }, 8840 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8841 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), 8842 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT), 8843 { } 8844 }; 8845 8846 static struct hda_verb alc268_acer_verbs[] = { 8847 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8848 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8849 8850 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 8851 { } 8852 }; 8853 8854 /* unsolicited event for HP jack sensing */ 8855 static void alc268_toshiba_unsol_event(struct hda_codec *codec, 8856 unsigned int res) 8857 { 8858 if ((res >> 26) != ALC880_HP_EVENT) 8859 return; 8860 alc268_toshiba_automute(codec); 8861 } 8862 8863 static void alc268_acer_unsol_event(struct hda_codec *codec, 8864 unsigned int res) 8865 { 8866 if ((res >> 26) != ALC880_HP_EVENT) 8867 return; 8868 alc268_acer_automute(codec, 1); 8869 } 8870 8871 static void alc268_acer_init_hook(struct hda_codec *codec) 8872 { 8873 alc268_acer_automute(codec, 1); 8874 } 8875 8876 /* 8877 * generic initialization of ADC, input mixers and output mixers 8878 */ 8879 static struct hda_verb alc268_base_init_verbs[] = { 8880 /* Unmute DAC0-1 and set vol = 0 */ 8881 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8882 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8883 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8884 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8885 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8886 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8887 8888 /* 8889 * Set up output mixers (0x0c - 0x0e) 8890 */ 8891 /* set vol=0 to output mixers */ 8892 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8893 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8894 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8895 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00}, 8896 8897 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8898 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8899 8900 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 8901 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 8902 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 8903 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 8904 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 8905 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 8906 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 8907 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 8908 8909 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8910 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8911 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8912 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8913 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8914 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8915 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8916 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 8917 8918 /* FIXME: use matrix-type input source selection */ 8919 /* Mixer elements: 0x18, 19, 1a, 1c, 14, 15, 0b */ 8920 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 8921 /* Input mixer2 */ 8922 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 8923 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 8924 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, 8925 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, 8926 8927 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 8928 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 8929 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, 8930 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, 8931 { } 8932 }; 8933 8934 /* 8935 * generic initialization of ADC, input mixers and output mixers 8936 */ 8937 static struct hda_verb alc268_volume_init_verbs[] = { 8938 /* set output DAC */ 8939 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8940 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8941 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8942 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8943 8944 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 8945 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 8946 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 8947 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 8948 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 8949 8950 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8951 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8952 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8953 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8954 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8955 8956 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8957 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8958 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8959 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8960 8961 /* set PCBEEP vol = 0 */ 8962 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, (0xb000 | (0x00 << 8))}, 8963 8964 { } 8965 }; 8966 8967 #define alc268_mux_enum_info alc_mux_enum_info 8968 #define alc268_mux_enum_get alc_mux_enum_get 8969 8970 static int alc268_mux_enum_put(struct snd_kcontrol *kcontrol, 8971 struct snd_ctl_elem_value *ucontrol) 8972 { 8973 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 8974 struct alc_spec *spec = codec->spec; 8975 const struct hda_input_mux *imux = spec->input_mux; 8976 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 8977 static hda_nid_t capture_mixers[3] = { 0x23, 0x24 }; 8978 hda_nid_t nid = capture_mixers[adc_idx]; 8979 unsigned int *cur_val = &spec->cur_mux[adc_idx]; 8980 unsigned int i, idx; 8981 8982 idx = ucontrol->value.enumerated.item[0]; 8983 if (idx >= imux->num_items) 8984 idx = imux->num_items - 1; 8985 if (*cur_val == idx) 8986 return 0; 8987 for (i = 0; i < imux->num_items; i++) { 8988 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE; 8989 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 8990 imux->items[i].index, 8991 HDA_AMP_MUTE, v); 8992 snd_hda_codec_write_cache(codec, nid, 0, 8993 AC_VERB_SET_CONNECT_SEL, 8994 idx ); 8995 } 8996 *cur_val = idx; 8997 return 1; 8998 } 8999 9000 static struct snd_kcontrol_new alc268_capture_alt_mixer[] = { 9001 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT), 9002 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT), 9003 { 9004 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 9005 /* The multiple "Capture Source" controls confuse alsamixer 9006 * So call somewhat different.. 9007 * FIXME: the controls appear in the "playback" view! 9008 */ 9009 /* .name = "Capture Source", */ 9010 .name = "Input Source", 9011 .count = 1, 9012 .info = alc268_mux_enum_info, 9013 .get = alc268_mux_enum_get, 9014 .put = alc268_mux_enum_put, 9015 }, 9016 { } /* end */ 9017 }; 9018 9019 static struct snd_kcontrol_new alc268_capture_mixer[] = { 9020 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT), 9021 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT), 9022 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT), 9023 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT), 9024 { 9025 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 9026 /* The multiple "Capture Source" controls confuse alsamixer 9027 * So call somewhat different.. 9028 * FIXME: the controls appear in the "playback" view! 9029 */ 9030 /* .name = "Capture Source", */ 9031 .name = "Input Source", 9032 .count = 2, 9033 .info = alc268_mux_enum_info, 9034 .get = alc268_mux_enum_get, 9035 .put = alc268_mux_enum_put, 9036 }, 9037 { } /* end */ 9038 }; 9039 9040 static struct hda_input_mux alc268_capture_source = { 9041 .num_items = 4, 9042 .items = { 9043 { "Mic", 0x0 }, 9044 { "Front Mic", 0x1 }, 9045 { "Line", 0x2 }, 9046 { "CD", 0x3 }, 9047 }, 9048 }; 9049 9050 /* create input playback/capture controls for the given pin */ 9051 static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid, 9052 const char *ctlname, int idx) 9053 { 9054 char name[32]; 9055 int err; 9056 9057 sprintf(name, "%s Playback Volume", ctlname); 9058 if (nid == 0x14) { 9059 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, 9060 HDA_COMPOSE_AMP_VAL(0x02, 3, idx, 9061 HDA_OUTPUT)); 9062 if (err < 0) 9063 return err; 9064 } else if (nid == 0x15) { 9065 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, 9066 HDA_COMPOSE_AMP_VAL(0x03, 3, idx, 9067 HDA_OUTPUT)); 9068 if (err < 0) 9069 return err; 9070 } else 9071 return -1; 9072 sprintf(name, "%s Playback Switch", ctlname); 9073 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, 9074 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT)); 9075 if (err < 0) 9076 return err; 9077 return 0; 9078 } 9079 9080 /* add playback controls from the parsed DAC table */ 9081 static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec, 9082 const struct auto_pin_cfg *cfg) 9083 { 9084 hda_nid_t nid; 9085 int err; 9086 9087 spec->multiout.num_dacs = 2; /* only use one dac */ 9088 spec->multiout.dac_nids = spec->private_dac_nids; 9089 spec->multiout.dac_nids[0] = 2; 9090 spec->multiout.dac_nids[1] = 3; 9091 9092 nid = cfg->line_out_pins[0]; 9093 if (nid) 9094 alc268_new_analog_output(spec, nid, "Front", 0); 9095 9096 nid = cfg->speaker_pins[0]; 9097 if (nid == 0x1d) { 9098 err = add_control(spec, ALC_CTL_WIDGET_VOL, 9099 "Speaker Playback Volume", 9100 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT)); 9101 if (err < 0) 9102 return err; 9103 } 9104 nid = cfg->hp_pins[0]; 9105 if (nid) 9106 alc268_new_analog_output(spec, nid, "Headphone", 0); 9107 9108 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2]; 9109 if (nid == 0x16) { 9110 err = add_control(spec, ALC_CTL_WIDGET_MUTE, 9111 "Mono Playback Switch", 9112 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT)); 9113 if (err < 0) 9114 return err; 9115 } 9116 return 0; 9117 } 9118 9119 /* create playback/capture controls for input pins */ 9120 static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec, 9121 const struct auto_pin_cfg *cfg) 9122 { 9123 struct hda_input_mux *imux = &spec->private_imux; 9124 int i, idx1; 9125 9126 for (i = 0; i < AUTO_PIN_LAST; i++) { 9127 switch(cfg->input_pins[i]) { 9128 case 0x18: 9129 idx1 = 0; /* Mic 1 */ 9130 break; 9131 case 0x19: 9132 idx1 = 1; /* Mic 2 */ 9133 break; 9134 case 0x1a: 9135 idx1 = 2; /* Line In */ 9136 break; 9137 case 0x1c: 9138 idx1 = 3; /* CD */ 9139 break; 9140 default: 9141 continue; 9142 } 9143 imux->items[imux->num_items].label = auto_pin_cfg_labels[i]; 9144 imux->items[imux->num_items].index = idx1; 9145 imux->num_items++; 9146 } 9147 return 0; 9148 } 9149 9150 static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec) 9151 { 9152 struct alc_spec *spec = codec->spec; 9153 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0]; 9154 hda_nid_t hp_nid = spec->autocfg.hp_pins[0]; 9155 hda_nid_t line_nid = spec->autocfg.line_out_pins[0]; 9156 unsigned int dac_vol1, dac_vol2; 9157 9158 if (speaker_nid) { 9159 snd_hda_codec_write(codec, speaker_nid, 0, 9160 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); 9161 snd_hda_codec_write(codec, 0x0f, 0, 9162 AC_VERB_SET_AMP_GAIN_MUTE, 9163 AMP_IN_UNMUTE(1)); 9164 snd_hda_codec_write(codec, 0x10, 0, 9165 AC_VERB_SET_AMP_GAIN_MUTE, 9166 AMP_IN_UNMUTE(1)); 9167 } else { 9168 snd_hda_codec_write(codec, 0x0f, 0, 9169 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)); 9170 snd_hda_codec_write(codec, 0x10, 0, 9171 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)); 9172 } 9173 9174 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */ 9175 if (line_nid == 0x14) 9176 dac_vol2 = AMP_OUT_ZERO; 9177 else if (line_nid == 0x15) 9178 dac_vol1 = AMP_OUT_ZERO; 9179 if (hp_nid == 0x14) 9180 dac_vol2 = AMP_OUT_ZERO; 9181 else if (hp_nid == 0x15) 9182 dac_vol1 = AMP_OUT_ZERO; 9183 if (line_nid != 0x16 || hp_nid != 0x16 || 9184 spec->autocfg.line_out_pins[1] != 0x16 || 9185 spec->autocfg.line_out_pins[2] != 0x16) 9186 dac_vol1 = dac_vol2 = AMP_OUT_ZERO; 9187 9188 snd_hda_codec_write(codec, 0x02, 0, 9189 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1); 9190 snd_hda_codec_write(codec, 0x03, 0, 9191 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2); 9192 } 9193 9194 /* pcm configuration: identiacal with ALC880 */ 9195 #define alc268_pcm_analog_playback alc880_pcm_analog_playback 9196 #define alc268_pcm_analog_capture alc880_pcm_analog_capture 9197 #define alc268_pcm_digital_playback alc880_pcm_digital_playback 9198 9199 /* 9200 * BIOS auto configuration 9201 */ 9202 static int alc268_parse_auto_config(struct hda_codec *codec) 9203 { 9204 struct alc_spec *spec = codec->spec; 9205 int err; 9206 static hda_nid_t alc268_ignore[] = { 0 }; 9207 9208 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 9209 alc268_ignore); 9210 if (err < 0) 9211 return err; 9212 if (!spec->autocfg.line_outs) 9213 return 0; /* can't find valid BIOS pin config */ 9214 9215 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg); 9216 if (err < 0) 9217 return err; 9218 err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg); 9219 if (err < 0) 9220 return err; 9221 9222 spec->multiout.max_channels = 2; 9223 9224 /* digital only support output */ 9225 if (spec->autocfg.dig_out_pin) 9226 spec->multiout.dig_out_nid = ALC268_DIGOUT_NID; 9227 9228 if (spec->kctl_alloc) 9229 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 9230 9231 spec->init_verbs[spec->num_init_verbs++] = alc268_volume_init_verbs; 9232 spec->num_mux_defs = 1; 9233 spec->input_mux = &spec->private_imux; 9234 9235 err = alc_auto_add_mic_boost(codec); 9236 if (err < 0) 9237 return err; 9238 9239 return 1; 9240 } 9241 9242 #define alc268_auto_init_multi_out alc882_auto_init_multi_out 9243 #define alc268_auto_init_hp_out alc882_auto_init_hp_out 9244 #define alc268_auto_init_analog_input alc882_auto_init_analog_input 9245 9246 /* init callback for auto-configuration model -- overriding the default init */ 9247 static void alc268_auto_init(struct hda_codec *codec) 9248 { 9249 alc268_auto_init_multi_out(codec); 9250 alc268_auto_init_hp_out(codec); 9251 alc268_auto_init_mono_speaker_out(codec); 9252 alc268_auto_init_analog_input(codec); 9253 } 9254 9255 /* 9256 * configuration and preset 9257 */ 9258 static const char *alc268_models[ALC268_MODEL_LAST] = { 9259 [ALC268_3ST] = "3stack", 9260 [ALC268_TOSHIBA] = "toshiba", 9261 [ALC268_ACER] = "acer", 9262 [ALC268_AUTO] = "auto", 9263 }; 9264 9265 static struct snd_pci_quirk alc268_cfg_tbl[] = { 9266 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST), 9267 SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA), 9268 SND_PCI_QUIRK(0x1179, 0xff50, "TOSHIBA A305", ALC268_TOSHIBA), 9269 SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA), 9270 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER), 9271 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER), 9272 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER), 9273 {} 9274 }; 9275 9276 static struct alc_config_preset alc268_presets[] = { 9277 [ALC268_3ST] = { 9278 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer }, 9279 .init_verbs = { alc268_base_init_verbs }, 9280 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 9281 .dac_nids = alc268_dac_nids, 9282 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 9283 .adc_nids = alc268_adc_nids_alt, 9284 .hp_nid = 0x03, 9285 .dig_out_nid = ALC268_DIGOUT_NID, 9286 .num_channel_mode = ARRAY_SIZE(alc268_modes), 9287 .channel_mode = alc268_modes, 9288 .input_mux = &alc268_capture_source, 9289 }, 9290 [ALC268_TOSHIBA] = { 9291 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer }, 9292 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 9293 alc268_toshiba_verbs }, 9294 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 9295 .dac_nids = alc268_dac_nids, 9296 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 9297 .adc_nids = alc268_adc_nids_alt, 9298 .hp_nid = 0x03, 9299 .num_channel_mode = ARRAY_SIZE(alc268_modes), 9300 .channel_mode = alc268_modes, 9301 .input_mux = &alc268_capture_source, 9302 .input_mux = &alc268_capture_source, 9303 .unsol_event = alc268_toshiba_unsol_event, 9304 .init_hook = alc268_toshiba_automute, 9305 }, 9306 [ALC268_ACER] = { 9307 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer }, 9308 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 9309 alc268_acer_verbs }, 9310 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 9311 .dac_nids = alc268_dac_nids, 9312 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 9313 .adc_nids = alc268_adc_nids_alt, 9314 .hp_nid = 0x02, 9315 .num_channel_mode = ARRAY_SIZE(alc268_modes), 9316 .channel_mode = alc268_modes, 9317 .input_mux = &alc268_capture_source, 9318 .unsol_event = alc268_acer_unsol_event, 9319 .init_hook = alc268_acer_init_hook, 9320 }, 9321 }; 9322 9323 static int patch_alc268(struct hda_codec *codec) 9324 { 9325 struct alc_spec *spec; 9326 int board_config; 9327 int err; 9328 9329 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); 9330 if (spec == NULL) 9331 return -ENOMEM; 9332 9333 codec->spec = spec; 9334 9335 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST, 9336 alc268_models, 9337 alc268_cfg_tbl); 9338 9339 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) { 9340 printk(KERN_INFO "hda_codec: Unknown model for ALC268, " 9341 "trying auto-probe from BIOS...\n"); 9342 board_config = ALC268_AUTO; 9343 } 9344 9345 if (board_config == ALC268_AUTO) { 9346 /* automatic parse from the BIOS config */ 9347 err = alc268_parse_auto_config(codec); 9348 if (err < 0) { 9349 alc_free(codec); 9350 return err; 9351 } else if (!err) { 9352 printk(KERN_INFO 9353 "hda_codec: Cannot set up configuration " 9354 "from BIOS. Using base mode...\n"); 9355 board_config = ALC268_3ST; 9356 } 9357 } 9358 9359 if (board_config != ALC268_AUTO) 9360 setup_preset(spec, &alc268_presets[board_config]); 9361 9362 spec->stream_name_analog = "ALC268 Analog"; 9363 spec->stream_analog_playback = &alc268_pcm_analog_playback; 9364 spec->stream_analog_capture = &alc268_pcm_analog_capture; 9365 9366 spec->stream_name_digital = "ALC268 Digital"; 9367 spec->stream_digital_playback = &alc268_pcm_digital_playback; 9368 9369 if (board_config == ALC268_AUTO) { 9370 if (!spec->adc_nids && spec->input_mux) { 9371 /* check whether NID 0x07 is valid */ 9372 unsigned int wcap = get_wcaps(codec, 0x07); 9373 9374 /* get type */ 9375 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; 9376 if (wcap != AC_WID_AUD_IN) { 9377 spec->adc_nids = alc268_adc_nids_alt; 9378 spec->num_adc_nids = 9379 ARRAY_SIZE(alc268_adc_nids_alt); 9380 spec->mixers[spec->num_mixers] = 9381 alc268_capture_alt_mixer; 9382 spec->num_mixers++; 9383 } else { 9384 spec->adc_nids = alc268_adc_nids; 9385 spec->num_adc_nids = 9386 ARRAY_SIZE(alc268_adc_nids); 9387 spec->mixers[spec->num_mixers] = 9388 alc268_capture_mixer; 9389 spec->num_mixers++; 9390 } 9391 } 9392 } 9393 codec->patch_ops = alc_patch_ops; 9394 if (board_config == ALC268_AUTO) 9395 spec->init_hook = alc268_auto_init; 9396 9397 return 0; 9398 } 9399 9400 /* 9401 * ALC861 channel source setting (2/6 channel selection for 3-stack) 9402 */ 9403 9404 /* 9405 * set the path ways for 2 channel output 9406 * need to set the codec line out and mic 1 pin widgets to inputs 9407 */ 9408 static struct hda_verb alc861_threestack_ch2_init[] = { 9409 /* set pin widget 1Ah (line in) for input */ 9410 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 9411 /* set pin widget 18h (mic1/2) for input, for mic also enable 9412 * the vref 9413 */ 9414 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 9415 9416 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, 9417 #if 0 9418 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/ 9419 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/ 9420 #endif 9421 { } /* end */ 9422 }; 9423 /* 9424 * 6ch mode 9425 * need to set the codec line out and mic 1 pin widgets to outputs 9426 */ 9427 static struct hda_verb alc861_threestack_ch6_init[] = { 9428 /* set pin widget 1Ah (line in) for output (Back Surround)*/ 9429 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 9430 /* set pin widget 18h (mic1) for output (CLFE)*/ 9431 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 9432 9433 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 }, 9434 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 }, 9435 9436 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 }, 9437 #if 0 9438 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/ 9439 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/ 9440 #endif 9441 { } /* end */ 9442 }; 9443 9444 static struct hda_channel_mode alc861_threestack_modes[2] = { 9445 { 2, alc861_threestack_ch2_init }, 9446 { 6, alc861_threestack_ch6_init }, 9447 }; 9448 /* Set mic1 as input and unmute the mixer */ 9449 static struct hda_verb alc861_uniwill_m31_ch2_init[] = { 9450 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 9451 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/ 9452 { } /* end */ 9453 }; 9454 /* Set mic1 as output and mute mixer */ 9455 static struct hda_verb alc861_uniwill_m31_ch4_init[] = { 9456 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 9457 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/ 9458 { } /* end */ 9459 }; 9460 9461 static struct hda_channel_mode alc861_uniwill_m31_modes[2] = { 9462 { 2, alc861_uniwill_m31_ch2_init }, 9463 { 4, alc861_uniwill_m31_ch4_init }, 9464 }; 9465 9466 /* Set mic1 and line-in as input and unmute the mixer */ 9467 static struct hda_verb alc861_asus_ch2_init[] = { 9468 /* set pin widget 1Ah (line in) for input */ 9469 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 9470 /* set pin widget 18h (mic1/2) for input, for mic also enable 9471 * the vref 9472 */ 9473 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 9474 9475 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, 9476 #if 0 9477 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/ 9478 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/ 9479 #endif 9480 { } /* end */ 9481 }; 9482 /* Set mic1 nad line-in as output and mute mixer */ 9483 static struct hda_verb alc861_asus_ch6_init[] = { 9484 /* set pin widget 1Ah (line in) for output (Back Surround)*/ 9485 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 9486 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */ 9487 /* set pin widget 18h (mic1) for output (CLFE)*/ 9488 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 9489 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */ 9490 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 }, 9491 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 }, 9492 9493 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 }, 9494 #if 0 9495 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/ 9496 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/ 9497 #endif 9498 { } /* end */ 9499 }; 9500 9501 static struct hda_channel_mode alc861_asus_modes[2] = { 9502 { 2, alc861_asus_ch2_init }, 9503 { 6, alc861_asus_ch6_init }, 9504 }; 9505 9506 /* patch-ALC861 */ 9507 9508 static struct snd_kcontrol_new alc861_base_mixer[] = { 9509 /* output mixer control */ 9510 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), 9511 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), 9512 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT), 9513 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT), 9514 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), 9515 9516 /*Input mixer control */ 9517 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT), 9518 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */ 9519 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), 9520 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), 9521 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT), 9522 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT), 9523 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), 9524 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), 9525 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), 9526 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT), 9527 9528 /* Capture mixer control */ 9529 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 9530 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 9531 { 9532 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 9533 .name = "Capture Source", 9534 .count = 1, 9535 .info = alc_mux_enum_info, 9536 .get = alc_mux_enum_get, 9537 .put = alc_mux_enum_put, 9538 }, 9539 { } /* end */ 9540 }; 9541 9542 static struct snd_kcontrol_new alc861_3ST_mixer[] = { 9543 /* output mixer control */ 9544 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), 9545 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), 9546 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT), 9547 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT), 9548 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */ 9549 9550 /* Input mixer control */ 9551 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT), 9552 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */ 9553 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), 9554 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), 9555 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT), 9556 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT), 9557 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), 9558 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), 9559 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), 9560 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT), 9561 9562 /* Capture mixer control */ 9563 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 9564 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 9565 { 9566 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 9567 .name = "Capture Source", 9568 .count = 1, 9569 .info = alc_mux_enum_info, 9570 .get = alc_mux_enum_get, 9571 .put = alc_mux_enum_put, 9572 }, 9573 { 9574 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 9575 .name = "Channel Mode", 9576 .info = alc_ch_mode_info, 9577 .get = alc_ch_mode_get, 9578 .put = alc_ch_mode_put, 9579 .private_value = ARRAY_SIZE(alc861_threestack_modes), 9580 }, 9581 { } /* end */ 9582 }; 9583 9584 static struct snd_kcontrol_new alc861_toshiba_mixer[] = { 9585 /* output mixer control */ 9586 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT), 9587 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), 9588 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), 9589 9590 /*Capture mixer control */ 9591 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 9592 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 9593 { 9594 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 9595 .name = "Capture Source", 9596 .count = 1, 9597 .info = alc_mux_enum_info, 9598 .get = alc_mux_enum_get, 9599 .put = alc_mux_enum_put, 9600 }, 9601 9602 { } /* end */ 9603 }; 9604 9605 static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = { 9606 /* output mixer control */ 9607 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), 9608 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), 9609 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT), 9610 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT), 9611 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */ 9612 9613 /* Input mixer control */ 9614 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT), 9615 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */ 9616 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), 9617 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), 9618 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT), 9619 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT), 9620 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), 9621 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), 9622 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), 9623 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT), 9624 9625 /* Capture mixer control */ 9626 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 9627 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 9628 { 9629 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 9630 .name = "Capture Source", 9631 .count = 1, 9632 .info = alc_mux_enum_info, 9633 .get = alc_mux_enum_get, 9634 .put = alc_mux_enum_put, 9635 }, 9636 { 9637 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 9638 .name = "Channel Mode", 9639 .info = alc_ch_mode_info, 9640 .get = alc_ch_mode_get, 9641 .put = alc_ch_mode_put, 9642 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes), 9643 }, 9644 { } /* end */ 9645 }; 9646 9647 static struct snd_kcontrol_new alc861_asus_mixer[] = { 9648 /* output mixer control */ 9649 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), 9650 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), 9651 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT), 9652 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT), 9653 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), 9654 9655 /* Input mixer control */ 9656 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT), 9657 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), 9658 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), 9659 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), 9660 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT), 9661 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT), 9662 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), 9663 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), 9664 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), 9665 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT), 9666 9667 /* Capture mixer control */ 9668 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 9669 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 9670 { 9671 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 9672 .name = "Capture Source", 9673 .count = 1, 9674 .info = alc_mux_enum_info, 9675 .get = alc_mux_enum_get, 9676 .put = alc_mux_enum_put, 9677 }, 9678 { 9679 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 9680 .name = "Channel Mode", 9681 .info = alc_ch_mode_info, 9682 .get = alc_ch_mode_get, 9683 .put = alc_ch_mode_put, 9684 .private_value = ARRAY_SIZE(alc861_asus_modes), 9685 }, 9686 { } 9687 }; 9688 9689 /* additional mixer */ 9690 static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = { 9691 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), 9692 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), 9693 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x23, 0x0, HDA_OUTPUT), 9694 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x23, 0x0, HDA_OUTPUT), 9695 { } 9696 }; 9697 9698 /* 9699 * generic initialization of ADC, input mixers and output mixers 9700 */ 9701 static struct hda_verb alc861_base_init_verbs[] = { 9702 /* 9703 * Unmute ADC0 and set the default input to mic-in 9704 */ 9705 /* port-A for surround (rear panel) */ 9706 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 9707 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 }, 9708 /* port-B for mic-in (rear panel) with vref */ 9709 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 9710 /* port-C for line-in (rear panel) */ 9711 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 9712 /* port-D for Front */ 9713 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 9714 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 }, 9715 /* port-E for HP out (front panel) */ 9716 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, 9717 /* route front PCM to HP */ 9718 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, 9719 /* port-F for mic-in (front panel) with vref */ 9720 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 9721 /* port-G for CLFE (rear panel) */ 9722 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 9723 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 }, 9724 /* port-H for side (rear panel) */ 9725 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 9726 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 }, 9727 /* CD-in */ 9728 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 9729 /* route front mic to ADC1*/ 9730 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 9731 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9732 9733 /* Unmute DAC0~3 & spdif out*/ 9734 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9735 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9736 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9737 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9738 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9739 9740 /* Unmute Mixer 14 (mic) 1c (Line in)*/ 9741 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9742 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9743 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9744 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9745 9746 /* Unmute Stereo Mixer 15 */ 9747 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9748 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9749 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 9750 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */ 9751 9752 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9753 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9754 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9755 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9756 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9757 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9758 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9759 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9760 /* hp used DAC 3 (Front) */ 9761 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 9762 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 9763 9764 { } 9765 }; 9766 9767 static struct hda_verb alc861_threestack_init_verbs[] = { 9768 /* 9769 * Unmute ADC0 and set the default input to mic-in 9770 */ 9771 /* port-A for surround (rear panel) */ 9772 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 9773 /* port-B for mic-in (rear panel) with vref */ 9774 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 9775 /* port-C for line-in (rear panel) */ 9776 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 9777 /* port-D for Front */ 9778 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 9779 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 }, 9780 /* port-E for HP out (front panel) */ 9781 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, 9782 /* route front PCM to HP */ 9783 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, 9784 /* port-F for mic-in (front panel) with vref */ 9785 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 9786 /* port-G for CLFE (rear panel) */ 9787 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 9788 /* port-H for side (rear panel) */ 9789 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 9790 /* CD-in */ 9791 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 9792 /* route front mic to ADC1*/ 9793 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 9794 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9795 /* Unmute DAC0~3 & spdif out*/ 9796 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9797 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9798 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9799 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9800 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9801 9802 /* Unmute Mixer 14 (mic) 1c (Line in)*/ 9803 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9804 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9805 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9806 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9807 9808 /* Unmute Stereo Mixer 15 */ 9809 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9810 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9811 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 9812 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */ 9813 9814 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9815 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9816 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9817 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9818 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9819 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9820 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9821 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9822 /* hp used DAC 3 (Front) */ 9823 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 9824 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 9825 { } 9826 }; 9827 9828 static struct hda_verb alc861_uniwill_m31_init_verbs[] = { 9829 /* 9830 * Unmute ADC0 and set the default input to mic-in 9831 */ 9832 /* port-A for surround (rear panel) */ 9833 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 9834 /* port-B for mic-in (rear panel) with vref */ 9835 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 9836 /* port-C for line-in (rear panel) */ 9837 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 9838 /* port-D for Front */ 9839 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 9840 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 }, 9841 /* port-E for HP out (front panel) */ 9842 /* this has to be set to VREF80 */ 9843 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 9844 /* route front PCM to HP */ 9845 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, 9846 /* port-F for mic-in (front panel) with vref */ 9847 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 9848 /* port-G for CLFE (rear panel) */ 9849 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 9850 /* port-H for side (rear panel) */ 9851 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 9852 /* CD-in */ 9853 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 9854 /* route front mic to ADC1*/ 9855 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 9856 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9857 /* Unmute DAC0~3 & spdif out*/ 9858 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9859 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9860 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9861 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9862 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9863 9864 /* Unmute Mixer 14 (mic) 1c (Line in)*/ 9865 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9866 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9867 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9868 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9869 9870 /* Unmute Stereo Mixer 15 */ 9871 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9872 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9873 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 9874 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */ 9875 9876 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9877 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9878 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9879 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9880 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9881 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9882 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9883 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9884 /* hp used DAC 3 (Front) */ 9885 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 9886 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 9887 { } 9888 }; 9889 9890 static struct hda_verb alc861_asus_init_verbs[] = { 9891 /* 9892 * Unmute ADC0 and set the default input to mic-in 9893 */ 9894 /* port-A for surround (rear panel) 9895 * according to codec#0 this is the HP jack 9896 */ 9897 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */ 9898 /* route front PCM to HP */ 9899 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 }, 9900 /* port-B for mic-in (rear panel) with vref */ 9901 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 9902 /* port-C for line-in (rear panel) */ 9903 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 9904 /* port-D for Front */ 9905 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 9906 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 }, 9907 /* port-E for HP out (front panel) */ 9908 /* this has to be set to VREF80 */ 9909 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 9910 /* route front PCM to HP */ 9911 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, 9912 /* port-F for mic-in (front panel) with vref */ 9913 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 9914 /* port-G for CLFE (rear panel) */ 9915 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 9916 /* port-H for side (rear panel) */ 9917 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 9918 /* CD-in */ 9919 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 9920 /* route front mic to ADC1*/ 9921 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 9922 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9923 /* Unmute DAC0~3 & spdif out*/ 9924 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9925 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9926 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9927 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9928 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9929 /* Unmute Mixer 14 (mic) 1c (Line in)*/ 9930 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9931 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9932 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9933 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9934 9935 /* Unmute Stereo Mixer 15 */ 9936 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9937 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9938 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 9939 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */ 9940 9941 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9942 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9943 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9944 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9945 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9946 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9947 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9948 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9949 /* hp used DAC 3 (Front) */ 9950 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 9951 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 9952 { } 9953 }; 9954 9955 /* additional init verbs for ASUS laptops */ 9956 static struct hda_verb alc861_asus_laptop_init_verbs[] = { 9957 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */ 9958 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */ 9959 { } 9960 }; 9961 9962 /* 9963 * generic initialization of ADC, input mixers and output mixers 9964 */ 9965 static struct hda_verb alc861_auto_init_verbs[] = { 9966 /* 9967 * Unmute ADC0 and set the default input to mic-in 9968 */ 9969 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */ 9970 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9971 9972 /* Unmute DAC0~3 & spdif out*/ 9973 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 9974 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 9975 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 9976 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 9977 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9978 9979 /* Unmute Mixer 14 (mic) 1c (Line in)*/ 9980 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9981 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9982 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9983 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9984 9985 /* Unmute Stereo Mixer 15 */ 9986 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9987 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9988 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 9989 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, 9990 9991 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9992 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9993 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9994 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9995 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9996 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9997 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9998 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9999 10000 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 10001 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 10002 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 10003 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 10004 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 10005 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 10006 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 10007 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 10008 10009 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */ 10010 10011 { } 10012 }; 10013 10014 static struct hda_verb alc861_toshiba_init_verbs[] = { 10015 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 10016 10017 { } 10018 }; 10019 10020 /* toggle speaker-output according to the hp-jack state */ 10021 static void alc861_toshiba_automute(struct hda_codec *codec) 10022 { 10023 unsigned int present; 10024 10025 present = snd_hda_codec_read(codec, 0x0f, 0, 10026 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 10027 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0, 10028 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 10029 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3, 10030 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE); 10031 } 10032 10033 static void alc861_toshiba_unsol_event(struct hda_codec *codec, 10034 unsigned int res) 10035 { 10036 if ((res >> 26) == ALC880_HP_EVENT) 10037 alc861_toshiba_automute(codec); 10038 } 10039 10040 /* pcm configuration: identiacal with ALC880 */ 10041 #define alc861_pcm_analog_playback alc880_pcm_analog_playback 10042 #define alc861_pcm_analog_capture alc880_pcm_analog_capture 10043 #define alc861_pcm_digital_playback alc880_pcm_digital_playback 10044 #define alc861_pcm_digital_capture alc880_pcm_digital_capture 10045 10046 10047 #define ALC861_DIGOUT_NID 0x07 10048 10049 static struct hda_channel_mode alc861_8ch_modes[1] = { 10050 { 8, NULL } 10051 }; 10052 10053 static hda_nid_t alc861_dac_nids[4] = { 10054 /* front, surround, clfe, side */ 10055 0x03, 0x06, 0x05, 0x04 10056 }; 10057 10058 static hda_nid_t alc660_dac_nids[3] = { 10059 /* front, clfe, surround */ 10060 0x03, 0x05, 0x06 10061 }; 10062 10063 static hda_nid_t alc861_adc_nids[1] = { 10064 /* ADC0-2 */ 10065 0x08, 10066 }; 10067 10068 static struct hda_input_mux alc861_capture_source = { 10069 .num_items = 5, 10070 .items = { 10071 { "Mic", 0x0 }, 10072 { "Front Mic", 0x3 }, 10073 { "Line", 0x1 }, 10074 { "CD", 0x4 }, 10075 { "Mixer", 0x5 }, 10076 }, 10077 }; 10078 10079 /* fill in the dac_nids table from the parsed pin configuration */ 10080 static int alc861_auto_fill_dac_nids(struct alc_spec *spec, 10081 const struct auto_pin_cfg *cfg) 10082 { 10083 int i; 10084 hda_nid_t nid; 10085 10086 spec->multiout.dac_nids = spec->private_dac_nids; 10087 for (i = 0; i < cfg->line_outs; i++) { 10088 nid = cfg->line_out_pins[i]; 10089 if (nid) { 10090 if (i >= ARRAY_SIZE(alc861_dac_nids)) 10091 continue; 10092 spec->multiout.dac_nids[i] = alc861_dac_nids[i]; 10093 } 10094 } 10095 spec->multiout.num_dacs = cfg->line_outs; 10096 return 0; 10097 } 10098 10099 /* add playback controls from the parsed DAC table */ 10100 static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec, 10101 const struct auto_pin_cfg *cfg) 10102 { 10103 char name[32]; 10104 static const char *chname[4] = { 10105 "Front", "Surround", NULL /*CLFE*/, "Side" 10106 }; 10107 hda_nid_t nid; 10108 int i, idx, err; 10109 10110 for (i = 0; i < cfg->line_outs; i++) { 10111 nid = spec->multiout.dac_nids[i]; 10112 if (!nid) 10113 continue; 10114 if (nid == 0x05) { 10115 /* Center/LFE */ 10116 err = add_control(spec, ALC_CTL_BIND_MUTE, 10117 "Center Playback Switch", 10118 HDA_COMPOSE_AMP_VAL(nid, 1, 0, 10119 HDA_OUTPUT)); 10120 if (err < 0) 10121 return err; 10122 err = add_control(spec, ALC_CTL_BIND_MUTE, 10123 "LFE Playback Switch", 10124 HDA_COMPOSE_AMP_VAL(nid, 2, 0, 10125 HDA_OUTPUT)); 10126 if (err < 0) 10127 return err; 10128 } else { 10129 for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1; 10130 idx++) 10131 if (nid == alc861_dac_nids[idx]) 10132 break; 10133 sprintf(name, "%s Playback Switch", chname[idx]); 10134 err = add_control(spec, ALC_CTL_BIND_MUTE, name, 10135 HDA_COMPOSE_AMP_VAL(nid, 3, 0, 10136 HDA_OUTPUT)); 10137 if (err < 0) 10138 return err; 10139 } 10140 } 10141 return 0; 10142 } 10143 10144 static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin) 10145 { 10146 int err; 10147 hda_nid_t nid; 10148 10149 if (!pin) 10150 return 0; 10151 10152 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) { 10153 nid = 0x03; 10154 err = add_control(spec, ALC_CTL_WIDGET_MUTE, 10155 "Headphone Playback Switch", 10156 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); 10157 if (err < 0) 10158 return err; 10159 spec->multiout.hp_nid = nid; 10160 } 10161 return 0; 10162 } 10163 10164 /* create playback/capture controls for input pins */ 10165 static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec, 10166 const struct auto_pin_cfg *cfg) 10167 { 10168 struct hda_input_mux *imux = &spec->private_imux; 10169 int i, err, idx, idx1; 10170 10171 for (i = 0; i < AUTO_PIN_LAST; i++) { 10172 switch (cfg->input_pins[i]) { 10173 case 0x0c: 10174 idx1 = 1; 10175 idx = 2; /* Line In */ 10176 break; 10177 case 0x0f: 10178 idx1 = 2; 10179 idx = 2; /* Line In */ 10180 break; 10181 case 0x0d: 10182 idx1 = 0; 10183 idx = 1; /* Mic In */ 10184 break; 10185 case 0x10: 10186 idx1 = 3; 10187 idx = 1; /* Mic In */ 10188 break; 10189 case 0x11: 10190 idx1 = 4; 10191 idx = 0; /* CD */ 10192 break; 10193 default: 10194 continue; 10195 } 10196 10197 err = new_analog_input(spec, cfg->input_pins[i], 10198 auto_pin_cfg_labels[i], idx, 0x15); 10199 if (err < 0) 10200 return err; 10201 10202 imux->items[imux->num_items].label = auto_pin_cfg_labels[i]; 10203 imux->items[imux->num_items].index = idx1; 10204 imux->num_items++; 10205 } 10206 return 0; 10207 } 10208 10209 static struct snd_kcontrol_new alc861_capture_mixer[] = { 10210 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 10211 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 10212 10213 { 10214 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 10215 /* The multiple "Capture Source" controls confuse alsamixer 10216 * So call somewhat different.. 10217 *FIXME: the controls appear in the "playback" view! 10218 */ 10219 /* .name = "Capture Source", */ 10220 .name = "Input Source", 10221 .count = 1, 10222 .info = alc_mux_enum_info, 10223 .get = alc_mux_enum_get, 10224 .put = alc_mux_enum_put, 10225 }, 10226 { } /* end */ 10227 }; 10228 10229 static void alc861_auto_set_output_and_unmute(struct hda_codec *codec, 10230 hda_nid_t nid, 10231 int pin_type, int dac_idx) 10232 { 10233 /* set as output */ 10234 10235 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 10236 pin_type); 10237 snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE, 10238 AMP_OUT_UNMUTE); 10239 10240 } 10241 10242 static void alc861_auto_init_multi_out(struct hda_codec *codec) 10243 { 10244 struct alc_spec *spec = codec->spec; 10245 int i; 10246 10247 alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b); 10248 for (i = 0; i < spec->autocfg.line_outs; i++) { 10249 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 10250 int pin_type = get_pin_type(spec->autocfg.line_out_type); 10251 if (nid) 10252 alc861_auto_set_output_and_unmute(codec, nid, pin_type, 10253 spec->multiout.dac_nids[i]); 10254 } 10255 } 10256 10257 static void alc861_auto_init_hp_out(struct hda_codec *codec) 10258 { 10259 struct alc_spec *spec = codec->spec; 10260 hda_nid_t pin; 10261 10262 pin = spec->autocfg.hp_pins[0]; 10263 if (pin) /* connect to front */ 10264 alc861_auto_set_output_and_unmute(codec, pin, PIN_HP, 10265 spec->multiout.dac_nids[0]); 10266 } 10267 10268 static void alc861_auto_init_analog_input(struct hda_codec *codec) 10269 { 10270 struct alc_spec *spec = codec->spec; 10271 int i; 10272 10273 for (i = 0; i < AUTO_PIN_LAST; i++) { 10274 hda_nid_t nid = spec->autocfg.input_pins[i]; 10275 if (nid >= 0x0c && nid <= 0x11) { 10276 snd_hda_codec_write(codec, nid, 0, 10277 AC_VERB_SET_PIN_WIDGET_CONTROL, 10278 i <= AUTO_PIN_FRONT_MIC ? 10279 PIN_VREF80 : PIN_IN); 10280 } 10281 } 10282 } 10283 10284 /* parse the BIOS configuration and set up the alc_spec */ 10285 /* return 1 if successful, 0 if the proper config is not found, 10286 * or a negative error code 10287 */ 10288 static int alc861_parse_auto_config(struct hda_codec *codec) 10289 { 10290 struct alc_spec *spec = codec->spec; 10291 int err; 10292 static hda_nid_t alc861_ignore[] = { 0x1d, 0 }; 10293 10294 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 10295 alc861_ignore); 10296 if (err < 0) 10297 return err; 10298 if (!spec->autocfg.line_outs) 10299 return 0; /* can't find valid BIOS pin config */ 10300 10301 err = alc861_auto_fill_dac_nids(spec, &spec->autocfg); 10302 if (err < 0) 10303 return err; 10304 err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg); 10305 if (err < 0) 10306 return err; 10307 err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]); 10308 if (err < 0) 10309 return err; 10310 err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg); 10311 if (err < 0) 10312 return err; 10313 10314 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 10315 10316 if (spec->autocfg.dig_out_pin) 10317 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID; 10318 10319 if (spec->kctl_alloc) 10320 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 10321 10322 spec->init_verbs[spec->num_init_verbs++] = alc861_auto_init_verbs; 10323 10324 spec->num_mux_defs = 1; 10325 spec->input_mux = &spec->private_imux; 10326 10327 spec->adc_nids = alc861_adc_nids; 10328 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids); 10329 spec->mixers[spec->num_mixers] = alc861_capture_mixer; 10330 spec->num_mixers++; 10331 10332 return 1; 10333 } 10334 10335 /* additional initialization for auto-configuration model */ 10336 static void alc861_auto_init(struct hda_codec *codec) 10337 { 10338 alc861_auto_init_multi_out(codec); 10339 alc861_auto_init_hp_out(codec); 10340 alc861_auto_init_analog_input(codec); 10341 } 10342 10343 #ifdef CONFIG_SND_HDA_POWER_SAVE 10344 static struct hda_amp_list alc861_loopbacks[] = { 10345 { 0x15, HDA_INPUT, 0 }, 10346 { 0x15, HDA_INPUT, 1 }, 10347 { 0x15, HDA_INPUT, 2 }, 10348 { 0x15, HDA_INPUT, 3 }, 10349 { } /* end */ 10350 }; 10351 #endif 10352 10353 10354 /* 10355 * configuration and preset 10356 */ 10357 static const char *alc861_models[ALC861_MODEL_LAST] = { 10358 [ALC861_3ST] = "3stack", 10359 [ALC660_3ST] = "3stack-660", 10360 [ALC861_3ST_DIG] = "3stack-dig", 10361 [ALC861_6ST_DIG] = "6stack-dig", 10362 [ALC861_UNIWILL_M31] = "uniwill-m31", 10363 [ALC861_TOSHIBA] = "toshiba", 10364 [ALC861_ASUS] = "asus", 10365 [ALC861_ASUS_LAPTOP] = "asus-laptop", 10366 [ALC861_AUTO] = "auto", 10367 }; 10368 10369 static struct snd_pci_quirk alc861_cfg_tbl[] = { 10370 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST), 10371 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP), 10372 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP), 10373 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP), 10374 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP), 10375 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS), 10376 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG), 10377 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA), 10378 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!) 10379 * Any other models that need this preset? 10380 */ 10381 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */ 10382 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31), 10383 SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), 10384 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31), 10385 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST), 10386 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST), 10387 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST), 10388 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST), 10389 {} 10390 }; 10391 10392 static struct alc_config_preset alc861_presets[] = { 10393 [ALC861_3ST] = { 10394 .mixers = { alc861_3ST_mixer }, 10395 .init_verbs = { alc861_threestack_init_verbs }, 10396 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 10397 .dac_nids = alc861_dac_nids, 10398 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes), 10399 .channel_mode = alc861_threestack_modes, 10400 .need_dac_fix = 1, 10401 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 10402 .adc_nids = alc861_adc_nids, 10403 .input_mux = &alc861_capture_source, 10404 }, 10405 [ALC861_3ST_DIG] = { 10406 .mixers = { alc861_base_mixer }, 10407 .init_verbs = { alc861_threestack_init_verbs }, 10408 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 10409 .dac_nids = alc861_dac_nids, 10410 .dig_out_nid = ALC861_DIGOUT_NID, 10411 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes), 10412 .channel_mode = alc861_threestack_modes, 10413 .need_dac_fix = 1, 10414 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 10415 .adc_nids = alc861_adc_nids, 10416 .input_mux = &alc861_capture_source, 10417 }, 10418 [ALC861_6ST_DIG] = { 10419 .mixers = { alc861_base_mixer }, 10420 .init_verbs = { alc861_base_init_verbs }, 10421 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 10422 .dac_nids = alc861_dac_nids, 10423 .dig_out_nid = ALC861_DIGOUT_NID, 10424 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes), 10425 .channel_mode = alc861_8ch_modes, 10426 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 10427 .adc_nids = alc861_adc_nids, 10428 .input_mux = &alc861_capture_source, 10429 }, 10430 [ALC660_3ST] = { 10431 .mixers = { alc861_3ST_mixer }, 10432 .init_verbs = { alc861_threestack_init_verbs }, 10433 .num_dacs = ARRAY_SIZE(alc660_dac_nids), 10434 .dac_nids = alc660_dac_nids, 10435 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes), 10436 .channel_mode = alc861_threestack_modes, 10437 .need_dac_fix = 1, 10438 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 10439 .adc_nids = alc861_adc_nids, 10440 .input_mux = &alc861_capture_source, 10441 }, 10442 [ALC861_UNIWILL_M31] = { 10443 .mixers = { alc861_uniwill_m31_mixer }, 10444 .init_verbs = { alc861_uniwill_m31_init_verbs }, 10445 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 10446 .dac_nids = alc861_dac_nids, 10447 .dig_out_nid = ALC861_DIGOUT_NID, 10448 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes), 10449 .channel_mode = alc861_uniwill_m31_modes, 10450 .need_dac_fix = 1, 10451 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 10452 .adc_nids = alc861_adc_nids, 10453 .input_mux = &alc861_capture_source, 10454 }, 10455 [ALC861_TOSHIBA] = { 10456 .mixers = { alc861_toshiba_mixer }, 10457 .init_verbs = { alc861_base_init_verbs, 10458 alc861_toshiba_init_verbs }, 10459 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 10460 .dac_nids = alc861_dac_nids, 10461 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10462 .channel_mode = alc883_3ST_2ch_modes, 10463 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 10464 .adc_nids = alc861_adc_nids, 10465 .input_mux = &alc861_capture_source, 10466 .unsol_event = alc861_toshiba_unsol_event, 10467 .init_hook = alc861_toshiba_automute, 10468 }, 10469 [ALC861_ASUS] = { 10470 .mixers = { alc861_asus_mixer }, 10471 .init_verbs = { alc861_asus_init_verbs }, 10472 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 10473 .dac_nids = alc861_dac_nids, 10474 .dig_out_nid = ALC861_DIGOUT_NID, 10475 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes), 10476 .channel_mode = alc861_asus_modes, 10477 .need_dac_fix = 1, 10478 .hp_nid = 0x06, 10479 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 10480 .adc_nids = alc861_adc_nids, 10481 .input_mux = &alc861_capture_source, 10482 }, 10483 [ALC861_ASUS_LAPTOP] = { 10484 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer }, 10485 .init_verbs = { alc861_asus_init_verbs, 10486 alc861_asus_laptop_init_verbs }, 10487 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 10488 .dac_nids = alc861_dac_nids, 10489 .dig_out_nid = ALC861_DIGOUT_NID, 10490 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10491 .channel_mode = alc883_3ST_2ch_modes, 10492 .need_dac_fix = 1, 10493 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 10494 .adc_nids = alc861_adc_nids, 10495 .input_mux = &alc861_capture_source, 10496 }, 10497 }; 10498 10499 10500 static int patch_alc861(struct hda_codec *codec) 10501 { 10502 struct alc_spec *spec; 10503 int board_config; 10504 int err; 10505 10506 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 10507 if (spec == NULL) 10508 return -ENOMEM; 10509 10510 codec->spec = spec; 10511 10512 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST, 10513 alc861_models, 10514 alc861_cfg_tbl); 10515 10516 if (board_config < 0) { 10517 printk(KERN_INFO "hda_codec: Unknown model for ALC861, " 10518 "trying auto-probe from BIOS...\n"); 10519 board_config = ALC861_AUTO; 10520 } 10521 10522 if (board_config == ALC861_AUTO) { 10523 /* automatic parse from the BIOS config */ 10524 err = alc861_parse_auto_config(codec); 10525 if (err < 0) { 10526 alc_free(codec); 10527 return err; 10528 } else if (!err) { 10529 printk(KERN_INFO 10530 "hda_codec: Cannot set up configuration " 10531 "from BIOS. Using base mode...\n"); 10532 board_config = ALC861_3ST_DIG; 10533 } 10534 } 10535 10536 if (board_config != ALC861_AUTO) 10537 setup_preset(spec, &alc861_presets[board_config]); 10538 10539 spec->stream_name_analog = "ALC861 Analog"; 10540 spec->stream_analog_playback = &alc861_pcm_analog_playback; 10541 spec->stream_analog_capture = &alc861_pcm_analog_capture; 10542 10543 spec->stream_name_digital = "ALC861 Digital"; 10544 spec->stream_digital_playback = &alc861_pcm_digital_playback; 10545 spec->stream_digital_capture = &alc861_pcm_digital_capture; 10546 10547 codec->patch_ops = alc_patch_ops; 10548 if (board_config == ALC861_AUTO) 10549 spec->init_hook = alc861_auto_init; 10550 #ifdef CONFIG_SND_HDA_POWER_SAVE 10551 if (!spec->loopback.amplist) 10552 spec->loopback.amplist = alc861_loopbacks; 10553 #endif 10554 10555 return 0; 10556 } 10557 10558 /* 10559 * ALC861-VD support 10560 * 10561 * Based on ALC882 10562 * 10563 * In addition, an independent DAC 10564 */ 10565 #define ALC861VD_DIGOUT_NID 0x06 10566 10567 static hda_nid_t alc861vd_dac_nids[4] = { 10568 /* front, surr, clfe, side surr */ 10569 0x02, 0x03, 0x04, 0x05 10570 }; 10571 10572 /* dac_nids for ALC660vd are in a different order - according to 10573 * Realtek's driver. 10574 * This should probably tesult in a different mixer for 6stack models 10575 * of ALC660vd codecs, but for now there is only 3stack mixer 10576 * - and it is the same as in 861vd. 10577 * adc_nids in ALC660vd are (is) the same as in 861vd 10578 */ 10579 static hda_nid_t alc660vd_dac_nids[3] = { 10580 /* front, rear, clfe, rear_surr */ 10581 0x02, 0x04, 0x03 10582 }; 10583 10584 static hda_nid_t alc861vd_adc_nids[1] = { 10585 /* ADC0 */ 10586 0x09, 10587 }; 10588 10589 /* input MUX */ 10590 /* FIXME: should be a matrix-type input source selection */ 10591 static struct hda_input_mux alc861vd_capture_source = { 10592 .num_items = 4, 10593 .items = { 10594 { "Mic", 0x0 }, 10595 { "Front Mic", 0x1 }, 10596 { "Line", 0x2 }, 10597 { "CD", 0x4 }, 10598 }, 10599 }; 10600 10601 static struct hda_input_mux alc861vd_dallas_capture_source = { 10602 .num_items = 3, 10603 .items = { 10604 { "Front Mic", 0x0 }, 10605 { "ATAPI Mic", 0x1 }, 10606 { "Line In", 0x5 }, 10607 }, 10608 }; 10609 10610 static struct hda_input_mux alc861vd_hp_capture_source = { 10611 .num_items = 2, 10612 .items = { 10613 { "Front Mic", 0x0 }, 10614 { "ATAPI Mic", 0x1 }, 10615 }, 10616 }; 10617 10618 #define alc861vd_mux_enum_info alc_mux_enum_info 10619 #define alc861vd_mux_enum_get alc_mux_enum_get 10620 10621 static int alc861vd_mux_enum_put(struct snd_kcontrol *kcontrol, 10622 struct snd_ctl_elem_value *ucontrol) 10623 { 10624 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 10625 struct alc_spec *spec = codec->spec; 10626 const struct hda_input_mux *imux = spec->input_mux; 10627 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 10628 static hda_nid_t capture_mixers[1] = { 0x22 }; 10629 hda_nid_t nid = capture_mixers[adc_idx]; 10630 unsigned int *cur_val = &spec->cur_mux[adc_idx]; 10631 unsigned int i, idx; 10632 10633 idx = ucontrol->value.enumerated.item[0]; 10634 if (idx >= imux->num_items) 10635 idx = imux->num_items - 1; 10636 if (*cur_val == idx) 10637 return 0; 10638 for (i = 0; i < imux->num_items; i++) { 10639 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE; 10640 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 10641 imux->items[i].index, 10642 HDA_AMP_MUTE, v); 10643 } 10644 *cur_val = idx; 10645 return 1; 10646 } 10647 10648 /* 10649 * 2ch mode 10650 */ 10651 static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = { 10652 { 2, NULL } 10653 }; 10654 10655 /* 10656 * 6ch mode 10657 */ 10658 static struct hda_verb alc861vd_6stack_ch6_init[] = { 10659 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 10660 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 10661 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 10662 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 10663 { } /* end */ 10664 }; 10665 10666 /* 10667 * 8ch mode 10668 */ 10669 static struct hda_verb alc861vd_6stack_ch8_init[] = { 10670 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 10671 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 10672 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 10673 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 10674 { } /* end */ 10675 }; 10676 10677 static struct hda_channel_mode alc861vd_6stack_modes[2] = { 10678 { 6, alc861vd_6stack_ch6_init }, 10679 { 8, alc861vd_6stack_ch8_init }, 10680 }; 10681 10682 static struct snd_kcontrol_new alc861vd_chmode_mixer[] = { 10683 { 10684 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 10685 .name = "Channel Mode", 10686 .info = alc_ch_mode_info, 10687 .get = alc_ch_mode_get, 10688 .put = alc_ch_mode_put, 10689 }, 10690 { } /* end */ 10691 }; 10692 10693 static struct snd_kcontrol_new alc861vd_capture_mixer[] = { 10694 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), 10695 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), 10696 10697 { 10698 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 10699 /* The multiple "Capture Source" controls confuse alsamixer 10700 * So call somewhat different.. 10701 *FIXME: the controls appear in the "playback" view! 10702 */ 10703 /* .name = "Capture Source", */ 10704 .name = "Input Source", 10705 .count = 1, 10706 .info = alc861vd_mux_enum_info, 10707 .get = alc861vd_mux_enum_get, 10708 .put = alc861vd_mux_enum_put, 10709 }, 10710 { } /* end */ 10711 }; 10712 10713 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 10714 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b 10715 */ 10716 static struct snd_kcontrol_new alc861vd_6st_mixer[] = { 10717 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 10718 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 10719 10720 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT), 10721 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 10722 10723 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, 10724 HDA_OUTPUT), 10725 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, 10726 HDA_OUTPUT), 10727 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 10728 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 10729 10730 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT), 10731 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 10732 10733 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 10734 10735 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 10736 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 10737 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 10738 10739 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 10740 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 10741 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 10742 10743 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 10744 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 10745 10746 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 10747 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 10748 10749 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 10750 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 10751 10752 { } /* end */ 10753 }; 10754 10755 static struct snd_kcontrol_new alc861vd_3st_mixer[] = { 10756 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 10757 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 10758 10759 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 10760 10761 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 10762 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 10763 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 10764 10765 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 10766 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 10767 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 10768 10769 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 10770 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 10771 10772 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 10773 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 10774 10775 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 10776 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 10777 10778 { } /* end */ 10779 }; 10780 10781 static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = { 10782 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 10783 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/ 10784 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 10785 10786 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 10787 10788 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 10789 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 10790 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 10791 10792 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 10793 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 10794 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 10795 10796 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 10797 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 10798 10799 { } /* end */ 10800 }; 10801 10802 /* Pin assignment: Front=0x14, HP = 0x15, 10803 * Front Mic=0x18, ATAPI Mic = 0x19, Line In = 0x1d 10804 */ 10805 static struct snd_kcontrol_new alc861vd_dallas_mixer[] = { 10806 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 10807 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 10808 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 10809 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT), 10810 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 10811 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 10812 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 10813 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 10814 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x05, HDA_INPUT), 10815 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x05, HDA_INPUT), 10816 { } /* end */ 10817 }; 10818 10819 /* Pin assignment: Speaker=0x14, Line-out = 0x15, 10820 * Front Mic=0x18, ATAPI Mic = 0x19, 10821 */ 10822 static struct snd_kcontrol_new alc861vd_hp_mixer[] = { 10823 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 10824 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 10825 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 10826 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT), 10827 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 10828 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 10829 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 10830 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 10831 10832 { } /* end */ 10833 }; 10834 10835 /* 10836 * generic initialization of ADC, input mixers and output mixers 10837 */ 10838 static struct hda_verb alc861vd_volume_init_verbs[] = { 10839 /* 10840 * Unmute ADC0 and set the default input to mic-in 10841 */ 10842 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 10843 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 10844 10845 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of 10846 * the analog-loopback mixer widget 10847 */ 10848 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 10849 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 10850 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 10851 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 10852 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 10853 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 10854 10855 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */ 10856 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 10857 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 10858 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 10859 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, 10860 10861 /* 10862 * Set up output mixers (0x02 - 0x05) 10863 */ 10864 /* set vol=0 to output mixers */ 10865 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 10866 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 10867 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 10868 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 10869 10870 /* set up input amps for analog loopback */ 10871 /* Amp Indices: DAC = 0, mixer = 1 */ 10872 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 10873 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 10874 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 10875 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 10876 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 10877 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 10878 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 10879 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 10880 10881 { } 10882 }; 10883 10884 /* 10885 * 3-stack pin configuration: 10886 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b 10887 */ 10888 static struct hda_verb alc861vd_3stack_init_verbs[] = { 10889 /* 10890 * Set pin mode and muting 10891 */ 10892 /* set front pin widgets 0x14 for output */ 10893 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 10894 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 10895 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 10896 10897 /* Mic (rear) pin: input vref at 80% */ 10898 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 10899 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 10900 /* Front Mic pin: input vref at 80% */ 10901 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 10902 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 10903 /* Line In pin: input */ 10904 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 10905 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 10906 /* Line-2 In: Headphone output (output 0 - 0x0c) */ 10907 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 10908 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 10909 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 10910 /* CD pin widget for input */ 10911 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 10912 10913 { } 10914 }; 10915 10916 /* 10917 * 6-stack pin configuration: 10918 */ 10919 static struct hda_verb alc861vd_6stack_init_verbs[] = { 10920 /* 10921 * Set pin mode and muting 10922 */ 10923 /* set front pin widgets 0x14 for output */ 10924 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 10925 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 10926 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 10927 10928 /* Rear Pin: output 1 (0x0d) */ 10929 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 10930 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 10931 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 10932 /* CLFE Pin: output 2 (0x0e) */ 10933 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 10934 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 10935 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, 10936 /* Side Pin: output 3 (0x0f) */ 10937 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 10938 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 10939 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, 10940 10941 /* Mic (rear) pin: input vref at 80% */ 10942 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 10943 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 10944 /* Front Mic pin: input vref at 80% */ 10945 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 10946 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 10947 /* Line In pin: input */ 10948 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 10949 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 10950 /* Line-2 In: Headphone output (output 0 - 0x0c) */ 10951 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 10952 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 10953 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 10954 /* CD pin widget for input */ 10955 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 10956 10957 { } 10958 }; 10959 10960 static struct hda_verb alc861vd_eapd_verbs[] = { 10961 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 10962 { } 10963 }; 10964 10965 static struct hda_verb alc861vd_lenovo_unsol_verbs[] = { 10966 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 10967 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 10968 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, 10969 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 10970 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 10971 {} 10972 }; 10973 10974 /* toggle speaker-output according to the hp-jack state */ 10975 static void alc861vd_lenovo_hp_automute(struct hda_codec *codec) 10976 { 10977 unsigned int present; 10978 unsigned char bits; 10979 10980 present = snd_hda_codec_read(codec, 0x1b, 0, 10981 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 10982 bits = present ? HDA_AMP_MUTE : 0; 10983 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 10984 HDA_AMP_MUTE, bits); 10985 } 10986 10987 static void alc861vd_lenovo_mic_automute(struct hda_codec *codec) 10988 { 10989 unsigned int present; 10990 unsigned char bits; 10991 10992 present = snd_hda_codec_read(codec, 0x18, 0, 10993 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 10994 bits = present ? HDA_AMP_MUTE : 0; 10995 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, 10996 HDA_AMP_MUTE, bits); 10997 } 10998 10999 static void alc861vd_lenovo_automute(struct hda_codec *codec) 11000 { 11001 alc861vd_lenovo_hp_automute(codec); 11002 alc861vd_lenovo_mic_automute(codec); 11003 } 11004 11005 static void alc861vd_lenovo_unsol_event(struct hda_codec *codec, 11006 unsigned int res) 11007 { 11008 switch (res >> 26) { 11009 case ALC880_HP_EVENT: 11010 alc861vd_lenovo_hp_automute(codec); 11011 break; 11012 case ALC880_MIC_EVENT: 11013 alc861vd_lenovo_mic_automute(codec); 11014 break; 11015 } 11016 } 11017 11018 static struct hda_verb alc861vd_dallas_verbs[] = { 11019 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 11020 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 11021 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 11022 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 11023 11024 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11025 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11026 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 11027 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 11028 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 11029 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 11030 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 11031 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 11032 11033 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 11034 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 11035 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 11036 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 11037 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 11038 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 11039 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 11040 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 11041 11042 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, 11043 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 11044 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, 11045 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 11046 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 11047 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 11048 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 11049 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 11050 11051 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11052 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 11053 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 11054 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 11055 11056 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 11057 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 11058 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 11059 11060 { } /* end */ 11061 }; 11062 11063 /* toggle speaker-output according to the hp-jack state */ 11064 static void alc861vd_dallas_automute(struct hda_codec *codec) 11065 { 11066 unsigned int present; 11067 11068 present = snd_hda_codec_read(codec, 0x15, 0, 11069 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 11070 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 11071 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 11072 } 11073 11074 static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int res) 11075 { 11076 if ((res >> 26) == ALC880_HP_EVENT) 11077 alc861vd_dallas_automute(codec); 11078 } 11079 11080 #ifdef CONFIG_SND_HDA_POWER_SAVE 11081 #define alc861vd_loopbacks alc880_loopbacks 11082 #endif 11083 11084 /* pcm configuration: identiacal with ALC880 */ 11085 #define alc861vd_pcm_analog_playback alc880_pcm_analog_playback 11086 #define alc861vd_pcm_analog_capture alc880_pcm_analog_capture 11087 #define alc861vd_pcm_digital_playback alc880_pcm_digital_playback 11088 #define alc861vd_pcm_digital_capture alc880_pcm_digital_capture 11089 11090 /* 11091 * configuration and preset 11092 */ 11093 static const char *alc861vd_models[ALC861VD_MODEL_LAST] = { 11094 [ALC660VD_3ST] = "3stack-660", 11095 [ALC660VD_3ST_DIG] = "3stack-660-digout", 11096 [ALC861VD_3ST] = "3stack", 11097 [ALC861VD_3ST_DIG] = "3stack-digout", 11098 [ALC861VD_6ST_DIG] = "6stack-digout", 11099 [ALC861VD_LENOVO] = "lenovo", 11100 [ALC861VD_DALLAS] = "dallas", 11101 [ALC861VD_HP] = "hp", 11102 [ALC861VD_AUTO] = "auto", 11103 }; 11104 11105 static struct snd_pci_quirk alc861vd_cfg_tbl[] = { 11106 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST), 11107 SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST), 11108 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG), 11109 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST), 11110 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST), 11111 11112 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/ 11113 SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS), 11114 SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO), 11115 SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO), 11116 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO), 11117 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO), 11118 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG), 11119 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG), 11120 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP), 11121 {} 11122 }; 11123 11124 static struct alc_config_preset alc861vd_presets[] = { 11125 [ALC660VD_3ST] = { 11126 .mixers = { alc861vd_3st_mixer }, 11127 .init_verbs = { alc861vd_volume_init_verbs, 11128 alc861vd_3stack_init_verbs }, 11129 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids), 11130 .dac_nids = alc660vd_dac_nids, 11131 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids), 11132 .adc_nids = alc861vd_adc_nids, 11133 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 11134 .channel_mode = alc861vd_3stack_2ch_modes, 11135 .input_mux = &alc861vd_capture_source, 11136 }, 11137 [ALC660VD_3ST_DIG] = { 11138 .mixers = { alc861vd_3st_mixer }, 11139 .init_verbs = { alc861vd_volume_init_verbs, 11140 alc861vd_3stack_init_verbs }, 11141 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids), 11142 .dac_nids = alc660vd_dac_nids, 11143 .dig_out_nid = ALC861VD_DIGOUT_NID, 11144 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids), 11145 .adc_nids = alc861vd_adc_nids, 11146 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 11147 .channel_mode = alc861vd_3stack_2ch_modes, 11148 .input_mux = &alc861vd_capture_source, 11149 }, 11150 [ALC861VD_3ST] = { 11151 .mixers = { alc861vd_3st_mixer }, 11152 .init_verbs = { alc861vd_volume_init_verbs, 11153 alc861vd_3stack_init_verbs }, 11154 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids), 11155 .dac_nids = alc861vd_dac_nids, 11156 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 11157 .channel_mode = alc861vd_3stack_2ch_modes, 11158 .input_mux = &alc861vd_capture_source, 11159 }, 11160 [ALC861VD_3ST_DIG] = { 11161 .mixers = { alc861vd_3st_mixer }, 11162 .init_verbs = { alc861vd_volume_init_verbs, 11163 alc861vd_3stack_init_verbs }, 11164 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids), 11165 .dac_nids = alc861vd_dac_nids, 11166 .dig_out_nid = ALC861VD_DIGOUT_NID, 11167 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 11168 .channel_mode = alc861vd_3stack_2ch_modes, 11169 .input_mux = &alc861vd_capture_source, 11170 }, 11171 [ALC861VD_6ST_DIG] = { 11172 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer }, 11173 .init_verbs = { alc861vd_volume_init_verbs, 11174 alc861vd_6stack_init_verbs }, 11175 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids), 11176 .dac_nids = alc861vd_dac_nids, 11177 .dig_out_nid = ALC861VD_DIGOUT_NID, 11178 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes), 11179 .channel_mode = alc861vd_6stack_modes, 11180 .input_mux = &alc861vd_capture_source, 11181 }, 11182 [ALC861VD_LENOVO] = { 11183 .mixers = { alc861vd_lenovo_mixer }, 11184 .init_verbs = { alc861vd_volume_init_verbs, 11185 alc861vd_3stack_init_verbs, 11186 alc861vd_eapd_verbs, 11187 alc861vd_lenovo_unsol_verbs }, 11188 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids), 11189 .dac_nids = alc660vd_dac_nids, 11190 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids), 11191 .adc_nids = alc861vd_adc_nids, 11192 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 11193 .channel_mode = alc861vd_3stack_2ch_modes, 11194 .input_mux = &alc861vd_capture_source, 11195 .unsol_event = alc861vd_lenovo_unsol_event, 11196 .init_hook = alc861vd_lenovo_automute, 11197 }, 11198 [ALC861VD_DALLAS] = { 11199 .mixers = { alc861vd_dallas_mixer }, 11200 .init_verbs = { alc861vd_dallas_verbs }, 11201 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids), 11202 .dac_nids = alc861vd_dac_nids, 11203 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids), 11204 .adc_nids = alc861vd_adc_nids, 11205 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 11206 .channel_mode = alc861vd_3stack_2ch_modes, 11207 .input_mux = &alc861vd_dallas_capture_source, 11208 .unsol_event = alc861vd_dallas_unsol_event, 11209 .init_hook = alc861vd_dallas_automute, 11210 }, 11211 [ALC861VD_HP] = { 11212 .mixers = { alc861vd_hp_mixer }, 11213 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs }, 11214 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids), 11215 .dac_nids = alc861vd_dac_nids, 11216 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids), 11217 .dig_out_nid = ALC861VD_DIGOUT_NID, 11218 .adc_nids = alc861vd_adc_nids, 11219 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 11220 .channel_mode = alc861vd_3stack_2ch_modes, 11221 .input_mux = &alc861vd_hp_capture_source, 11222 .unsol_event = alc861vd_dallas_unsol_event, 11223 .init_hook = alc861vd_dallas_automute, 11224 }, 11225 }; 11226 11227 /* 11228 * BIOS auto configuration 11229 */ 11230 static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec, 11231 hda_nid_t nid, int pin_type, int dac_idx) 11232 { 11233 /* set as output */ 11234 snd_hda_codec_write(codec, nid, 0, 11235 AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type); 11236 snd_hda_codec_write(codec, nid, 0, 11237 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); 11238 } 11239 11240 static void alc861vd_auto_init_multi_out(struct hda_codec *codec) 11241 { 11242 struct alc_spec *spec = codec->spec; 11243 int i; 11244 11245 alc_subsystem_id(codec, 0x15, 0x1b, 0x14); 11246 for (i = 0; i <= HDA_SIDE; i++) { 11247 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 11248 int pin_type = get_pin_type(spec->autocfg.line_out_type); 11249 if (nid) 11250 alc861vd_auto_set_output_and_unmute(codec, nid, 11251 pin_type, i); 11252 } 11253 } 11254 11255 11256 static void alc861vd_auto_init_hp_out(struct hda_codec *codec) 11257 { 11258 struct alc_spec *spec = codec->spec; 11259 hda_nid_t pin; 11260 11261 pin = spec->autocfg.hp_pins[0]; 11262 if (pin) /* connect to front and use dac 0 */ 11263 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); 11264 } 11265 11266 #define alc861vd_is_input_pin(nid) alc880_is_input_pin(nid) 11267 #define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID 11268 11269 static void alc861vd_auto_init_analog_input(struct hda_codec *codec) 11270 { 11271 struct alc_spec *spec = codec->spec; 11272 int i; 11273 11274 for (i = 0; i < AUTO_PIN_LAST; i++) { 11275 hda_nid_t nid = spec->autocfg.input_pins[i]; 11276 if (alc861vd_is_input_pin(nid)) { 11277 snd_hda_codec_write(codec, nid, 0, 11278 AC_VERB_SET_PIN_WIDGET_CONTROL, 11279 i <= AUTO_PIN_FRONT_MIC ? 11280 PIN_VREF80 : PIN_IN); 11281 if (nid != ALC861VD_PIN_CD_NID) 11282 snd_hda_codec_write(codec, nid, 0, 11283 AC_VERB_SET_AMP_GAIN_MUTE, 11284 AMP_OUT_MUTE); 11285 } 11286 } 11287 } 11288 11289 #define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02) 11290 #define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c) 11291 11292 /* add playback controls from the parsed DAC table */ 11293 /* Based on ALC880 version. But ALC861VD has separate, 11294 * different NIDs for mute/unmute switch and volume control */ 11295 static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec, 11296 const struct auto_pin_cfg *cfg) 11297 { 11298 char name[32]; 11299 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"}; 11300 hda_nid_t nid_v, nid_s; 11301 int i, err; 11302 11303 for (i = 0; i < cfg->line_outs; i++) { 11304 if (!spec->multiout.dac_nids[i]) 11305 continue; 11306 nid_v = alc861vd_idx_to_mixer_vol( 11307 alc880_dac_to_idx( 11308 spec->multiout.dac_nids[i])); 11309 nid_s = alc861vd_idx_to_mixer_switch( 11310 alc880_dac_to_idx( 11311 spec->multiout.dac_nids[i])); 11312 11313 if (i == 2) { 11314 /* Center/LFE */ 11315 err = add_control(spec, ALC_CTL_WIDGET_VOL, 11316 "Center Playback Volume", 11317 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0, 11318 HDA_OUTPUT)); 11319 if (err < 0) 11320 return err; 11321 err = add_control(spec, ALC_CTL_WIDGET_VOL, 11322 "LFE Playback Volume", 11323 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0, 11324 HDA_OUTPUT)); 11325 if (err < 0) 11326 return err; 11327 err = add_control(spec, ALC_CTL_BIND_MUTE, 11328 "Center Playback Switch", 11329 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2, 11330 HDA_INPUT)); 11331 if (err < 0) 11332 return err; 11333 err = add_control(spec, ALC_CTL_BIND_MUTE, 11334 "LFE Playback Switch", 11335 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2, 11336 HDA_INPUT)); 11337 if (err < 0) 11338 return err; 11339 } else { 11340 sprintf(name, "%s Playback Volume", chname[i]); 11341 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, 11342 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, 11343 HDA_OUTPUT)); 11344 if (err < 0) 11345 return err; 11346 sprintf(name, "%s Playback Switch", chname[i]); 11347 err = add_control(spec, ALC_CTL_BIND_MUTE, name, 11348 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, 11349 HDA_INPUT)); 11350 if (err < 0) 11351 return err; 11352 } 11353 } 11354 return 0; 11355 } 11356 11357 /* add playback controls for speaker and HP outputs */ 11358 /* Based on ALC880 version. But ALC861VD has separate, 11359 * different NIDs for mute/unmute switch and volume control */ 11360 static int alc861vd_auto_create_extra_out(struct alc_spec *spec, 11361 hda_nid_t pin, const char *pfx) 11362 { 11363 hda_nid_t nid_v, nid_s; 11364 int err; 11365 char name[32]; 11366 11367 if (!pin) 11368 return 0; 11369 11370 if (alc880_is_fixed_pin(pin)) { 11371 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); 11372 /* specify the DAC as the extra output */ 11373 if (!spec->multiout.hp_nid) 11374 spec->multiout.hp_nid = nid_v; 11375 else 11376 spec->multiout.extra_out_nid[0] = nid_v; 11377 /* control HP volume/switch on the output mixer amp */ 11378 nid_v = alc861vd_idx_to_mixer_vol( 11379 alc880_fixed_pin_idx(pin)); 11380 nid_s = alc861vd_idx_to_mixer_switch( 11381 alc880_fixed_pin_idx(pin)); 11382 11383 sprintf(name, "%s Playback Volume", pfx); 11384 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, 11385 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT)); 11386 if (err < 0) 11387 return err; 11388 sprintf(name, "%s Playback Switch", pfx); 11389 err = add_control(spec, ALC_CTL_BIND_MUTE, name, 11390 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT)); 11391 if (err < 0) 11392 return err; 11393 } else if (alc880_is_multi_pin(pin)) { 11394 /* set manual connection */ 11395 /* we have only a switch on HP-out PIN */ 11396 sprintf(name, "%s Playback Switch", pfx); 11397 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, 11398 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); 11399 if (err < 0) 11400 return err; 11401 } 11402 return 0; 11403 } 11404 11405 /* parse the BIOS configuration and set up the alc_spec 11406 * return 1 if successful, 0 if the proper config is not found, 11407 * or a negative error code 11408 * Based on ALC880 version - had to change it to override 11409 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */ 11410 static int alc861vd_parse_auto_config(struct hda_codec *codec) 11411 { 11412 struct alc_spec *spec = codec->spec; 11413 int err; 11414 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 }; 11415 11416 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 11417 alc861vd_ignore); 11418 if (err < 0) 11419 return err; 11420 if (!spec->autocfg.line_outs) 11421 return 0; /* can't find valid BIOS pin config */ 11422 11423 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); 11424 if (err < 0) 11425 return err; 11426 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg); 11427 if (err < 0) 11428 return err; 11429 err = alc861vd_auto_create_extra_out(spec, 11430 spec->autocfg.speaker_pins[0], 11431 "Speaker"); 11432 if (err < 0) 11433 return err; 11434 err = alc861vd_auto_create_extra_out(spec, 11435 spec->autocfg.hp_pins[0], 11436 "Headphone"); 11437 if (err < 0) 11438 return err; 11439 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg); 11440 if (err < 0) 11441 return err; 11442 11443 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 11444 11445 if (spec->autocfg.dig_out_pin) 11446 spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID; 11447 11448 if (spec->kctl_alloc) 11449 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 11450 11451 spec->init_verbs[spec->num_init_verbs++] 11452 = alc861vd_volume_init_verbs; 11453 11454 spec->num_mux_defs = 1; 11455 spec->input_mux = &spec->private_imux; 11456 11457 err = alc_auto_add_mic_boost(codec); 11458 if (err < 0) 11459 return err; 11460 11461 return 1; 11462 } 11463 11464 /* additional initialization for auto-configuration model */ 11465 static void alc861vd_auto_init(struct hda_codec *codec) 11466 { 11467 alc861vd_auto_init_multi_out(codec); 11468 alc861vd_auto_init_hp_out(codec); 11469 alc861vd_auto_init_analog_input(codec); 11470 } 11471 11472 static int patch_alc861vd(struct hda_codec *codec) 11473 { 11474 struct alc_spec *spec; 11475 int err, board_config; 11476 11477 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 11478 if (spec == NULL) 11479 return -ENOMEM; 11480 11481 codec->spec = spec; 11482 11483 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST, 11484 alc861vd_models, 11485 alc861vd_cfg_tbl); 11486 11487 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) { 11488 printk(KERN_INFO "hda_codec: Unknown model for ALC660VD/" 11489 "ALC861VD, trying auto-probe from BIOS...\n"); 11490 board_config = ALC861VD_AUTO; 11491 } 11492 11493 if (board_config == ALC861VD_AUTO) { 11494 /* automatic parse from the BIOS config */ 11495 err = alc861vd_parse_auto_config(codec); 11496 if (err < 0) { 11497 alc_free(codec); 11498 return err; 11499 } else if (!err) { 11500 printk(KERN_INFO 11501 "hda_codec: Cannot set up configuration " 11502 "from BIOS. Using base mode...\n"); 11503 board_config = ALC861VD_3ST; 11504 } 11505 } 11506 11507 if (board_config != ALC861VD_AUTO) 11508 setup_preset(spec, &alc861vd_presets[board_config]); 11509 11510 spec->stream_name_analog = "ALC861VD Analog"; 11511 spec->stream_analog_playback = &alc861vd_pcm_analog_playback; 11512 spec->stream_analog_capture = &alc861vd_pcm_analog_capture; 11513 11514 spec->stream_name_digital = "ALC861VD Digital"; 11515 spec->stream_digital_playback = &alc861vd_pcm_digital_playback; 11516 spec->stream_digital_capture = &alc861vd_pcm_digital_capture; 11517 11518 spec->adc_nids = alc861vd_adc_nids; 11519 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids); 11520 11521 spec->mixers[spec->num_mixers] = alc861vd_capture_mixer; 11522 spec->num_mixers++; 11523 11524 codec->patch_ops = alc_patch_ops; 11525 11526 if (board_config == ALC861VD_AUTO) 11527 spec->init_hook = alc861vd_auto_init; 11528 #ifdef CONFIG_SND_HDA_POWER_SAVE 11529 if (!spec->loopback.amplist) 11530 spec->loopback.amplist = alc861vd_loopbacks; 11531 #endif 11532 11533 return 0; 11534 } 11535 11536 /* 11537 * ALC662 support 11538 * 11539 * ALC662 is almost identical with ALC880 but has cleaner and more flexible 11540 * configuration. Each pin widget can choose any input DACs and a mixer. 11541 * Each ADC is connected from a mixer of all inputs. This makes possible 11542 * 6-channel independent captures. 11543 * 11544 * In addition, an independent DAC for the multi-playback (not used in this 11545 * driver yet). 11546 */ 11547 #define ALC662_DIGOUT_NID 0x06 11548 #define ALC662_DIGIN_NID 0x0a 11549 11550 static hda_nid_t alc662_dac_nids[4] = { 11551 /* front, rear, clfe, rear_surr */ 11552 0x02, 0x03, 0x04 11553 }; 11554 11555 static hda_nid_t alc662_adc_nids[1] = { 11556 /* ADC1-2 */ 11557 0x09, 11558 }; 11559 /* input MUX */ 11560 /* FIXME: should be a matrix-type input source selection */ 11561 11562 static struct hda_input_mux alc662_capture_source = { 11563 .num_items = 4, 11564 .items = { 11565 { "Mic", 0x0 }, 11566 { "Front Mic", 0x1 }, 11567 { "Line", 0x2 }, 11568 { "CD", 0x4 }, 11569 }, 11570 }; 11571 11572 static struct hda_input_mux alc662_lenovo_101e_capture_source = { 11573 .num_items = 2, 11574 .items = { 11575 { "Mic", 0x1 }, 11576 { "Line", 0x2 }, 11577 }, 11578 }; 11579 11580 static struct hda_input_mux alc662_eeepc_capture_source = { 11581 .num_items = 2, 11582 .items = { 11583 { "i-Mic", 0x1 }, 11584 { "e-Mic", 0x0 }, 11585 }, 11586 }; 11587 11588 #define alc662_mux_enum_info alc_mux_enum_info 11589 #define alc662_mux_enum_get alc_mux_enum_get 11590 11591 static int alc662_mux_enum_put(struct snd_kcontrol *kcontrol, 11592 struct snd_ctl_elem_value *ucontrol) 11593 { 11594 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 11595 struct alc_spec *spec = codec->spec; 11596 const struct hda_input_mux *imux = spec->input_mux; 11597 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 11598 static hda_nid_t capture_mixers[2] = { 0x23, 0x22 }; 11599 hda_nid_t nid = capture_mixers[adc_idx]; 11600 unsigned int *cur_val = &spec->cur_mux[adc_idx]; 11601 unsigned int i, idx; 11602 11603 idx = ucontrol->value.enumerated.item[0]; 11604 if (idx >= imux->num_items) 11605 idx = imux->num_items - 1; 11606 if (*cur_val == idx) 11607 return 0; 11608 for (i = 0; i < imux->num_items; i++) { 11609 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE; 11610 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 11611 imux->items[i].index, 11612 HDA_AMP_MUTE, v); 11613 } 11614 *cur_val = idx; 11615 return 1; 11616 } 11617 /* 11618 * 2ch mode 11619 */ 11620 static struct hda_channel_mode alc662_3ST_2ch_modes[1] = { 11621 { 2, NULL } 11622 }; 11623 11624 /* 11625 * 2ch mode 11626 */ 11627 static struct hda_verb alc662_3ST_ch2_init[] = { 11628 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 11629 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 11630 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 11631 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 11632 { } /* end */ 11633 }; 11634 11635 /* 11636 * 6ch mode 11637 */ 11638 static struct hda_verb alc662_3ST_ch6_init[] = { 11639 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 11640 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 11641 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, 11642 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 11643 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 11644 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 11645 { } /* end */ 11646 }; 11647 11648 static struct hda_channel_mode alc662_3ST_6ch_modes[2] = { 11649 { 2, alc662_3ST_ch2_init }, 11650 { 6, alc662_3ST_ch6_init }, 11651 }; 11652 11653 /* 11654 * 2ch mode 11655 */ 11656 static struct hda_verb alc662_sixstack_ch6_init[] = { 11657 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 11658 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 11659 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 11660 { } /* end */ 11661 }; 11662 11663 /* 11664 * 6ch mode 11665 */ 11666 static struct hda_verb alc662_sixstack_ch8_init[] = { 11667 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 11668 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 11669 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 11670 { } /* end */ 11671 }; 11672 11673 static struct hda_channel_mode alc662_5stack_modes[2] = { 11674 { 2, alc662_sixstack_ch6_init }, 11675 { 6, alc662_sixstack_ch8_init }, 11676 }; 11677 11678 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 11679 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b 11680 */ 11681 11682 static struct snd_kcontrol_new alc662_base_mixer[] = { 11683 /* output mixer control */ 11684 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), 11685 HDA_CODEC_MUTE("Front Playback Switch", 0x02, 0x0, HDA_OUTPUT), 11686 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT), 11687 HDA_CODEC_MUTE("Surround Playback Switch", 0x03, 0x0, HDA_OUTPUT), 11688 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT), 11689 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT), 11690 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT), 11691 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT), 11692 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 11693 11694 /*Input mixer control */ 11695 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT), 11696 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT), 11697 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT), 11698 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT), 11699 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT), 11700 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT), 11701 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT), 11702 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT), 11703 11704 /* Capture mixer control */ 11705 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), 11706 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), 11707 { 11708 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 11709 .name = "Capture Source", 11710 .count = 1, 11711 .info = alc_mux_enum_info, 11712 .get = alc_mux_enum_get, 11713 .put = alc_mux_enum_put, 11714 }, 11715 { } /* end */ 11716 }; 11717 11718 static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = { 11719 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 11720 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT), 11721 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 11722 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 11723 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 11724 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 11725 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 11726 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11727 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11728 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 11729 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 11730 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 11731 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 11732 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), 11733 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), 11734 { 11735 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 11736 /* .name = "Capture Source", */ 11737 .name = "Input Source", 11738 .count = 1, 11739 .info = alc662_mux_enum_info, 11740 .get = alc662_mux_enum_get, 11741 .put = alc662_mux_enum_put, 11742 }, 11743 { } /* end */ 11744 }; 11745 11746 static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = { 11747 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 11748 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT), 11749 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT), 11750 HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT), 11751 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT), 11752 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT), 11753 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT), 11754 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT), 11755 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 11756 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 11757 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 11758 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 11759 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 11760 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11761 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11762 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 11763 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 11764 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 11765 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 11766 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), 11767 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), 11768 { 11769 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 11770 /* .name = "Capture Source", */ 11771 .name = "Input Source", 11772 .count = 1, 11773 .info = alc662_mux_enum_info, 11774 .get = alc662_mux_enum_get, 11775 .put = alc662_mux_enum_put, 11776 }, 11777 { } /* end */ 11778 }; 11779 11780 static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = { 11781 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 11782 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT), 11783 HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x03, 0x0, HDA_OUTPUT), 11784 HDA_BIND_MUTE("iSpeaker Playback Switch", 0x03, 2, HDA_INPUT), 11785 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 11786 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 11787 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 11788 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 11789 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 11790 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), 11791 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), 11792 { 11793 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 11794 /* .name = "Capture Source", */ 11795 .name = "Input Source", 11796 .count = 1, 11797 .info = alc662_mux_enum_info, 11798 .get = alc662_mux_enum_get, 11799 .put = alc662_mux_enum_put, 11800 }, 11801 { } /* end */ 11802 }; 11803 11804 static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = { 11805 HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 11806 11807 HDA_CODEC_VOLUME("LineOut Playback Volume", 0x02, 0x0, HDA_OUTPUT), 11808 HDA_CODEC_MUTE("LineOut Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 11809 11810 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT), 11811 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11812 HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11813 11814 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT), 11815 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 11816 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 11817 { } /* end */ 11818 }; 11819 11820 static struct snd_kcontrol_new alc662_chmode_mixer[] = { 11821 { 11822 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 11823 .name = "Channel Mode", 11824 .info = alc_ch_mode_info, 11825 .get = alc_ch_mode_get, 11826 .put = alc_ch_mode_put, 11827 }, 11828 { } /* end */ 11829 }; 11830 11831 static struct hda_verb alc662_init_verbs[] = { 11832 /* ADC: mute amp left and right */ 11833 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 11834 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 11835 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 11836 11837 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 11838 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 11839 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 11840 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 11841 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 11842 11843 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11844 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11845 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11846 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11847 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11848 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11849 11850 /* Front Pin: output 0 (0x0c) */ 11851 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 11852 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 11853 11854 /* Rear Pin: output 1 (0x0d) */ 11855 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 11856 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 11857 11858 /* CLFE Pin: output 2 (0x0e) */ 11859 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 11860 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 11861 11862 /* Mic (rear) pin: input vref at 80% */ 11863 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 11864 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 11865 /* Front Mic pin: input vref at 80% */ 11866 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 11867 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 11868 /* Line In pin: input */ 11869 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 11870 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 11871 /* Line-2 In: Headphone output (output 0 - 0x0c) */ 11872 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11873 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 11874 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 11875 /* CD pin widget for input */ 11876 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 11877 11878 /* FIXME: use matrix-type input source selection */ 11879 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 11880 /* Input mixer */ 11881 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11882 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11883 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 11884 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, 11885 11886 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11887 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11888 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 11889 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, 11890 { } 11891 }; 11892 11893 static struct hda_verb alc662_sue_init_verbs[] = { 11894 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT}, 11895 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT}, 11896 {} 11897 }; 11898 11899 static struct hda_verb alc662_eeepc_sue_init_verbs[] = { 11900 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 11901 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 11902 {} 11903 }; 11904 11905 /* 11906 * generic initialization of ADC, input mixers and output mixers 11907 */ 11908 static struct hda_verb alc662_auto_init_verbs[] = { 11909 /* 11910 * Unmute ADC and set the default input to mic-in 11911 */ 11912 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 11913 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11914 11915 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 11916 * mixer widget 11917 * Note: PASD motherboards uses the Line In 2 as the input for front 11918 * panel mic (mic 2) 11919 */ 11920 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 11921 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 11922 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 11923 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 11924 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 11925 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 11926 11927 /* 11928 * Set up output mixers (0x0c - 0x0f) 11929 */ 11930 /* set vol=0 to output mixers */ 11931 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 11932 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 11933 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 11934 11935 /* set up input amps for analog loopback */ 11936 /* Amp Indices: DAC = 0, mixer = 1 */ 11937 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11938 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11939 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11940 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11941 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11942 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11943 11944 11945 /* FIXME: use matrix-type input source selection */ 11946 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 11947 /* Input mixer */ 11948 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11949 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11950 { } 11951 }; 11952 11953 /* capture mixer elements */ 11954 static struct snd_kcontrol_new alc662_capture_mixer[] = { 11955 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), 11956 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), 11957 { 11958 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 11959 /* The multiple "Capture Source" controls confuse alsamixer 11960 * So call somewhat different.. 11961 * FIXME: the controls appear in the "playback" view! 11962 */ 11963 /* .name = "Capture Source", */ 11964 .name = "Input Source", 11965 .count = 1, 11966 .info = alc882_mux_enum_info, 11967 .get = alc882_mux_enum_get, 11968 .put = alc882_mux_enum_put, 11969 }, 11970 { } /* end */ 11971 }; 11972 11973 static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec) 11974 { 11975 unsigned int present; 11976 unsigned char bits; 11977 11978 present = snd_hda_codec_read(codec, 0x14, 0, 11979 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 11980 bits = present ? HDA_AMP_MUTE : 0; 11981 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 11982 HDA_AMP_MUTE, bits); 11983 } 11984 11985 static void alc662_lenovo_101e_all_automute(struct hda_codec *codec) 11986 { 11987 unsigned int present; 11988 unsigned char bits; 11989 11990 present = snd_hda_codec_read(codec, 0x1b, 0, 11991 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 11992 bits = present ? HDA_AMP_MUTE : 0; 11993 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 11994 HDA_AMP_MUTE, bits); 11995 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 11996 HDA_AMP_MUTE, bits); 11997 } 11998 11999 static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec, 12000 unsigned int res) 12001 { 12002 if ((res >> 26) == ALC880_HP_EVENT) 12003 alc662_lenovo_101e_all_automute(codec); 12004 if ((res >> 26) == ALC880_FRONT_EVENT) 12005 alc662_lenovo_101e_ispeaker_automute(codec); 12006 } 12007 12008 static void alc662_eeepc_mic_automute(struct hda_codec *codec) 12009 { 12010 unsigned int present; 12011 12012 present = snd_hda_codec_read(codec, 0x18, 0, 12013 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 12014 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE, 12015 0x7000 | (0x00 << 8) | (present ? 0 : 0x80)); 12016 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE, 12017 0x7000 | (0x00 << 8) | (present ? 0 : 0x80)); 12018 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE, 12019 0x7000 | (0x01 << 8) | (present ? 0x80 : 0)); 12020 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE, 12021 0x7000 | (0x01 << 8) | (present ? 0x80 : 0)); 12022 } 12023 12024 /* unsolicited event for HP jack sensing */ 12025 static void alc662_eeepc_unsol_event(struct hda_codec *codec, 12026 unsigned int res) 12027 { 12028 if ((res >> 26) == ALC880_HP_EVENT) 12029 alc262_hippo1_automute( codec ); 12030 12031 if ((res >> 26) == ALC880_MIC_EVENT) 12032 alc662_eeepc_mic_automute(codec); 12033 } 12034 12035 static void alc662_eeepc_inithook(struct hda_codec *codec) 12036 { 12037 alc262_hippo1_automute( codec ); 12038 alc662_eeepc_mic_automute(codec); 12039 } 12040 12041 #ifdef CONFIG_SND_HDA_POWER_SAVE 12042 #define alc662_loopbacks alc880_loopbacks 12043 #endif 12044 12045 12046 /* pcm configuration: identiacal with ALC880 */ 12047 #define alc662_pcm_analog_playback alc880_pcm_analog_playback 12048 #define alc662_pcm_analog_capture alc880_pcm_analog_capture 12049 #define alc662_pcm_digital_playback alc880_pcm_digital_playback 12050 #define alc662_pcm_digital_capture alc880_pcm_digital_capture 12051 12052 /* 12053 * configuration and preset 12054 */ 12055 static const char *alc662_models[ALC662_MODEL_LAST] = { 12056 [ALC662_3ST_2ch_DIG] = "3stack-dig", 12057 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig", 12058 [ALC662_3ST_6ch] = "3stack-6ch", 12059 [ALC662_5ST_DIG] = "6stack-dig", 12060 [ALC662_LENOVO_101E] = "lenovo-101e", 12061 [ALC662_AUTO] = "auto", 12062 }; 12063 12064 static struct snd_pci_quirk alc662_cfg_tbl[] = { 12065 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E), 12066 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701), 12067 {} 12068 }; 12069 12070 static struct alc_config_preset alc662_presets[] = { 12071 [ALC662_3ST_2ch_DIG] = { 12072 .mixers = { alc662_3ST_2ch_mixer, alc662_capture_mixer }, 12073 .init_verbs = { alc662_init_verbs }, 12074 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 12075 .dac_nids = alc662_dac_nids, 12076 .dig_out_nid = ALC662_DIGOUT_NID, 12077 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids), 12078 .adc_nids = alc662_adc_nids, 12079 .dig_in_nid = ALC662_DIGIN_NID, 12080 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 12081 .channel_mode = alc662_3ST_2ch_modes, 12082 .input_mux = &alc662_capture_source, 12083 }, 12084 [ALC662_3ST_6ch_DIG] = { 12085 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer, 12086 alc662_capture_mixer }, 12087 .init_verbs = { alc662_init_verbs }, 12088 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 12089 .dac_nids = alc662_dac_nids, 12090 .dig_out_nid = ALC662_DIGOUT_NID, 12091 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids), 12092 .adc_nids = alc662_adc_nids, 12093 .dig_in_nid = ALC662_DIGIN_NID, 12094 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), 12095 .channel_mode = alc662_3ST_6ch_modes, 12096 .need_dac_fix = 1, 12097 .input_mux = &alc662_capture_source, 12098 }, 12099 [ALC662_3ST_6ch] = { 12100 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer, 12101 alc662_capture_mixer }, 12102 .init_verbs = { alc662_init_verbs }, 12103 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 12104 .dac_nids = alc662_dac_nids, 12105 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids), 12106 .adc_nids = alc662_adc_nids, 12107 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), 12108 .channel_mode = alc662_3ST_6ch_modes, 12109 .need_dac_fix = 1, 12110 .input_mux = &alc662_capture_source, 12111 }, 12112 [ALC662_5ST_DIG] = { 12113 .mixers = { alc662_base_mixer, alc662_chmode_mixer, 12114 alc662_capture_mixer }, 12115 .init_verbs = { alc662_init_verbs }, 12116 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 12117 .dac_nids = alc662_dac_nids, 12118 .dig_out_nid = ALC662_DIGOUT_NID, 12119 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids), 12120 .adc_nids = alc662_adc_nids, 12121 .dig_in_nid = ALC662_DIGIN_NID, 12122 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes), 12123 .channel_mode = alc662_5stack_modes, 12124 .input_mux = &alc662_capture_source, 12125 }, 12126 [ALC662_LENOVO_101E] = { 12127 .mixers = { alc662_lenovo_101e_mixer, alc662_capture_mixer }, 12128 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs }, 12129 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 12130 .dac_nids = alc662_dac_nids, 12131 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids), 12132 .adc_nids = alc662_adc_nids, 12133 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 12134 .channel_mode = alc662_3ST_2ch_modes, 12135 .input_mux = &alc662_lenovo_101e_capture_source, 12136 .unsol_event = alc662_lenovo_101e_unsol_event, 12137 .init_hook = alc662_lenovo_101e_all_automute, 12138 }, 12139 [ALC662_ASUS_EEEPC_P701] = { 12140 .mixers = { alc662_eeepc_p701_mixer, alc662_capture_mixer }, 12141 .init_verbs = { alc662_init_verbs, 12142 alc662_eeepc_sue_init_verbs }, 12143 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 12144 .dac_nids = alc662_dac_nids, 12145 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids), 12146 .adc_nids = alc662_adc_nids, 12147 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 12148 .channel_mode = alc662_3ST_2ch_modes, 12149 .input_mux = &alc662_eeepc_capture_source, 12150 .unsol_event = alc662_eeepc_unsol_event, 12151 .init_hook = alc662_eeepc_inithook, 12152 }, 12153 12154 }; 12155 12156 12157 /* 12158 * BIOS auto configuration 12159 */ 12160 12161 /* add playback controls from the parsed DAC table */ 12162 static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec, 12163 const struct auto_pin_cfg *cfg) 12164 { 12165 char name[32]; 12166 static const char *chname[4] = { 12167 "Front", "Surround", NULL /*CLFE*/, "Side" 12168 }; 12169 hda_nid_t nid; 12170 int i, err; 12171 12172 for (i = 0; i < cfg->line_outs; i++) { 12173 if (!spec->multiout.dac_nids[i]) 12174 continue; 12175 nid = alc880_idx_to_dac(i); 12176 if (i == 2) { 12177 /* Center/LFE */ 12178 err = add_control(spec, ALC_CTL_WIDGET_VOL, 12179 "Center Playback Volume", 12180 HDA_COMPOSE_AMP_VAL(nid, 1, 0, 12181 HDA_OUTPUT)); 12182 if (err < 0) 12183 return err; 12184 err = add_control(spec, ALC_CTL_WIDGET_VOL, 12185 "LFE Playback Volume", 12186 HDA_COMPOSE_AMP_VAL(nid, 2, 0, 12187 HDA_OUTPUT)); 12188 if (err < 0) 12189 return err; 12190 err = add_control(spec, ALC_CTL_BIND_MUTE, 12191 "Center Playback Switch", 12192 HDA_COMPOSE_AMP_VAL(nid, 1, 2, 12193 HDA_INPUT)); 12194 if (err < 0) 12195 return err; 12196 err = add_control(spec, ALC_CTL_BIND_MUTE, 12197 "LFE Playback Switch", 12198 HDA_COMPOSE_AMP_VAL(nid, 2, 2, 12199 HDA_INPUT)); 12200 if (err < 0) 12201 return err; 12202 } else { 12203 sprintf(name, "%s Playback Volume", chname[i]); 12204 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, 12205 HDA_COMPOSE_AMP_VAL(nid, 3, 0, 12206 HDA_OUTPUT)); 12207 if (err < 0) 12208 return err; 12209 sprintf(name, "%s Playback Switch", chname[i]); 12210 err = add_control(spec, ALC_CTL_BIND_MUTE, name, 12211 HDA_COMPOSE_AMP_VAL(nid, 3, 2, 12212 HDA_INPUT)); 12213 if (err < 0) 12214 return err; 12215 } 12216 } 12217 return 0; 12218 } 12219 12220 /* add playback controls for speaker and HP outputs */ 12221 static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin, 12222 const char *pfx) 12223 { 12224 hda_nid_t nid; 12225 int err; 12226 char name[32]; 12227 12228 if (!pin) 12229 return 0; 12230 12231 if (alc880_is_fixed_pin(pin)) { 12232 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); 12233 /* printk("DAC nid=%x\n",nid); */ 12234 /* specify the DAC as the extra output */ 12235 if (!spec->multiout.hp_nid) 12236 spec->multiout.hp_nid = nid; 12237 else 12238 spec->multiout.extra_out_nid[0] = nid; 12239 /* control HP volume/switch on the output mixer amp */ 12240 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); 12241 sprintf(name, "%s Playback Volume", pfx); 12242 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, 12243 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); 12244 if (err < 0) 12245 return err; 12246 sprintf(name, "%s Playback Switch", pfx); 12247 err = add_control(spec, ALC_CTL_BIND_MUTE, name, 12248 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT)); 12249 if (err < 0) 12250 return err; 12251 } else if (alc880_is_multi_pin(pin)) { 12252 /* set manual connection */ 12253 /* we have only a switch on HP-out PIN */ 12254 sprintf(name, "%s Playback Switch", pfx); 12255 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, 12256 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); 12257 if (err < 0) 12258 return err; 12259 } 12260 return 0; 12261 } 12262 12263 /* create playback/capture controls for input pins */ 12264 static int alc662_auto_create_analog_input_ctls(struct alc_spec *spec, 12265 const struct auto_pin_cfg *cfg) 12266 { 12267 struct hda_input_mux *imux = &spec->private_imux; 12268 int i, err, idx; 12269 12270 for (i = 0; i < AUTO_PIN_LAST; i++) { 12271 if (alc880_is_input_pin(cfg->input_pins[i])) { 12272 idx = alc880_input_pin_idx(cfg->input_pins[i]); 12273 err = new_analog_input(spec, cfg->input_pins[i], 12274 auto_pin_cfg_labels[i], 12275 idx, 0x0b); 12276 if (err < 0) 12277 return err; 12278 imux->items[imux->num_items].label = 12279 auto_pin_cfg_labels[i]; 12280 imux->items[imux->num_items].index = 12281 alc880_input_pin_idx(cfg->input_pins[i]); 12282 imux->num_items++; 12283 } 12284 } 12285 return 0; 12286 } 12287 12288 static void alc662_auto_set_output_and_unmute(struct hda_codec *codec, 12289 hda_nid_t nid, int pin_type, 12290 int dac_idx) 12291 { 12292 /* set as output */ 12293 snd_hda_codec_write(codec, nid, 0, 12294 AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type); 12295 snd_hda_codec_write(codec, nid, 0, 12296 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); 12297 /* need the manual connection? */ 12298 if (alc880_is_multi_pin(nid)) { 12299 struct alc_spec *spec = codec->spec; 12300 int idx = alc880_multi_pin_idx(nid); 12301 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0, 12302 AC_VERB_SET_CONNECT_SEL, 12303 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx])); 12304 } 12305 } 12306 12307 static void alc662_auto_init_multi_out(struct hda_codec *codec) 12308 { 12309 struct alc_spec *spec = codec->spec; 12310 int i; 12311 12312 for (i = 0; i <= HDA_SIDE; i++) { 12313 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 12314 int pin_type = get_pin_type(spec->autocfg.line_out_type); 12315 if (nid) 12316 alc662_auto_set_output_and_unmute(codec, nid, pin_type, 12317 i); 12318 } 12319 } 12320 12321 static void alc662_auto_init_hp_out(struct hda_codec *codec) 12322 { 12323 struct alc_spec *spec = codec->spec; 12324 hda_nid_t pin; 12325 12326 pin = spec->autocfg.hp_pins[0]; 12327 if (pin) /* connect to front */ 12328 /* use dac 0 */ 12329 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); 12330 } 12331 12332 #define alc662_is_input_pin(nid) alc880_is_input_pin(nid) 12333 #define ALC662_PIN_CD_NID ALC880_PIN_CD_NID 12334 12335 static void alc662_auto_init_analog_input(struct hda_codec *codec) 12336 { 12337 struct alc_spec *spec = codec->spec; 12338 int i; 12339 12340 for (i = 0; i < AUTO_PIN_LAST; i++) { 12341 hda_nid_t nid = spec->autocfg.input_pins[i]; 12342 if (alc662_is_input_pin(nid)) { 12343 snd_hda_codec_write(codec, nid, 0, 12344 AC_VERB_SET_PIN_WIDGET_CONTROL, 12345 (i <= AUTO_PIN_FRONT_MIC ? 12346 PIN_VREF80 : PIN_IN)); 12347 if (nid != ALC662_PIN_CD_NID) 12348 snd_hda_codec_write(codec, nid, 0, 12349 AC_VERB_SET_AMP_GAIN_MUTE, 12350 AMP_OUT_MUTE); 12351 } 12352 } 12353 } 12354 12355 static int alc662_parse_auto_config(struct hda_codec *codec) 12356 { 12357 struct alc_spec *spec = codec->spec; 12358 int err; 12359 static hda_nid_t alc662_ignore[] = { 0x1d, 0 }; 12360 12361 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 12362 alc662_ignore); 12363 if (err < 0) 12364 return err; 12365 if (!spec->autocfg.line_outs) 12366 return 0; /* can't find valid BIOS pin config */ 12367 12368 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); 12369 if (err < 0) 12370 return err; 12371 err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg); 12372 if (err < 0) 12373 return err; 12374 err = alc662_auto_create_extra_out(spec, 12375 spec->autocfg.speaker_pins[0], 12376 "Speaker"); 12377 if (err < 0) 12378 return err; 12379 err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0], 12380 "Headphone"); 12381 if (err < 0) 12382 return err; 12383 err = alc662_auto_create_analog_input_ctls(spec, &spec->autocfg); 12384 if (err < 0) 12385 return err; 12386 12387 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 12388 12389 if (spec->autocfg.dig_out_pin) 12390 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID; 12391 12392 if (spec->kctl_alloc) 12393 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 12394 12395 spec->num_mux_defs = 1; 12396 spec->input_mux = &spec->private_imux; 12397 12398 spec->init_verbs[spec->num_init_verbs++] = alc662_auto_init_verbs; 12399 spec->mixers[spec->num_mixers] = alc662_capture_mixer; 12400 spec->num_mixers++; 12401 return 1; 12402 } 12403 12404 /* additional initialization for auto-configuration model */ 12405 static void alc662_auto_init(struct hda_codec *codec) 12406 { 12407 alc662_auto_init_multi_out(codec); 12408 alc662_auto_init_hp_out(codec); 12409 alc662_auto_init_analog_input(codec); 12410 } 12411 12412 static int patch_alc662(struct hda_codec *codec) 12413 { 12414 struct alc_spec *spec; 12415 int err, board_config; 12416 12417 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 12418 if (!spec) 12419 return -ENOMEM; 12420 12421 codec->spec = spec; 12422 12423 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST, 12424 alc662_models, 12425 alc662_cfg_tbl); 12426 if (board_config < 0) { 12427 printk(KERN_INFO "hda_codec: Unknown model for ALC662, " 12428 "trying auto-probe from BIOS...\n"); 12429 board_config = ALC662_AUTO; 12430 } 12431 12432 if (board_config == ALC662_AUTO) { 12433 /* automatic parse from the BIOS config */ 12434 err = alc662_parse_auto_config(codec); 12435 if (err < 0) { 12436 alc_free(codec); 12437 return err; 12438 } else if (!err) { 12439 printk(KERN_INFO 12440 "hda_codec: Cannot set up configuration " 12441 "from BIOS. Using base mode...\n"); 12442 board_config = ALC662_3ST_2ch_DIG; 12443 } 12444 } 12445 12446 if (board_config != ALC662_AUTO) 12447 setup_preset(spec, &alc662_presets[board_config]); 12448 12449 spec->stream_name_analog = "ALC662 Analog"; 12450 spec->stream_analog_playback = &alc662_pcm_analog_playback; 12451 spec->stream_analog_capture = &alc662_pcm_analog_capture; 12452 12453 spec->stream_name_digital = "ALC662 Digital"; 12454 spec->stream_digital_playback = &alc662_pcm_digital_playback; 12455 spec->stream_digital_capture = &alc662_pcm_digital_capture; 12456 12457 if (!spec->adc_nids && spec->input_mux) { 12458 spec->adc_nids = alc662_adc_nids; 12459 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids); 12460 } 12461 12462 codec->patch_ops = alc_patch_ops; 12463 if (board_config == ALC662_AUTO) 12464 spec->init_hook = alc662_auto_init; 12465 #ifdef CONFIG_SND_HDA_POWER_SAVE 12466 if (!spec->loopback.amplist) 12467 spec->loopback.amplist = alc662_loopbacks; 12468 #endif 12469 12470 return 0; 12471 } 12472 12473 /* 12474 * patch entries 12475 */ 12476 struct hda_codec_preset snd_hda_preset_realtek[] = { 12477 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 }, 12478 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 }, 12479 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 }, 12480 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660", 12481 .patch = patch_alc861 }, 12482 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd }, 12483 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 }, 12484 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd }, 12485 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2", 12486 .patch = patch_alc883 }, 12487 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1", 12488 .patch = patch_alc662 }, 12489 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 }, 12490 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 }, 12491 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 }, 12492 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 }, 12493 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 }, 12494 {} /* terminator */ 12495 }; 12496