patch_realtek.c revision 61dc35de78d2b28e3c28fd7a352ef8c4ff63f42d
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 */ 41enum { 42 ALC880_3ST, 43 ALC880_3ST_DIG, 44 ALC880_5ST, 45 ALC880_5ST_DIG, 46 ALC880_W810, 47 ALC880_Z71V, 48 ALC880_6ST, 49 ALC880_6ST_DIG, 50 ALC880_F1734, 51 ALC880_ASUS, 52 ALC880_ASUS_DIG, 53 ALC880_ASUS_W1V, 54 ALC880_ASUS_DIG2, 55 ALC880_FUJITSU, 56 ALC880_UNIWILL_DIG, 57 ALC880_UNIWILL, 58 ALC880_UNIWILL_P53, 59 ALC880_CLEVO, 60 ALC880_TCL_S700, 61 ALC880_LG, 62 ALC880_LG_LW, 63#ifdef CONFIG_SND_DEBUG 64 ALC880_TEST, 65#endif 66 ALC880_AUTO, 67 ALC880_MODEL_LAST /* last tag */ 68}; 69 70/* ALC260 models */ 71enum { 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 */ 87enum { 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_HP_TC_T5735, 96 ALC262_BENQ_ED8, 97 ALC262_SONY_ASSAMD, 98 ALC262_BENQ_T31, 99 ALC262_ULTRA, 100 ALC262_AUTO, 101 ALC262_MODEL_LAST /* last tag */ 102}; 103 104/* ALC268 models */ 105enum { 106 ALC268_3ST, 107 ALC268_TOSHIBA, 108 ALC268_ACER, 109 ALC268_AUTO, 110 ALC268_MODEL_LAST /* last tag */ 111}; 112 113/* ALC861 models */ 114enum { 115 ALC861_3ST, 116 ALC660_3ST, 117 ALC861_3ST_DIG, 118 ALC861_6ST_DIG, 119 ALC861_UNIWILL_M31, 120 ALC861_TOSHIBA, 121 ALC861_ASUS, 122 ALC861_ASUS_LAPTOP, 123 ALC861_AUTO, 124 ALC861_MODEL_LAST, 125}; 126 127/* ALC861-VD models */ 128enum { 129 ALC660VD_3ST, 130 ALC660VD_3ST_DIG, 131 ALC861VD_3ST, 132 ALC861VD_3ST_DIG, 133 ALC861VD_6ST_DIG, 134 ALC861VD_LENOVO, 135 ALC861VD_DALLAS, 136 ALC861VD_HP, 137 ALC861VD_AUTO, 138 ALC861VD_MODEL_LAST, 139}; 140 141/* ALC662 models */ 142enum { 143 ALC662_3ST_2ch_DIG, 144 ALC662_3ST_6ch_DIG, 145 ALC662_3ST_6ch, 146 ALC662_5ST_DIG, 147 ALC662_LENOVO_101E, 148 ALC662_ASUS_EEEPC_P701, 149 ALC662_AUTO, 150 ALC662_MODEL_LAST, 151}; 152 153/* ALC882 models */ 154enum { 155 ALC882_3ST_DIG, 156 ALC882_6ST_DIG, 157 ALC882_ARIMA, 158 ALC882_W2JC, 159 ALC882_TARGA, 160 ALC882_ASUS_A7J, 161 ALC882_ASUS_A7M, 162 ALC885_MACPRO, 163 ALC885_MBP3, 164 ALC885_IMAC24, 165 ALC882_AUTO, 166 ALC882_MODEL_LAST, 167}; 168 169/* ALC883 models */ 170enum { 171 ALC883_3ST_2ch_DIG, 172 ALC883_3ST_6ch_DIG, 173 ALC883_3ST_6ch, 174 ALC883_6ST_DIG, 175 ALC883_TARGA_DIG, 176 ALC883_TARGA_2ch_DIG, 177 ALC883_ACER, 178 ALC883_ACER_ASPIRE, 179 ALC883_MEDION, 180 ALC883_MEDION_MD2, 181 ALC883_LAPTOP_EAPD, 182 ALC883_LENOVO_101E_2ch, 183 ALC883_LENOVO_NB0763, 184 ALC888_LENOVO_MS7195_DIG, 185 ALC883_HAIER_W66, 186 ALC888_6ST_HP, 187 ALC888_3ST_HP, 188 ALC883_AUTO, 189 ALC883_MODEL_LAST, 190}; 191 192/* for GPIO Poll */ 193#define GPIO_MASK 0x03 194 195struct alc_spec { 196 /* codec parameterization */ 197 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */ 198 unsigned int num_mixers; 199 200 const struct hda_verb *init_verbs[5]; /* initialization verbs 201 * don't forget NULL 202 * termination! 203 */ 204 unsigned int num_init_verbs; 205 206 char *stream_name_analog; /* analog PCM stream */ 207 struct hda_pcm_stream *stream_analog_playback; 208 struct hda_pcm_stream *stream_analog_capture; 209 210 char *stream_name_digital; /* digital PCM stream */ 211 struct hda_pcm_stream *stream_digital_playback; 212 struct hda_pcm_stream *stream_digital_capture; 213 214 /* playback */ 215 struct hda_multi_out multiout; /* playback set-up 216 * max_channels, dacs must be set 217 * dig_out_nid and hp_nid are optional 218 */ 219 220 /* capture */ 221 unsigned int num_adc_nids; 222 hda_nid_t *adc_nids; 223 hda_nid_t dig_in_nid; /* digital-in NID; optional */ 224 225 /* capture source */ 226 unsigned int num_mux_defs; 227 const struct hda_input_mux *input_mux; 228 unsigned int cur_mux[3]; 229 230 /* channel model */ 231 const struct hda_channel_mode *channel_mode; 232 int num_channel_mode; 233 int need_dac_fix; 234 235 /* PCM information */ 236 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */ 237 238 /* dynamic controls, init_verbs and input_mux */ 239 struct auto_pin_cfg autocfg; 240 unsigned int num_kctl_alloc, num_kctl_used; 241 struct snd_kcontrol_new *kctl_alloc; 242 struct hda_input_mux private_imux; 243 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; 244 245 /* hooks */ 246 void (*init_hook)(struct hda_codec *codec); 247 void (*unsol_event)(struct hda_codec *codec, unsigned int res); 248 249 /* for pin sensing */ 250 unsigned int sense_updated: 1; 251 unsigned int jack_present: 1; 252 253#ifdef CONFIG_SND_HDA_POWER_SAVE 254 struct hda_loopback_check loopback; 255#endif 256}; 257 258/* 259 * configuration template - to be copied to the spec instance 260 */ 261struct alc_config_preset { 262 struct snd_kcontrol_new *mixers[5]; /* should be identical size 263 * with spec 264 */ 265 const struct hda_verb *init_verbs[5]; 266 unsigned int num_dacs; 267 hda_nid_t *dac_nids; 268 hda_nid_t dig_out_nid; /* optional */ 269 hda_nid_t hp_nid; /* optional */ 270 unsigned int num_adc_nids; 271 hda_nid_t *adc_nids; 272 hda_nid_t dig_in_nid; 273 unsigned int num_channel_mode; 274 const struct hda_channel_mode *channel_mode; 275 int need_dac_fix; 276 unsigned int num_mux_defs; 277 const struct hda_input_mux *input_mux; 278 void (*unsol_event)(struct hda_codec *, unsigned int); 279 void (*init_hook)(struct hda_codec *); 280#ifdef CONFIG_SND_HDA_POWER_SAVE 281 struct hda_amp_list *loopbacks; 282#endif 283}; 284 285 286/* 287 * input MUX handling 288 */ 289static int alc_mux_enum_info(struct snd_kcontrol *kcontrol, 290 struct snd_ctl_elem_info *uinfo) 291{ 292 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 293 struct alc_spec *spec = codec->spec; 294 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id); 295 if (mux_idx >= spec->num_mux_defs) 296 mux_idx = 0; 297 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo); 298} 299 300static int alc_mux_enum_get(struct snd_kcontrol *kcontrol, 301 struct snd_ctl_elem_value *ucontrol) 302{ 303 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 304 struct alc_spec *spec = codec->spec; 305 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 306 307 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx]; 308 return 0; 309} 310 311static int alc_mux_enum_put(struct snd_kcontrol *kcontrol, 312 struct snd_ctl_elem_value *ucontrol) 313{ 314 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 315 struct alc_spec *spec = codec->spec; 316 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 317 unsigned int mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx; 318 return snd_hda_input_mux_put(codec, &spec->input_mux[mux_idx], ucontrol, 319 spec->adc_nids[adc_idx], 320 &spec->cur_mux[adc_idx]); 321} 322 323 324/* 325 * channel mode setting 326 */ 327static int alc_ch_mode_info(struct snd_kcontrol *kcontrol, 328 struct snd_ctl_elem_info *uinfo) 329{ 330 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 331 struct alc_spec *spec = codec->spec; 332 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode, 333 spec->num_channel_mode); 334} 335 336static int alc_ch_mode_get(struct snd_kcontrol *kcontrol, 337 struct snd_ctl_elem_value *ucontrol) 338{ 339 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 340 struct alc_spec *spec = codec->spec; 341 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode, 342 spec->num_channel_mode, 343 spec->multiout.max_channels); 344} 345 346static int alc_ch_mode_put(struct snd_kcontrol *kcontrol, 347 struct snd_ctl_elem_value *ucontrol) 348{ 349 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 350 struct alc_spec *spec = codec->spec; 351 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode, 352 spec->num_channel_mode, 353 &spec->multiout.max_channels); 354 if (err >= 0 && spec->need_dac_fix) 355 spec->multiout.num_dacs = spec->multiout.max_channels / 2; 356 return err; 357} 358 359/* 360 * Control the mode of pin widget settings via the mixer. "pc" is used 361 * instead of "%" to avoid consequences of accidently treating the % as 362 * being part of a format specifier. Maximum allowed length of a value is 363 * 63 characters plus NULL terminator. 364 * 365 * Note: some retasking pin complexes seem to ignore requests for input 366 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these 367 * are requested. Therefore order this list so that this behaviour will not 368 * cause problems when mixer clients move through the enum sequentially. 369 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of 370 * March 2006. 371 */ 372static char *alc_pin_mode_names[] = { 373 "Mic 50pc bias", "Mic 80pc bias", 374 "Line in", "Line out", "Headphone out", 375}; 376static unsigned char alc_pin_mode_values[] = { 377 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP, 378}; 379/* The control can present all 5 options, or it can limit the options based 380 * in the pin being assumed to be exclusively an input or an output pin. In 381 * addition, "input" pins may or may not process the mic bias option 382 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to 383 * accept requests for bias as of chip versions up to March 2006) and/or 384 * wiring in the computer. 385 */ 386#define ALC_PIN_DIR_IN 0x00 387#define ALC_PIN_DIR_OUT 0x01 388#define ALC_PIN_DIR_INOUT 0x02 389#define ALC_PIN_DIR_IN_NOMICBIAS 0x03 390#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04 391 392/* Info about the pin modes supported by the different pin direction modes. 393 * For each direction the minimum and maximum values are given. 394 */ 395static signed char alc_pin_mode_dir_info[5][2] = { 396 { 0, 2 }, /* ALC_PIN_DIR_IN */ 397 { 3, 4 }, /* ALC_PIN_DIR_OUT */ 398 { 0, 4 }, /* ALC_PIN_DIR_INOUT */ 399 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */ 400 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */ 401}; 402#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0]) 403#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1]) 404#define alc_pin_mode_n_items(_dir) \ 405 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1) 406 407static int alc_pin_mode_info(struct snd_kcontrol *kcontrol, 408 struct snd_ctl_elem_info *uinfo) 409{ 410 unsigned int item_num = uinfo->value.enumerated.item; 411 unsigned char dir = (kcontrol->private_value >> 16) & 0xff; 412 413 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 414 uinfo->count = 1; 415 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir); 416 417 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir)) 418 item_num = alc_pin_mode_min(dir); 419 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]); 420 return 0; 421} 422 423static int alc_pin_mode_get(struct snd_kcontrol *kcontrol, 424 struct snd_ctl_elem_value *ucontrol) 425{ 426 unsigned int i; 427 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 428 hda_nid_t nid = kcontrol->private_value & 0xffff; 429 unsigned char dir = (kcontrol->private_value >> 16) & 0xff; 430 long *valp = ucontrol->value.integer.value; 431 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0, 432 AC_VERB_GET_PIN_WIDGET_CONTROL, 433 0x00); 434 435 /* Find enumerated value for current pinctl setting */ 436 i = alc_pin_mode_min(dir); 437 while (alc_pin_mode_values[i] != pinctl && i <= alc_pin_mode_max(dir)) 438 i++; 439 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir); 440 return 0; 441} 442 443static int alc_pin_mode_put(struct snd_kcontrol *kcontrol, 444 struct snd_ctl_elem_value *ucontrol) 445{ 446 signed int change; 447 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 448 hda_nid_t nid = kcontrol->private_value & 0xffff; 449 unsigned char dir = (kcontrol->private_value >> 16) & 0xff; 450 long val = *ucontrol->value.integer.value; 451 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0, 452 AC_VERB_GET_PIN_WIDGET_CONTROL, 453 0x00); 454 455 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir)) 456 val = alc_pin_mode_min(dir); 457 458 change = pinctl != alc_pin_mode_values[val]; 459 if (change) { 460 /* Set pin mode to that requested */ 461 snd_hda_codec_write_cache(codec, nid, 0, 462 AC_VERB_SET_PIN_WIDGET_CONTROL, 463 alc_pin_mode_values[val]); 464 465 /* Also enable the retasking pin's input/output as required 466 * for the requested pin mode. Enum values of 2 or less are 467 * input modes. 468 * 469 * Dynamically switching the input/output buffers probably 470 * reduces noise slightly (particularly on input) so we'll 471 * do it. However, having both input and output buffers 472 * enabled simultaneously doesn't seem to be problematic if 473 * this turns out to be necessary in the future. 474 */ 475 if (val <= 2) { 476 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, 477 HDA_AMP_MUTE, HDA_AMP_MUTE); 478 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0, 479 HDA_AMP_MUTE, 0); 480 } else { 481 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0, 482 HDA_AMP_MUTE, HDA_AMP_MUTE); 483 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, 484 HDA_AMP_MUTE, 0); 485 } 486 } 487 return change; 488} 489 490#define ALC_PIN_MODE(xname, nid, dir) \ 491 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 492 .info = alc_pin_mode_info, \ 493 .get = alc_pin_mode_get, \ 494 .put = alc_pin_mode_put, \ 495 .private_value = nid | (dir<<16) } 496 497/* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged 498 * together using a mask with more than one bit set. This control is 499 * currently used only by the ALC260 test model. At this stage they are not 500 * needed for any "production" models. 501 */ 502#ifdef CONFIG_SND_DEBUG 503#define alc_gpio_data_info snd_ctl_boolean_mono_info 504 505static int alc_gpio_data_get(struct snd_kcontrol *kcontrol, 506 struct snd_ctl_elem_value *ucontrol) 507{ 508 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 509 hda_nid_t nid = kcontrol->private_value & 0xffff; 510 unsigned char mask = (kcontrol->private_value >> 16) & 0xff; 511 long *valp = ucontrol->value.integer.value; 512 unsigned int val = snd_hda_codec_read(codec, nid, 0, 513 AC_VERB_GET_GPIO_DATA, 0x00); 514 515 *valp = (val & mask) != 0; 516 return 0; 517} 518static int alc_gpio_data_put(struct snd_kcontrol *kcontrol, 519 struct snd_ctl_elem_value *ucontrol) 520{ 521 signed int change; 522 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 523 hda_nid_t nid = kcontrol->private_value & 0xffff; 524 unsigned char mask = (kcontrol->private_value >> 16) & 0xff; 525 long val = *ucontrol->value.integer.value; 526 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0, 527 AC_VERB_GET_GPIO_DATA, 528 0x00); 529 530 /* Set/unset the masked GPIO bit(s) as needed */ 531 change = (val == 0 ? 0 : mask) != (gpio_data & mask); 532 if (val == 0) 533 gpio_data &= ~mask; 534 else 535 gpio_data |= mask; 536 snd_hda_codec_write_cache(codec, nid, 0, 537 AC_VERB_SET_GPIO_DATA, gpio_data); 538 539 return change; 540} 541#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \ 542 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 543 .info = alc_gpio_data_info, \ 544 .get = alc_gpio_data_get, \ 545 .put = alc_gpio_data_put, \ 546 .private_value = nid | (mask<<16) } 547#endif /* CONFIG_SND_DEBUG */ 548 549/* A switch control to allow the enabling of the digital IO pins on the 550 * ALC260. This is incredibly simplistic; the intention of this control is 551 * to provide something in the test model allowing digital outputs to be 552 * identified if present. If models are found which can utilise these 553 * outputs a more complete mixer control can be devised for those models if 554 * necessary. 555 */ 556#ifdef CONFIG_SND_DEBUG 557#define alc_spdif_ctrl_info snd_ctl_boolean_mono_info 558 559static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol, 560 struct snd_ctl_elem_value *ucontrol) 561{ 562 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 563 hda_nid_t nid = kcontrol->private_value & 0xffff; 564 unsigned char mask = (kcontrol->private_value >> 16) & 0xff; 565 long *valp = ucontrol->value.integer.value; 566 unsigned int val = snd_hda_codec_read(codec, nid, 0, 567 AC_VERB_GET_DIGI_CONVERT, 0x00); 568 569 *valp = (val & mask) != 0; 570 return 0; 571} 572static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol, 573 struct snd_ctl_elem_value *ucontrol) 574{ 575 signed int change; 576 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 577 hda_nid_t nid = kcontrol->private_value & 0xffff; 578 unsigned char mask = (kcontrol->private_value >> 16) & 0xff; 579 long val = *ucontrol->value.integer.value; 580 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0, 581 AC_VERB_GET_DIGI_CONVERT, 582 0x00); 583 584 /* Set/unset the masked control bit(s) as needed */ 585 change = (val == 0 ? 0 : mask) != (ctrl_data & mask); 586 if (val==0) 587 ctrl_data &= ~mask; 588 else 589 ctrl_data |= mask; 590 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, 591 ctrl_data); 592 593 return change; 594} 595#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \ 596 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 597 .info = alc_spdif_ctrl_info, \ 598 .get = alc_spdif_ctrl_get, \ 599 .put = alc_spdif_ctrl_put, \ 600 .private_value = nid | (mask<<16) } 601#endif /* CONFIG_SND_DEBUG */ 602 603/* 604 * set up from the preset table 605 */ 606static void setup_preset(struct alc_spec *spec, 607 const struct alc_config_preset *preset) 608{ 609 int i; 610 611 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++) 612 spec->mixers[spec->num_mixers++] = preset->mixers[i]; 613 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i]; 614 i++) 615 spec->init_verbs[spec->num_init_verbs++] = 616 preset->init_verbs[i]; 617 618 spec->channel_mode = preset->channel_mode; 619 spec->num_channel_mode = preset->num_channel_mode; 620 spec->need_dac_fix = preset->need_dac_fix; 621 622 spec->multiout.max_channels = spec->channel_mode[0].channels; 623 624 spec->multiout.num_dacs = preset->num_dacs; 625 spec->multiout.dac_nids = preset->dac_nids; 626 spec->multiout.dig_out_nid = preset->dig_out_nid; 627 spec->multiout.hp_nid = preset->hp_nid; 628 629 spec->num_mux_defs = preset->num_mux_defs; 630 if (!spec->num_mux_defs) 631 spec->num_mux_defs = 1; 632 spec->input_mux = preset->input_mux; 633 634 spec->num_adc_nids = preset->num_adc_nids; 635 spec->adc_nids = preset->adc_nids; 636 spec->dig_in_nid = preset->dig_in_nid; 637 638 spec->unsol_event = preset->unsol_event; 639 spec->init_hook = preset->init_hook; 640#ifdef CONFIG_SND_HDA_POWER_SAVE 641 spec->loopback.amplist = preset->loopbacks; 642#endif 643} 644 645/* Enable GPIO mask and set output */ 646static struct hda_verb alc_gpio1_init_verbs[] = { 647 {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, 648 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, 649 {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, 650 { } 651}; 652 653static struct hda_verb alc_gpio2_init_verbs[] = { 654 {0x01, AC_VERB_SET_GPIO_MASK, 0x02}, 655 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02}, 656 {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, 657 { } 658}; 659 660static struct hda_verb alc_gpio3_init_verbs[] = { 661 {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, 662 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03}, 663 {0x01, AC_VERB_SET_GPIO_DATA, 0x03}, 664 { } 665}; 666 667static void alc_sku_automute(struct hda_codec *codec) 668{ 669 struct alc_spec *spec = codec->spec; 670 unsigned int mute; 671 unsigned int present; 672 unsigned int hp_nid = spec->autocfg.hp_pins[0]; 673 unsigned int sp_nid = spec->autocfg.speaker_pins[0]; 674 675 /* need to execute and sync at first */ 676 snd_hda_codec_read(codec, hp_nid, 0, AC_VERB_SET_PIN_SENSE, 0); 677 present = snd_hda_codec_read(codec, hp_nid, 0, 678 AC_VERB_GET_PIN_SENSE, 0); 679 spec->jack_present = (present & 0x80000000) != 0; 680 if (spec->jack_present) { 681 /* mute internal speaker */ 682 snd_hda_codec_amp_stereo(codec, sp_nid, HDA_OUTPUT, 0, 683 HDA_AMP_MUTE, HDA_AMP_MUTE); 684 } else { 685 /* unmute internal speaker if necessary */ 686 mute = snd_hda_codec_amp_read(codec, hp_nid, 0, HDA_OUTPUT, 0); 687 snd_hda_codec_amp_stereo(codec, sp_nid, HDA_OUTPUT, 0, 688 HDA_AMP_MUTE, mute); 689 } 690} 691 692/* unsolicited event for HP jack sensing */ 693static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res) 694{ 695 if (codec->vendor_id == 0x10ec0880) 696 res >>= 28; 697 else 698 res >>= 26; 699 if (res != ALC880_HP_EVENT) 700 return; 701 702 alc_sku_automute(codec); 703} 704 705/* 32-bit subsystem ID for BIOS loading in HD Audio codec. 706 * 31 ~ 16 : Manufacture ID 707 * 15 ~ 8 : SKU ID 708 * 7 ~ 0 : Assembly ID 709 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36 710 */ 711static void alc_subsystem_id(struct hda_codec *codec, 712 unsigned int porta, unsigned int porte, 713 unsigned int portd) 714{ 715 unsigned int ass, tmp, i; 716 unsigned nid; 717 struct alc_spec *spec = codec->spec; 718 719 ass = codec->subsystem_id & 0xffff; 720 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1)) 721 goto do_sku; 722 723 /* 724 * 31~30 : port conetcivity 725 * 29~21 : reserve 726 * 20 : PCBEEP input 727 * 19~16 : Check sum (15:1) 728 * 15~1 : Custom 729 * 0 : override 730 */ 731 nid = 0x1d; 732 if (codec->vendor_id == 0x10ec0260) 733 nid = 0x17; 734 ass = snd_hda_codec_read(codec, nid, 0, 735 AC_VERB_GET_CONFIG_DEFAULT, 0); 736 if (!(ass & 1) && !(ass & 0x100000)) 737 return; 738 if ((ass >> 30) != 1) /* no physical connection */ 739 return; 740 741 /* check sum */ 742 tmp = 0; 743 for (i = 1; i < 16; i++) { 744 if ((ass >> i) && 1) 745 tmp++; 746 } 747 if (((ass >> 16) & 0xf) != tmp) 748 return; 749do_sku: 750 /* 751 * 0 : override 752 * 1 : Swap Jack 753 * 2 : 0 --> Desktop, 1 --> Laptop 754 * 3~5 : External Amplifier control 755 * 7~6 : Reserved 756 */ 757 tmp = (ass & 0x38) >> 3; /* external Amp control */ 758 switch (tmp) { 759 case 1: 760 snd_hda_sequence_write(codec, alc_gpio1_init_verbs); 761 break; 762 case 3: 763 snd_hda_sequence_write(codec, alc_gpio2_init_verbs); 764 break; 765 case 7: 766 snd_hda_sequence_write(codec, alc_gpio3_init_verbs); 767 break; 768 case 5: /* set EAPD output high */ 769 switch (codec->vendor_id) { 770 case 0x10ec0260: 771 snd_hda_codec_write(codec, 0x0f, 0, 772 AC_VERB_SET_EAPD_BTLENABLE, 2); 773 snd_hda_codec_write(codec, 0x10, 0, 774 AC_VERB_SET_EAPD_BTLENABLE, 2); 775 break; 776 case 0x10ec0262: 777 case 0x10ec0267: 778 case 0x10ec0268: 779 case 0x10ec0269: 780 case 0x10ec0862: 781 case 0x10ec0662: 782 snd_hda_codec_write(codec, 0x14, 0, 783 AC_VERB_SET_EAPD_BTLENABLE, 2); 784 snd_hda_codec_write(codec, 0x15, 0, 785 AC_VERB_SET_EAPD_BTLENABLE, 2); 786 break; 787 } 788 switch (codec->vendor_id) { 789 case 0x10ec0260: 790 snd_hda_codec_write(codec, 0x1a, 0, 791 AC_VERB_SET_COEF_INDEX, 7); 792 tmp = snd_hda_codec_read(codec, 0x1a, 0, 793 AC_VERB_GET_PROC_COEF, 0); 794 snd_hda_codec_write(codec, 0x1a, 0, 795 AC_VERB_SET_COEF_INDEX, 7); 796 snd_hda_codec_write(codec, 0x1a, 0, 797 AC_VERB_SET_PROC_COEF, 798 tmp | 0x2010); 799 break; 800 case 0x10ec0262: 801 case 0x10ec0880: 802 case 0x10ec0882: 803 case 0x10ec0883: 804 case 0x10ec0885: 805 case 0x10ec0888: 806 snd_hda_codec_write(codec, 0x20, 0, 807 AC_VERB_SET_COEF_INDEX, 7); 808 tmp = snd_hda_codec_read(codec, 0x20, 0, 809 AC_VERB_GET_PROC_COEF, 0); 810 snd_hda_codec_write(codec, 0x20, 0, 811 AC_VERB_SET_COEF_INDEX, 7); 812 snd_hda_codec_write(codec, 0x20, 0, 813 AC_VERB_SET_PROC_COEF, 814 tmp | 0x2010); 815 break; 816 case 0x10ec0267: 817 case 0x10ec0268: 818 snd_hda_codec_write(codec, 0x20, 0, 819 AC_VERB_SET_COEF_INDEX, 7); 820 tmp = snd_hda_codec_read(codec, 0x20, 0, 821 AC_VERB_GET_PROC_COEF, 0); 822 snd_hda_codec_write(codec, 0x20, 0, 823 AC_VERB_SET_COEF_INDEX, 7); 824 snd_hda_codec_write(codec, 0x20, 0, 825 AC_VERB_SET_PROC_COEF, 826 tmp | 0x3000); 827 break; 828 } 829 default: 830 break; 831 } 832 833 /* is laptop and enable the function "Mute internal speaker 834 * when the external headphone out jack is plugged" 835 */ 836 if (!(ass & 0x4) || !(ass & 0x8000)) 837 return; 838 /* 839 * 10~8 : Jack location 840 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered 841 * 14~13: Resvered 842 * 15 : 1 --> enable the function "Mute internal speaker 843 * when the external headphone out jack is plugged" 844 */ 845 if (!spec->autocfg.speaker_pins[0]) { 846 if (spec->multiout.dac_nids[0]) 847 spec->autocfg.speaker_pins[0] = 848 spec->multiout.dac_nids[0]; 849 else 850 return; 851 } 852 853 if (!spec->autocfg.hp_pins[0]) { 854 tmp = (ass >> 11) & 0x3; /* HP to chassis */ 855 if (tmp == 0) 856 spec->autocfg.hp_pins[0] = porta; 857 else if (tmp == 1) 858 spec->autocfg.hp_pins[0] = porte; 859 else if (tmp == 2) 860 spec->autocfg.hp_pins[0] = portd; 861 else 862 return; 863 } 864 865 snd_hda_codec_write(codec, spec->autocfg.hp_pins[0], 0, 866 AC_VERB_SET_UNSOLICITED_ENABLE, 867 AC_USRSP_EN | ALC880_HP_EVENT); 868 spec->unsol_event = alc_sku_unsol_event; 869 spec->init_hook = alc_sku_automute; 870} 871 872/* 873 * Fix-up pin default configurations 874 */ 875 876struct alc_pincfg { 877 hda_nid_t nid; 878 u32 val; 879}; 880 881static void alc_fix_pincfg(struct hda_codec *codec, 882 const struct snd_pci_quirk *quirk, 883 const struct alc_pincfg **pinfix) 884{ 885 const struct alc_pincfg *cfg; 886 887 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk); 888 if (!quirk) 889 return; 890 891 cfg = pinfix[quirk->value]; 892 for (; cfg->nid; cfg++) { 893 int i; 894 u32 val = cfg->val; 895 for (i = 0; i < 4; i++) { 896 snd_hda_codec_write(codec, cfg->nid, 0, 897 AC_VERB_SET_CONFIG_DEFAULT_BYTES_0 + i, 898 val & 0xff); 899 val >>= 8; 900 } 901 } 902} 903 904/* 905 * ALC880 3-stack model 906 * 907 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e) 908 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18, 909 * F-Mic = 0x1b, HP = 0x19 910 */ 911 912static hda_nid_t alc880_dac_nids[4] = { 913 /* front, rear, clfe, rear_surr */ 914 0x02, 0x05, 0x04, 0x03 915}; 916 917static hda_nid_t alc880_adc_nids[3] = { 918 /* ADC0-2 */ 919 0x07, 0x08, 0x09, 920}; 921 922/* The datasheet says the node 0x07 is connected from inputs, 923 * but it shows zero connection in the real implementation on some devices. 924 * Note: this is a 915GAV bug, fixed on 915GLV 925 */ 926static hda_nid_t alc880_adc_nids_alt[2] = { 927 /* ADC1-2 */ 928 0x08, 0x09, 929}; 930 931#define ALC880_DIGOUT_NID 0x06 932#define ALC880_DIGIN_NID 0x0a 933 934static struct hda_input_mux alc880_capture_source = { 935 .num_items = 4, 936 .items = { 937 { "Mic", 0x0 }, 938 { "Front Mic", 0x3 }, 939 { "Line", 0x2 }, 940 { "CD", 0x4 }, 941 }, 942}; 943 944/* channel source setting (2/6 channel selection for 3-stack) */ 945/* 2ch mode */ 946static struct hda_verb alc880_threestack_ch2_init[] = { 947 /* set line-in to input, mute it */ 948 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 949 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 950 /* set mic-in to input vref 80%, mute it */ 951 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 952 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 953 { } /* end */ 954}; 955 956/* 6ch mode */ 957static struct hda_verb alc880_threestack_ch6_init[] = { 958 /* set line-in to output, unmute it */ 959 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 960 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 961 /* set mic-in to output, unmute it */ 962 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 963 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 964 { } /* end */ 965}; 966 967static struct hda_channel_mode alc880_threestack_modes[2] = { 968 { 2, alc880_threestack_ch2_init }, 969 { 6, alc880_threestack_ch6_init }, 970}; 971 972static struct snd_kcontrol_new alc880_three_stack_mixer[] = { 973 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 974 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 975 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 976 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT), 977 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 978 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 979 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 980 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 981 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 982 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 983 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 984 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 985 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 986 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 987 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT), 988 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT), 989 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 990 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 991 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT), 992 { 993 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 994 .name = "Channel Mode", 995 .info = alc_ch_mode_info, 996 .get = alc_ch_mode_get, 997 .put = alc_ch_mode_put, 998 }, 999 { } /* end */ 1000}; 1001 1002/* capture mixer elements */ 1003static struct snd_kcontrol_new alc880_capture_mixer[] = { 1004 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT), 1005 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT), 1006 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT), 1007 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT), 1008 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT), 1009 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT), 1010 { 1011 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1012 /* The multiple "Capture Source" controls confuse alsamixer 1013 * So call somewhat different.. 1014 * FIXME: the controls appear in the "playback" view! 1015 */ 1016 /* .name = "Capture Source", */ 1017 .name = "Input Source", 1018 .count = 3, 1019 .info = alc_mux_enum_info, 1020 .get = alc_mux_enum_get, 1021 .put = alc_mux_enum_put, 1022 }, 1023 { } /* end */ 1024}; 1025 1026/* capture mixer elements (in case NID 0x07 not available) */ 1027static struct snd_kcontrol_new alc880_capture_alt_mixer[] = { 1028 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 1029 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 1030 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), 1031 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), 1032 { 1033 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1034 /* The multiple "Capture Source" controls confuse alsamixer 1035 * So call somewhat different.. 1036 * FIXME: the controls appear in the "playback" view! 1037 */ 1038 /* .name = "Capture Source", */ 1039 .name = "Input Source", 1040 .count = 2, 1041 .info = alc_mux_enum_info, 1042 .get = alc_mux_enum_get, 1043 .put = alc_mux_enum_put, 1044 }, 1045 { } /* end */ 1046}; 1047 1048 1049 1050/* 1051 * ALC880 5-stack model 1052 * 1053 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d), 1054 * Side = 0x02 (0xd) 1055 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16 1056 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19 1057 */ 1058 1059/* additional mixers to alc880_three_stack_mixer */ 1060static struct snd_kcontrol_new alc880_five_stack_mixer[] = { 1061 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 1062 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT), 1063 { } /* end */ 1064}; 1065 1066/* channel source setting (6/8 channel selection for 5-stack) */ 1067/* 6ch mode */ 1068static struct hda_verb alc880_fivestack_ch6_init[] = { 1069 /* set line-in to input, mute it */ 1070 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 1071 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 1072 { } /* end */ 1073}; 1074 1075/* 8ch mode */ 1076static struct hda_verb alc880_fivestack_ch8_init[] = { 1077 /* set line-in to output, unmute it */ 1078 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 1079 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 1080 { } /* end */ 1081}; 1082 1083static struct hda_channel_mode alc880_fivestack_modes[2] = { 1084 { 6, alc880_fivestack_ch6_init }, 1085 { 8, alc880_fivestack_ch8_init }, 1086}; 1087 1088 1089/* 1090 * ALC880 6-stack model 1091 * 1092 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e), 1093 * Side = 0x05 (0x0f) 1094 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17, 1095 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b 1096 */ 1097 1098static hda_nid_t alc880_6st_dac_nids[4] = { 1099 /* front, rear, clfe, rear_surr */ 1100 0x02, 0x03, 0x04, 0x05 1101}; 1102 1103static struct hda_input_mux alc880_6stack_capture_source = { 1104 .num_items = 4, 1105 .items = { 1106 { "Mic", 0x0 }, 1107 { "Front Mic", 0x1 }, 1108 { "Line", 0x2 }, 1109 { "CD", 0x4 }, 1110 }, 1111}; 1112 1113/* fixed 8-channels */ 1114static struct hda_channel_mode alc880_sixstack_modes[1] = { 1115 { 8, NULL }, 1116}; 1117 1118static struct snd_kcontrol_new alc880_six_stack_mixer[] = { 1119 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 1120 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 1121 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 1122 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 1123 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 1124 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 1125 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 1126 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 1127 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 1128 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 1129 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 1130 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 1131 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 1132 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 1133 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 1134 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 1135 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 1136 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 1137 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 1138 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 1139 { 1140 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1141 .name = "Channel Mode", 1142 .info = alc_ch_mode_info, 1143 .get = alc_ch_mode_get, 1144 .put = alc_ch_mode_put, 1145 }, 1146 { } /* end */ 1147}; 1148 1149 1150/* 1151 * ALC880 W810 model 1152 * 1153 * W810 has rear IO for: 1154 * Front (DAC 02) 1155 * Surround (DAC 03) 1156 * Center/LFE (DAC 04) 1157 * Digital out (06) 1158 * 1159 * The system also has a pair of internal speakers, and a headphone jack. 1160 * These are both connected to Line2 on the codec, hence to DAC 02. 1161 * 1162 * There is a variable resistor to control the speaker or headphone 1163 * volume. This is a hardware-only device without a software API. 1164 * 1165 * Plugging headphones in will disable the internal speakers. This is 1166 * implemented in hardware, not via the driver using jack sense. In 1167 * a similar fashion, plugging into the rear socket marked "front" will 1168 * disable both the speakers and headphones. 1169 * 1170 * For input, there's a microphone jack, and an "audio in" jack. 1171 * These may not do anything useful with this driver yet, because I 1172 * haven't setup any initialization verbs for these yet... 1173 */ 1174 1175static hda_nid_t alc880_w810_dac_nids[3] = { 1176 /* front, rear/surround, clfe */ 1177 0x02, 0x03, 0x04 1178}; 1179 1180/* fixed 6 channels */ 1181static struct hda_channel_mode alc880_w810_modes[1] = { 1182 { 6, NULL } 1183}; 1184 1185/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */ 1186static struct snd_kcontrol_new alc880_w810_base_mixer[] = { 1187 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 1188 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 1189 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 1190 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 1191 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 1192 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 1193 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 1194 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 1195 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 1196 { } /* end */ 1197}; 1198 1199 1200/* 1201 * Z710V model 1202 * 1203 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d) 1204 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?), 1205 * Line = 0x1a 1206 */ 1207 1208static hda_nid_t alc880_z71v_dac_nids[1] = { 1209 0x02 1210}; 1211#define ALC880_Z71V_HP_DAC 0x03 1212 1213/* fixed 2 channels */ 1214static struct hda_channel_mode alc880_2_jack_modes[1] = { 1215 { 2, NULL } 1216}; 1217 1218static struct snd_kcontrol_new alc880_z71v_mixer[] = { 1219 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 1220 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 1221 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 1222 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT), 1223 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 1224 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 1225 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 1226 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 1227 { } /* end */ 1228}; 1229 1230 1231/* FIXME! */ 1232/* 1233 * ALC880 F1734 model 1234 * 1235 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d) 1236 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18 1237 */ 1238 1239static hda_nid_t alc880_f1734_dac_nids[1] = { 1240 0x03 1241}; 1242#define ALC880_F1734_HP_DAC 0x02 1243 1244static struct snd_kcontrol_new alc880_f1734_mixer[] = { 1245 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 1246 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), 1247 HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 1248 HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 1249 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 1250 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 1251 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 1252 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 1253 { } /* end */ 1254}; 1255 1256 1257/* FIXME! */ 1258/* 1259 * ALC880 ASUS model 1260 * 1261 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e) 1262 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16, 1263 * Mic = 0x18, Line = 0x1a 1264 */ 1265 1266#define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */ 1267#define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */ 1268 1269static struct snd_kcontrol_new alc880_asus_mixer[] = { 1270 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 1271 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 1272 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 1273 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 1274 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 1275 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 1276 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 1277 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 1278 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 1279 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 1280 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 1281 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 1282 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 1283 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 1284 { 1285 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1286 .name = "Channel Mode", 1287 .info = alc_ch_mode_info, 1288 .get = alc_ch_mode_get, 1289 .put = alc_ch_mode_put, 1290 }, 1291 { } /* end */ 1292}; 1293 1294/* FIXME! */ 1295/* 1296 * ALC880 ASUS W1V model 1297 * 1298 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e) 1299 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16, 1300 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b 1301 */ 1302 1303/* additional mixers to alc880_asus_mixer */ 1304static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = { 1305 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT), 1306 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT), 1307 { } /* end */ 1308}; 1309 1310/* additional mixers to alc880_asus_mixer */ 1311static struct snd_kcontrol_new alc880_pcbeep_mixer[] = { 1312 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 1313 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 1314 { } /* end */ 1315}; 1316 1317/* TCL S700 */ 1318static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = { 1319 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 1320 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 1321 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 1322 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT), 1323 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT), 1324 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT), 1325 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT), 1326 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 1327 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 1328 { 1329 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1330 /* The multiple "Capture Source" controls confuse alsamixer 1331 * So call somewhat different.. 1332 * FIXME: the controls appear in the "playback" view! 1333 */ 1334 /* .name = "Capture Source", */ 1335 .name = "Input Source", 1336 .count = 1, 1337 .info = alc_mux_enum_info, 1338 .get = alc_mux_enum_get, 1339 .put = alc_mux_enum_put, 1340 }, 1341 { } /* end */ 1342}; 1343 1344/* Uniwill */ 1345static struct snd_kcontrol_new alc880_uniwill_mixer[] = { 1346 HDA_CODEC_VOLUME("HPhone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 1347 HDA_BIND_MUTE("HPhone Playback Switch", 0x0c, 2, HDA_INPUT), 1348 HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 1349 HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT), 1350 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 1351 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 1352 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 1353 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 1354 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 1355 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 1356 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 1357 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 1358 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 1359 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 1360 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 1361 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 1362 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 1363 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 1364 { 1365 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1366 .name = "Channel Mode", 1367 .info = alc_ch_mode_info, 1368 .get = alc_ch_mode_get, 1369 .put = alc_ch_mode_put, 1370 }, 1371 { } /* end */ 1372}; 1373 1374static struct snd_kcontrol_new alc880_fujitsu_mixer[] = { 1375 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 1376 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), 1377 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 1378 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 1379 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 1380 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 1381 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 1382 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 1383 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 1384 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 1385 { } /* end */ 1386}; 1387 1388static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = { 1389 HDA_CODEC_VOLUME("HPhone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 1390 HDA_BIND_MUTE("HPhone Playback Switch", 0x0c, 2, HDA_INPUT), 1391 HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 1392 HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT), 1393 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 1394 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 1395 { } /* end */ 1396}; 1397 1398/* 1399 * build control elements 1400 */ 1401static int alc_build_controls(struct hda_codec *codec) 1402{ 1403 struct alc_spec *spec = codec->spec; 1404 int err; 1405 int i; 1406 1407 for (i = 0; i < spec->num_mixers; i++) { 1408 err = snd_hda_add_new_ctls(codec, spec->mixers[i]); 1409 if (err < 0) 1410 return err; 1411 } 1412 1413 if (spec->multiout.dig_out_nid) { 1414 err = snd_hda_create_spdif_out_ctls(codec, 1415 spec->multiout.dig_out_nid); 1416 if (err < 0) 1417 return err; 1418 } 1419 if (spec->dig_in_nid) { 1420 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid); 1421 if (err < 0) 1422 return err; 1423 } 1424 return 0; 1425} 1426 1427 1428/* 1429 * initialize the codec volumes, etc 1430 */ 1431 1432/* 1433 * generic initialization of ADC, input mixers and output mixers 1434 */ 1435static struct hda_verb alc880_volume_init_verbs[] = { 1436 /* 1437 * Unmute ADC0-2 and set the default input to mic-in 1438 */ 1439 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 1440 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1441 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 1442 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1443 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 1444 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1445 1446 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 1447 * mixer widget 1448 * Note: PASD motherboards uses the Line In 2 as the input for front 1449 * panel mic (mic 2) 1450 */ 1451 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 1452 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 1453 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 1454 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 1455 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 1456 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 1457 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, 1458 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, 1459 1460 /* 1461 * Set up output mixers (0x0c - 0x0f) 1462 */ 1463 /* set vol=0 to output mixers */ 1464 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 1465 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 1466 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 1467 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 1468 /* set up input amps for analog loopback */ 1469 /* Amp Indices: DAC = 0, mixer = 1 */ 1470 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 1471 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 1472 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 1473 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 1474 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 1475 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 1476 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 1477 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 1478 1479 { } 1480}; 1481 1482/* 1483 * 3-stack pin configuration: 1484 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b 1485 */ 1486static struct hda_verb alc880_pin_3stack_init_verbs[] = { 1487 /* 1488 * preset connection lists of input pins 1489 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround 1490 */ 1491 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ 1492 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 1493 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */ 1494 1495 /* 1496 * Set pin mode and muting 1497 */ 1498 /* set front pin widgets 0x14 for output */ 1499 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1500 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1501 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 1502 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1503 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1504 /* Mic2 (as headphone out) for HP output */ 1505 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1506 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1507 /* Line In pin widget for input */ 1508 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1509 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1510 /* Line2 (as front mic) pin widget for input and vref at 80% */ 1511 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1512 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1513 /* CD pin widget for input */ 1514 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1515 1516 { } 1517}; 1518 1519/* 1520 * 5-stack pin configuration: 1521 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19, 1522 * line-in/side = 0x1a, f-mic = 0x1b 1523 */ 1524static struct hda_verb alc880_pin_5stack_init_verbs[] = { 1525 /* 1526 * preset connection lists of input pins 1527 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround 1528 */ 1529 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 1530 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */ 1531 1532 /* 1533 * Set pin mode and muting 1534 */ 1535 /* set pin widgets 0x14-0x17 for output */ 1536 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1537 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1538 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1539 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1540 /* unmute pins for output (no gain on this amp) */ 1541 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1542 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1543 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1544 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1545 1546 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 1547 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1548 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1549 /* Mic2 (as headphone out) for HP output */ 1550 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1551 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1552 /* Line In pin widget for input */ 1553 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1554 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1555 /* Line2 (as front mic) pin widget for input and vref at 80% */ 1556 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1557 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1558 /* CD pin widget for input */ 1559 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1560 1561 { } 1562}; 1563 1564/* 1565 * W810 pin configuration: 1566 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b 1567 */ 1568static struct hda_verb alc880_pin_w810_init_verbs[] = { 1569 /* hphone/speaker input selector: front DAC */ 1570 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0}, 1571 1572 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1573 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1574 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1575 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1576 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1577 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1578 1579 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1580 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1581 1582 { } 1583}; 1584 1585/* 1586 * Z71V pin configuration: 1587 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?) 1588 */ 1589static struct hda_verb alc880_pin_z71v_init_verbs[] = { 1590 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1591 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1592 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1593 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1594 1595 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1596 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1597 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1598 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1599 1600 { } 1601}; 1602 1603/* 1604 * 6-stack pin configuration: 1605 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18, 1606 * f-mic = 0x19, line = 0x1a, HP = 0x1b 1607 */ 1608static struct hda_verb alc880_pin_6stack_init_verbs[] = { 1609 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 1610 1611 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1612 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1613 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1614 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1615 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1616 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1617 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1618 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1619 1620 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1621 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1622 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1623 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1624 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1625 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1626 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1627 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1628 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1629 1630 { } 1631}; 1632 1633/* 1634 * Uniwill pin configuration: 1635 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19, 1636 * line = 0x1a 1637 */ 1638static struct hda_verb alc880_uniwill_init_verbs[] = { 1639 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 1640 1641 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1642 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1643 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1644 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1645 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1646 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1647 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1648 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1649 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 1650 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 1651 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 1652 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 1653 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 1654 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 1655 1656 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1657 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1658 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1659 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1660 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1661 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1662 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */ 1663 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */ 1664 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1665 1666 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 1667 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 1668 1669 { } 1670}; 1671 1672/* 1673* Uniwill P53 1674* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19, 1675 */ 1676static struct hda_verb alc880_uniwill_p53_init_verbs[] = { 1677 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 1678 1679 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1680 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1681 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1682 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1683 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1684 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1685 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 1686 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 1687 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 1688 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 1689 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 1690 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 1691 1692 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1693 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1694 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1695 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1696 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1697 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1698 1699 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 1700 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT}, 1701 1702 { } 1703}; 1704 1705static struct hda_verb alc880_beep_init_verbs[] = { 1706 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) }, 1707 { } 1708}; 1709 1710/* toggle speaker-output according to the hp-jack state */ 1711static void alc880_uniwill_hp_automute(struct hda_codec *codec) 1712{ 1713 unsigned int present; 1714 unsigned char bits; 1715 1716 present = snd_hda_codec_read(codec, 0x14, 0, 1717 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 1718 bits = present ? HDA_AMP_MUTE : 0; 1719 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 1720 HDA_AMP_MUTE, bits); 1721 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0, 1722 HDA_AMP_MUTE, bits); 1723} 1724 1725/* auto-toggle front mic */ 1726static void alc880_uniwill_mic_automute(struct hda_codec *codec) 1727{ 1728 unsigned int present; 1729 unsigned char bits; 1730 1731 present = snd_hda_codec_read(codec, 0x18, 0, 1732 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 1733 bits = present ? HDA_AMP_MUTE : 0; 1734 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits); 1735} 1736 1737static void alc880_uniwill_automute(struct hda_codec *codec) 1738{ 1739 alc880_uniwill_hp_automute(codec); 1740 alc880_uniwill_mic_automute(codec); 1741} 1742 1743static void alc880_uniwill_unsol_event(struct hda_codec *codec, 1744 unsigned int res) 1745{ 1746 /* Looks like the unsol event is incompatible with the standard 1747 * definition. 4bit tag is placed at 28 bit! 1748 */ 1749 switch (res >> 28) { 1750 case ALC880_HP_EVENT: 1751 alc880_uniwill_hp_automute(codec); 1752 break; 1753 case ALC880_MIC_EVENT: 1754 alc880_uniwill_mic_automute(codec); 1755 break; 1756 } 1757} 1758 1759static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec) 1760{ 1761 unsigned int present; 1762 unsigned char bits; 1763 1764 present = snd_hda_codec_read(codec, 0x14, 0, 1765 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 1766 bits = present ? HDA_AMP_MUTE : 0; 1767 snd_hda_codec_amp_stereo(codec, 0x15, HDA_INPUT, 0, HDA_AMP_MUTE, bits); 1768} 1769 1770static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec) 1771{ 1772 unsigned int present; 1773 1774 present = snd_hda_codec_read(codec, 0x21, 0, 1775 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0); 1776 present &= HDA_AMP_VOLMASK; 1777 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0, 1778 HDA_AMP_VOLMASK, present); 1779 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0, 1780 HDA_AMP_VOLMASK, present); 1781} 1782 1783static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec, 1784 unsigned int res) 1785{ 1786 /* Looks like the unsol event is incompatible with the standard 1787 * definition. 4bit tag is placed at 28 bit! 1788 */ 1789 if ((res >> 28) == ALC880_HP_EVENT) 1790 alc880_uniwill_p53_hp_automute(codec); 1791 if ((res >> 28) == ALC880_DCVOL_EVENT) 1792 alc880_uniwill_p53_dcvol_automute(codec); 1793} 1794 1795/* FIXME! */ 1796/* 1797 * F1734 pin configuration: 1798 * HP = 0x14, speaker-out = 0x15, mic = 0x18 1799 */ 1800static struct hda_verb alc880_pin_f1734_init_verbs[] = { 1801 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, 1802 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, 1803 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, 1804 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, 1805 1806 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1807 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1808 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1809 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1810 1811 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1812 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1813 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1814 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1815 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1816 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1817 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1818 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1819 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1820 1821 { } 1822}; 1823 1824/* FIXME! */ 1825/* 1826 * ASUS pin configuration: 1827 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a 1828 */ 1829static struct hda_verb alc880_pin_asus_init_verbs[] = { 1830 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, 1831 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, 1832 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, 1833 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, 1834 1835 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1836 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1837 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1838 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1839 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1840 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1841 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1842 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1843 1844 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1845 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1846 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1847 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1848 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1849 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1850 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1851 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1852 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1853 1854 { } 1855}; 1856 1857/* Enable GPIO mask and set output */ 1858#define alc880_gpio1_init_verbs alc_gpio1_init_verbs 1859#define alc880_gpio2_init_verbs alc_gpio2_init_verbs 1860 1861/* Clevo m520g init */ 1862static struct hda_verb alc880_pin_clevo_init_verbs[] = { 1863 /* headphone output */ 1864 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01}, 1865 /* line-out */ 1866 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1867 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1868 /* Line-in */ 1869 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1870 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1871 /* CD */ 1872 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1873 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1874 /* Mic1 (rear panel) */ 1875 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1876 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1877 /* Mic2 (front panel) */ 1878 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1879 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1880 /* headphone */ 1881 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1882 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1883 /* change to EAPD mode */ 1884 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 1885 {0x20, AC_VERB_SET_PROC_COEF, 0x3060}, 1886 1887 { } 1888}; 1889 1890static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = { 1891 /* change to EAPD mode */ 1892 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 1893 {0x20, AC_VERB_SET_PROC_COEF, 0x3060}, 1894 1895 /* Headphone output */ 1896 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1897 /* Front output*/ 1898 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1899 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 1900 1901 /* Line In pin widget for input */ 1902 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1903 /* CD pin widget for input */ 1904 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1905 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 1906 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1907 1908 /* change to EAPD mode */ 1909 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 1910 {0x20, AC_VERB_SET_PROC_COEF, 0x3070}, 1911 1912 { } 1913}; 1914 1915/* 1916 * LG m1 express dual 1917 * 1918 * Pin assignment: 1919 * Rear Line-In/Out (blue): 0x14 1920 * Build-in Mic-In: 0x15 1921 * Speaker-out: 0x17 1922 * HP-Out (green): 0x1b 1923 * Mic-In/Out (red): 0x19 1924 * SPDIF-Out: 0x1e 1925 */ 1926 1927/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */ 1928static hda_nid_t alc880_lg_dac_nids[3] = { 1929 0x05, 0x02, 0x03 1930}; 1931 1932/* seems analog CD is not working */ 1933static struct hda_input_mux alc880_lg_capture_source = { 1934 .num_items = 3, 1935 .items = { 1936 { "Mic", 0x1 }, 1937 { "Line", 0x5 }, 1938 { "Internal Mic", 0x6 }, 1939 }, 1940}; 1941 1942/* 2,4,6 channel modes */ 1943static struct hda_verb alc880_lg_ch2_init[] = { 1944 /* set line-in and mic-in to input */ 1945 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 1946 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 1947 { } 1948}; 1949 1950static struct hda_verb alc880_lg_ch4_init[] = { 1951 /* set line-in to out and mic-in to input */ 1952 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, 1953 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 1954 { } 1955}; 1956 1957static struct hda_verb alc880_lg_ch6_init[] = { 1958 /* set line-in and mic-in to output */ 1959 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, 1960 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, 1961 { } 1962}; 1963 1964static struct hda_channel_mode alc880_lg_ch_modes[3] = { 1965 { 2, alc880_lg_ch2_init }, 1966 { 4, alc880_lg_ch4_init }, 1967 { 6, alc880_lg_ch6_init }, 1968}; 1969 1970static struct snd_kcontrol_new alc880_lg_mixer[] = { 1971 /* FIXME: it's not really "master" but front channels */ 1972 HDA_CODEC_VOLUME("Master Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 1973 HDA_BIND_MUTE("Master Playback Switch", 0x0f, 2, HDA_INPUT), 1974 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 1975 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT), 1976 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT), 1977 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT), 1978 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT), 1979 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT), 1980 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 1981 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 1982 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT), 1983 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT), 1984 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT), 1985 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT), 1986 { 1987 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1988 .name = "Channel Mode", 1989 .info = alc_ch_mode_info, 1990 .get = alc_ch_mode_get, 1991 .put = alc_ch_mode_put, 1992 }, 1993 { } /* end */ 1994}; 1995 1996static struct hda_verb alc880_lg_init_verbs[] = { 1997 /* set capture source to mic-in */ 1998 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 1999 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 2000 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 2001 /* mute all amp mixer inputs */ 2002 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)}, 2003 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, 2004 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, 2005 /* line-in to input */ 2006 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2007 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2008 /* built-in mic */ 2009 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2010 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2011 /* speaker-out */ 2012 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 2013 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2014 /* mic-in to input */ 2015 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01}, 2016 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2017 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2018 /* HP-out */ 2019 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03}, 2020 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 2021 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2022 /* jack sense */ 2023 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1}, 2024 { } 2025}; 2026 2027/* toggle speaker-output according to the hp-jack state */ 2028static void alc880_lg_automute(struct hda_codec *codec) 2029{ 2030 unsigned int present; 2031 unsigned char bits; 2032 2033 present = snd_hda_codec_read(codec, 0x1b, 0, 2034 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 2035 bits = present ? HDA_AMP_MUTE : 0; 2036 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0, 2037 HDA_AMP_MUTE, bits); 2038} 2039 2040static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res) 2041{ 2042 /* Looks like the unsol event is incompatible with the standard 2043 * definition. 4bit tag is placed at 28 bit! 2044 */ 2045 if ((res >> 28) == 0x01) 2046 alc880_lg_automute(codec); 2047} 2048 2049/* 2050 * LG LW20 2051 * 2052 * Pin assignment: 2053 * Speaker-out: 0x14 2054 * Mic-In: 0x18 2055 * Built-in Mic-In: 0x19 2056 * Line-In: 0x1b 2057 * HP-Out: 0x1a 2058 * SPDIF-Out: 0x1e 2059 */ 2060 2061static struct hda_input_mux alc880_lg_lw_capture_source = { 2062 .num_items = 3, 2063 .items = { 2064 { "Mic", 0x0 }, 2065 { "Internal Mic", 0x1 }, 2066 { "Line In", 0x2 }, 2067 }, 2068}; 2069 2070#define alc880_lg_lw_modes alc880_threestack_modes 2071 2072static struct snd_kcontrol_new alc880_lg_lw_mixer[] = { 2073 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2074 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 2075 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 2076 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT), 2077 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 2078 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 2079 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 2080 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 2081 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 2082 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 2083 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 2084 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 2085 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 2086 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 2087 { 2088 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2089 .name = "Channel Mode", 2090 .info = alc_ch_mode_info, 2091 .get = alc_ch_mode_get, 2092 .put = alc_ch_mode_put, 2093 }, 2094 { } /* end */ 2095}; 2096 2097static struct hda_verb alc880_lg_lw_init_verbs[] = { 2098 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 2099 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ 2100 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */ 2101 2102 /* set capture source to mic-in */ 2103 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 2104 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 2105 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 2106 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, 2107 /* speaker-out */ 2108 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 2109 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2110 /* HP-out */ 2111 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 2112 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2113 /* mic-in to input */ 2114 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2115 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2116 /* built-in mic */ 2117 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2118 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2119 /* jack sense */ 2120 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1}, 2121 { } 2122}; 2123 2124/* toggle speaker-output according to the hp-jack state */ 2125static void alc880_lg_lw_automute(struct hda_codec *codec) 2126{ 2127 unsigned int present; 2128 unsigned char bits; 2129 2130 present = snd_hda_codec_read(codec, 0x1b, 0, 2131 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 2132 bits = present ? HDA_AMP_MUTE : 0; 2133 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 2134 HDA_AMP_MUTE, bits); 2135} 2136 2137static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res) 2138{ 2139 /* Looks like the unsol event is incompatible with the standard 2140 * definition. 4bit tag is placed at 28 bit! 2141 */ 2142 if ((res >> 28) == 0x01) 2143 alc880_lg_lw_automute(codec); 2144} 2145 2146#ifdef CONFIG_SND_HDA_POWER_SAVE 2147static struct hda_amp_list alc880_loopbacks[] = { 2148 { 0x0b, HDA_INPUT, 0 }, 2149 { 0x0b, HDA_INPUT, 1 }, 2150 { 0x0b, HDA_INPUT, 2 }, 2151 { 0x0b, HDA_INPUT, 3 }, 2152 { 0x0b, HDA_INPUT, 4 }, 2153 { } /* end */ 2154}; 2155 2156static struct hda_amp_list alc880_lg_loopbacks[] = { 2157 { 0x0b, HDA_INPUT, 1 }, 2158 { 0x0b, HDA_INPUT, 6 }, 2159 { 0x0b, HDA_INPUT, 7 }, 2160 { } /* end */ 2161}; 2162#endif 2163 2164/* 2165 * Common callbacks 2166 */ 2167 2168static int alc_init(struct hda_codec *codec) 2169{ 2170 struct alc_spec *spec = codec->spec; 2171 unsigned int i; 2172 2173 for (i = 0; i < spec->num_init_verbs; i++) 2174 snd_hda_sequence_write(codec, spec->init_verbs[i]); 2175 2176 if (spec->init_hook) 2177 spec->init_hook(codec); 2178 2179 return 0; 2180} 2181 2182static void alc_unsol_event(struct hda_codec *codec, unsigned int res) 2183{ 2184 struct alc_spec *spec = codec->spec; 2185 2186 if (spec->unsol_event) 2187 spec->unsol_event(codec, res); 2188} 2189 2190#ifdef CONFIG_SND_HDA_POWER_SAVE 2191static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid) 2192{ 2193 struct alc_spec *spec = codec->spec; 2194 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid); 2195} 2196#endif 2197 2198/* 2199 * Analog playback callbacks 2200 */ 2201static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo, 2202 struct hda_codec *codec, 2203 struct snd_pcm_substream *substream) 2204{ 2205 struct alc_spec *spec = codec->spec; 2206 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream); 2207} 2208 2209static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo, 2210 struct hda_codec *codec, 2211 unsigned int stream_tag, 2212 unsigned int format, 2213 struct snd_pcm_substream *substream) 2214{ 2215 struct alc_spec *spec = codec->spec; 2216 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, 2217 stream_tag, format, substream); 2218} 2219 2220static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, 2221 struct hda_codec *codec, 2222 struct snd_pcm_substream *substream) 2223{ 2224 struct alc_spec *spec = codec->spec; 2225 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); 2226} 2227 2228/* 2229 * Digital out 2230 */ 2231static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo, 2232 struct hda_codec *codec, 2233 struct snd_pcm_substream *substream) 2234{ 2235 struct alc_spec *spec = codec->spec; 2236 return snd_hda_multi_out_dig_open(codec, &spec->multiout); 2237} 2238 2239static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, 2240 struct hda_codec *codec, 2241 unsigned int stream_tag, 2242 unsigned int format, 2243 struct snd_pcm_substream *substream) 2244{ 2245 struct alc_spec *spec = codec->spec; 2246 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, 2247 stream_tag, format, substream); 2248} 2249 2250static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, 2251 struct hda_codec *codec, 2252 struct snd_pcm_substream *substream) 2253{ 2254 struct alc_spec *spec = codec->spec; 2255 return snd_hda_multi_out_dig_close(codec, &spec->multiout); 2256} 2257 2258/* 2259 * Analog capture 2260 */ 2261static int alc880_capture_pcm_prepare(struct hda_pcm_stream *hinfo, 2262 struct hda_codec *codec, 2263 unsigned int stream_tag, 2264 unsigned int format, 2265 struct snd_pcm_substream *substream) 2266{ 2267 struct alc_spec *spec = codec->spec; 2268 2269 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number], 2270 stream_tag, 0, format); 2271 return 0; 2272} 2273 2274static int alc880_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, 2275 struct hda_codec *codec, 2276 struct snd_pcm_substream *substream) 2277{ 2278 struct alc_spec *spec = codec->spec; 2279 2280 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number], 2281 0, 0, 0); 2282 return 0; 2283} 2284 2285 2286/* 2287 */ 2288static struct hda_pcm_stream alc880_pcm_analog_playback = { 2289 .substreams = 1, 2290 .channels_min = 2, 2291 .channels_max = 8, 2292 /* NID is set in alc_build_pcms */ 2293 .ops = { 2294 .open = alc880_playback_pcm_open, 2295 .prepare = alc880_playback_pcm_prepare, 2296 .cleanup = alc880_playback_pcm_cleanup 2297 }, 2298}; 2299 2300static struct hda_pcm_stream alc880_pcm_analog_capture = { 2301 .substreams = 2, 2302 .channels_min = 2, 2303 .channels_max = 2, 2304 /* NID is set in alc_build_pcms */ 2305 .ops = { 2306 .prepare = alc880_capture_pcm_prepare, 2307 .cleanup = alc880_capture_pcm_cleanup 2308 }, 2309}; 2310 2311static struct hda_pcm_stream alc880_pcm_digital_playback = { 2312 .substreams = 1, 2313 .channels_min = 2, 2314 .channels_max = 2, 2315 /* NID is set in alc_build_pcms */ 2316 .ops = { 2317 .open = alc880_dig_playback_pcm_open, 2318 .close = alc880_dig_playback_pcm_close, 2319 .prepare = alc880_dig_playback_pcm_prepare 2320 }, 2321}; 2322 2323static struct hda_pcm_stream alc880_pcm_digital_capture = { 2324 .substreams = 1, 2325 .channels_min = 2, 2326 .channels_max = 2, 2327 /* NID is set in alc_build_pcms */ 2328}; 2329 2330/* Used by alc_build_pcms to flag that a PCM has no playback stream */ 2331static struct hda_pcm_stream alc_pcm_null_playback = { 2332 .substreams = 0, 2333 .channels_min = 0, 2334 .channels_max = 0, 2335}; 2336 2337static int alc_build_pcms(struct hda_codec *codec) 2338{ 2339 struct alc_spec *spec = codec->spec; 2340 struct hda_pcm *info = spec->pcm_rec; 2341 int i; 2342 2343 codec->num_pcms = 1; 2344 codec->pcm_info = info; 2345 2346 info->name = spec->stream_name_analog; 2347 if (spec->stream_analog_playback) { 2348 snd_assert(spec->multiout.dac_nids, return -EINVAL); 2349 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback); 2350 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0]; 2351 } 2352 if (spec->stream_analog_capture) { 2353 snd_assert(spec->adc_nids, return -EINVAL); 2354 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture); 2355 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0]; 2356 } 2357 2358 if (spec->channel_mode) { 2359 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0; 2360 for (i = 0; i < spec->num_channel_mode; i++) { 2361 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) { 2362 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels; 2363 } 2364 } 2365 } 2366 2367 /* SPDIF for stream index #1 */ 2368 if (spec->multiout.dig_out_nid || spec->dig_in_nid) { 2369 codec->num_pcms = 2; 2370 info = spec->pcm_rec + 1; 2371 info->name = spec->stream_name_digital; 2372 if (spec->multiout.dig_out_nid && 2373 spec->stream_digital_playback) { 2374 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback); 2375 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid; 2376 } 2377 if (spec->dig_in_nid && 2378 spec->stream_digital_capture) { 2379 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture); 2380 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid; 2381 } 2382 } 2383 2384 /* If the use of more than one ADC is requested for the current 2385 * model, configure a second analog capture-only PCM. 2386 */ 2387 /* Additional Analaog capture for index #2 */ 2388 if (spec->num_adc_nids > 1 && spec->stream_analog_capture && 2389 spec->adc_nids) { 2390 codec->num_pcms = 3; 2391 info = spec->pcm_rec + 2; 2392 info->name = spec->stream_name_analog; 2393 /* No playback stream for second PCM */ 2394 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = alc_pcm_null_playback; 2395 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0; 2396 if (spec->stream_analog_capture) { 2397 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture); 2398 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[1]; 2399 } 2400 } 2401 2402 return 0; 2403} 2404 2405static void alc_free(struct hda_codec *codec) 2406{ 2407 struct alc_spec *spec = codec->spec; 2408 unsigned int i; 2409 2410 if (!spec) 2411 return; 2412 2413 if (spec->kctl_alloc) { 2414 for (i = 0; i < spec->num_kctl_used; i++) 2415 kfree(spec->kctl_alloc[i].name); 2416 kfree(spec->kctl_alloc); 2417 } 2418 kfree(spec); 2419} 2420 2421/* 2422 */ 2423static struct hda_codec_ops alc_patch_ops = { 2424 .build_controls = alc_build_controls, 2425 .build_pcms = alc_build_pcms, 2426 .init = alc_init, 2427 .free = alc_free, 2428 .unsol_event = alc_unsol_event, 2429#ifdef CONFIG_SND_HDA_POWER_SAVE 2430 .check_power_status = alc_check_power_status, 2431#endif 2432}; 2433 2434 2435/* 2436 * Test configuration for debugging 2437 * 2438 * Almost all inputs/outputs are enabled. I/O pins can be configured via 2439 * enum controls. 2440 */ 2441#ifdef CONFIG_SND_DEBUG 2442static hda_nid_t alc880_test_dac_nids[4] = { 2443 0x02, 0x03, 0x04, 0x05 2444}; 2445 2446static struct hda_input_mux alc880_test_capture_source = { 2447 .num_items = 7, 2448 .items = { 2449 { "In-1", 0x0 }, 2450 { "In-2", 0x1 }, 2451 { "In-3", 0x2 }, 2452 { "In-4", 0x3 }, 2453 { "CD", 0x4 }, 2454 { "Front", 0x5 }, 2455 { "Surround", 0x6 }, 2456 }, 2457}; 2458 2459static struct hda_channel_mode alc880_test_modes[4] = { 2460 { 2, NULL }, 2461 { 4, NULL }, 2462 { 6, NULL }, 2463 { 8, NULL }, 2464}; 2465 2466static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol, 2467 struct snd_ctl_elem_info *uinfo) 2468{ 2469 static char *texts[] = { 2470 "N/A", "Line Out", "HP Out", 2471 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%" 2472 }; 2473 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 2474 uinfo->count = 1; 2475 uinfo->value.enumerated.items = 8; 2476 if (uinfo->value.enumerated.item >= 8) 2477 uinfo->value.enumerated.item = 7; 2478 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); 2479 return 0; 2480} 2481 2482static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol, 2483 struct snd_ctl_elem_value *ucontrol) 2484{ 2485 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2486 hda_nid_t nid = (hda_nid_t)kcontrol->private_value; 2487 unsigned int pin_ctl, item = 0; 2488 2489 pin_ctl = snd_hda_codec_read(codec, nid, 0, 2490 AC_VERB_GET_PIN_WIDGET_CONTROL, 0); 2491 if (pin_ctl & AC_PINCTL_OUT_EN) { 2492 if (pin_ctl & AC_PINCTL_HP_EN) 2493 item = 2; 2494 else 2495 item = 1; 2496 } else if (pin_ctl & AC_PINCTL_IN_EN) { 2497 switch (pin_ctl & AC_PINCTL_VREFEN) { 2498 case AC_PINCTL_VREF_HIZ: item = 3; break; 2499 case AC_PINCTL_VREF_50: item = 4; break; 2500 case AC_PINCTL_VREF_GRD: item = 5; break; 2501 case AC_PINCTL_VREF_80: item = 6; break; 2502 case AC_PINCTL_VREF_100: item = 7; break; 2503 } 2504 } 2505 ucontrol->value.enumerated.item[0] = item; 2506 return 0; 2507} 2508 2509static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol, 2510 struct snd_ctl_elem_value *ucontrol) 2511{ 2512 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2513 hda_nid_t nid = (hda_nid_t)kcontrol->private_value; 2514 static unsigned int ctls[] = { 2515 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN, 2516 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ, 2517 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50, 2518 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD, 2519 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80, 2520 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100, 2521 }; 2522 unsigned int old_ctl, new_ctl; 2523 2524 old_ctl = snd_hda_codec_read(codec, nid, 0, 2525 AC_VERB_GET_PIN_WIDGET_CONTROL, 0); 2526 new_ctl = ctls[ucontrol->value.enumerated.item[0]]; 2527 if (old_ctl != new_ctl) { 2528 int val; 2529 snd_hda_codec_write_cache(codec, nid, 0, 2530 AC_VERB_SET_PIN_WIDGET_CONTROL, 2531 new_ctl); 2532 val = ucontrol->value.enumerated.item[0] >= 3 ? 2533 HDA_AMP_MUTE : 0; 2534 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, 2535 HDA_AMP_MUTE, val); 2536 return 1; 2537 } 2538 return 0; 2539} 2540 2541static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol, 2542 struct snd_ctl_elem_info *uinfo) 2543{ 2544 static char *texts[] = { 2545 "Front", "Surround", "CLFE", "Side" 2546 }; 2547 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 2548 uinfo->count = 1; 2549 uinfo->value.enumerated.items = 4; 2550 if (uinfo->value.enumerated.item >= 4) 2551 uinfo->value.enumerated.item = 3; 2552 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); 2553 return 0; 2554} 2555 2556static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol, 2557 struct snd_ctl_elem_value *ucontrol) 2558{ 2559 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2560 hda_nid_t nid = (hda_nid_t)kcontrol->private_value; 2561 unsigned int sel; 2562 2563 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0); 2564 ucontrol->value.enumerated.item[0] = sel & 3; 2565 return 0; 2566} 2567 2568static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol, 2569 struct snd_ctl_elem_value *ucontrol) 2570{ 2571 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2572 hda_nid_t nid = (hda_nid_t)kcontrol->private_value; 2573 unsigned int sel; 2574 2575 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3; 2576 if (ucontrol->value.enumerated.item[0] != sel) { 2577 sel = ucontrol->value.enumerated.item[0] & 3; 2578 snd_hda_codec_write_cache(codec, nid, 0, 2579 AC_VERB_SET_CONNECT_SEL, sel); 2580 return 1; 2581 } 2582 return 0; 2583} 2584 2585#define PIN_CTL_TEST(xname,nid) { \ 2586 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 2587 .name = xname, \ 2588 .info = alc_test_pin_ctl_info, \ 2589 .get = alc_test_pin_ctl_get, \ 2590 .put = alc_test_pin_ctl_put, \ 2591 .private_value = nid \ 2592 } 2593 2594#define PIN_SRC_TEST(xname,nid) { \ 2595 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 2596 .name = xname, \ 2597 .info = alc_test_pin_src_info, \ 2598 .get = alc_test_pin_src_get, \ 2599 .put = alc_test_pin_src_put, \ 2600 .private_value = nid \ 2601 } 2602 2603static struct snd_kcontrol_new alc880_test_mixer[] = { 2604 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2605 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2606 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT), 2607 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 2608 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 2609 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 2610 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT), 2611 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 2612 PIN_CTL_TEST("Front Pin Mode", 0x14), 2613 PIN_CTL_TEST("Surround Pin Mode", 0x15), 2614 PIN_CTL_TEST("CLFE Pin Mode", 0x16), 2615 PIN_CTL_TEST("Side Pin Mode", 0x17), 2616 PIN_CTL_TEST("In-1 Pin Mode", 0x18), 2617 PIN_CTL_TEST("In-2 Pin Mode", 0x19), 2618 PIN_CTL_TEST("In-3 Pin Mode", 0x1a), 2619 PIN_CTL_TEST("In-4 Pin Mode", 0x1b), 2620 PIN_SRC_TEST("In-1 Pin Source", 0x18), 2621 PIN_SRC_TEST("In-2 Pin Source", 0x19), 2622 PIN_SRC_TEST("In-3 Pin Source", 0x1a), 2623 PIN_SRC_TEST("In-4 Pin Source", 0x1b), 2624 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT), 2625 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT), 2626 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT), 2627 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT), 2628 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT), 2629 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT), 2630 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT), 2631 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT), 2632 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT), 2633 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT), 2634 { 2635 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2636 .name = "Channel Mode", 2637 .info = alc_ch_mode_info, 2638 .get = alc_ch_mode_get, 2639 .put = alc_ch_mode_put, 2640 }, 2641 { } /* end */ 2642}; 2643 2644static struct hda_verb alc880_test_init_verbs[] = { 2645 /* Unmute inputs of 0x0c - 0x0f */ 2646 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 2647 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 2648 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 2649 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 2650 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 2651 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 2652 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 2653 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 2654 /* Vol output for 0x0c-0x0f */ 2655 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 2656 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 2657 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 2658 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 2659 /* Set output pins 0x14-0x17 */ 2660 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2661 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2662 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2663 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2664 /* Unmute output pins 0x14-0x17 */ 2665 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2666 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2667 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2668 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2669 /* Set input pins 0x18-0x1c */ 2670 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2671 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2672 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2673 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2674 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2675 /* Mute input pins 0x18-0x1b */ 2676 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2677 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2678 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2679 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2680 /* ADC set up */ 2681 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 2682 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 2683 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 2684 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 2685 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 2686 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 2687 /* Analog input/passthru */ 2688 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 2689 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 2690 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 2691 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 2692 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 2693 { } 2694}; 2695#endif 2696 2697/* 2698 */ 2699 2700static const char *alc880_models[ALC880_MODEL_LAST] = { 2701 [ALC880_3ST] = "3stack", 2702 [ALC880_TCL_S700] = "tcl", 2703 [ALC880_3ST_DIG] = "3stack-digout", 2704 [ALC880_CLEVO] = "clevo", 2705 [ALC880_5ST] = "5stack", 2706 [ALC880_5ST_DIG] = "5stack-digout", 2707 [ALC880_W810] = "w810", 2708 [ALC880_Z71V] = "z71v", 2709 [ALC880_6ST] = "6stack", 2710 [ALC880_6ST_DIG] = "6stack-digout", 2711 [ALC880_ASUS] = "asus", 2712 [ALC880_ASUS_W1V] = "asus-w1v", 2713 [ALC880_ASUS_DIG] = "asus-dig", 2714 [ALC880_ASUS_DIG2] = "asus-dig2", 2715 [ALC880_UNIWILL_DIG] = "uniwill", 2716 [ALC880_UNIWILL_P53] = "uniwill-p53", 2717 [ALC880_FUJITSU] = "fujitsu", 2718 [ALC880_F1734] = "F1734", 2719 [ALC880_LG] = "lg", 2720 [ALC880_LG_LW] = "lg-lw", 2721#ifdef CONFIG_SND_DEBUG 2722 [ALC880_TEST] = "test", 2723#endif 2724 [ALC880_AUTO] = "auto", 2725}; 2726 2727static struct snd_pci_quirk alc880_cfg_tbl[] = { 2728 /* Broken BIOS configuration */ 2729 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), 2730 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG), 2731 2732 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG), 2733 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST), 2734 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810), 2735 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG), 2736 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG), 2737 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG), 2738 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG), 2739 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG), 2740 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST), 2741 2742 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG), 2743 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST), 2744 2745 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V), 2746 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG), 2747 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG), 2748 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG), 2749 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG), 2750 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG), 2751 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V), 2752 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */ 2753 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG), 2754 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG), 2755 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS", ALC880_ASUS), 2756 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG), 2757 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST), 2758 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST), 2759 SND_PCI_QUIRK(0x1043, 0, "ASUS", ALC880_ASUS), 2760 2761 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST), 2762 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST), 2763 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST), 2764 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST), 2765 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST), 2766 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO), 2767 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO), 2768 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG), 2769 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810), 2770 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG), 2771 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700), 2772 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG), 2773 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG), 2774 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG), 2775 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG), 2776 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG), 2777 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG), 2778 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2), 2779 2780 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG), 2781 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL), 2782 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53), 2783 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734), 2784 2785 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG), 2786 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL), 2787 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734), 2788 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU), 2789 2790 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG), 2791 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG), 2792 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW), 2793 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW), 2794 2795 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG), 2796 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG), 2797 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG), 2798 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG), 2799 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG), 2800 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG), 2801 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG), 2802 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG), 2803 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG), 2804 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG), 2805 SND_PCI_QUIRK(0x8086, 0, "Intel mobo", ALC880_3ST), 2806 2807 {} 2808}; 2809 2810/* 2811 * ALC880 codec presets 2812 */ 2813static struct alc_config_preset alc880_presets[] = { 2814 [ALC880_3ST] = { 2815 .mixers = { alc880_three_stack_mixer }, 2816 .init_verbs = { alc880_volume_init_verbs, 2817 alc880_pin_3stack_init_verbs }, 2818 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 2819 .dac_nids = alc880_dac_nids, 2820 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), 2821 .channel_mode = alc880_threestack_modes, 2822 .need_dac_fix = 1, 2823 .input_mux = &alc880_capture_source, 2824 }, 2825 [ALC880_3ST_DIG] = { 2826 .mixers = { alc880_three_stack_mixer }, 2827 .init_verbs = { alc880_volume_init_verbs, 2828 alc880_pin_3stack_init_verbs }, 2829 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 2830 .dac_nids = alc880_dac_nids, 2831 .dig_out_nid = ALC880_DIGOUT_NID, 2832 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), 2833 .channel_mode = alc880_threestack_modes, 2834 .need_dac_fix = 1, 2835 .input_mux = &alc880_capture_source, 2836 }, 2837 [ALC880_TCL_S700] = { 2838 .mixers = { alc880_tcl_s700_mixer }, 2839 .init_verbs = { alc880_volume_init_verbs, 2840 alc880_pin_tcl_S700_init_verbs, 2841 alc880_gpio2_init_verbs }, 2842 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 2843 .dac_nids = alc880_dac_nids, 2844 .hp_nid = 0x03, 2845 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), 2846 .channel_mode = alc880_2_jack_modes, 2847 .input_mux = &alc880_capture_source, 2848 }, 2849 [ALC880_5ST] = { 2850 .mixers = { alc880_three_stack_mixer, 2851 alc880_five_stack_mixer}, 2852 .init_verbs = { alc880_volume_init_verbs, 2853 alc880_pin_5stack_init_verbs }, 2854 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 2855 .dac_nids = alc880_dac_nids, 2856 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes), 2857 .channel_mode = alc880_fivestack_modes, 2858 .input_mux = &alc880_capture_source, 2859 }, 2860 [ALC880_5ST_DIG] = { 2861 .mixers = { alc880_three_stack_mixer, 2862 alc880_five_stack_mixer }, 2863 .init_verbs = { alc880_volume_init_verbs, 2864 alc880_pin_5stack_init_verbs }, 2865 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 2866 .dac_nids = alc880_dac_nids, 2867 .dig_out_nid = ALC880_DIGOUT_NID, 2868 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes), 2869 .channel_mode = alc880_fivestack_modes, 2870 .input_mux = &alc880_capture_source, 2871 }, 2872 [ALC880_6ST] = { 2873 .mixers = { alc880_six_stack_mixer }, 2874 .init_verbs = { alc880_volume_init_verbs, 2875 alc880_pin_6stack_init_verbs }, 2876 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids), 2877 .dac_nids = alc880_6st_dac_nids, 2878 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes), 2879 .channel_mode = alc880_sixstack_modes, 2880 .input_mux = &alc880_6stack_capture_source, 2881 }, 2882 [ALC880_6ST_DIG] = { 2883 .mixers = { alc880_six_stack_mixer }, 2884 .init_verbs = { alc880_volume_init_verbs, 2885 alc880_pin_6stack_init_verbs }, 2886 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids), 2887 .dac_nids = alc880_6st_dac_nids, 2888 .dig_out_nid = ALC880_DIGOUT_NID, 2889 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes), 2890 .channel_mode = alc880_sixstack_modes, 2891 .input_mux = &alc880_6stack_capture_source, 2892 }, 2893 [ALC880_W810] = { 2894 .mixers = { alc880_w810_base_mixer }, 2895 .init_verbs = { alc880_volume_init_verbs, 2896 alc880_pin_w810_init_verbs, 2897 alc880_gpio2_init_verbs }, 2898 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids), 2899 .dac_nids = alc880_w810_dac_nids, 2900 .dig_out_nid = ALC880_DIGOUT_NID, 2901 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes), 2902 .channel_mode = alc880_w810_modes, 2903 .input_mux = &alc880_capture_source, 2904 }, 2905 [ALC880_Z71V] = { 2906 .mixers = { alc880_z71v_mixer }, 2907 .init_verbs = { alc880_volume_init_verbs, 2908 alc880_pin_z71v_init_verbs }, 2909 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids), 2910 .dac_nids = alc880_z71v_dac_nids, 2911 .dig_out_nid = ALC880_DIGOUT_NID, 2912 .hp_nid = 0x03, 2913 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), 2914 .channel_mode = alc880_2_jack_modes, 2915 .input_mux = &alc880_capture_source, 2916 }, 2917 [ALC880_F1734] = { 2918 .mixers = { alc880_f1734_mixer }, 2919 .init_verbs = { alc880_volume_init_verbs, 2920 alc880_pin_f1734_init_verbs }, 2921 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids), 2922 .dac_nids = alc880_f1734_dac_nids, 2923 .hp_nid = 0x02, 2924 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), 2925 .channel_mode = alc880_2_jack_modes, 2926 .input_mux = &alc880_capture_source, 2927 }, 2928 [ALC880_ASUS] = { 2929 .mixers = { alc880_asus_mixer }, 2930 .init_verbs = { alc880_volume_init_verbs, 2931 alc880_pin_asus_init_verbs, 2932 alc880_gpio1_init_verbs }, 2933 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 2934 .dac_nids = alc880_asus_dac_nids, 2935 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), 2936 .channel_mode = alc880_asus_modes, 2937 .need_dac_fix = 1, 2938 .input_mux = &alc880_capture_source, 2939 }, 2940 [ALC880_ASUS_DIG] = { 2941 .mixers = { alc880_asus_mixer }, 2942 .init_verbs = { alc880_volume_init_verbs, 2943 alc880_pin_asus_init_verbs, 2944 alc880_gpio1_init_verbs }, 2945 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 2946 .dac_nids = alc880_asus_dac_nids, 2947 .dig_out_nid = ALC880_DIGOUT_NID, 2948 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), 2949 .channel_mode = alc880_asus_modes, 2950 .need_dac_fix = 1, 2951 .input_mux = &alc880_capture_source, 2952 }, 2953 [ALC880_ASUS_DIG2] = { 2954 .mixers = { alc880_asus_mixer }, 2955 .init_verbs = { alc880_volume_init_verbs, 2956 alc880_pin_asus_init_verbs, 2957 alc880_gpio2_init_verbs }, /* use GPIO2 */ 2958 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 2959 .dac_nids = alc880_asus_dac_nids, 2960 .dig_out_nid = ALC880_DIGOUT_NID, 2961 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), 2962 .channel_mode = alc880_asus_modes, 2963 .need_dac_fix = 1, 2964 .input_mux = &alc880_capture_source, 2965 }, 2966 [ALC880_ASUS_W1V] = { 2967 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer }, 2968 .init_verbs = { alc880_volume_init_verbs, 2969 alc880_pin_asus_init_verbs, 2970 alc880_gpio1_init_verbs }, 2971 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 2972 .dac_nids = alc880_asus_dac_nids, 2973 .dig_out_nid = ALC880_DIGOUT_NID, 2974 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), 2975 .channel_mode = alc880_asus_modes, 2976 .need_dac_fix = 1, 2977 .input_mux = &alc880_capture_source, 2978 }, 2979 [ALC880_UNIWILL_DIG] = { 2980 .mixers = { alc880_asus_mixer, alc880_pcbeep_mixer }, 2981 .init_verbs = { alc880_volume_init_verbs, 2982 alc880_pin_asus_init_verbs }, 2983 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 2984 .dac_nids = alc880_asus_dac_nids, 2985 .dig_out_nid = ALC880_DIGOUT_NID, 2986 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), 2987 .channel_mode = alc880_asus_modes, 2988 .need_dac_fix = 1, 2989 .input_mux = &alc880_capture_source, 2990 }, 2991 [ALC880_UNIWILL] = { 2992 .mixers = { alc880_uniwill_mixer }, 2993 .init_verbs = { alc880_volume_init_verbs, 2994 alc880_uniwill_init_verbs }, 2995 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 2996 .dac_nids = alc880_asus_dac_nids, 2997 .dig_out_nid = ALC880_DIGOUT_NID, 2998 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), 2999 .channel_mode = alc880_threestack_modes, 3000 .need_dac_fix = 1, 3001 .input_mux = &alc880_capture_source, 3002 .unsol_event = alc880_uniwill_unsol_event, 3003 .init_hook = alc880_uniwill_automute, 3004 }, 3005 [ALC880_UNIWILL_P53] = { 3006 .mixers = { alc880_uniwill_p53_mixer }, 3007 .init_verbs = { alc880_volume_init_verbs, 3008 alc880_uniwill_p53_init_verbs }, 3009 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 3010 .dac_nids = alc880_asus_dac_nids, 3011 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes), 3012 .channel_mode = alc880_threestack_modes, 3013 .input_mux = &alc880_capture_source, 3014 .unsol_event = alc880_uniwill_p53_unsol_event, 3015 .init_hook = alc880_uniwill_p53_hp_automute, 3016 }, 3017 [ALC880_FUJITSU] = { 3018 .mixers = { alc880_fujitsu_mixer, 3019 alc880_pcbeep_mixer, }, 3020 .init_verbs = { alc880_volume_init_verbs, 3021 alc880_uniwill_p53_init_verbs, 3022 alc880_beep_init_verbs }, 3023 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 3024 .dac_nids = alc880_dac_nids, 3025 .dig_out_nid = ALC880_DIGOUT_NID, 3026 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), 3027 .channel_mode = alc880_2_jack_modes, 3028 .input_mux = &alc880_capture_source, 3029 .unsol_event = alc880_uniwill_p53_unsol_event, 3030 .init_hook = alc880_uniwill_p53_hp_automute, 3031 }, 3032 [ALC880_CLEVO] = { 3033 .mixers = { alc880_three_stack_mixer }, 3034 .init_verbs = { alc880_volume_init_verbs, 3035 alc880_pin_clevo_init_verbs }, 3036 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 3037 .dac_nids = alc880_dac_nids, 3038 .hp_nid = 0x03, 3039 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), 3040 .channel_mode = alc880_threestack_modes, 3041 .need_dac_fix = 1, 3042 .input_mux = &alc880_capture_source, 3043 }, 3044 [ALC880_LG] = { 3045 .mixers = { alc880_lg_mixer }, 3046 .init_verbs = { alc880_volume_init_verbs, 3047 alc880_lg_init_verbs }, 3048 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids), 3049 .dac_nids = alc880_lg_dac_nids, 3050 .dig_out_nid = ALC880_DIGOUT_NID, 3051 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes), 3052 .channel_mode = alc880_lg_ch_modes, 3053 .need_dac_fix = 1, 3054 .input_mux = &alc880_lg_capture_source, 3055 .unsol_event = alc880_lg_unsol_event, 3056 .init_hook = alc880_lg_automute, 3057#ifdef CONFIG_SND_HDA_POWER_SAVE 3058 .loopbacks = alc880_lg_loopbacks, 3059#endif 3060 }, 3061 [ALC880_LG_LW] = { 3062 .mixers = { alc880_lg_lw_mixer }, 3063 .init_verbs = { alc880_volume_init_verbs, 3064 alc880_lg_lw_init_verbs }, 3065 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 3066 .dac_nids = alc880_dac_nids, 3067 .dig_out_nid = ALC880_DIGOUT_NID, 3068 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes), 3069 .channel_mode = alc880_lg_lw_modes, 3070 .input_mux = &alc880_lg_lw_capture_source, 3071 .unsol_event = alc880_lg_lw_unsol_event, 3072 .init_hook = alc880_lg_lw_automute, 3073 }, 3074#ifdef CONFIG_SND_DEBUG 3075 [ALC880_TEST] = { 3076 .mixers = { alc880_test_mixer }, 3077 .init_verbs = { alc880_test_init_verbs }, 3078 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids), 3079 .dac_nids = alc880_test_dac_nids, 3080 .dig_out_nid = ALC880_DIGOUT_NID, 3081 .num_channel_mode = ARRAY_SIZE(alc880_test_modes), 3082 .channel_mode = alc880_test_modes, 3083 .input_mux = &alc880_test_capture_source, 3084 }, 3085#endif 3086}; 3087 3088/* 3089 * Automatic parse of I/O pins from the BIOS configuration 3090 */ 3091 3092#define NUM_CONTROL_ALLOC 32 3093#define NUM_VERB_ALLOC 32 3094 3095enum { 3096 ALC_CTL_WIDGET_VOL, 3097 ALC_CTL_WIDGET_MUTE, 3098 ALC_CTL_BIND_MUTE, 3099}; 3100static struct snd_kcontrol_new alc880_control_templates[] = { 3101 HDA_CODEC_VOLUME(NULL, 0, 0, 0), 3102 HDA_CODEC_MUTE(NULL, 0, 0, 0), 3103 HDA_BIND_MUTE(NULL, 0, 0, 0), 3104}; 3105 3106/* add dynamic controls */ 3107static int add_control(struct alc_spec *spec, int type, const char *name, 3108 unsigned long val) 3109{ 3110 struct snd_kcontrol_new *knew; 3111 3112 if (spec->num_kctl_used >= spec->num_kctl_alloc) { 3113 int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC; 3114 3115 /* array + terminator */ 3116 knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL); 3117 if (!knew) 3118 return -ENOMEM; 3119 if (spec->kctl_alloc) { 3120 memcpy(knew, spec->kctl_alloc, 3121 sizeof(*knew) * spec->num_kctl_alloc); 3122 kfree(spec->kctl_alloc); 3123 } 3124 spec->kctl_alloc = knew; 3125 spec->num_kctl_alloc = num; 3126 } 3127 3128 knew = &spec->kctl_alloc[spec->num_kctl_used]; 3129 *knew = alc880_control_templates[type]; 3130 knew->name = kstrdup(name, GFP_KERNEL); 3131 if (!knew->name) 3132 return -ENOMEM; 3133 knew->private_value = val; 3134 spec->num_kctl_used++; 3135 return 0; 3136} 3137 3138#define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17) 3139#define alc880_fixed_pin_idx(nid) ((nid) - 0x14) 3140#define alc880_is_multi_pin(nid) ((nid) >= 0x18) 3141#define alc880_multi_pin_idx(nid) ((nid) - 0x18) 3142#define alc880_is_input_pin(nid) ((nid) >= 0x18) 3143#define alc880_input_pin_idx(nid) ((nid) - 0x18) 3144#define alc880_idx_to_dac(nid) ((nid) + 0x02) 3145#define alc880_dac_to_idx(nid) ((nid) - 0x02) 3146#define alc880_idx_to_mixer(nid) ((nid) + 0x0c) 3147#define alc880_idx_to_selector(nid) ((nid) + 0x10) 3148#define ALC880_PIN_CD_NID 0x1c 3149 3150/* fill in the dac_nids table from the parsed pin configuration */ 3151static int alc880_auto_fill_dac_nids(struct alc_spec *spec, 3152 const struct auto_pin_cfg *cfg) 3153{ 3154 hda_nid_t nid; 3155 int assigned[4]; 3156 int i, j; 3157 3158 memset(assigned, 0, sizeof(assigned)); 3159 spec->multiout.dac_nids = spec->private_dac_nids; 3160 3161 /* check the pins hardwired to audio widget */ 3162 for (i = 0; i < cfg->line_outs; i++) { 3163 nid = cfg->line_out_pins[i]; 3164 if (alc880_is_fixed_pin(nid)) { 3165 int idx = alc880_fixed_pin_idx(nid); 3166 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx); 3167 assigned[idx] = 1; 3168 } 3169 } 3170 /* left pins can be connect to any audio widget */ 3171 for (i = 0; i < cfg->line_outs; i++) { 3172 nid = cfg->line_out_pins[i]; 3173 if (alc880_is_fixed_pin(nid)) 3174 continue; 3175 /* search for an empty channel */ 3176 for (j = 0; j < cfg->line_outs; j++) { 3177 if (!assigned[j]) { 3178 spec->multiout.dac_nids[i] = 3179 alc880_idx_to_dac(j); 3180 assigned[j] = 1; 3181 break; 3182 } 3183 } 3184 } 3185 spec->multiout.num_dacs = cfg->line_outs; 3186 return 0; 3187} 3188 3189/* add playback controls from the parsed DAC table */ 3190static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec, 3191 const struct auto_pin_cfg *cfg) 3192{ 3193 char name[32]; 3194 static const char *chname[4] = { 3195 "Front", "Surround", NULL /*CLFE*/, "Side" 3196 }; 3197 hda_nid_t nid; 3198 int i, err; 3199 3200 for (i = 0; i < cfg->line_outs; i++) { 3201 if (!spec->multiout.dac_nids[i]) 3202 continue; 3203 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i])); 3204 if (i == 2) { 3205 /* Center/LFE */ 3206 err = add_control(spec, ALC_CTL_WIDGET_VOL, 3207 "Center Playback Volume", 3208 HDA_COMPOSE_AMP_VAL(nid, 1, 0, 3209 HDA_OUTPUT)); 3210 if (err < 0) 3211 return err; 3212 err = add_control(spec, ALC_CTL_WIDGET_VOL, 3213 "LFE Playback Volume", 3214 HDA_COMPOSE_AMP_VAL(nid, 2, 0, 3215 HDA_OUTPUT)); 3216 if (err < 0) 3217 return err; 3218 err = add_control(spec, ALC_CTL_BIND_MUTE, 3219 "Center Playback Switch", 3220 HDA_COMPOSE_AMP_VAL(nid, 1, 2, 3221 HDA_INPUT)); 3222 if (err < 0) 3223 return err; 3224 err = add_control(spec, ALC_CTL_BIND_MUTE, 3225 "LFE Playback Switch", 3226 HDA_COMPOSE_AMP_VAL(nid, 2, 2, 3227 HDA_INPUT)); 3228 if (err < 0) 3229 return err; 3230 } else { 3231 sprintf(name, "%s Playback Volume", chname[i]); 3232 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, 3233 HDA_COMPOSE_AMP_VAL(nid, 3, 0, 3234 HDA_OUTPUT)); 3235 if (err < 0) 3236 return err; 3237 sprintf(name, "%s Playback Switch", chname[i]); 3238 err = add_control(spec, ALC_CTL_BIND_MUTE, name, 3239 HDA_COMPOSE_AMP_VAL(nid, 3, 2, 3240 HDA_INPUT)); 3241 if (err < 0) 3242 return err; 3243 } 3244 } 3245 return 0; 3246} 3247 3248/* add playback controls for speaker and HP outputs */ 3249static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin, 3250 const char *pfx) 3251{ 3252 hda_nid_t nid; 3253 int err; 3254 char name[32]; 3255 3256 if (!pin) 3257 return 0; 3258 3259 if (alc880_is_fixed_pin(pin)) { 3260 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); 3261 /* specify the DAC as the extra output */ 3262 if (!spec->multiout.hp_nid) 3263 spec->multiout.hp_nid = nid; 3264 else 3265 spec->multiout.extra_out_nid[0] = nid; 3266 /* control HP volume/switch on the output mixer amp */ 3267 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin)); 3268 sprintf(name, "%s Playback Volume", pfx); 3269 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, 3270 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); 3271 if (err < 0) 3272 return err; 3273 sprintf(name, "%s Playback Switch", pfx); 3274 err = add_control(spec, ALC_CTL_BIND_MUTE, name, 3275 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT)); 3276 if (err < 0) 3277 return err; 3278 } else if (alc880_is_multi_pin(pin)) { 3279 /* set manual connection */ 3280 /* we have only a switch on HP-out PIN */ 3281 sprintf(name, "%s Playback Switch", pfx); 3282 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, 3283 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); 3284 if (err < 0) 3285 return err; 3286 } 3287 return 0; 3288} 3289 3290/* create input playback/capture controls for the given pin */ 3291static int new_analog_input(struct alc_spec *spec, hda_nid_t pin, 3292 const char *ctlname, 3293 int idx, hda_nid_t mix_nid) 3294{ 3295 char name[32]; 3296 int err; 3297 3298 sprintf(name, "%s Playback Volume", ctlname); 3299 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, 3300 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT)); 3301 if (err < 0) 3302 return err; 3303 sprintf(name, "%s Playback Switch", ctlname); 3304 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, 3305 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT)); 3306 if (err < 0) 3307 return err; 3308 return 0; 3309} 3310 3311/* create playback/capture controls for input pins */ 3312static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec, 3313 const struct auto_pin_cfg *cfg) 3314{ 3315 struct hda_input_mux *imux = &spec->private_imux; 3316 int i, err, idx; 3317 3318 for (i = 0; i < AUTO_PIN_LAST; i++) { 3319 if (alc880_is_input_pin(cfg->input_pins[i])) { 3320 idx = alc880_input_pin_idx(cfg->input_pins[i]); 3321 err = new_analog_input(spec, cfg->input_pins[i], 3322 auto_pin_cfg_labels[i], 3323 idx, 0x0b); 3324 if (err < 0) 3325 return err; 3326 imux->items[imux->num_items].label = 3327 auto_pin_cfg_labels[i]; 3328 imux->items[imux->num_items].index = 3329 alc880_input_pin_idx(cfg->input_pins[i]); 3330 imux->num_items++; 3331 } 3332 } 3333 return 0; 3334} 3335 3336static void alc880_auto_set_output_and_unmute(struct hda_codec *codec, 3337 hda_nid_t nid, int pin_type, 3338 int dac_idx) 3339{ 3340 /* set as output */ 3341 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 3342 pin_type); 3343 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, 3344 AMP_OUT_UNMUTE); 3345 /* need the manual connection? */ 3346 if (alc880_is_multi_pin(nid)) { 3347 struct alc_spec *spec = codec->spec; 3348 int idx = alc880_multi_pin_idx(nid); 3349 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0, 3350 AC_VERB_SET_CONNECT_SEL, 3351 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx])); 3352 } 3353} 3354 3355static int get_pin_type(int line_out_type) 3356{ 3357 if (line_out_type == AUTO_PIN_HP_OUT) 3358 return PIN_HP; 3359 else 3360 return PIN_OUT; 3361} 3362 3363static void alc880_auto_init_multi_out(struct hda_codec *codec) 3364{ 3365 struct alc_spec *spec = codec->spec; 3366 int i; 3367 3368 alc_subsystem_id(codec, 0x15, 0x1b, 0x14); 3369 for (i = 0; i < spec->autocfg.line_outs; i++) { 3370 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 3371 int pin_type = get_pin_type(spec->autocfg.line_out_type); 3372 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i); 3373 } 3374} 3375 3376static void alc880_auto_init_extra_out(struct hda_codec *codec) 3377{ 3378 struct alc_spec *spec = codec->spec; 3379 hda_nid_t pin; 3380 3381 pin = spec->autocfg.speaker_pins[0]; 3382 if (pin) /* connect to front */ 3383 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0); 3384 pin = spec->autocfg.hp_pins[0]; 3385 if (pin) /* connect to front */ 3386 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); 3387} 3388 3389static void alc880_auto_init_analog_input(struct hda_codec *codec) 3390{ 3391 struct alc_spec *spec = codec->spec; 3392 int i; 3393 3394 for (i = 0; i < AUTO_PIN_LAST; i++) { 3395 hda_nid_t nid = spec->autocfg.input_pins[i]; 3396 if (alc880_is_input_pin(nid)) { 3397 snd_hda_codec_write(codec, nid, 0, 3398 AC_VERB_SET_PIN_WIDGET_CONTROL, 3399 i <= AUTO_PIN_FRONT_MIC ? 3400 PIN_VREF80 : PIN_IN); 3401 if (nid != ALC880_PIN_CD_NID) 3402 snd_hda_codec_write(codec, nid, 0, 3403 AC_VERB_SET_AMP_GAIN_MUTE, 3404 AMP_OUT_MUTE); 3405 } 3406 } 3407} 3408 3409/* parse the BIOS configuration and set up the alc_spec */ 3410/* return 1 if successful, 0 if the proper config is not found, 3411 * or a negative error code 3412 */ 3413static int alc880_parse_auto_config(struct hda_codec *codec) 3414{ 3415 struct alc_spec *spec = codec->spec; 3416 int err; 3417 static hda_nid_t alc880_ignore[] = { 0x1d, 0 }; 3418 3419 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 3420 alc880_ignore); 3421 if (err < 0) 3422 return err; 3423 if (!spec->autocfg.line_outs) 3424 return 0; /* can't find valid BIOS pin config */ 3425 3426 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); 3427 if (err < 0) 3428 return err; 3429 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg); 3430 if (err < 0) 3431 return err; 3432 err = alc880_auto_create_extra_out(spec, 3433 spec->autocfg.speaker_pins[0], 3434 "Speaker"); 3435 if (err < 0) 3436 return err; 3437 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0], 3438 "Headphone"); 3439 if (err < 0) 3440 return err; 3441 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg); 3442 if (err < 0) 3443 return err; 3444 3445 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 3446 3447 if (spec->autocfg.dig_out_pin) 3448 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID; 3449 if (spec->autocfg.dig_in_pin) 3450 spec->dig_in_nid = ALC880_DIGIN_NID; 3451 3452 if (spec->kctl_alloc) 3453 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 3454 3455 spec->init_verbs[spec->num_init_verbs++] = alc880_volume_init_verbs; 3456 3457 spec->num_mux_defs = 1; 3458 spec->input_mux = &spec->private_imux; 3459 3460 return 1; 3461} 3462 3463/* additional initialization for auto-configuration model */ 3464static void alc880_auto_init(struct hda_codec *codec) 3465{ 3466 alc880_auto_init_multi_out(codec); 3467 alc880_auto_init_extra_out(codec); 3468 alc880_auto_init_analog_input(codec); 3469} 3470 3471/* 3472 * OK, here we have finally the patch for ALC880 3473 */ 3474 3475static int patch_alc880(struct hda_codec *codec) 3476{ 3477 struct alc_spec *spec; 3478 int board_config; 3479 int err; 3480 3481 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 3482 if (spec == NULL) 3483 return -ENOMEM; 3484 3485 codec->spec = spec; 3486 3487 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST, 3488 alc880_models, 3489 alc880_cfg_tbl); 3490 if (board_config < 0) { 3491 printk(KERN_INFO "hda_codec: Unknown model for ALC880, " 3492 "trying auto-probe from BIOS...\n"); 3493 board_config = ALC880_AUTO; 3494 } 3495 3496 if (board_config == ALC880_AUTO) { 3497 /* automatic parse from the BIOS config */ 3498 err = alc880_parse_auto_config(codec); 3499 if (err < 0) { 3500 alc_free(codec); 3501 return err; 3502 } else if (!err) { 3503 printk(KERN_INFO 3504 "hda_codec: Cannot set up configuration " 3505 "from BIOS. Using 3-stack mode...\n"); 3506 board_config = ALC880_3ST; 3507 } 3508 } 3509 3510 if (board_config != ALC880_AUTO) 3511 setup_preset(spec, &alc880_presets[board_config]); 3512 3513 spec->stream_name_analog = "ALC880 Analog"; 3514 spec->stream_analog_playback = &alc880_pcm_analog_playback; 3515 spec->stream_analog_capture = &alc880_pcm_analog_capture; 3516 3517 spec->stream_name_digital = "ALC880 Digital"; 3518 spec->stream_digital_playback = &alc880_pcm_digital_playback; 3519 spec->stream_digital_capture = &alc880_pcm_digital_capture; 3520 3521 if (!spec->adc_nids && spec->input_mux) { 3522 /* check whether NID 0x07 is valid */ 3523 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]); 3524 /* get type */ 3525 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; 3526 if (wcap != AC_WID_AUD_IN) { 3527 spec->adc_nids = alc880_adc_nids_alt; 3528 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt); 3529 spec->mixers[spec->num_mixers] = 3530 alc880_capture_alt_mixer; 3531 spec->num_mixers++; 3532 } else { 3533 spec->adc_nids = alc880_adc_nids; 3534 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids); 3535 spec->mixers[spec->num_mixers] = alc880_capture_mixer; 3536 spec->num_mixers++; 3537 } 3538 } 3539 3540 codec->patch_ops = alc_patch_ops; 3541 if (board_config == ALC880_AUTO) 3542 spec->init_hook = alc880_auto_init; 3543#ifdef CONFIG_SND_HDA_POWER_SAVE 3544 if (!spec->loopback.amplist) 3545 spec->loopback.amplist = alc880_loopbacks; 3546#endif 3547 3548 return 0; 3549} 3550 3551 3552/* 3553 * ALC260 support 3554 */ 3555 3556static hda_nid_t alc260_dac_nids[1] = { 3557 /* front */ 3558 0x02, 3559}; 3560 3561static hda_nid_t alc260_adc_nids[1] = { 3562 /* ADC0 */ 3563 0x04, 3564}; 3565 3566static hda_nid_t alc260_adc_nids_alt[1] = { 3567 /* ADC1 */ 3568 0x05, 3569}; 3570 3571static hda_nid_t alc260_hp_adc_nids[2] = { 3572 /* ADC1, 0 */ 3573 0x05, 0x04 3574}; 3575 3576/* NIDs used when simultaneous access to both ADCs makes sense. Note that 3577 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC. 3578 */ 3579static hda_nid_t alc260_dual_adc_nids[2] = { 3580 /* ADC0, ADC1 */ 3581 0x04, 0x05 3582}; 3583 3584#define ALC260_DIGOUT_NID 0x03 3585#define ALC260_DIGIN_NID 0x06 3586 3587static struct hda_input_mux alc260_capture_source = { 3588 .num_items = 4, 3589 .items = { 3590 { "Mic", 0x0 }, 3591 { "Front Mic", 0x1 }, 3592 { "Line", 0x2 }, 3593 { "CD", 0x4 }, 3594 }, 3595}; 3596 3597/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack, 3598 * headphone jack and the internal CD lines since these are the only pins at 3599 * which audio can appear. For flexibility, also allow the option of 3600 * recording the mixer output on the second ADC (ADC0 doesn't have a 3601 * connection to the mixer output). 3602 */ 3603static struct hda_input_mux alc260_fujitsu_capture_sources[2] = { 3604 { 3605 .num_items = 3, 3606 .items = { 3607 { "Mic/Line", 0x0 }, 3608 { "CD", 0x4 }, 3609 { "Headphone", 0x2 }, 3610 }, 3611 }, 3612 { 3613 .num_items = 4, 3614 .items = { 3615 { "Mic/Line", 0x0 }, 3616 { "CD", 0x4 }, 3617 { "Headphone", 0x2 }, 3618 { "Mixer", 0x5 }, 3619 }, 3620 }, 3621 3622}; 3623 3624/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to 3625 * the Fujitsu S702x, but jacks are marked differently. 3626 */ 3627static struct hda_input_mux alc260_acer_capture_sources[2] = { 3628 { 3629 .num_items = 4, 3630 .items = { 3631 { "Mic", 0x0 }, 3632 { "Line", 0x2 }, 3633 { "CD", 0x4 }, 3634 { "Headphone", 0x5 }, 3635 }, 3636 }, 3637 { 3638 .num_items = 5, 3639 .items = { 3640 { "Mic", 0x0 }, 3641 { "Line", 0x2 }, 3642 { "CD", 0x4 }, 3643 { "Headphone", 0x6 }, 3644 { "Mixer", 0x5 }, 3645 }, 3646 }, 3647}; 3648/* 3649 * This is just place-holder, so there's something for alc_build_pcms to look 3650 * at when it calculates the maximum number of channels. ALC260 has no mixer 3651 * element which allows changing the channel mode, so the verb list is 3652 * never used. 3653 */ 3654static struct hda_channel_mode alc260_modes[1] = { 3655 { 2, NULL }, 3656}; 3657 3658 3659/* Mixer combinations 3660 * 3661 * basic: base_output + input + pc_beep + capture 3662 * HP: base_output + input + capture_alt 3663 * HP_3013: hp_3013 + input + capture 3664 * fujitsu: fujitsu + capture 3665 * acer: acer + capture 3666 */ 3667 3668static struct snd_kcontrol_new alc260_base_output_mixer[] = { 3669 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT), 3670 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT), 3671 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT), 3672 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT), 3673 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), 3674 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT), 3675 { } /* end */ 3676}; 3677 3678static struct snd_kcontrol_new alc260_input_mixer[] = { 3679 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), 3680 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), 3681 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), 3682 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT), 3683 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), 3684 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT), 3685 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT), 3686 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT), 3687 { } /* end */ 3688}; 3689 3690static struct snd_kcontrol_new alc260_pc_beep_mixer[] = { 3691 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT), 3692 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT), 3693 { } /* end */ 3694}; 3695 3696static struct snd_kcontrol_new alc260_hp_3013_mixer[] = { 3697 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT), 3698 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT), 3699 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT), 3700 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT), 3701 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT), 3702 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 3703 HDA_CODEC_VOLUME_MONO("iSpeaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), 3704 HDA_CODEC_MUTE_MONO("iSpeaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT), 3705 { } /* end */ 3706}; 3707 3708/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12, 3709 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10. 3710 */ 3711static struct snd_kcontrol_new alc260_fujitsu_mixer[] = { 3712 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT), 3713 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT), 3714 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT), 3715 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), 3716 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), 3717 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT), 3718 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT), 3719 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN), 3720 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT), 3721 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT), 3722 HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT), 3723 HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x09, 2, HDA_INPUT), 3724 { } /* end */ 3725}; 3726 3727/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current 3728 * versions of the ALC260 don't act on requests to enable mic bias from NID 3729 * 0x0f (used to drive the headphone jack in these laptops). The ALC260 3730 * datasheet doesn't mention this restriction. At this stage it's not clear 3731 * whether this behaviour is intentional or is a hardware bug in chip 3732 * revisions available in early 2006. Therefore for now allow the 3733 * "Headphone Jack Mode" control to span all choices, but if it turns out 3734 * that the lack of mic bias for this NID is intentional we could change the 3735 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS. 3736 * 3737 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006 3738 * don't appear to make the mic bias available from the "line" jack, even 3739 * though the NID used for this jack (0x14) can supply it. The theory is 3740 * that perhaps Acer have included blocking capacitors between the ALC260 3741 * and the output jack. If this turns out to be the case for all such 3742 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT 3743 * to ALC_PIN_DIR_INOUT_NOMICBIAS. 3744 * 3745 * The C20x Tablet series have a mono internal speaker which is controlled 3746 * via the chip's Mono sum widget and pin complex, so include the necessary 3747 * controls for such models. On models without a "mono speaker" the control 3748 * won't do anything. 3749 */ 3750static struct snd_kcontrol_new alc260_acer_mixer[] = { 3751 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), 3752 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT), 3753 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT), 3754 HDA_CODEC_VOLUME_MONO("Mono Speaker Playback Volume", 0x0a, 1, 0x0, 3755 HDA_OUTPUT), 3756 HDA_BIND_MUTE_MONO("Mono Speaker Playback Switch", 0x0a, 1, 2, 3757 HDA_INPUT), 3758 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), 3759 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), 3760 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), 3761 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT), 3762 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN), 3763 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), 3764 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT), 3765 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT), 3766 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT), 3767 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT), 3768 { } /* end */ 3769}; 3770 3771/* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12, 3772 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17. 3773 */ 3774static struct snd_kcontrol_new alc260_will_mixer[] = { 3775 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), 3776 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT), 3777 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), 3778 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT), 3779 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN), 3780 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), 3781 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT), 3782 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT), 3783 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), 3784 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), 3785 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT), 3786 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT), 3787 { } /* end */ 3788}; 3789 3790/* Replacer 672V ALC260 pin usage: Mic jack = 0x12, 3791 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f. 3792 */ 3793static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = { 3794 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), 3795 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT), 3796 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), 3797 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT), 3798 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN), 3799 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT), 3800 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT), 3801 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), 3802 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT), 3803 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT), 3804 { } /* end */ 3805}; 3806 3807/* capture mixer elements */ 3808static struct snd_kcontrol_new alc260_capture_mixer[] = { 3809 HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT), 3810 HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT), 3811 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x05, 0x0, HDA_INPUT), 3812 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x05, 0x0, HDA_INPUT), 3813 { 3814 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 3815 /* The multiple "Capture Source" controls confuse alsamixer 3816 * So call somewhat different.. 3817 * FIXME: the controls appear in the "playback" view! 3818 */ 3819 /* .name = "Capture Source", */ 3820 .name = "Input Source", 3821 .count = 2, 3822 .info = alc_mux_enum_info, 3823 .get = alc_mux_enum_get, 3824 .put = alc_mux_enum_put, 3825 }, 3826 { } /* end */ 3827}; 3828 3829static struct snd_kcontrol_new alc260_capture_alt_mixer[] = { 3830 HDA_CODEC_VOLUME("Capture Volume", 0x05, 0x0, HDA_INPUT), 3831 HDA_CODEC_MUTE("Capture Switch", 0x05, 0x0, HDA_INPUT), 3832 { 3833 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 3834 /* The multiple "Capture Source" controls confuse alsamixer 3835 * So call somewhat different.. 3836 * FIXME: the controls appear in the "playback" view! 3837 */ 3838 /* .name = "Capture Source", */ 3839 .name = "Input Source", 3840 .count = 1, 3841 .info = alc_mux_enum_info, 3842 .get = alc_mux_enum_get, 3843 .put = alc_mux_enum_put, 3844 }, 3845 { } /* end */ 3846}; 3847 3848/* 3849 * initialization verbs 3850 */ 3851static struct hda_verb alc260_init_verbs[] = { 3852 /* Line In pin widget for input */ 3853 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3854 /* CD pin widget for input */ 3855 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3856 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 3857 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3858 /* Mic2 (front panel) pin widget for input and vref at 80% */ 3859 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3860 /* LINE-2 is used for line-out in rear */ 3861 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3862 /* select line-out */ 3863 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00}, 3864 /* LINE-OUT pin */ 3865 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3866 /* enable HP */ 3867 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3868 /* enable Mono */ 3869 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3870 /* mute capture amp left and right */ 3871 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3872 /* set connection select to line in (default select for this ADC) */ 3873 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02}, 3874 /* mute capture amp left and right */ 3875 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3876 /* set connection select to line in (default select for this ADC) */ 3877 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02}, 3878 /* set vol=0 Line-Out mixer amp left and right */ 3879 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3880 /* unmute pin widget amp left and right (no gain on this amp) */ 3881 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3882 /* set vol=0 HP mixer amp left and right */ 3883 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3884 /* unmute pin widget amp left and right (no gain on this amp) */ 3885 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3886 /* set vol=0 Mono mixer amp left and right */ 3887 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3888 /* unmute pin widget amp left and right (no gain on this amp) */ 3889 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3890 /* unmute LINE-2 out pin */ 3891 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3892 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & 3893 * Line In 2 = 0x03 3894 */ 3895 /* mute analog inputs */ 3896 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3897 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 3898 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 3899 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 3900 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 3901 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */ 3902 /* mute Front out path */ 3903 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3904 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 3905 /* mute Headphone out path */ 3906 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3907 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 3908 /* mute Mono out path */ 3909 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3910 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 3911 { } 3912}; 3913 3914#if 0 /* should be identical with alc260_init_verbs? */ 3915static struct hda_verb alc260_hp_init_verbs[] = { 3916 /* Headphone and output */ 3917 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 3918 /* mono output */ 3919 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 3920 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 3921 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 3922 /* Mic2 (front panel) pin widget for input and vref at 80% */ 3923 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 3924 /* Line In pin widget for input */ 3925 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 3926 /* Line-2 pin widget for output */ 3927 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 3928 /* CD pin widget for input */ 3929 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 3930 /* unmute amp left and right */ 3931 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000}, 3932 /* set connection select to line in (default select for this ADC) */ 3933 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02}, 3934 /* unmute Line-Out mixer amp left and right (volume = 0) */ 3935 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 3936 /* mute pin widget amp left and right (no gain on this amp) */ 3937 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 3938 /* unmute HP mixer amp left and right (volume = 0) */ 3939 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 3940 /* mute pin widget amp left and right (no gain on this amp) */ 3941 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 3942 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & 3943 * Line In 2 = 0x03 3944 */ 3945 /* mute analog inputs */ 3946 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3947 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 3948 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 3949 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 3950 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 3951 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */ 3952 /* Unmute Front out path */ 3953 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 3954 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 3955 /* Unmute Headphone out path */ 3956 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 3957 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 3958 /* Unmute Mono out path */ 3959 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 3960 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 3961 { } 3962}; 3963#endif 3964 3965static struct hda_verb alc260_hp_3013_init_verbs[] = { 3966 /* Line out and output */ 3967 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 3968 /* mono output */ 3969 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 3970 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 3971 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 3972 /* Mic2 (front panel) pin widget for input and vref at 80% */ 3973 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 3974 /* Line In pin widget for input */ 3975 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 3976 /* Headphone pin widget for output */ 3977 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 3978 /* CD pin widget for input */ 3979 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 3980 /* unmute amp left and right */ 3981 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000}, 3982 /* set connection select to line in (default select for this ADC) */ 3983 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02}, 3984 /* unmute Line-Out mixer amp left and right (volume = 0) */ 3985 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 3986 /* mute pin widget amp left and right (no gain on this amp) */ 3987 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 3988 /* unmute HP mixer amp left and right (volume = 0) */ 3989 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 3990 /* mute pin widget amp left and right (no gain on this amp) */ 3991 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 3992 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & 3993 * Line In 2 = 0x03 3994 */ 3995 /* mute analog inputs */ 3996 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3997 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 3998 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 3999 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 4000 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 4001 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */ 4002 /* Unmute Front out path */ 4003 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 4004 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 4005 /* Unmute Headphone out path */ 4006 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 4007 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 4008 /* Unmute Mono out path */ 4009 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 4010 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 4011 { } 4012}; 4013 4014/* Initialisation sequence for ALC260 as configured in Fujitsu S702x 4015 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD 4016 * audio = 0x16, internal speaker = 0x10. 4017 */ 4018static struct hda_verb alc260_fujitsu_init_verbs[] = { 4019 /* Disable all GPIOs */ 4020 {0x01, AC_VERB_SET_GPIO_MASK, 0}, 4021 /* Internal speaker is connected to headphone pin */ 4022 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 4023 /* Headphone/Line-out jack connects to Line1 pin; make it an output */ 4024 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4025 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */ 4026 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 4027 /* Ensure all other unused pins are disabled and muted. */ 4028 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 4029 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4030 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 4031 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4032 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 4033 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4034 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 4035 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4036 4037 /* Disable digital (SPDIF) pins */ 4038 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0}, 4039 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0}, 4040 4041 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus 4042 * when acting as an output. 4043 */ 4044 {0x0d, AC_VERB_SET_CONNECT_SEL, 0}, 4045 4046 /* Start with output sum widgets muted and their output gains at min */ 4047 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4048 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4049 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4050 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4051 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4052 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4053 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4054 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4055 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4056 4057 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */ 4058 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4059 /* Unmute Line1 pin widget output buffer since it starts as an output. 4060 * If the pin mode is changed by the user the pin mode control will 4061 * take care of enabling the pin's input/output buffers as needed. 4062 * Therefore there's no need to enable the input buffer at this 4063 * stage. 4064 */ 4065 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4066 /* Unmute input buffer of pin widget used for Line-in (no equiv 4067 * mixer ctrl) 4068 */ 4069 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4070 4071 /* Mute capture amp left and right */ 4072 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4073 /* Set ADC connection select to match default mixer setting - line 4074 * in (on mic1 pin) 4075 */ 4076 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, 4077 4078 /* Do the same for the second ADC: mute capture input amp and 4079 * set ADC connection to line in (on mic1 pin) 4080 */ 4081 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4082 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, 4083 4084 /* Mute all inputs to mixer widget (even unconnected ones) */ 4085 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */ 4086 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */ 4087 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */ 4088 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */ 4089 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */ 4090 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */ 4091 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */ 4092 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */ 4093 4094 { } 4095}; 4096 4097/* Initialisation sequence for ALC260 as configured in Acer TravelMate and 4098 * similar laptops (adapted from Fujitsu init verbs). 4099 */ 4100static struct hda_verb alc260_acer_init_verbs[] = { 4101 /* On TravelMate laptops, GPIO 0 enables the internal speaker and 4102 * the headphone jack. Turn this on and rely on the standard mute 4103 * methods whenever the user wants to turn these outputs off. 4104 */ 4105 {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, 4106 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, 4107 {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, 4108 /* Internal speaker/Headphone jack is connected to Line-out pin */ 4109 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 4110 /* Internal microphone/Mic jack is connected to Mic1 pin */ 4111 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, 4112 /* Line In jack is connected to Line1 pin */ 4113 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 4114 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */ 4115 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 4116 /* Ensure all other unused pins are disabled and muted. */ 4117 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 4118 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4119 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 4120 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4121 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 4122 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4123 /* Disable digital (SPDIF) pins */ 4124 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0}, 4125 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0}, 4126 4127 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum 4128 * bus when acting as outputs. 4129 */ 4130 {0x0b, AC_VERB_SET_CONNECT_SEL, 0}, 4131 {0x0d, AC_VERB_SET_CONNECT_SEL, 0}, 4132 4133 /* Start with output sum widgets muted and their output gains at min */ 4134 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4135 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4136 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4137 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4138 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4139 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4140 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4141 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4142 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4143 4144 /* Unmute Line-out pin widget amp left and right 4145 * (no equiv mixer ctrl) 4146 */ 4147 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4148 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */ 4149 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4150 /* Unmute Mic1 and Line1 pin widget input buffers since they start as 4151 * inputs. If the pin mode is changed by the user the pin mode control 4152 * will take care of enabling the pin's input/output buffers as needed. 4153 * Therefore there's no need to enable the input buffer at this 4154 * stage. 4155 */ 4156 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4157 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4158 4159 /* Mute capture amp left and right */ 4160 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4161 /* Set ADC connection select to match default mixer setting - mic 4162 * (on mic1 pin) 4163 */ 4164 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, 4165 4166 /* Do similar with the second ADC: mute capture input amp and 4167 * set ADC connection to mic to match ALSA's default state. 4168 */ 4169 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4170 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, 4171 4172 /* Mute all inputs to mixer widget (even unconnected ones) */ 4173 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */ 4174 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */ 4175 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */ 4176 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */ 4177 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */ 4178 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */ 4179 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */ 4180 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */ 4181 4182 { } 4183}; 4184 4185static struct hda_verb alc260_will_verbs[] = { 4186 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 4187 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00}, 4188 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00}, 4189 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02}, 4190 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07}, 4191 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040}, 4192 {} 4193}; 4194 4195static struct hda_verb alc260_replacer_672v_verbs[] = { 4196 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02}, 4197 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07}, 4198 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050}, 4199 4200 {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, 4201 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, 4202 {0x01, AC_VERB_SET_GPIO_DATA, 0x00}, 4203 4204 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 4205 {} 4206}; 4207 4208/* toggle speaker-output according to the hp-jack state */ 4209static void alc260_replacer_672v_automute(struct hda_codec *codec) 4210{ 4211 unsigned int present; 4212 4213 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */ 4214 present = snd_hda_codec_read(codec, 0x0f, 0, 4215 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 4216 if (present) { 4217 snd_hda_codec_write_cache(codec, 0x01, 0, 4218 AC_VERB_SET_GPIO_DATA, 1); 4219 snd_hda_codec_write_cache(codec, 0x0f, 0, 4220 AC_VERB_SET_PIN_WIDGET_CONTROL, 4221 PIN_HP); 4222 } else { 4223 snd_hda_codec_write_cache(codec, 0x01, 0, 4224 AC_VERB_SET_GPIO_DATA, 0); 4225 snd_hda_codec_write_cache(codec, 0x0f, 0, 4226 AC_VERB_SET_PIN_WIDGET_CONTROL, 4227 PIN_OUT); 4228 } 4229} 4230 4231static void alc260_replacer_672v_unsol_event(struct hda_codec *codec, 4232 unsigned int res) 4233{ 4234 if ((res >> 26) == ALC880_HP_EVENT) 4235 alc260_replacer_672v_automute(codec); 4236} 4237 4238/* Test configuration for debugging, modelled after the ALC880 test 4239 * configuration. 4240 */ 4241#ifdef CONFIG_SND_DEBUG 4242static hda_nid_t alc260_test_dac_nids[1] = { 4243 0x02, 4244}; 4245static hda_nid_t alc260_test_adc_nids[2] = { 4246 0x04, 0x05, 4247}; 4248/* For testing the ALC260, each input MUX needs its own definition since 4249 * the signal assignments are different. This assumes that the first ADC 4250 * is NID 0x04. 4251 */ 4252static struct hda_input_mux alc260_test_capture_sources[2] = { 4253 { 4254 .num_items = 7, 4255 .items = { 4256 { "MIC1 pin", 0x0 }, 4257 { "MIC2 pin", 0x1 }, 4258 { "LINE1 pin", 0x2 }, 4259 { "LINE2 pin", 0x3 }, 4260 { "CD pin", 0x4 }, 4261 { "LINE-OUT pin", 0x5 }, 4262 { "HP-OUT pin", 0x6 }, 4263 }, 4264 }, 4265 { 4266 .num_items = 8, 4267 .items = { 4268 { "MIC1 pin", 0x0 }, 4269 { "MIC2 pin", 0x1 }, 4270 { "LINE1 pin", 0x2 }, 4271 { "LINE2 pin", 0x3 }, 4272 { "CD pin", 0x4 }, 4273 { "Mixer", 0x5 }, 4274 { "LINE-OUT pin", 0x6 }, 4275 { "HP-OUT pin", 0x7 }, 4276 }, 4277 }, 4278}; 4279static struct snd_kcontrol_new alc260_test_mixer[] = { 4280 /* Output driver widgets */ 4281 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), 4282 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT), 4283 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT), 4284 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT), 4285 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT), 4286 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT), 4287 4288 /* Modes for retasking pin widgets 4289 * Note: the ALC260 doesn't seem to act on requests to enable mic 4290 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't 4291 * mention this restriction. At this stage it's not clear whether 4292 * this behaviour is intentional or is a hardware bug in chip 4293 * revisions available at least up until early 2006. Therefore for 4294 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all 4295 * choices, but if it turns out that the lack of mic bias for these 4296 * NIDs is intentional we could change their modes from 4297 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS. 4298 */ 4299 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT), 4300 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT), 4301 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT), 4302 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT), 4303 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT), 4304 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT), 4305 4306 /* Loopback mixer controls */ 4307 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT), 4308 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT), 4309 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT), 4310 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT), 4311 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT), 4312 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT), 4313 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT), 4314 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT), 4315 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), 4316 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), 4317 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT), 4318 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT), 4319 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT), 4320 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT), 4321 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT), 4322 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT), 4323 4324 /* Controls for GPIO pins, assuming they are configured as outputs */ 4325 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01), 4326 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02), 4327 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04), 4328 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08), 4329 4330 /* Switches to allow the digital IO pins to be enabled. The datasheet 4331 * is ambigious as to which NID is which; testing on laptops which 4332 * make this output available should provide clarification. 4333 */ 4334 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01), 4335 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01), 4336 4337 { } /* end */ 4338}; 4339static struct hda_verb alc260_test_init_verbs[] = { 4340 /* Enable all GPIOs as outputs with an initial value of 0 */ 4341 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f}, 4342 {0x01, AC_VERB_SET_GPIO_DATA, 0x00}, 4343 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f}, 4344 4345 /* Enable retasking pins as output, initially without power amp */ 4346 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4347 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4348 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4349 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4350 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4351 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4352 4353 /* Disable digital (SPDIF) pins initially, but users can enable 4354 * them via a mixer switch. In the case of SPDIF-out, this initverb 4355 * payload also sets the generation to 0, output to be in "consumer" 4356 * PCM format, copyright asserted, no pre-emphasis and no validity 4357 * control. 4358 */ 4359 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0}, 4360 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0}, 4361 4362 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the 4363 * OUT1 sum bus when acting as an output. 4364 */ 4365 {0x0b, AC_VERB_SET_CONNECT_SEL, 0}, 4366 {0x0c, AC_VERB_SET_CONNECT_SEL, 0}, 4367 {0x0d, AC_VERB_SET_CONNECT_SEL, 0}, 4368 {0x0e, AC_VERB_SET_CONNECT_SEL, 0}, 4369 4370 /* Start with output sum widgets muted and their output gains at min */ 4371 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4372 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4373 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4374 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4375 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4376 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4377 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4378 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4379 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4380 4381 /* Unmute retasking pin widget output buffers since the default 4382 * state appears to be output. As the pin mode is changed by the 4383 * user the pin mode control will take care of enabling the pin's 4384 * input/output buffers as needed. 4385 */ 4386 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4387 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4388 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4389 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4390 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4391 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4392 /* Also unmute the mono-out pin widget */ 4393 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4394 4395 /* Mute capture amp left and right */ 4396 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4397 /* Set ADC connection select to match default mixer setting (mic1 4398 * pin) 4399 */ 4400 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, 4401 4402 /* Do the same for the second ADC: mute capture input amp and 4403 * set ADC connection to mic1 pin 4404 */ 4405 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4406 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, 4407 4408 /* Mute all inputs to mixer widget (even unconnected ones) */ 4409 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */ 4410 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */ 4411 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */ 4412 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */ 4413 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */ 4414 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */ 4415 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */ 4416 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */ 4417 4418 { } 4419}; 4420#endif 4421 4422static struct hda_pcm_stream alc260_pcm_analog_playback = { 4423 .substreams = 1, 4424 .channels_min = 2, 4425 .channels_max = 2, 4426}; 4427 4428static struct hda_pcm_stream alc260_pcm_analog_capture = { 4429 .substreams = 1, 4430 .channels_min = 2, 4431 .channels_max = 2, 4432}; 4433 4434#define alc260_pcm_digital_playback alc880_pcm_digital_playback 4435#define alc260_pcm_digital_capture alc880_pcm_digital_capture 4436 4437/* 4438 * for BIOS auto-configuration 4439 */ 4440 4441static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid, 4442 const char *pfx) 4443{ 4444 hda_nid_t nid_vol; 4445 unsigned long vol_val, sw_val; 4446 char name[32]; 4447 int err; 4448 4449 if (nid >= 0x0f && nid < 0x11) { 4450 nid_vol = nid - 0x7; 4451 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT); 4452 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT); 4453 } else if (nid == 0x11) { 4454 nid_vol = nid - 0x7; 4455 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT); 4456 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT); 4457 } else if (nid >= 0x12 && nid <= 0x15) { 4458 nid_vol = 0x08; 4459 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT); 4460 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT); 4461 } else 4462 return 0; /* N/A */ 4463 4464 snprintf(name, sizeof(name), "%s Playback Volume", pfx); 4465 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val); 4466 if (err < 0) 4467 return err; 4468 snprintf(name, sizeof(name), "%s Playback Switch", pfx); 4469 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val); 4470 if (err < 0) 4471 return err; 4472 return 1; 4473} 4474 4475/* add playback controls from the parsed DAC table */ 4476static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec, 4477 const struct auto_pin_cfg *cfg) 4478{ 4479 hda_nid_t nid; 4480 int err; 4481 4482 spec->multiout.num_dacs = 1; 4483 spec->multiout.dac_nids = spec->private_dac_nids; 4484 spec->multiout.dac_nids[0] = 0x02; 4485 4486 nid = cfg->line_out_pins[0]; 4487 if (nid) { 4488 err = alc260_add_playback_controls(spec, nid, "Front"); 4489 if (err < 0) 4490 return err; 4491 } 4492 4493 nid = cfg->speaker_pins[0]; 4494 if (nid) { 4495 err = alc260_add_playback_controls(spec, nid, "Speaker"); 4496 if (err < 0) 4497 return err; 4498 } 4499 4500 nid = cfg->hp_pins[0]; 4501 if (nid) { 4502 err = alc260_add_playback_controls(spec, nid, "Headphone"); 4503 if (err < 0) 4504 return err; 4505 } 4506 return 0; 4507} 4508 4509/* create playback/capture controls for input pins */ 4510static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec, 4511 const struct auto_pin_cfg *cfg) 4512{ 4513 struct hda_input_mux *imux = &spec->private_imux; 4514 int i, err, idx; 4515 4516 for (i = 0; i < AUTO_PIN_LAST; i++) { 4517 if (cfg->input_pins[i] >= 0x12) { 4518 idx = cfg->input_pins[i] - 0x12; 4519 err = new_analog_input(spec, cfg->input_pins[i], 4520 auto_pin_cfg_labels[i], idx, 4521 0x07); 4522 if (err < 0) 4523 return err; 4524 imux->items[imux->num_items].label = 4525 auto_pin_cfg_labels[i]; 4526 imux->items[imux->num_items].index = idx; 4527 imux->num_items++; 4528 } 4529 if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){ 4530 idx = cfg->input_pins[i] - 0x09; 4531 err = new_analog_input(spec, cfg->input_pins[i], 4532 auto_pin_cfg_labels[i], idx, 4533 0x07); 4534 if (err < 0) 4535 return err; 4536 imux->items[imux->num_items].label = 4537 auto_pin_cfg_labels[i]; 4538 imux->items[imux->num_items].index = idx; 4539 imux->num_items++; 4540 } 4541 } 4542 return 0; 4543} 4544 4545static void alc260_auto_set_output_and_unmute(struct hda_codec *codec, 4546 hda_nid_t nid, int pin_type, 4547 int sel_idx) 4548{ 4549 /* set as output */ 4550 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 4551 pin_type); 4552 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, 4553 AMP_OUT_UNMUTE); 4554 /* need the manual connection? */ 4555 if (nid >= 0x12) { 4556 int idx = nid - 0x12; 4557 snd_hda_codec_write(codec, idx + 0x0b, 0, 4558 AC_VERB_SET_CONNECT_SEL, sel_idx); 4559 } 4560} 4561 4562static void alc260_auto_init_multi_out(struct hda_codec *codec) 4563{ 4564 struct alc_spec *spec = codec->spec; 4565 hda_nid_t nid; 4566 4567 alc_subsystem_id(codec, 0x10, 0x15, 0x0f); 4568 nid = spec->autocfg.line_out_pins[0]; 4569 if (nid) { 4570 int pin_type = get_pin_type(spec->autocfg.line_out_type); 4571 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0); 4572 } 4573 4574 nid = spec->autocfg.speaker_pins[0]; 4575 if (nid) 4576 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0); 4577 4578 nid = spec->autocfg.hp_pins[0]; 4579 if (nid) 4580 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0); 4581} 4582 4583#define ALC260_PIN_CD_NID 0x16 4584static void alc260_auto_init_analog_input(struct hda_codec *codec) 4585{ 4586 struct alc_spec *spec = codec->spec; 4587 int i; 4588 4589 for (i = 0; i < AUTO_PIN_LAST; i++) { 4590 hda_nid_t nid = spec->autocfg.input_pins[i]; 4591 if (nid >= 0x12) { 4592 snd_hda_codec_write(codec, nid, 0, 4593 AC_VERB_SET_PIN_WIDGET_CONTROL, 4594 i <= AUTO_PIN_FRONT_MIC ? 4595 PIN_VREF80 : PIN_IN); 4596 if (nid != ALC260_PIN_CD_NID) 4597 snd_hda_codec_write(codec, nid, 0, 4598 AC_VERB_SET_AMP_GAIN_MUTE, 4599 AMP_OUT_MUTE); 4600 } 4601 } 4602} 4603 4604/* 4605 * generic initialization of ADC, input mixers and output mixers 4606 */ 4607static struct hda_verb alc260_volume_init_verbs[] = { 4608 /* 4609 * Unmute ADC0-1 and set the default input to mic-in 4610 */ 4611 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, 4612 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4613 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, 4614 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4615 4616 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 4617 * mixer widget 4618 * Note: PASD motherboards uses the Line In 2 as the input for 4619 * front panel mic (mic 2) 4620 */ 4621 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 4622 /* mute analog inputs */ 4623 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4624 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4625 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 4626 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 4627 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 4628 4629 /* 4630 * Set up output mixers (0x08 - 0x0a) 4631 */ 4632 /* set vol=0 to output mixers */ 4633 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4634 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4635 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4636 /* set up input amps for analog loopback */ 4637 /* Amp Indices: DAC = 0, mixer = 1 */ 4638 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4639 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4640 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4641 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4642 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4643 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4644 4645 { } 4646}; 4647 4648static int alc260_parse_auto_config(struct hda_codec *codec) 4649{ 4650 struct alc_spec *spec = codec->spec; 4651 unsigned int wcap; 4652 int err; 4653 static hda_nid_t alc260_ignore[] = { 0x17, 0 }; 4654 4655 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 4656 alc260_ignore); 4657 if (err < 0) 4658 return err; 4659 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg); 4660 if (err < 0) 4661 return err; 4662 if (!spec->kctl_alloc) 4663 return 0; /* can't find valid BIOS pin config */ 4664 err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg); 4665 if (err < 0) 4666 return err; 4667 4668 spec->multiout.max_channels = 2; 4669 4670 if (spec->autocfg.dig_out_pin) 4671 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID; 4672 if (spec->kctl_alloc) 4673 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 4674 4675 spec->init_verbs[spec->num_init_verbs++] = alc260_volume_init_verbs; 4676 4677 spec->num_mux_defs = 1; 4678 spec->input_mux = &spec->private_imux; 4679 4680 /* check whether NID 0x04 is valid */ 4681 wcap = get_wcaps(codec, 0x04); 4682 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */ 4683 if (wcap != AC_WID_AUD_IN) { 4684 spec->adc_nids = alc260_adc_nids_alt; 4685 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt); 4686 spec->mixers[spec->num_mixers] = alc260_capture_alt_mixer; 4687 } else { 4688 spec->adc_nids = alc260_adc_nids; 4689 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids); 4690 spec->mixers[spec->num_mixers] = alc260_capture_mixer; 4691 } 4692 spec->num_mixers++; 4693 4694 return 1; 4695} 4696 4697/* additional initialization for auto-configuration model */ 4698static void alc260_auto_init(struct hda_codec *codec) 4699{ 4700 alc260_auto_init_multi_out(codec); 4701 alc260_auto_init_analog_input(codec); 4702} 4703 4704#ifdef CONFIG_SND_HDA_POWER_SAVE 4705static struct hda_amp_list alc260_loopbacks[] = { 4706 { 0x07, HDA_INPUT, 0 }, 4707 { 0x07, HDA_INPUT, 1 }, 4708 { 0x07, HDA_INPUT, 2 }, 4709 { 0x07, HDA_INPUT, 3 }, 4710 { 0x07, HDA_INPUT, 4 }, 4711 { } /* end */ 4712}; 4713#endif 4714 4715/* 4716 * ALC260 configurations 4717 */ 4718static const char *alc260_models[ALC260_MODEL_LAST] = { 4719 [ALC260_BASIC] = "basic", 4720 [ALC260_HP] = "hp", 4721 [ALC260_HP_3013] = "hp-3013", 4722 [ALC260_FUJITSU_S702X] = "fujitsu", 4723 [ALC260_ACER] = "acer", 4724 [ALC260_WILL] = "will", 4725 [ALC260_REPLACER_672V] = "replacer", 4726#ifdef CONFIG_SND_DEBUG 4727 [ALC260_TEST] = "test", 4728#endif 4729 [ALC260_AUTO] = "auto", 4730}; 4731 4732static struct snd_pci_quirk alc260_cfg_tbl[] = { 4733 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER), 4734 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER), 4735 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013), 4736 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013), 4737 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013), 4738 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP), 4739 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_3013), 4740 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013), 4741 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP), 4742 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP), 4743 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP), 4744 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC), 4745 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC), 4746 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC), 4747 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X), 4748 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC), 4749 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL), 4750 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V), 4751 {} 4752}; 4753 4754static struct alc_config_preset alc260_presets[] = { 4755 [ALC260_BASIC] = { 4756 .mixers = { alc260_base_output_mixer, 4757 alc260_input_mixer, 4758 alc260_pc_beep_mixer, 4759 alc260_capture_mixer }, 4760 .init_verbs = { alc260_init_verbs }, 4761 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 4762 .dac_nids = alc260_dac_nids, 4763 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids), 4764 .adc_nids = alc260_adc_nids, 4765 .num_channel_mode = ARRAY_SIZE(alc260_modes), 4766 .channel_mode = alc260_modes, 4767 .input_mux = &alc260_capture_source, 4768 }, 4769 [ALC260_HP] = { 4770 .mixers = { alc260_base_output_mixer, 4771 alc260_input_mixer, 4772 alc260_capture_alt_mixer }, 4773 .init_verbs = { alc260_init_verbs }, 4774 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 4775 .dac_nids = alc260_dac_nids, 4776 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids), 4777 .adc_nids = alc260_hp_adc_nids, 4778 .num_channel_mode = ARRAY_SIZE(alc260_modes), 4779 .channel_mode = alc260_modes, 4780 .input_mux = &alc260_capture_source, 4781 }, 4782 [ALC260_HP_3013] = { 4783 .mixers = { alc260_hp_3013_mixer, 4784 alc260_input_mixer, 4785 alc260_capture_alt_mixer }, 4786 .init_verbs = { alc260_hp_3013_init_verbs }, 4787 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 4788 .dac_nids = alc260_dac_nids, 4789 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids), 4790 .adc_nids = alc260_hp_adc_nids, 4791 .num_channel_mode = ARRAY_SIZE(alc260_modes), 4792 .channel_mode = alc260_modes, 4793 .input_mux = &alc260_capture_source, 4794 }, 4795 [ALC260_FUJITSU_S702X] = { 4796 .mixers = { alc260_fujitsu_mixer, 4797 alc260_capture_mixer }, 4798 .init_verbs = { alc260_fujitsu_init_verbs }, 4799 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 4800 .dac_nids = alc260_dac_nids, 4801 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids), 4802 .adc_nids = alc260_dual_adc_nids, 4803 .num_channel_mode = ARRAY_SIZE(alc260_modes), 4804 .channel_mode = alc260_modes, 4805 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources), 4806 .input_mux = alc260_fujitsu_capture_sources, 4807 }, 4808 [ALC260_ACER] = { 4809 .mixers = { alc260_acer_mixer, 4810 alc260_capture_mixer }, 4811 .init_verbs = { alc260_acer_init_verbs }, 4812 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 4813 .dac_nids = alc260_dac_nids, 4814 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids), 4815 .adc_nids = alc260_dual_adc_nids, 4816 .num_channel_mode = ARRAY_SIZE(alc260_modes), 4817 .channel_mode = alc260_modes, 4818 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources), 4819 .input_mux = alc260_acer_capture_sources, 4820 }, 4821 [ALC260_WILL] = { 4822 .mixers = { alc260_will_mixer, 4823 alc260_capture_mixer }, 4824 .init_verbs = { alc260_init_verbs, alc260_will_verbs }, 4825 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 4826 .dac_nids = alc260_dac_nids, 4827 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids), 4828 .adc_nids = alc260_adc_nids, 4829 .dig_out_nid = ALC260_DIGOUT_NID, 4830 .num_channel_mode = ARRAY_SIZE(alc260_modes), 4831 .channel_mode = alc260_modes, 4832 .input_mux = &alc260_capture_source, 4833 }, 4834 [ALC260_REPLACER_672V] = { 4835 .mixers = { alc260_replacer_672v_mixer, 4836 alc260_capture_mixer }, 4837 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs }, 4838 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 4839 .dac_nids = alc260_dac_nids, 4840 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids), 4841 .adc_nids = alc260_adc_nids, 4842 .dig_out_nid = ALC260_DIGOUT_NID, 4843 .num_channel_mode = ARRAY_SIZE(alc260_modes), 4844 .channel_mode = alc260_modes, 4845 .input_mux = &alc260_capture_source, 4846 .unsol_event = alc260_replacer_672v_unsol_event, 4847 .init_hook = alc260_replacer_672v_automute, 4848 }, 4849#ifdef CONFIG_SND_DEBUG 4850 [ALC260_TEST] = { 4851 .mixers = { alc260_test_mixer, 4852 alc260_capture_mixer }, 4853 .init_verbs = { alc260_test_init_verbs }, 4854 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids), 4855 .dac_nids = alc260_test_dac_nids, 4856 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids), 4857 .adc_nids = alc260_test_adc_nids, 4858 .num_channel_mode = ARRAY_SIZE(alc260_modes), 4859 .channel_mode = alc260_modes, 4860 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources), 4861 .input_mux = alc260_test_capture_sources, 4862 }, 4863#endif 4864}; 4865 4866static int patch_alc260(struct hda_codec *codec) 4867{ 4868 struct alc_spec *spec; 4869 int err, board_config; 4870 4871 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 4872 if (spec == NULL) 4873 return -ENOMEM; 4874 4875 codec->spec = spec; 4876 4877 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST, 4878 alc260_models, 4879 alc260_cfg_tbl); 4880 if (board_config < 0) { 4881 snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, " 4882 "trying auto-probe from BIOS...\n"); 4883 board_config = ALC260_AUTO; 4884 } 4885 4886 if (board_config == ALC260_AUTO) { 4887 /* automatic parse from the BIOS config */ 4888 err = alc260_parse_auto_config(codec); 4889 if (err < 0) { 4890 alc_free(codec); 4891 return err; 4892 } else if (!err) { 4893 printk(KERN_INFO 4894 "hda_codec: Cannot set up configuration " 4895 "from BIOS. Using base mode...\n"); 4896 board_config = ALC260_BASIC; 4897 } 4898 } 4899 4900 if (board_config != ALC260_AUTO) 4901 setup_preset(spec, &alc260_presets[board_config]); 4902 4903 spec->stream_name_analog = "ALC260 Analog"; 4904 spec->stream_analog_playback = &alc260_pcm_analog_playback; 4905 spec->stream_analog_capture = &alc260_pcm_analog_capture; 4906 4907 spec->stream_name_digital = "ALC260 Digital"; 4908 spec->stream_digital_playback = &alc260_pcm_digital_playback; 4909 spec->stream_digital_capture = &alc260_pcm_digital_capture; 4910 4911 codec->patch_ops = alc_patch_ops; 4912 if (board_config == ALC260_AUTO) 4913 spec->init_hook = alc260_auto_init; 4914#ifdef CONFIG_SND_HDA_POWER_SAVE 4915 if (!spec->loopback.amplist) 4916 spec->loopback.amplist = alc260_loopbacks; 4917#endif 4918 4919 return 0; 4920} 4921 4922 4923/* 4924 * ALC882 support 4925 * 4926 * ALC882 is almost identical with ALC880 but has cleaner and more flexible 4927 * configuration. Each pin widget can choose any input DACs and a mixer. 4928 * Each ADC is connected from a mixer of all inputs. This makes possible 4929 * 6-channel independent captures. 4930 * 4931 * In addition, an independent DAC for the multi-playback (not used in this 4932 * driver yet). 4933 */ 4934#define ALC882_DIGOUT_NID 0x06 4935#define ALC882_DIGIN_NID 0x0a 4936 4937static struct hda_channel_mode alc882_ch_modes[1] = { 4938 { 8, NULL } 4939}; 4940 4941static hda_nid_t alc882_dac_nids[4] = { 4942 /* front, rear, clfe, rear_surr */ 4943 0x02, 0x03, 0x04, 0x05 4944}; 4945 4946/* identical with ALC880 */ 4947#define alc882_adc_nids alc880_adc_nids 4948#define alc882_adc_nids_alt alc880_adc_nids_alt 4949 4950/* input MUX */ 4951/* FIXME: should be a matrix-type input source selection */ 4952 4953static struct hda_input_mux alc882_capture_source = { 4954 .num_items = 4, 4955 .items = { 4956 { "Mic", 0x0 }, 4957 { "Front Mic", 0x1 }, 4958 { "Line", 0x2 }, 4959 { "CD", 0x4 }, 4960 }, 4961}; 4962#define alc882_mux_enum_info alc_mux_enum_info 4963#define alc882_mux_enum_get alc_mux_enum_get 4964 4965static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol, 4966 struct snd_ctl_elem_value *ucontrol) 4967{ 4968 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 4969 struct alc_spec *spec = codec->spec; 4970 const struct hda_input_mux *imux = spec->input_mux; 4971 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 4972 static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 }; 4973 hda_nid_t nid = capture_mixers[adc_idx]; 4974 unsigned int *cur_val = &spec->cur_mux[adc_idx]; 4975 unsigned int i, idx; 4976 4977 idx = ucontrol->value.enumerated.item[0]; 4978 if (idx >= imux->num_items) 4979 idx = imux->num_items - 1; 4980 if (*cur_val == idx) 4981 return 0; 4982 for (i = 0; i < imux->num_items; i++) { 4983 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE; 4984 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 4985 imux->items[i].index, 4986 HDA_AMP_MUTE, v); 4987 } 4988 *cur_val = idx; 4989 return 1; 4990} 4991 4992/* 4993 * 2ch mode 4994 */ 4995static struct hda_verb alc882_3ST_ch2_init[] = { 4996 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 4997 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 4998 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 4999 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 5000 { } /* end */ 5001}; 5002 5003/* 5004 * 6ch mode 5005 */ 5006static struct hda_verb alc882_3ST_ch6_init[] = { 5007 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 5008 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 5009 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, 5010 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 5011 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 5012 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 5013 { } /* end */ 5014}; 5015 5016static struct hda_channel_mode alc882_3ST_6ch_modes[2] = { 5017 { 2, alc882_3ST_ch2_init }, 5018 { 6, alc882_3ST_ch6_init }, 5019}; 5020 5021/* 5022 * 6ch mode 5023 */ 5024static struct hda_verb alc882_sixstack_ch6_init[] = { 5025 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 5026 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 5027 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 5028 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 5029 { } /* end */ 5030}; 5031 5032/* 5033 * 8ch mode 5034 */ 5035static struct hda_verb alc882_sixstack_ch8_init[] = { 5036 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 5037 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 5038 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 5039 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 5040 { } /* end */ 5041}; 5042 5043static struct hda_channel_mode alc882_sixstack_modes[2] = { 5044 { 6, alc882_sixstack_ch6_init }, 5045 { 8, alc882_sixstack_ch8_init }, 5046}; 5047 5048/* 5049 * macbook pro ALC885 can switch LineIn to LineOut without loosing Mic 5050 */ 5051 5052/* 5053 * 2ch mode 5054 */ 5055static struct hda_verb alc885_mbp_ch2_init[] = { 5056 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 5057 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5058 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 5059 { } /* end */ 5060}; 5061 5062/* 5063 * 6ch mode 5064 */ 5065static struct hda_verb alc885_mbp_ch6_init[] = { 5066 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 5067 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5068 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 5069 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5070 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 5071 { } /* end */ 5072}; 5073 5074static struct hda_channel_mode alc885_mbp_6ch_modes[2] = { 5075 { 2, alc885_mbp_ch2_init }, 5076 { 6, alc885_mbp_ch6_init }, 5077}; 5078 5079 5080/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 5081 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b 5082 */ 5083static struct snd_kcontrol_new alc882_base_mixer[] = { 5084 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 5085 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 5086 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 5087 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 5088 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 5089 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 5090 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 5091 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 5092 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 5093 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 5094 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 5095 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 5096 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 5097 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 5098 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 5099 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 5100 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 5101 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 5102 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 5103 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 5104 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 5105 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 5106 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 5107 { } /* end */ 5108}; 5109 5110static struct snd_kcontrol_new alc885_mbp3_mixer[] = { 5111 HDA_CODEC_VOLUME("Master Volume", 0x0c, 0x00, HDA_OUTPUT), 5112 HDA_BIND_MUTE ("Master Switch", 0x0c, 0x02, HDA_INPUT), 5113 HDA_CODEC_MUTE ("Speaker Switch", 0x14, 0x00, HDA_OUTPUT), 5114 HDA_CODEC_VOLUME("Line Out Volume", 0x0d,0x00, HDA_OUTPUT), 5115 HDA_CODEC_VOLUME("Line In Playback Volume", 0x0b, 0x02, HDA_INPUT), 5116 HDA_CODEC_MUTE ("Line In Playback Switch", 0x0b, 0x02, HDA_INPUT), 5117 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT), 5118 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT), 5119 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0x00, HDA_INPUT), 5120 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT), 5121 { } /* end */ 5122}; 5123static struct snd_kcontrol_new alc882_w2jc_mixer[] = { 5124 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 5125 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 5126 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 5127 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 5128 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 5129 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 5130 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 5131 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 5132 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 5133 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 5134 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 5135 { } /* end */ 5136}; 5137 5138static struct snd_kcontrol_new alc882_targa_mixer[] = { 5139 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 5140 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 5141 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 5142 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 5143 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 5144 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 5145 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 5146 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 5147 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 5148 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 5149 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 5150 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 5151 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 5152 { } /* end */ 5153}; 5154 5155/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ??? 5156 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c 5157 */ 5158static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = { 5159 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 5160 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 5161 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 5162 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT), 5163 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 5164 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 5165 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 5166 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 5167 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT), 5168 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT), 5169 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 5170 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 5171 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 5172 { } /* end */ 5173}; 5174 5175static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = { 5176 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 5177 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 5178 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 5179 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 5180 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 5181 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 5182 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 5183 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 5184 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 5185 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 5186 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 5187 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 5188 { } /* end */ 5189}; 5190 5191static struct snd_kcontrol_new alc882_chmode_mixer[] = { 5192 { 5193 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 5194 .name = "Channel Mode", 5195 .info = alc_ch_mode_info, 5196 .get = alc_ch_mode_get, 5197 .put = alc_ch_mode_put, 5198 }, 5199 { } /* end */ 5200}; 5201 5202static struct hda_verb alc882_init_verbs[] = { 5203 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 5204 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5205 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5206 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 5207 /* Rear mixer */ 5208 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5209 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5210 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 5211 /* CLFE mixer */ 5212 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5213 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5214 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 5215 /* Side mixer */ 5216 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5217 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5218 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 5219 5220 /* Front Pin: output 0 (0x0c) */ 5221 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5222 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5223 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 5224 /* Rear Pin: output 1 (0x0d) */ 5225 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5226 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5227 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 5228 /* CLFE Pin: output 2 (0x0e) */ 5229 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5230 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5231 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, 5232 /* Side Pin: output 3 (0x0f) */ 5233 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5234 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5235 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, 5236 /* Mic (rear) pin: input vref at 80% */ 5237 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 5238 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 5239 /* Front Mic pin: input vref at 80% */ 5240 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 5241 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 5242 /* Line In pin: input */ 5243 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 5244 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 5245 /* Line-2 In: Headphone output (output 0 - 0x0c) */ 5246 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 5247 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5248 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 5249 /* CD pin widget for input */ 5250 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 5251 5252 /* FIXME: use matrix-type input source selection */ 5253 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 5254 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 5255 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5256 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 5257 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 5258 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 5259 /* Input mixer2 */ 5260 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5261 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 5262 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 5263 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 5264 /* Input mixer3 */ 5265 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5266 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 5267 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 5268 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 5269 /* ADC1: mute amp left and right */ 5270 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5271 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 5272 /* ADC2: mute amp left and right */ 5273 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5274 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 5275 /* ADC3: mute amp left and right */ 5276 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5277 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 5278 5279 { } 5280}; 5281 5282static struct hda_verb alc882_eapd_verbs[] = { 5283 /* change to EAPD mode */ 5284 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 5285 {0x20, AC_VERB_SET_PROC_COEF, 0x3060}, 5286 { } 5287}; 5288 5289/* Mac Pro test */ 5290static struct snd_kcontrol_new alc882_macpro_mixer[] = { 5291 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 5292 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 5293 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT), 5294 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT), 5295 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT), 5296 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT), 5297 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT), 5298 { } /* end */ 5299}; 5300 5301static struct hda_verb alc882_macpro_init_verbs[] = { 5302 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 5303 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5304 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5305 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 5306 /* Front Pin: output 0 (0x0c) */ 5307 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5308 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5309 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 5310 /* Front Mic pin: input vref at 80% */ 5311 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 5312 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 5313 /* Speaker: output */ 5314 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5315 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5316 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04}, 5317 /* Headphone output (output 0 - 0x0c) */ 5318 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 5319 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5320 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00}, 5321 5322 /* FIXME: use matrix-type input source selection */ 5323 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 5324 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 5325 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5326 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 5327 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 5328 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 5329 /* Input mixer2 */ 5330 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5331 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 5332 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 5333 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 5334 /* Input mixer3 */ 5335 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5336 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 5337 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 5338 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 5339 /* ADC1: mute amp left and right */ 5340 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5341 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 5342 /* ADC2: mute amp left and right */ 5343 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5344 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 5345 /* ADC3: mute amp left and right */ 5346 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5347 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 5348 5349 { } 5350}; 5351 5352/* Macbook Pro rev3 */ 5353static struct hda_verb alc885_mbp3_init_verbs[] = { 5354 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 5355 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5356 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5357 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 5358 /* Rear mixer */ 5359 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5360 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5361 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 5362 /* Front Pin: output 0 (0x0c) */ 5363 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5364 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5365 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 5366 /* HP Pin: output 0 (0x0d) */ 5367 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, 5368 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 5369 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 5370 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 5371 /* Mic (rear) pin: input vref at 80% */ 5372 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 5373 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 5374 /* Front Mic pin: input vref at 80% */ 5375 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 5376 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 5377 /* Line In pin: use output 1 when in LineOut mode */ 5378 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 5379 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 5380 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, 5381 5382 /* FIXME: use matrix-type input source selection */ 5383 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 5384 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 5385 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5386 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 5387 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 5388 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 5389 /* Input mixer2 */ 5390 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5391 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 5392 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 5393 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 5394 /* Input mixer3 */ 5395 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5396 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 5397 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 5398 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 5399 /* ADC1: mute amp left and right */ 5400 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5401 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 5402 /* ADC2: mute amp left and right */ 5403 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5404 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 5405 /* ADC3: mute amp left and right */ 5406 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5407 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 5408 5409 { } 5410}; 5411 5412/* iMac 24 mixer. */ 5413static struct snd_kcontrol_new alc885_imac24_mixer[] = { 5414 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 5415 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT), 5416 { } /* end */ 5417}; 5418 5419/* iMac 24 init verbs. */ 5420static struct hda_verb alc885_imac24_init_verbs[] = { 5421 /* Internal speakers: output 0 (0x0c) */ 5422 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5423 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5424 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00}, 5425 /* Internal speakers: output 0 (0x0c) */ 5426 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5427 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5428 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00}, 5429 /* Headphone: output 0 (0x0c) */ 5430 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 5431 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5432 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 5433 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 5434 /* Front Mic: input vref at 80% */ 5435 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 5436 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 5437 { } 5438}; 5439 5440/* Toggle speaker-output according to the hp-jack state */ 5441static void alc885_imac24_automute(struct hda_codec *codec) 5442{ 5443 unsigned int present; 5444 5445 present = snd_hda_codec_read(codec, 0x14, 0, 5446 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 5447 snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0, 5448 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 5449 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0, 5450 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 5451} 5452 5453/* Processes unsolicited events. */ 5454static void alc885_imac24_unsol_event(struct hda_codec *codec, 5455 unsigned int res) 5456{ 5457 /* Headphone insertion or removal. */ 5458 if ((res >> 26) == ALC880_HP_EVENT) 5459 alc885_imac24_automute(codec); 5460} 5461 5462static void alc885_mbp3_automute(struct hda_codec *codec) 5463{ 5464 unsigned int present; 5465 5466 present = snd_hda_codec_read(codec, 0x15, 0, 5467 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 5468 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 5469 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 5470 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 5471 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE); 5472 5473} 5474static void alc885_mbp3_unsol_event(struct hda_codec *codec, 5475 unsigned int res) 5476{ 5477 /* Headphone insertion or removal. */ 5478 if ((res >> 26) == ALC880_HP_EVENT) 5479 alc885_mbp3_automute(codec); 5480} 5481 5482 5483static struct hda_verb alc882_targa_verbs[] = { 5484 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5485 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 5486 5487 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 5488 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5489 5490 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ 5491 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */ 5492 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 5493 5494 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 5495 {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, 5496 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03}, 5497 {0x01, AC_VERB_SET_GPIO_DATA, 0x03}, 5498 { } /* end */ 5499}; 5500 5501/* toggle speaker-output according to the hp-jack state */ 5502static void alc882_targa_automute(struct hda_codec *codec) 5503{ 5504 unsigned int present; 5505 5506 present = snd_hda_codec_read(codec, 0x14, 0, 5507 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 5508 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0, 5509 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 5510 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA, 5511 present ? 1 : 3); 5512} 5513 5514static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res) 5515{ 5516 /* Looks like the unsol event is incompatible with the standard 5517 * definition. 4bit tag is placed at 26 bit! 5518 */ 5519 if (((res >> 26) == ALC880_HP_EVENT)) { 5520 alc882_targa_automute(codec); 5521 } 5522} 5523 5524static struct hda_verb alc882_asus_a7j_verbs[] = { 5525 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5526 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 5527 5528 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 5529 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5530 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5531 5532 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */ 5533 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 5534 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */ 5535 5536 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ 5537 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */ 5538 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 5539 { } /* end */ 5540}; 5541 5542static struct hda_verb alc882_asus_a7m_verbs[] = { 5543 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5544 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 5545 5546 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 5547 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5548 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5549 5550 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */ 5551 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 5552 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */ 5553 5554 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ 5555 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */ 5556 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 5557 { } /* end */ 5558}; 5559 5560static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted) 5561{ 5562 unsigned int gpiostate, gpiomask, gpiodir; 5563 5564 gpiostate = snd_hda_codec_read(codec, codec->afg, 0, 5565 AC_VERB_GET_GPIO_DATA, 0); 5566 5567 if (!muted) 5568 gpiostate |= (1 << pin); 5569 else 5570 gpiostate &= ~(1 << pin); 5571 5572 gpiomask = snd_hda_codec_read(codec, codec->afg, 0, 5573 AC_VERB_GET_GPIO_MASK, 0); 5574 gpiomask |= (1 << pin); 5575 5576 gpiodir = snd_hda_codec_read(codec, codec->afg, 0, 5577 AC_VERB_GET_GPIO_DIRECTION, 0); 5578 gpiodir |= (1 << pin); 5579 5580 5581 snd_hda_codec_write(codec, codec->afg, 0, 5582 AC_VERB_SET_GPIO_MASK, gpiomask); 5583 snd_hda_codec_write(codec, codec->afg, 0, 5584 AC_VERB_SET_GPIO_DIRECTION, gpiodir); 5585 5586 msleep(1); 5587 5588 snd_hda_codec_write(codec, codec->afg, 0, 5589 AC_VERB_SET_GPIO_DATA, gpiostate); 5590} 5591 5592/* set up GPIO at initialization */ 5593static void alc885_macpro_init_hook(struct hda_codec *codec) 5594{ 5595 alc882_gpio_mute(codec, 0, 0); 5596 alc882_gpio_mute(codec, 1, 0); 5597} 5598 5599/* set up GPIO and update auto-muting at initialization */ 5600static void alc885_imac24_init_hook(struct hda_codec *codec) 5601{ 5602 alc885_macpro_init_hook(codec); 5603 alc885_imac24_automute(codec); 5604} 5605 5606/* 5607 * generic initialization of ADC, input mixers and output mixers 5608 */ 5609static struct hda_verb alc882_auto_init_verbs[] = { 5610 /* 5611 * Unmute ADC0-2 and set the default input to mic-in 5612 */ 5613 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 5614 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5615 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 5616 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5617 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 5618 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5619 5620 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 5621 * mixer widget 5622 * Note: PASD motherboards uses the Line In 2 as the input for 5623 * front panel mic (mic 2) 5624 */ 5625 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 5626 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5627 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 5628 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 5629 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 5630 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 5631 5632 /* 5633 * Set up output mixers (0x0c - 0x0f) 5634 */ 5635 /* set vol=0 to output mixers */ 5636 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5637 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5638 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5639 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5640 /* set up input amps for analog loopback */ 5641 /* Amp Indices: DAC = 0, mixer = 1 */ 5642 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5643 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 5644 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5645 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 5646 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5647 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 5648 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5649 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 5650 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5651 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 5652 5653 /* FIXME: use matrix-type input source selection */ 5654 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 5655 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 5656 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 5657 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 5658 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 5659 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 5660 /* Input mixer2 */ 5661 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 5662 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 5663 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 5664 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 5665 /* Input mixer3 */ 5666 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 5667 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 5668 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 5669 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 5670 5671 { } 5672}; 5673 5674/* capture mixer elements */ 5675static struct snd_kcontrol_new alc882_capture_alt_mixer[] = { 5676 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 5677 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 5678 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), 5679 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), 5680 { 5681 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 5682 /* The multiple "Capture Source" controls confuse alsamixer 5683 * So call somewhat different.. 5684 * FIXME: the controls appear in the "playback" view! 5685 */ 5686 /* .name = "Capture Source", */ 5687 .name = "Input Source", 5688 .count = 2, 5689 .info = alc882_mux_enum_info, 5690 .get = alc882_mux_enum_get, 5691 .put = alc882_mux_enum_put, 5692 }, 5693 { } /* end */ 5694}; 5695 5696static struct snd_kcontrol_new alc882_capture_mixer[] = { 5697 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT), 5698 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT), 5699 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT), 5700 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT), 5701 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT), 5702 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT), 5703 { 5704 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 5705 /* The multiple "Capture Source" controls confuse alsamixer 5706 * So call somewhat different.. 5707 * FIXME: the controls appear in the "playback" view! 5708 */ 5709 /* .name = "Capture Source", */ 5710 .name = "Input Source", 5711 .count = 3, 5712 .info = alc882_mux_enum_info, 5713 .get = alc882_mux_enum_get, 5714 .put = alc882_mux_enum_put, 5715 }, 5716 { } /* end */ 5717}; 5718 5719#ifdef CONFIG_SND_HDA_POWER_SAVE 5720#define alc882_loopbacks alc880_loopbacks 5721#endif 5722 5723/* pcm configuration: identiacal with ALC880 */ 5724#define alc882_pcm_analog_playback alc880_pcm_analog_playback 5725#define alc882_pcm_analog_capture alc880_pcm_analog_capture 5726#define alc882_pcm_digital_playback alc880_pcm_digital_playback 5727#define alc882_pcm_digital_capture alc880_pcm_digital_capture 5728 5729/* 5730 * configuration and preset 5731 */ 5732static const char *alc882_models[ALC882_MODEL_LAST] = { 5733 [ALC882_3ST_DIG] = "3stack-dig", 5734 [ALC882_6ST_DIG] = "6stack-dig", 5735 [ALC882_ARIMA] = "arima", 5736 [ALC882_W2JC] = "w2jc", 5737 [ALC882_TARGA] = "targa", 5738 [ALC882_ASUS_A7J] = "asus-a7j", 5739 [ALC882_ASUS_A7M] = "asus-a7m", 5740 [ALC885_MACPRO] = "macpro", 5741 [ALC885_MBP3] = "mbp3", 5742 [ALC885_IMAC24] = "imac24", 5743 [ALC882_AUTO] = "auto", 5744}; 5745 5746static struct snd_pci_quirk alc882_cfg_tbl[] = { 5747 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG), 5748 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG), 5749 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG), 5750 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */ 5751 SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), 5752 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J), 5753 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J), 5754 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M), 5755 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG), 5756 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG), 5757 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC), 5758 {} 5759}; 5760 5761static struct alc_config_preset alc882_presets[] = { 5762 [ALC882_3ST_DIG] = { 5763 .mixers = { alc882_base_mixer }, 5764 .init_verbs = { alc882_init_verbs }, 5765 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 5766 .dac_nids = alc882_dac_nids, 5767 .dig_out_nid = ALC882_DIGOUT_NID, 5768 .dig_in_nid = ALC882_DIGIN_NID, 5769 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes), 5770 .channel_mode = alc882_ch_modes, 5771 .need_dac_fix = 1, 5772 .input_mux = &alc882_capture_source, 5773 }, 5774 [ALC882_6ST_DIG] = { 5775 .mixers = { alc882_base_mixer, alc882_chmode_mixer }, 5776 .init_verbs = { alc882_init_verbs }, 5777 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 5778 .dac_nids = alc882_dac_nids, 5779 .dig_out_nid = ALC882_DIGOUT_NID, 5780 .dig_in_nid = ALC882_DIGIN_NID, 5781 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes), 5782 .channel_mode = alc882_sixstack_modes, 5783 .input_mux = &alc882_capture_source, 5784 }, 5785 [ALC882_ARIMA] = { 5786 .mixers = { alc882_base_mixer, alc882_chmode_mixer }, 5787 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs }, 5788 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 5789 .dac_nids = alc882_dac_nids, 5790 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes), 5791 .channel_mode = alc882_sixstack_modes, 5792 .input_mux = &alc882_capture_source, 5793 }, 5794 [ALC882_W2JC] = { 5795 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer }, 5796 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs, 5797 alc880_gpio1_init_verbs }, 5798 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 5799 .dac_nids = alc882_dac_nids, 5800 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), 5801 .channel_mode = alc880_threestack_modes, 5802 .need_dac_fix = 1, 5803 .input_mux = &alc882_capture_source, 5804 .dig_out_nid = ALC882_DIGOUT_NID, 5805 }, 5806 [ALC885_MBP3] = { 5807 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer }, 5808 .init_verbs = { alc885_mbp3_init_verbs, 5809 alc880_gpio1_init_verbs }, 5810 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 5811 .dac_nids = alc882_dac_nids, 5812 .channel_mode = alc885_mbp_6ch_modes, 5813 .num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes), 5814 .input_mux = &alc882_capture_source, 5815 .dig_out_nid = ALC882_DIGOUT_NID, 5816 .dig_in_nid = ALC882_DIGIN_NID, 5817 .unsol_event = alc885_mbp3_unsol_event, 5818 .init_hook = alc885_mbp3_automute, 5819 }, 5820 [ALC885_MACPRO] = { 5821 .mixers = { alc882_macpro_mixer }, 5822 .init_verbs = { alc882_macpro_init_verbs }, 5823 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 5824 .dac_nids = alc882_dac_nids, 5825 .dig_out_nid = ALC882_DIGOUT_NID, 5826 .dig_in_nid = ALC882_DIGIN_NID, 5827 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes), 5828 .channel_mode = alc882_ch_modes, 5829 .input_mux = &alc882_capture_source, 5830 .init_hook = alc885_macpro_init_hook, 5831 }, 5832 [ALC885_IMAC24] = { 5833 .mixers = { alc885_imac24_mixer }, 5834 .init_verbs = { alc885_imac24_init_verbs }, 5835 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 5836 .dac_nids = alc882_dac_nids, 5837 .dig_out_nid = ALC882_DIGOUT_NID, 5838 .dig_in_nid = ALC882_DIGIN_NID, 5839 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes), 5840 .channel_mode = alc882_ch_modes, 5841 .input_mux = &alc882_capture_source, 5842 .unsol_event = alc885_imac24_unsol_event, 5843 .init_hook = alc885_imac24_init_hook, 5844 }, 5845 [ALC882_TARGA] = { 5846 .mixers = { alc882_targa_mixer, alc882_chmode_mixer, 5847 alc882_capture_mixer }, 5848 .init_verbs = { alc882_init_verbs, alc882_targa_verbs}, 5849 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 5850 .dac_nids = alc882_dac_nids, 5851 .dig_out_nid = ALC882_DIGOUT_NID, 5852 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids), 5853 .adc_nids = alc882_adc_nids, 5854 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes), 5855 .channel_mode = alc882_3ST_6ch_modes, 5856 .need_dac_fix = 1, 5857 .input_mux = &alc882_capture_source, 5858 .unsol_event = alc882_targa_unsol_event, 5859 .init_hook = alc882_targa_automute, 5860 }, 5861 [ALC882_ASUS_A7J] = { 5862 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer, 5863 alc882_capture_mixer }, 5864 .init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs}, 5865 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 5866 .dac_nids = alc882_dac_nids, 5867 .dig_out_nid = ALC882_DIGOUT_NID, 5868 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids), 5869 .adc_nids = alc882_adc_nids, 5870 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes), 5871 .channel_mode = alc882_3ST_6ch_modes, 5872 .need_dac_fix = 1, 5873 .input_mux = &alc882_capture_source, 5874 }, 5875 [ALC882_ASUS_A7M] = { 5876 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer }, 5877 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs, 5878 alc880_gpio1_init_verbs, 5879 alc882_asus_a7m_verbs }, 5880 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 5881 .dac_nids = alc882_dac_nids, 5882 .dig_out_nid = ALC882_DIGOUT_NID, 5883 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), 5884 .channel_mode = alc880_threestack_modes, 5885 .need_dac_fix = 1, 5886 .input_mux = &alc882_capture_source, 5887 }, 5888}; 5889 5890 5891/* 5892 * Pin config fixes 5893 */ 5894enum { 5895 PINFIX_ABIT_AW9D_MAX 5896}; 5897 5898static struct alc_pincfg alc882_abit_aw9d_pinfix[] = { 5899 { 0x15, 0x01080104 }, /* side */ 5900 { 0x16, 0x01011012 }, /* rear */ 5901 { 0x17, 0x01016011 }, /* clfe */ 5902 { } 5903}; 5904 5905static const struct alc_pincfg *alc882_pin_fixes[] = { 5906 [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix, 5907}; 5908 5909static struct snd_pci_quirk alc882_pinfix_tbl[] = { 5910 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX), 5911 {} 5912}; 5913 5914/* 5915 * BIOS auto configuration 5916 */ 5917static void alc882_auto_set_output_and_unmute(struct hda_codec *codec, 5918 hda_nid_t nid, int pin_type, 5919 int dac_idx) 5920{ 5921 /* set as output */ 5922 struct alc_spec *spec = codec->spec; 5923 int idx; 5924 5925 if (spec->multiout.dac_nids[dac_idx] == 0x25) 5926 idx = 4; 5927 else 5928 idx = spec->multiout.dac_nids[dac_idx] - 2; 5929 5930 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 5931 pin_type); 5932 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, 5933 AMP_OUT_UNMUTE); 5934 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx); 5935 5936} 5937 5938static void alc882_auto_init_multi_out(struct hda_codec *codec) 5939{ 5940 struct alc_spec *spec = codec->spec; 5941 int i; 5942 5943 alc_subsystem_id(codec, 0x15, 0x1b, 0x14); 5944 for (i = 0; i <= HDA_SIDE; i++) { 5945 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 5946 int pin_type = get_pin_type(spec->autocfg.line_out_type); 5947 if (nid) 5948 alc882_auto_set_output_and_unmute(codec, nid, pin_type, 5949 i); 5950 } 5951} 5952 5953static void alc882_auto_init_hp_out(struct hda_codec *codec) 5954{ 5955 struct alc_spec *spec = codec->spec; 5956 hda_nid_t pin; 5957 5958 pin = spec->autocfg.hp_pins[0]; 5959 if (pin) /* connect to front */ 5960 /* use dac 0 */ 5961 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); 5962} 5963 5964#define alc882_is_input_pin(nid) alc880_is_input_pin(nid) 5965#define ALC882_PIN_CD_NID ALC880_PIN_CD_NID 5966 5967static void alc882_auto_init_analog_input(struct hda_codec *codec) 5968{ 5969 struct alc_spec *spec = codec->spec; 5970 int i; 5971 5972 for (i = 0; i < AUTO_PIN_LAST; i++) { 5973 hda_nid_t nid = spec->autocfg.input_pins[i]; 5974 if (alc882_is_input_pin(nid)) { 5975 snd_hda_codec_write(codec, nid, 0, 5976 AC_VERB_SET_PIN_WIDGET_CONTROL, 5977 i <= AUTO_PIN_FRONT_MIC ? 5978 PIN_VREF80 : PIN_IN); 5979 if (nid != ALC882_PIN_CD_NID) 5980 snd_hda_codec_write(codec, nid, 0, 5981 AC_VERB_SET_AMP_GAIN_MUTE, 5982 AMP_OUT_MUTE); 5983 } 5984 } 5985} 5986 5987/* add mic boosts if needed */ 5988static int alc_auto_add_mic_boost(struct hda_codec *codec) 5989{ 5990 struct alc_spec *spec = codec->spec; 5991 int err; 5992 hda_nid_t nid; 5993 5994 nid = spec->autocfg.input_pins[AUTO_PIN_MIC]; 5995 if (nid) { 5996 err = add_control(spec, ALC_CTL_WIDGET_VOL, 5997 "Mic Boost", 5998 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT)); 5999 if (err < 0) 6000 return err; 6001 } 6002 nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC]; 6003 if (nid) { 6004 err = add_control(spec, ALC_CTL_WIDGET_VOL, 6005 "Front Mic Boost", 6006 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT)); 6007 if (err < 0) 6008 return err; 6009 } 6010 return 0; 6011} 6012 6013/* almost identical with ALC880 parser... */ 6014static int alc882_parse_auto_config(struct hda_codec *codec) 6015{ 6016 struct alc_spec *spec = codec->spec; 6017 int err = alc880_parse_auto_config(codec); 6018 6019 if (err < 0) 6020 return err; 6021 else if (!err) 6022 return 0; /* no config found */ 6023 6024 err = alc_auto_add_mic_boost(codec); 6025 if (err < 0) 6026 return err; 6027 6028 /* hack - override the init verbs */ 6029 spec->init_verbs[0] = alc882_auto_init_verbs; 6030 6031 return 1; /* config found */ 6032} 6033 6034/* additional initialization for auto-configuration model */ 6035static void alc882_auto_init(struct hda_codec *codec) 6036{ 6037 alc882_auto_init_multi_out(codec); 6038 alc882_auto_init_hp_out(codec); 6039 alc882_auto_init_analog_input(codec); 6040} 6041 6042static int patch_alc882(struct hda_codec *codec) 6043{ 6044 struct alc_spec *spec; 6045 int err, board_config; 6046 6047 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 6048 if (spec == NULL) 6049 return -ENOMEM; 6050 6051 codec->spec = spec; 6052 6053 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST, 6054 alc882_models, 6055 alc882_cfg_tbl); 6056 6057 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) { 6058 /* Pick up systems that don't supply PCI SSID */ 6059 switch (codec->subsystem_id) { 6060 case 0x106b0c00: /* Mac Pro */ 6061 board_config = ALC885_MACPRO; 6062 break; 6063 case 0x106b1000: /* iMac 24 */ 6064 board_config = ALC885_IMAC24; 6065 break; 6066 case 0x106b2c00: /* Macbook Pro rev3 */ 6067 board_config = ALC885_MBP3; 6068 break; 6069 default: 6070 printk(KERN_INFO "hda_codec: Unknown model for ALC882, " 6071 "trying auto-probe from BIOS...\n"); 6072 board_config = ALC882_AUTO; 6073 } 6074 } 6075 6076 alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes); 6077 6078 if (board_config == ALC882_AUTO) { 6079 /* automatic parse from the BIOS config */ 6080 err = alc882_parse_auto_config(codec); 6081 if (err < 0) { 6082 alc_free(codec); 6083 return err; 6084 } else if (!err) { 6085 printk(KERN_INFO 6086 "hda_codec: Cannot set up configuration " 6087 "from BIOS. Using base mode...\n"); 6088 board_config = ALC882_3ST_DIG; 6089 } 6090 } 6091 6092 if (board_config != ALC882_AUTO) 6093 setup_preset(spec, &alc882_presets[board_config]); 6094 6095 spec->stream_name_analog = "ALC882 Analog"; 6096 spec->stream_analog_playback = &alc882_pcm_analog_playback; 6097 spec->stream_analog_capture = &alc882_pcm_analog_capture; 6098 6099 spec->stream_name_digital = "ALC882 Digital"; 6100 spec->stream_digital_playback = &alc882_pcm_digital_playback; 6101 spec->stream_digital_capture = &alc882_pcm_digital_capture; 6102 6103 if (!spec->adc_nids && spec->input_mux) { 6104 /* check whether NID 0x07 is valid */ 6105 unsigned int wcap = get_wcaps(codec, 0x07); 6106 /* get type */ 6107 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; 6108 if (wcap != AC_WID_AUD_IN) { 6109 spec->adc_nids = alc882_adc_nids_alt; 6110 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt); 6111 spec->mixers[spec->num_mixers] = 6112 alc882_capture_alt_mixer; 6113 spec->num_mixers++; 6114 } else { 6115 spec->adc_nids = alc882_adc_nids; 6116 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids); 6117 spec->mixers[spec->num_mixers] = alc882_capture_mixer; 6118 spec->num_mixers++; 6119 } 6120 } 6121 6122 codec->patch_ops = alc_patch_ops; 6123 if (board_config == ALC882_AUTO) 6124 spec->init_hook = alc882_auto_init; 6125#ifdef CONFIG_SND_HDA_POWER_SAVE 6126 if (!spec->loopback.amplist) 6127 spec->loopback.amplist = alc882_loopbacks; 6128#endif 6129 6130 return 0; 6131} 6132 6133/* 6134 * ALC883 support 6135 * 6136 * ALC883 is almost identical with ALC880 but has cleaner and more flexible 6137 * configuration. Each pin widget can choose any input DACs and a mixer. 6138 * Each ADC is connected from a mixer of all inputs. This makes possible 6139 * 6-channel independent captures. 6140 * 6141 * In addition, an independent DAC for the multi-playback (not used in this 6142 * driver yet). 6143 */ 6144#define ALC883_DIGOUT_NID 0x06 6145#define ALC883_DIGIN_NID 0x0a 6146 6147static hda_nid_t alc883_dac_nids[4] = { 6148 /* front, rear, clfe, rear_surr */ 6149 0x02, 0x04, 0x03, 0x05 6150}; 6151 6152static hda_nid_t alc883_adc_nids[2] = { 6153 /* ADC1-2 */ 6154 0x08, 0x09, 6155}; 6156 6157/* input MUX */ 6158/* FIXME: should be a matrix-type input source selection */ 6159 6160static struct hda_input_mux alc883_capture_source = { 6161 .num_items = 4, 6162 .items = { 6163 { "Mic", 0x0 }, 6164 { "Front Mic", 0x1 }, 6165 { "Line", 0x2 }, 6166 { "CD", 0x4 }, 6167 }, 6168}; 6169 6170static struct hda_input_mux alc883_lenovo_101e_capture_source = { 6171 .num_items = 2, 6172 .items = { 6173 { "Mic", 0x1 }, 6174 { "Line", 0x2 }, 6175 }, 6176}; 6177 6178static struct hda_input_mux alc883_lenovo_nb0763_capture_source = { 6179 .num_items = 4, 6180 .items = { 6181 { "Mic", 0x0 }, 6182 { "iMic", 0x1 }, 6183 { "Line", 0x2 }, 6184 { "CD", 0x4 }, 6185 }, 6186}; 6187 6188#define alc883_mux_enum_info alc_mux_enum_info 6189#define alc883_mux_enum_get alc_mux_enum_get 6190 6191static int alc883_mux_enum_put(struct snd_kcontrol *kcontrol, 6192 struct snd_ctl_elem_value *ucontrol) 6193{ 6194 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 6195 struct alc_spec *spec = codec->spec; 6196 const struct hda_input_mux *imux = spec->input_mux; 6197 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 6198 static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 }; 6199 hda_nid_t nid = capture_mixers[adc_idx]; 6200 unsigned int *cur_val = &spec->cur_mux[adc_idx]; 6201 unsigned int i, idx; 6202 6203 idx = ucontrol->value.enumerated.item[0]; 6204 if (idx >= imux->num_items) 6205 idx = imux->num_items - 1; 6206 if (*cur_val == idx) 6207 return 0; 6208 for (i = 0; i < imux->num_items; i++) { 6209 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE; 6210 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 6211 imux->items[i].index, 6212 HDA_AMP_MUTE, v); 6213 } 6214 *cur_val = idx; 6215 return 1; 6216} 6217 6218/* 6219 * 2ch mode 6220 */ 6221static struct hda_channel_mode alc883_3ST_2ch_modes[1] = { 6222 { 2, NULL } 6223}; 6224 6225/* 6226 * 2ch mode 6227 */ 6228static struct hda_verb alc883_3ST_ch2_init[] = { 6229 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 6230 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 6231 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 6232 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 6233 { } /* end */ 6234}; 6235 6236/* 6237 * 4ch mode 6238 */ 6239static struct hda_verb alc883_3ST_ch4_init[] = { 6240 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 6241 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 6242 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 6243 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 6244 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 6245 { } /* end */ 6246}; 6247 6248/* 6249 * 6ch mode 6250 */ 6251static struct hda_verb alc883_3ST_ch6_init[] = { 6252 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 6253 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 6254 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, 6255 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 6256 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 6257 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 6258 { } /* end */ 6259}; 6260 6261static struct hda_channel_mode alc883_3ST_6ch_modes[3] = { 6262 { 2, alc883_3ST_ch2_init }, 6263 { 4, alc883_3ST_ch4_init }, 6264 { 6, alc883_3ST_ch6_init }, 6265}; 6266 6267/* 6268 * 6ch mode 6269 */ 6270static struct hda_verb alc883_sixstack_ch6_init[] = { 6271 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 6272 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 6273 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 6274 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 6275 { } /* end */ 6276}; 6277 6278/* 6279 * 8ch mode 6280 */ 6281static struct hda_verb alc883_sixstack_ch8_init[] = { 6282 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 6283 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 6284 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 6285 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 6286 { } /* end */ 6287}; 6288 6289static struct hda_channel_mode alc883_sixstack_modes[2] = { 6290 { 6, alc883_sixstack_ch6_init }, 6291 { 8, alc883_sixstack_ch8_init }, 6292}; 6293 6294static struct hda_verb alc883_medion_eapd_verbs[] = { 6295 /* eanable EAPD on medion laptop */ 6296 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 6297 {0x20, AC_VERB_SET_PROC_COEF, 0x3070}, 6298 { } 6299}; 6300 6301/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 6302 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b 6303 */ 6304 6305static struct snd_kcontrol_new alc883_base_mixer[] = { 6306 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 6307 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 6308 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 6309 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 6310 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 6311 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 6312 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 6313 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 6314 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 6315 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 6316 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 6317 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 6318 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 6319 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 6320 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 6321 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 6322 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 6323 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 6324 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 6325 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 6326 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 6327 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 6328 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 6329 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 6330 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 6331 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), 6332 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), 6333 { 6334 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 6335 /* .name = "Capture Source", */ 6336 .name = "Input Source", 6337 .count = 2, 6338 .info = alc883_mux_enum_info, 6339 .get = alc883_mux_enum_get, 6340 .put = alc883_mux_enum_put, 6341 }, 6342 { } /* end */ 6343}; 6344 6345static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = { 6346 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 6347 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 6348 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 6349 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 6350 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 6351 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 6352 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 6353 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 6354 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 6355 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 6356 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 6357 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 6358 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 6359 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 6360 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 6361 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 6362 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 6363 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), 6364 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), 6365 { 6366 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 6367 /* .name = "Capture Source", */ 6368 .name = "Input Source", 6369 .count = 2, 6370 .info = alc883_mux_enum_info, 6371 .get = alc883_mux_enum_get, 6372 .put = alc883_mux_enum_put, 6373 }, 6374 { } /* end */ 6375}; 6376 6377static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = { 6378 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 6379 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 6380 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 6381 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 6382 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 6383 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 6384 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 6385 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 6386 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 6387 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 6388 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 6389 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 6390 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 6391 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 6392 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 6393 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 6394 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 6395 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 6396 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 6397 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 6398 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 6399 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 6400 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 6401 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), 6402 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), 6403 { 6404 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 6405 /* .name = "Capture Source", */ 6406 .name = "Input Source", 6407 .count = 2, 6408 .info = alc883_mux_enum_info, 6409 .get = alc883_mux_enum_get, 6410 .put = alc883_mux_enum_put, 6411 }, 6412 { } /* end */ 6413}; 6414 6415static struct snd_kcontrol_new alc883_fivestack_mixer[] = { 6416 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 6417 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 6418 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 6419 HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT), 6420 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 6421 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 6422 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x16, 1, 0x0, HDA_OUTPUT), 6423 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT), 6424 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 6425 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 6426 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 6427 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 6428 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 6429 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 6430 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 6431 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 6432 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 6433 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 6434 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 6435 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 6436 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 6437 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 6438 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 6439 6440 { 6441 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 6442 /* .name = "Capture Source", */ 6443 .name = "Input Source", 6444 .count = 1, 6445 .info = alc883_mux_enum_info, 6446 .get = alc883_mux_enum_get, 6447 .put = alc883_mux_enum_put, 6448 }, 6449 { } /* end */ 6450}; 6451 6452static struct snd_kcontrol_new alc883_tagra_mixer[] = { 6453 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 6454 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 6455 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 6456 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 6457 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 6458 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 6459 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 6460 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 6461 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 6462 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 6463 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 6464 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 6465 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 6466 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 6467 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 6468 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 6469 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 6470 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 6471 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), 6472 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), 6473 { 6474 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 6475 /* .name = "Capture Source", */ 6476 .name = "Input Source", 6477 .count = 2, 6478 .info = alc883_mux_enum_info, 6479 .get = alc883_mux_enum_get, 6480 .put = alc883_mux_enum_put, 6481 }, 6482 { } /* end */ 6483}; 6484 6485static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = { 6486 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 6487 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 6488 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 6489 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 6490 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 6491 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 6492 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 6493 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 6494 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 6495 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 6496 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), 6497 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), 6498 { 6499 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 6500 /* .name = "Capture Source", */ 6501 .name = "Input Source", 6502 .count = 2, 6503 .info = alc883_mux_enum_info, 6504 .get = alc883_mux_enum_get, 6505 .put = alc883_mux_enum_put, 6506 }, 6507 { } /* end */ 6508}; 6509 6510static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = { 6511 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 6512 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 6513 HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 6514 HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT), 6515 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 6516 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 6517 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 6518 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 6519 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 6520 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 6521 { 6522 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 6523 /* .name = "Capture Source", */ 6524 .name = "Input Source", 6525 .count = 1, 6526 .info = alc883_mux_enum_info, 6527 .get = alc883_mux_enum_get, 6528 .put = alc883_mux_enum_put, 6529 }, 6530 { } /* end */ 6531}; 6532 6533static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = { 6534 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 6535 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT), 6536 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 6537 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 6538 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 6539 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 6540 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 6541 HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT), 6542 HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT), 6543 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 6544 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 6545 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), 6546 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), 6547 { 6548 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 6549 /* .name = "Capture Source", */ 6550 .name = "Input Source", 6551 .count = 2, 6552 .info = alc883_mux_enum_info, 6553 .get = alc883_mux_enum_get, 6554 .put = alc883_mux_enum_put, 6555 }, 6556 { } /* end */ 6557}; 6558 6559static struct snd_kcontrol_new alc883_medion_md2_mixer[] = { 6560 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 6561 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 6562 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT), 6563 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 6564 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 6565 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 6566 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 6567 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 6568 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 6569 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 6570 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 6571 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), 6572 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), 6573 { 6574 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 6575 /* .name = "Capture Source", */ 6576 .name = "Input Source", 6577 .count = 2, 6578 .info = alc883_mux_enum_info, 6579 .get = alc883_mux_enum_get, 6580 .put = alc883_mux_enum_put, 6581 }, 6582 { } /* end */ 6583}; 6584 6585static struct snd_kcontrol_new alc888_6st_hp_mixer[] = { 6586 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 6587 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 6588 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT), 6589 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT), 6590 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT), 6591 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT), 6592 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT), 6593 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT), 6594 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 6595 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 6596 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 6597 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 6598 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 6599 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 6600 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 6601 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 6602 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 6603 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 6604 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 6605 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 6606 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 6607 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 6608 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 6609 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 6610 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 6611 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), 6612 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), 6613 { 6614 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 6615 /* .name = "Capture Source", */ 6616 .name = "Input Source", 6617 .count = 2, 6618 .info = alc883_mux_enum_info, 6619 .get = alc883_mux_enum_get, 6620 .put = alc883_mux_enum_put, 6621 }, 6622 { } /* end */ 6623}; 6624 6625static struct snd_kcontrol_new alc888_3st_hp_mixer[] = { 6626 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 6627 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 6628 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT), 6629 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT), 6630 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT), 6631 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT), 6632 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT), 6633 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT), 6634 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 6635 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 6636 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 6637 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 6638 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 6639 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 6640 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 6641 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 6642 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 6643 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 6644 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 6645 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 6646 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 6647 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 6648 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 6649 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), 6650 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), 6651 { 6652 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 6653 /* .name = "Capture Source", */ 6654 .name = "Input Source", 6655 .count = 2, 6656 .info = alc883_mux_enum_info, 6657 .get = alc883_mux_enum_get, 6658 .put = alc883_mux_enum_put, 6659 }, 6660 { } /* end */ 6661}; 6662 6663static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = { 6664 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 6665 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 6666 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 6667 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 6668 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 6669 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 6670 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 6671 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 6672 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 6673 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 6674 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), 6675 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), 6676 { 6677 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 6678 /* .name = "Capture Source", */ 6679 .name = "Input Source", 6680 .count = 2, 6681 .info = alc883_mux_enum_info, 6682 .get = alc883_mux_enum_get, 6683 .put = alc883_mux_enum_put, 6684 }, 6685 { } /* end */ 6686}; 6687 6688static struct snd_kcontrol_new alc883_chmode_mixer[] = { 6689 { 6690 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 6691 .name = "Channel Mode", 6692 .info = alc_ch_mode_info, 6693 .get = alc_ch_mode_get, 6694 .put = alc_ch_mode_put, 6695 }, 6696 { } /* end */ 6697}; 6698 6699static struct hda_verb alc883_init_verbs[] = { 6700 /* ADC1: mute amp left and right */ 6701 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6702 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 6703 /* ADC2: mute amp left and right */ 6704 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6705 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 6706 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 6707 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6708 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6709 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6710 /* Rear mixer */ 6711 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6712 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6713 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6714 /* CLFE mixer */ 6715 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6716 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6717 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6718 /* Side mixer */ 6719 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6720 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6721 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6722 6723 /* mute analog input loopbacks */ 6724 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6725 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6726 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 6727 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 6728 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 6729 6730 /* Front Pin: output 0 (0x0c) */ 6731 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6732 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6733 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 6734 /* Rear Pin: output 1 (0x0d) */ 6735 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6736 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6737 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 6738 /* CLFE Pin: output 2 (0x0e) */ 6739 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6740 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6741 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, 6742 /* Side Pin: output 3 (0x0f) */ 6743 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6744 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6745 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, 6746 /* Mic (rear) pin: input vref at 80% */ 6747 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 6748 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 6749 /* Front Mic pin: input vref at 80% */ 6750 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 6751 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 6752 /* Line In pin: input */ 6753 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 6754 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 6755 /* Line-2 In: Headphone output (output 0 - 0x0c) */ 6756 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6757 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6758 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 6759 /* CD pin widget for input */ 6760 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 6761 6762 /* FIXME: use matrix-type input source selection */ 6763 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 6764 /* Input mixer2 */ 6765 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6766 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 6767 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 6768 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, 6769 /* Input mixer3 */ 6770 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6771 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 6772 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 6773 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, 6774 { } 6775}; 6776 6777static struct hda_verb alc883_tagra_verbs[] = { 6778 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6779 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 6780 6781 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6782 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6783 6784 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ 6785 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */ 6786 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 6787 6788 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 6789 {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, 6790 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03}, 6791 {0x01, AC_VERB_SET_GPIO_DATA, 0x03}, 6792 6793 { } /* end */ 6794}; 6795 6796static struct hda_verb alc883_lenovo_101e_verbs[] = { 6797 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 6798 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN}, 6799 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN}, 6800 { } /* end */ 6801}; 6802 6803static struct hda_verb alc883_lenovo_nb0763_verbs[] = { 6804 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 6805 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6806 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 6807 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6808 { } /* end */ 6809}; 6810 6811static struct hda_verb alc888_lenovo_ms7195_verbs[] = { 6812 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6813 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 6814 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 6815 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN}, 6816 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 6817 { } /* end */ 6818}; 6819 6820static struct hda_verb alc883_haier_w66_verbs[] = { 6821 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6822 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 6823 6824 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6825 6826 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 6827 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6828 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 6829 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6830 { } /* end */ 6831}; 6832 6833static struct hda_verb alc888_6st_hp_verbs[] = { 6834 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */ 6835 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Rear : output 2 (0x0e) */ 6836 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* CLFE : output 1 (0x0d) */ 6837 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, /* Side : output 3 (0x0f) */ 6838 { } 6839}; 6840 6841static struct hda_verb alc888_3st_hp_verbs[] = { 6842 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */ 6843 {0x18, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */ 6844 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */ 6845 { } 6846}; 6847 6848static struct hda_verb alc888_3st_hp_2ch_init[] = { 6849 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 6850 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 6851 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 6852 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 6853 { } 6854}; 6855 6856static struct hda_verb alc888_3st_hp_6ch_init[] = { 6857 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 6858 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 6859 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 6860 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 6861 { } 6862}; 6863 6864static struct hda_channel_mode alc888_3st_hp_modes[2] = { 6865 { 2, alc888_3st_hp_2ch_init }, 6866 { 6, alc888_3st_hp_6ch_init }, 6867}; 6868 6869/* toggle front-jack and RCA according to the hp-jack state */ 6870static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec) 6871{ 6872 unsigned int present; 6873 6874 present = snd_hda_codec_read(codec, 0x1b, 0, 6875 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 6876 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 6877 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 6878 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 6879 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 6880} 6881 6882/* toggle RCA according to the front-jack state */ 6883static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec) 6884{ 6885 unsigned int present; 6886 6887 present = snd_hda_codec_read(codec, 0x14, 0, 6888 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 6889 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 6890 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 6891} 6892 6893static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec, 6894 unsigned int res) 6895{ 6896 if ((res >> 26) == ALC880_HP_EVENT) 6897 alc888_lenovo_ms7195_front_automute(codec); 6898 if ((res >> 26) == ALC880_FRONT_EVENT) 6899 alc888_lenovo_ms7195_rca_automute(codec); 6900} 6901 6902static struct hda_verb alc883_medion_md2_verbs[] = { 6903 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6904 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 6905 6906 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6907 6908 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 6909 { } /* end */ 6910}; 6911 6912/* toggle speaker-output according to the hp-jack state */ 6913static void alc883_medion_md2_automute(struct hda_codec *codec) 6914{ 6915 unsigned int present; 6916 6917 present = snd_hda_codec_read(codec, 0x14, 0, 6918 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 6919 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 6920 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 6921} 6922 6923static void alc883_medion_md2_unsol_event(struct hda_codec *codec, 6924 unsigned int res) 6925{ 6926 if ((res >> 26) == ALC880_HP_EVENT) 6927 alc883_medion_md2_automute(codec); 6928} 6929 6930/* toggle speaker-output according to the hp-jack state */ 6931static void alc883_tagra_automute(struct hda_codec *codec) 6932{ 6933 unsigned int present; 6934 unsigned char bits; 6935 6936 present = snd_hda_codec_read(codec, 0x14, 0, 6937 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 6938 bits = present ? HDA_AMP_MUTE : 0; 6939 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0, 6940 HDA_AMP_MUTE, bits); 6941 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA, 6942 present ? 1 : 3); 6943} 6944 6945static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res) 6946{ 6947 if ((res >> 26) == ALC880_HP_EVENT) 6948 alc883_tagra_automute(codec); 6949} 6950 6951static void alc883_haier_w66_automute(struct hda_codec *codec) 6952{ 6953 unsigned int present; 6954 unsigned char bits; 6955 6956 present = snd_hda_codec_read(codec, 0x1b, 0, 6957 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 6958 bits = present ? 0x80 : 0; 6959 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 6960 0x80, bits); 6961} 6962 6963static void alc883_haier_w66_unsol_event(struct hda_codec *codec, 6964 unsigned int res) 6965{ 6966 if ((res >> 26) == ALC880_HP_EVENT) 6967 alc883_haier_w66_automute(codec); 6968} 6969 6970static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec) 6971{ 6972 unsigned int present; 6973 unsigned char bits; 6974 6975 present = snd_hda_codec_read(codec, 0x14, 0, 6976 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 6977 bits = present ? HDA_AMP_MUTE : 0; 6978 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 6979 HDA_AMP_MUTE, bits); 6980} 6981 6982static void alc883_lenovo_101e_all_automute(struct hda_codec *codec) 6983{ 6984 unsigned int present; 6985 unsigned char bits; 6986 6987 present = snd_hda_codec_read(codec, 0x1b, 0, 6988 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 6989 bits = present ? HDA_AMP_MUTE : 0; 6990 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 6991 HDA_AMP_MUTE, bits); 6992 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 6993 HDA_AMP_MUTE, bits); 6994} 6995 6996static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec, 6997 unsigned int res) 6998{ 6999 if ((res >> 26) == ALC880_HP_EVENT) 7000 alc883_lenovo_101e_all_automute(codec); 7001 if ((res >> 26) == ALC880_FRONT_EVENT) 7002 alc883_lenovo_101e_ispeaker_automute(codec); 7003} 7004 7005/* toggle speaker-output according to the hp-jack state */ 7006static void alc883_acer_aspire_automute(struct hda_codec *codec) 7007{ 7008 unsigned int present; 7009 7010 present = snd_hda_codec_read(codec, 0x14, 0, 7011 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 7012 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 7013 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 7014 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0, 7015 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 7016} 7017 7018static void alc883_acer_aspire_unsol_event(struct hda_codec *codec, 7019 unsigned int res) 7020{ 7021 if ((res >> 26) == ALC880_HP_EVENT) 7022 alc883_acer_aspire_automute(codec); 7023} 7024 7025static struct hda_verb alc883_acer_eapd_verbs[] = { 7026 /* HP Pin: output 0 (0x0c) */ 7027 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 7028 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7029 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 7030 /* Front Pin: output 0 (0x0c) */ 7031 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 7032 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 7033 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 7034 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, 7035 /* eanable EAPD on medion laptop */ 7036 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 7037 {0x20, AC_VERB_SET_PROC_COEF, 0x3050}, 7038 /* enable unsolicited event */ 7039 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 7040 { } 7041}; 7042 7043/* 7044 * generic initialization of ADC, input mixers and output mixers 7045 */ 7046static struct hda_verb alc883_auto_init_verbs[] = { 7047 /* 7048 * Unmute ADC0-2 and set the default input to mic-in 7049 */ 7050 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 7051 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7052 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 7053 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7054 7055 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 7056 * mixer widget 7057 * Note: PASD motherboards uses the Line In 2 as the input for 7058 * front panel mic (mic 2) 7059 */ 7060 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 7061 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7062 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7063 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 7064 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 7065 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 7066 7067 /* 7068 * Set up output mixers (0x0c - 0x0f) 7069 */ 7070 /* set vol=0 to output mixers */ 7071 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 7072 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 7073 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 7074 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 7075 /* set up input amps for analog loopback */ 7076 /* Amp Indices: DAC = 0, mixer = 1 */ 7077 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7078 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 7079 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7080 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 7081 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7082 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 7083 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7084 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 7085 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7086 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 7087 7088 /* FIXME: use matrix-type input source selection */ 7089 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 7090 /* Input mixer1 */ 7091 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7092 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 7093 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 7094 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */ 7095 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, 7096 /* Input mixer2 */ 7097 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7098 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 7099 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 7100 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */ 7101 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, 7102 7103 { } 7104}; 7105 7106/* capture mixer elements */ 7107static struct snd_kcontrol_new alc883_capture_mixer[] = { 7108 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 7109 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 7110 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), 7111 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), 7112 { 7113 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 7114 /* The multiple "Capture Source" controls confuse alsamixer 7115 * So call somewhat different.. 7116 * FIXME: the controls appear in the "playback" view! 7117 */ 7118 /* .name = "Capture Source", */ 7119 .name = "Input Source", 7120 .count = 2, 7121 .info = alc882_mux_enum_info, 7122 .get = alc882_mux_enum_get, 7123 .put = alc882_mux_enum_put, 7124 }, 7125 { } /* end */ 7126}; 7127 7128#ifdef CONFIG_SND_HDA_POWER_SAVE 7129#define alc883_loopbacks alc880_loopbacks 7130#endif 7131 7132/* pcm configuration: identiacal with ALC880 */ 7133#define alc883_pcm_analog_playback alc880_pcm_analog_playback 7134#define alc883_pcm_analog_capture alc880_pcm_analog_capture 7135#define alc883_pcm_digital_playback alc880_pcm_digital_playback 7136#define alc883_pcm_digital_capture alc880_pcm_digital_capture 7137 7138/* 7139 * configuration and preset 7140 */ 7141static const char *alc883_models[ALC883_MODEL_LAST] = { 7142 [ALC883_3ST_2ch_DIG] = "3stack-dig", 7143 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig", 7144 [ALC883_3ST_6ch] = "3stack-6ch", 7145 [ALC883_6ST_DIG] = "6stack-dig", 7146 [ALC883_TARGA_DIG] = "targa-dig", 7147 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig", 7148 [ALC883_ACER] = "acer", 7149 [ALC883_ACER_ASPIRE] = "acer-aspire", 7150 [ALC883_MEDION] = "medion", 7151 [ALC883_MEDION_MD2] = "medion-md2", 7152 [ALC883_LAPTOP_EAPD] = "laptop-eapd", 7153 [ALC883_LENOVO_101E_2ch] = "lenovo-101e", 7154 [ALC883_LENOVO_NB0763] = "lenovo-nb0763", 7155 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig", 7156 [ALC883_HAIER_W66] = "haier-w66", 7157 [ALC888_6ST_HP] = "6stack-hp", 7158 [ALC888_3ST_HP] = "3stack-hp", 7159 [ALC883_AUTO] = "auto", 7160}; 7161 7162static struct snd_pci_quirk alc883_cfg_tbl[] = { 7163 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG), 7164 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG), 7165 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch), 7166 SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD), 7167 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG), 7168 SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG), 7169 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG), 7170 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG), 7171 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG), 7172 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG), 7173 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG), 7174 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG), 7175 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG), 7176 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG), 7177 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG), 7178 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG), 7179 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG), 7180 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG), 7181 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG), 7182 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG), 7183 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG), 7184 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG), 7185 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG), 7186 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG), 7187 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE), 7188 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE), 7189 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE), 7190 SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER), 7191 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch), 7192 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION), 7193 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD), 7194 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch), 7195 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch), 7196 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763), 7197 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763), 7198 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC888_6ST_HP), 7199 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP), 7200 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP), 7201 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2), 7202 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66), 7203 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763), 7204 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG), 7205 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG), 7206 {} 7207}; 7208 7209static struct alc_config_preset alc883_presets[] = { 7210 [ALC883_3ST_2ch_DIG] = { 7211 .mixers = { alc883_3ST_2ch_mixer }, 7212 .init_verbs = { alc883_init_verbs }, 7213 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 7214 .dac_nids = alc883_dac_nids, 7215 .dig_out_nid = ALC883_DIGOUT_NID, 7216 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 7217 .adc_nids = alc883_adc_nids, 7218 .dig_in_nid = ALC883_DIGIN_NID, 7219 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 7220 .channel_mode = alc883_3ST_2ch_modes, 7221 .input_mux = &alc883_capture_source, 7222 }, 7223 [ALC883_3ST_6ch_DIG] = { 7224 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, 7225 .init_verbs = { alc883_init_verbs }, 7226 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 7227 .dac_nids = alc883_dac_nids, 7228 .dig_out_nid = ALC883_DIGOUT_NID, 7229 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 7230 .adc_nids = alc883_adc_nids, 7231 .dig_in_nid = ALC883_DIGIN_NID, 7232 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 7233 .channel_mode = alc883_3ST_6ch_modes, 7234 .need_dac_fix = 1, 7235 .input_mux = &alc883_capture_source, 7236 }, 7237 [ALC883_3ST_6ch] = { 7238 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, 7239 .init_verbs = { alc883_init_verbs }, 7240 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 7241 .dac_nids = alc883_dac_nids, 7242 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 7243 .adc_nids = alc883_adc_nids, 7244 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 7245 .channel_mode = alc883_3ST_6ch_modes, 7246 .need_dac_fix = 1, 7247 .input_mux = &alc883_capture_source, 7248 }, 7249 [ALC883_6ST_DIG] = { 7250 .mixers = { alc883_base_mixer, alc883_chmode_mixer }, 7251 .init_verbs = { alc883_init_verbs }, 7252 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 7253 .dac_nids = alc883_dac_nids, 7254 .dig_out_nid = ALC883_DIGOUT_NID, 7255 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 7256 .adc_nids = alc883_adc_nids, 7257 .dig_in_nid = ALC883_DIGIN_NID, 7258 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), 7259 .channel_mode = alc883_sixstack_modes, 7260 .input_mux = &alc883_capture_source, 7261 }, 7262 [ALC883_TARGA_DIG] = { 7263 .mixers = { alc883_tagra_mixer, alc883_chmode_mixer }, 7264 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs}, 7265 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 7266 .dac_nids = alc883_dac_nids, 7267 .dig_out_nid = ALC883_DIGOUT_NID, 7268 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 7269 .adc_nids = alc883_adc_nids, 7270 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 7271 .channel_mode = alc883_3ST_6ch_modes, 7272 .need_dac_fix = 1, 7273 .input_mux = &alc883_capture_source, 7274 .unsol_event = alc883_tagra_unsol_event, 7275 .init_hook = alc883_tagra_automute, 7276 }, 7277 [ALC883_TARGA_2ch_DIG] = { 7278 .mixers = { alc883_tagra_2ch_mixer}, 7279 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs}, 7280 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 7281 .dac_nids = alc883_dac_nids, 7282 .dig_out_nid = ALC883_DIGOUT_NID, 7283 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 7284 .adc_nids = alc883_adc_nids, 7285 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 7286 .channel_mode = alc883_3ST_2ch_modes, 7287 .input_mux = &alc883_capture_source, 7288 .unsol_event = alc883_tagra_unsol_event, 7289 .init_hook = alc883_tagra_automute, 7290 }, 7291 [ALC883_ACER] = { 7292 .mixers = { alc883_base_mixer }, 7293 /* On TravelMate laptops, GPIO 0 enables the internal speaker 7294 * and the headphone jack. Turn this on and rely on the 7295 * standard mute methods whenever the user wants to turn 7296 * these outputs off. 7297 */ 7298 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs }, 7299 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 7300 .dac_nids = alc883_dac_nids, 7301 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 7302 .adc_nids = alc883_adc_nids, 7303 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 7304 .channel_mode = alc883_3ST_2ch_modes, 7305 .input_mux = &alc883_capture_source, 7306 }, 7307 [ALC883_ACER_ASPIRE] = { 7308 .mixers = { alc883_acer_aspire_mixer }, 7309 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs }, 7310 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 7311 .dac_nids = alc883_dac_nids, 7312 .dig_out_nid = ALC883_DIGOUT_NID, 7313 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 7314 .adc_nids = alc883_adc_nids, 7315 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 7316 .channel_mode = alc883_3ST_2ch_modes, 7317 .input_mux = &alc883_capture_source, 7318 .unsol_event = alc883_acer_aspire_unsol_event, 7319 .init_hook = alc883_acer_aspire_automute, 7320 }, 7321 [ALC883_MEDION] = { 7322 .mixers = { alc883_fivestack_mixer, 7323 alc883_chmode_mixer }, 7324 .init_verbs = { alc883_init_verbs, 7325 alc883_medion_eapd_verbs }, 7326 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 7327 .dac_nids = alc883_dac_nids, 7328 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 7329 .adc_nids = alc883_adc_nids, 7330 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), 7331 .channel_mode = alc883_sixstack_modes, 7332 .input_mux = &alc883_capture_source, 7333 }, 7334 [ALC883_MEDION_MD2] = { 7335 .mixers = { alc883_medion_md2_mixer}, 7336 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs}, 7337 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 7338 .dac_nids = alc883_dac_nids, 7339 .dig_out_nid = ALC883_DIGOUT_NID, 7340 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 7341 .adc_nids = alc883_adc_nids, 7342 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 7343 .channel_mode = alc883_3ST_2ch_modes, 7344 .input_mux = &alc883_capture_source, 7345 .unsol_event = alc883_medion_md2_unsol_event, 7346 .init_hook = alc883_medion_md2_automute, 7347 }, 7348 [ALC883_LAPTOP_EAPD] = { 7349 .mixers = { alc883_base_mixer }, 7350 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs }, 7351 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 7352 .dac_nids = alc883_dac_nids, 7353 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 7354 .adc_nids = alc883_adc_nids, 7355 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 7356 .channel_mode = alc883_3ST_2ch_modes, 7357 .input_mux = &alc883_capture_source, 7358 }, 7359 [ALC883_LENOVO_101E_2ch] = { 7360 .mixers = { alc883_lenovo_101e_2ch_mixer}, 7361 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs}, 7362 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 7363 .dac_nids = alc883_dac_nids, 7364 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 7365 .adc_nids = alc883_adc_nids, 7366 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 7367 .channel_mode = alc883_3ST_2ch_modes, 7368 .input_mux = &alc883_lenovo_101e_capture_source, 7369 .unsol_event = alc883_lenovo_101e_unsol_event, 7370 .init_hook = alc883_lenovo_101e_all_automute, 7371 }, 7372 [ALC883_LENOVO_NB0763] = { 7373 .mixers = { alc883_lenovo_nb0763_mixer }, 7374 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs}, 7375 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 7376 .dac_nids = alc883_dac_nids, 7377 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 7378 .adc_nids = alc883_adc_nids, 7379 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 7380 .channel_mode = alc883_3ST_2ch_modes, 7381 .need_dac_fix = 1, 7382 .input_mux = &alc883_lenovo_nb0763_capture_source, 7383 .unsol_event = alc883_medion_md2_unsol_event, 7384 .init_hook = alc883_medion_md2_automute, 7385 }, 7386 [ALC888_LENOVO_MS7195_DIG] = { 7387 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, 7388 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs}, 7389 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 7390 .dac_nids = alc883_dac_nids, 7391 .dig_out_nid = ALC883_DIGOUT_NID, 7392 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 7393 .adc_nids = alc883_adc_nids, 7394 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 7395 .channel_mode = alc883_3ST_6ch_modes, 7396 .need_dac_fix = 1, 7397 .input_mux = &alc883_capture_source, 7398 .unsol_event = alc883_lenovo_ms7195_unsol_event, 7399 .init_hook = alc888_lenovo_ms7195_front_automute, 7400 }, 7401 [ALC883_HAIER_W66] = { 7402 .mixers = { alc883_tagra_2ch_mixer}, 7403 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs}, 7404 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 7405 .dac_nids = alc883_dac_nids, 7406 .dig_out_nid = ALC883_DIGOUT_NID, 7407 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 7408 .adc_nids = alc883_adc_nids, 7409 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 7410 .channel_mode = alc883_3ST_2ch_modes, 7411 .input_mux = &alc883_capture_source, 7412 .unsol_event = alc883_haier_w66_unsol_event, 7413 .init_hook = alc883_haier_w66_automute, 7414 }, 7415 [ALC888_6ST_HP] = { 7416 .mixers = { alc888_6st_hp_mixer, alc883_chmode_mixer }, 7417 .init_verbs = { alc883_init_verbs, alc888_6st_hp_verbs }, 7418 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 7419 .dac_nids = alc883_dac_nids, 7420 .dig_out_nid = ALC883_DIGOUT_NID, 7421 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 7422 .adc_nids = alc883_adc_nids, 7423 .dig_in_nid = ALC883_DIGIN_NID, 7424 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), 7425 .channel_mode = alc883_sixstack_modes, 7426 .input_mux = &alc883_capture_source, 7427 }, 7428 [ALC888_3ST_HP] = { 7429 .mixers = { alc888_3st_hp_mixer, alc883_chmode_mixer }, 7430 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs }, 7431 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 7432 .dac_nids = alc883_dac_nids, 7433 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 7434 .adc_nids = alc883_adc_nids, 7435 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes), 7436 .channel_mode = alc888_3st_hp_modes, 7437 .need_dac_fix = 1, 7438 .input_mux = &alc883_capture_source, 7439 }, 7440}; 7441 7442 7443/* 7444 * BIOS auto configuration 7445 */ 7446static void alc883_auto_set_output_and_unmute(struct hda_codec *codec, 7447 hda_nid_t nid, int pin_type, 7448 int dac_idx) 7449{ 7450 /* set as output */ 7451 struct alc_spec *spec = codec->spec; 7452 int idx; 7453 7454 if (spec->multiout.dac_nids[dac_idx] == 0x25) 7455 idx = 4; 7456 else 7457 idx = spec->multiout.dac_nids[dac_idx] - 2; 7458 7459 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 7460 pin_type); 7461 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, 7462 AMP_OUT_UNMUTE); 7463 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx); 7464 7465} 7466 7467static void alc883_auto_init_multi_out(struct hda_codec *codec) 7468{ 7469 struct alc_spec *spec = codec->spec; 7470 int i; 7471 7472 alc_subsystem_id(codec, 0x15, 0x1b, 0x14); 7473 for (i = 0; i <= HDA_SIDE; i++) { 7474 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 7475 int pin_type = get_pin_type(spec->autocfg.line_out_type); 7476 if (nid) 7477 alc883_auto_set_output_and_unmute(codec, nid, pin_type, 7478 i); 7479 } 7480} 7481 7482static void alc883_auto_init_hp_out(struct hda_codec *codec) 7483{ 7484 struct alc_spec *spec = codec->spec; 7485 hda_nid_t pin; 7486 7487 pin = spec->autocfg.hp_pins[0]; 7488 if (pin) /* connect to front */ 7489 /* use dac 0 */ 7490 alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); 7491} 7492 7493#define alc883_is_input_pin(nid) alc880_is_input_pin(nid) 7494#define ALC883_PIN_CD_NID ALC880_PIN_CD_NID 7495 7496static void alc883_auto_init_analog_input(struct hda_codec *codec) 7497{ 7498 struct alc_spec *spec = codec->spec; 7499 int i; 7500 7501 for (i = 0; i < AUTO_PIN_LAST; i++) { 7502 hda_nid_t nid = spec->autocfg.input_pins[i]; 7503 if (alc883_is_input_pin(nid)) { 7504 snd_hda_codec_write(codec, nid, 0, 7505 AC_VERB_SET_PIN_WIDGET_CONTROL, 7506 (i <= AUTO_PIN_FRONT_MIC ? 7507 PIN_VREF80 : PIN_IN)); 7508 if (nid != ALC883_PIN_CD_NID) 7509 snd_hda_codec_write(codec, nid, 0, 7510 AC_VERB_SET_AMP_GAIN_MUTE, 7511 AMP_OUT_MUTE); 7512 } 7513 } 7514} 7515 7516/* almost identical with ALC880 parser... */ 7517static int alc883_parse_auto_config(struct hda_codec *codec) 7518{ 7519 struct alc_spec *spec = codec->spec; 7520 int err = alc880_parse_auto_config(codec); 7521 7522 if (err < 0) 7523 return err; 7524 else if (!err) 7525 return 0; /* no config found */ 7526 7527 err = alc_auto_add_mic_boost(codec); 7528 if (err < 0) 7529 return err; 7530 7531 /* hack - override the init verbs */ 7532 spec->init_verbs[0] = alc883_auto_init_verbs; 7533 spec->mixers[spec->num_mixers] = alc883_capture_mixer; 7534 spec->num_mixers++; 7535 7536 return 1; /* config found */ 7537} 7538 7539/* additional initialization for auto-configuration model */ 7540static void alc883_auto_init(struct hda_codec *codec) 7541{ 7542 alc883_auto_init_multi_out(codec); 7543 alc883_auto_init_hp_out(codec); 7544 alc883_auto_init_analog_input(codec); 7545} 7546 7547static int patch_alc883(struct hda_codec *codec) 7548{ 7549 struct alc_spec *spec; 7550 int err, board_config; 7551 7552 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 7553 if (spec == NULL) 7554 return -ENOMEM; 7555 7556 codec->spec = spec; 7557 7558 board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST, 7559 alc883_models, 7560 alc883_cfg_tbl); 7561 if (board_config < 0) { 7562 printk(KERN_INFO "hda_codec: Unknown model for ALC883, " 7563 "trying auto-probe from BIOS...\n"); 7564 board_config = ALC883_AUTO; 7565 } 7566 7567 if (board_config == ALC883_AUTO) { 7568 /* automatic parse from the BIOS config */ 7569 err = alc883_parse_auto_config(codec); 7570 if (err < 0) { 7571 alc_free(codec); 7572 return err; 7573 } else if (!err) { 7574 printk(KERN_INFO 7575 "hda_codec: Cannot set up configuration " 7576 "from BIOS. Using base mode...\n"); 7577 board_config = ALC883_3ST_2ch_DIG; 7578 } 7579 } 7580 7581 if (board_config != ALC883_AUTO) 7582 setup_preset(spec, &alc883_presets[board_config]); 7583 7584 spec->stream_name_analog = "ALC883 Analog"; 7585 spec->stream_analog_playback = &alc883_pcm_analog_playback; 7586 spec->stream_analog_capture = &alc883_pcm_analog_capture; 7587 7588 spec->stream_name_digital = "ALC883 Digital"; 7589 spec->stream_digital_playback = &alc883_pcm_digital_playback; 7590 spec->stream_digital_capture = &alc883_pcm_digital_capture; 7591 7592 if (!spec->adc_nids && spec->input_mux) { 7593 spec->adc_nids = alc883_adc_nids; 7594 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids); 7595 } 7596 7597 codec->patch_ops = alc_patch_ops; 7598 if (board_config == ALC883_AUTO) 7599 spec->init_hook = alc883_auto_init; 7600#ifdef CONFIG_SND_HDA_POWER_SAVE 7601 if (!spec->loopback.amplist) 7602 spec->loopback.amplist = alc883_loopbacks; 7603#endif 7604 7605 return 0; 7606} 7607 7608/* 7609 * ALC262 support 7610 */ 7611 7612#define ALC262_DIGOUT_NID ALC880_DIGOUT_NID 7613#define ALC262_DIGIN_NID ALC880_DIGIN_NID 7614 7615#define alc262_dac_nids alc260_dac_nids 7616#define alc262_adc_nids alc882_adc_nids 7617#define alc262_adc_nids_alt alc882_adc_nids_alt 7618 7619#define alc262_modes alc260_modes 7620#define alc262_capture_source alc882_capture_source 7621 7622static struct snd_kcontrol_new alc262_base_mixer[] = { 7623 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7624 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 7625 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 7626 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 7627 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 7628 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 7629 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7630 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7631 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 7632 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 7633 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 7634 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 7635 /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT), 7636 HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */ 7637 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT), 7638 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 7639 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 7640 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT), 7641 { } /* end */ 7642}; 7643 7644static struct snd_kcontrol_new alc262_hippo1_mixer[] = { 7645 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7646 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 7647 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 7648 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 7649 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 7650 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 7651 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7652 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7653 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 7654 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 7655 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 7656 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 7657 /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT), 7658 HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */ 7659 /*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/ 7660 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 7661 { } /* end */ 7662}; 7663 7664static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = { 7665 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7666 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT), 7667 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 7668 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 7669 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT), 7670 7671 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7672 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7673 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 7674 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 7675 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 7676 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 7677 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 7678 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 7679 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 7680 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 7681 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT), 7682 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), 7683 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT), 7684 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT), 7685 { } /* end */ 7686}; 7687 7688static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = { 7689 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7690 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 7691 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 7692 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 7693 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 7694 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT), 7695 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT), 7696 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT), 7697 HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT), 7698 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT), 7699 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT), 7700 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 7701 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 7702 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT), 7703 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), 7704 { } /* end */ 7705}; 7706 7707static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = { 7708 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7709 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7710 HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT), 7711 { } /* end */ 7712}; 7713 7714static struct hda_bind_ctls alc262_hp_t5735_bind_front_vol = { 7715 .ops = &snd_hda_bind_vol, 7716 .values = { 7717 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT), 7718 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT), 7719 0 7720 }, 7721}; 7722 7723static struct hda_bind_ctls alc262_hp_t5735_bind_front_sw = { 7724 .ops = &snd_hda_bind_sw, 7725 .values = { 7726 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 7727 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT), 7728 0 7729 }, 7730}; 7731 7732/* mute/unmute internal speaker according to the hp jack and mute state */ 7733static void alc262_hp_t5735_automute(struct hda_codec *codec, int force) 7734{ 7735 struct alc_spec *spec = codec->spec; 7736 unsigned int mute; 7737 7738 if (force || !spec->sense_updated) { 7739 unsigned int present; 7740 present = snd_hda_codec_read(codec, 0x15, 0, 7741 AC_VERB_GET_PIN_SENSE, 0); 7742 spec->jack_present = (present & 0x80000000) != 0; 7743 spec->sense_updated = 1; 7744 } 7745 if (spec->jack_present) 7746 mute = (0x7080 | ((0)<<8)); /* mute internal speaker */ 7747 else /* unmute internal speaker if necessary */ 7748 mute = (0x7000 | ((0)<<8)); 7749 snd_hda_codec_write(codec, 0x0c, 0, 7750 AC_VERB_SET_AMP_GAIN_MUTE, mute ); 7751} 7752 7753static void alc262_hp_t5735_unsol_event(struct hda_codec *codec, 7754 unsigned int res) 7755{ 7756 if ((res >> 26) != ALC880_HP_EVENT) 7757 return; 7758 alc262_hp_t5735_automute(codec, 1); 7759} 7760 7761static void alc262_hp_t5735_init_hook(struct hda_codec *codec) 7762{ 7763 alc262_hp_t5735_automute(codec, 1); 7764} 7765 7766static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = { 7767 HDA_BIND_VOL("PCM Playback Volume", &alc262_hp_t5735_bind_front_vol), 7768 HDA_BIND_SW("PCM Playback Switch",&alc262_hp_t5735_bind_front_sw), 7769 HDA_CODEC_VOLUME("LineOut Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7770 HDA_CODEC_MUTE("LineOut Playback Switch", 0x14, 0x0, HDA_OUTPUT), 7771 HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7772 HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 7773 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 7774 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 7775 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7776 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7777 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 7778 { } /* end */ 7779}; 7780 7781static struct hda_verb alc262_hp_t5735_verbs[] = { 7782 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 7783 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 7784 7785 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 7786 { } 7787}; 7788 7789/* bind hp and internal speaker mute (with plug check) */ 7790static int alc262_sony_master_sw_put(struct snd_kcontrol *kcontrol, 7791 struct snd_ctl_elem_value *ucontrol) 7792{ 7793 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 7794 long *valp = ucontrol->value.integer.value; 7795 int change; 7796 7797 /* change hp mute */ 7798 change = snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0, 7799 HDA_AMP_MUTE, 7800 valp[0] ? 0 : HDA_AMP_MUTE); 7801 change |= snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0, 7802 HDA_AMP_MUTE, 7803 valp[1] ? 0 : HDA_AMP_MUTE); 7804 if (change) { 7805 /* change speaker according to HP jack state */ 7806 struct alc_spec *spec = codec->spec; 7807 unsigned int mute; 7808 if (spec->jack_present) 7809 mute = HDA_AMP_MUTE; 7810 else 7811 mute = snd_hda_codec_amp_read(codec, 0x15, 0, 7812 HDA_OUTPUT, 0); 7813 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 7814 HDA_AMP_MUTE, mute); 7815 } 7816 return change; 7817} 7818 7819static struct snd_kcontrol_new alc262_sony_mixer[] = { 7820 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7821 { 7822 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 7823 .name = "Master Playback Switch", 7824 .info = snd_hda_mixer_amp_switch_info, 7825 .get = snd_hda_mixer_amp_switch_get, 7826 .put = alc262_sony_master_sw_put, 7827 .private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT), 7828 }, 7829 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7830 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7831 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 7832 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 7833 { } /* end */ 7834}; 7835 7836static struct snd_kcontrol_new alc262_benq_t31_mixer[] = { 7837 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7838 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 7839 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 7840 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7841 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7842 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 7843 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 7844 { } /* end */ 7845}; 7846 7847#define alc262_capture_mixer alc882_capture_mixer 7848#define alc262_capture_alt_mixer alc882_capture_alt_mixer 7849 7850/* 7851 * generic initialization of ADC, input mixers and output mixers 7852 */ 7853static struct hda_verb alc262_init_verbs[] = { 7854 /* 7855 * Unmute ADC0-2 and set the default input to mic-in 7856 */ 7857 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 7858 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7859 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 7860 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7861 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 7862 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7863 7864 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 7865 * mixer widget 7866 * Note: PASD motherboards uses the Line In 2 as the input for 7867 * front panel mic (mic 2) 7868 */ 7869 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 7870 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7871 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7872 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 7873 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 7874 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 7875 7876 /* 7877 * Set up output mixers (0x0c - 0x0e) 7878 */ 7879 /* set vol=0 to output mixers */ 7880 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 7881 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 7882 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 7883 /* set up input amps for analog loopback */ 7884 /* Amp Indices: DAC = 0, mixer = 1 */ 7885 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7886 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 7887 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7888 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 7889 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7890 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 7891 7892 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 7893 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 7894 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 7895 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 7896 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 7897 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 7898 7899 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 7900 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 7901 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 7902 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 7903 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 7904 7905 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 7906 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 7907 7908 /* FIXME: use matrix-type input source selection */ 7909 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 7910 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 7911 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 7912 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 7913 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 7914 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 7915 /* Input mixer2 */ 7916 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 7917 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 7918 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 7919 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 7920 /* Input mixer3 */ 7921 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 7922 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 7923 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 7924 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 7925 7926 { } 7927}; 7928 7929static struct hda_verb alc262_hippo_unsol_verbs[] = { 7930 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 7931 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 7932 {} 7933}; 7934 7935static struct hda_verb alc262_hippo1_unsol_verbs[] = { 7936 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 7937 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 7938 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 7939 7940 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 7941 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 7942 {} 7943}; 7944 7945static struct hda_verb alc262_sony_unsol_verbs[] = { 7946 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 7947 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 7948 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic 7949 7950 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 7951 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 7952}; 7953 7954/* mute/unmute internal speaker according to the hp jack and mute state */ 7955static void alc262_hippo_automute(struct hda_codec *codec) 7956{ 7957 struct alc_spec *spec = codec->spec; 7958 unsigned int mute; 7959 unsigned int present; 7960 7961 /* need to execute and sync at first */ 7962 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0); 7963 present = snd_hda_codec_read(codec, 0x15, 0, 7964 AC_VERB_GET_PIN_SENSE, 0); 7965 spec->jack_present = (present & 0x80000000) != 0; 7966 if (spec->jack_present) { 7967 /* mute internal speaker */ 7968 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 7969 HDA_AMP_MUTE, HDA_AMP_MUTE); 7970 } else { 7971 /* unmute internal speaker if necessary */ 7972 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0); 7973 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 7974 HDA_AMP_MUTE, mute); 7975 } 7976} 7977 7978/* unsolicited event for HP jack sensing */ 7979static void alc262_hippo_unsol_event(struct hda_codec *codec, 7980 unsigned int res) 7981{ 7982 if ((res >> 26) != ALC880_HP_EVENT) 7983 return; 7984 alc262_hippo_automute(codec); 7985} 7986 7987static void alc262_hippo1_automute(struct hda_codec *codec) 7988{ 7989 unsigned int mute; 7990 unsigned int present; 7991 7992 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0); 7993 present = snd_hda_codec_read(codec, 0x1b, 0, 7994 AC_VERB_GET_PIN_SENSE, 0); 7995 present = (present & 0x80000000) != 0; 7996 if (present) { 7997 /* mute internal speaker */ 7998 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 7999 HDA_AMP_MUTE, HDA_AMP_MUTE); 8000 } else { 8001 /* unmute internal speaker if necessary */ 8002 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0); 8003 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 8004 HDA_AMP_MUTE, mute); 8005 } 8006} 8007 8008/* unsolicited event for HP jack sensing */ 8009static void alc262_hippo1_unsol_event(struct hda_codec *codec, 8010 unsigned int res) 8011{ 8012 if ((res >> 26) != ALC880_HP_EVENT) 8013 return; 8014 alc262_hippo1_automute(codec); 8015} 8016 8017/* 8018 * fujitsu model 8019 * 0x14 = headphone/spdif-out, 0x15 = internal speaker 8020 */ 8021 8022#define ALC_HP_EVENT 0x37 8023 8024static struct hda_verb alc262_fujitsu_unsol_verbs[] = { 8025 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, 8026 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8027 {} 8028}; 8029 8030static struct hda_input_mux alc262_fujitsu_capture_source = { 8031 .num_items = 3, 8032 .items = { 8033 { "Mic", 0x0 }, 8034 { "Int Mic", 0x1 }, 8035 { "CD", 0x4 }, 8036 }, 8037}; 8038 8039static struct hda_input_mux alc262_HP_capture_source = { 8040 .num_items = 5, 8041 .items = { 8042 { "Mic", 0x0 }, 8043 { "Front Mic", 0x1 }, 8044 { "Line", 0x2 }, 8045 { "CD", 0x4 }, 8046 { "AUX IN", 0x6 }, 8047 }, 8048}; 8049 8050static struct hda_input_mux alc262_HP_D7000_capture_source = { 8051 .num_items = 4, 8052 .items = { 8053 { "Mic", 0x0 }, 8054 { "Front Mic", 0x2 }, 8055 { "Line", 0x1 }, 8056 { "CD", 0x4 }, 8057 }, 8058}; 8059 8060/* mute/unmute internal speaker according to the hp jack and mute state */ 8061static void alc262_fujitsu_automute(struct hda_codec *codec, int force) 8062{ 8063 struct alc_spec *spec = codec->spec; 8064 unsigned int mute; 8065 8066 if (force || !spec->sense_updated) { 8067 unsigned int present; 8068 /* need to execute and sync at first */ 8069 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0); 8070 present = snd_hda_codec_read(codec, 0x14, 0, 8071 AC_VERB_GET_PIN_SENSE, 0); 8072 spec->jack_present = (present & 0x80000000) != 0; 8073 spec->sense_updated = 1; 8074 } 8075 if (spec->jack_present) { 8076 /* mute internal speaker */ 8077 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 8078 HDA_AMP_MUTE, HDA_AMP_MUTE); 8079 } else { 8080 /* unmute internal speaker if necessary */ 8081 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0); 8082 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 8083 HDA_AMP_MUTE, mute); 8084 } 8085} 8086 8087/* unsolicited event for HP jack sensing */ 8088static void alc262_fujitsu_unsol_event(struct hda_codec *codec, 8089 unsigned int res) 8090{ 8091 if ((res >> 26) != ALC_HP_EVENT) 8092 return; 8093 alc262_fujitsu_automute(codec, 1); 8094} 8095 8096/* bind volumes of both NID 0x0c and 0x0d */ 8097static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = { 8098 .ops = &snd_hda_bind_vol, 8099 .values = { 8100 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT), 8101 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT), 8102 0 8103 }, 8104}; 8105 8106/* bind hp and internal speaker mute (with plug check) */ 8107static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol, 8108 struct snd_ctl_elem_value *ucontrol) 8109{ 8110 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 8111 long *valp = ucontrol->value.integer.value; 8112 int change; 8113 8114 change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0, 8115 HDA_AMP_MUTE, 8116 valp[0] ? 0 : HDA_AMP_MUTE); 8117 change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0, 8118 HDA_AMP_MUTE, 8119 valp[1] ? 0 : HDA_AMP_MUTE); 8120 if (change) 8121 alc262_fujitsu_automute(codec, 0); 8122 return change; 8123} 8124 8125static struct snd_kcontrol_new alc262_fujitsu_mixer[] = { 8126 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol), 8127 { 8128 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 8129 .name = "Master Playback Switch", 8130 .info = snd_hda_mixer_amp_switch_info, 8131 .get = snd_hda_mixer_amp_switch_get, 8132 .put = alc262_fujitsu_master_sw_put, 8133 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 8134 }, 8135 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 8136 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 8137 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8138 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8139 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8140 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 8141 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8142 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8143 { } /* end */ 8144}; 8145 8146/* additional init verbs for Benq laptops */ 8147static struct hda_verb alc262_EAPD_verbs[] = { 8148 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 8149 {0x20, AC_VERB_SET_PROC_COEF, 0x3070}, 8150 {} 8151}; 8152 8153static struct hda_verb alc262_benq_t31_EAPD_verbs[] = { 8154 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 8155 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 8156 8157 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 8158 {0x20, AC_VERB_SET_PROC_COEF, 0x3050}, 8159 {} 8160}; 8161 8162/* Samsung Q1 Ultra Vista model setup */ 8163static struct snd_kcontrol_new alc262_ultra_mixer[] = { 8164 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8165 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 8166 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 8167 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 8168 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 8169 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT), 8170 { } /* end */ 8171}; 8172 8173static struct hda_verb alc262_ultra_verbs[] = { 8174 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 8175 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8176 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 8177 /* Mic is on Node 0x19 */ 8178 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 8179 {0x22, AC_VERB_SET_CONNECT_SEL, 0x01}, 8180 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 8181 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01}, 8182 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 8183 {0x24, AC_VERB_SET_CONNECT_SEL, 0x01}, 8184 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 8185 {} 8186}; 8187 8188static struct hda_input_mux alc262_ultra_capture_source = { 8189 .num_items = 1, 8190 .items = { 8191 { "Mic", 0x1 }, 8192 }, 8193}; 8194 8195/* mute/unmute internal speaker according to the hp jack and mute state */ 8196static void alc262_ultra_automute(struct hda_codec *codec) 8197{ 8198 struct alc_spec *spec = codec->spec; 8199 unsigned int mute; 8200 unsigned int present; 8201 8202 /* need to execute and sync at first */ 8203 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0); 8204 present = snd_hda_codec_read(codec, 0x15, 0, 8205 AC_VERB_GET_PIN_SENSE, 0); 8206 spec->jack_present = (present & 0x80000000) != 0; 8207 if (spec->jack_present) { 8208 /* mute internal speaker */ 8209 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 8210 HDA_AMP_MUTE, HDA_AMP_MUTE); 8211 } else { 8212 /* unmute internal speaker if necessary */ 8213 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0); 8214 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 8215 HDA_AMP_MUTE, mute); 8216 } 8217} 8218 8219/* unsolicited event for HP jack sensing */ 8220static void alc262_ultra_unsol_event(struct hda_codec *codec, 8221 unsigned int res) 8222{ 8223 if ((res >> 26) != ALC880_HP_EVENT) 8224 return; 8225 alc262_ultra_automute(codec); 8226} 8227 8228/* add playback controls from the parsed DAC table */ 8229static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, 8230 const struct auto_pin_cfg *cfg) 8231{ 8232 hda_nid_t nid; 8233 int err; 8234 8235 spec->multiout.num_dacs = 1; /* only use one dac */ 8236 spec->multiout.dac_nids = spec->private_dac_nids; 8237 spec->multiout.dac_nids[0] = 2; 8238 8239 nid = cfg->line_out_pins[0]; 8240 if (nid) { 8241 err = add_control(spec, ALC_CTL_WIDGET_VOL, 8242 "Front Playback Volume", 8243 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT)); 8244 if (err < 0) 8245 return err; 8246 err = add_control(spec, ALC_CTL_WIDGET_MUTE, 8247 "Front Playback Switch", 8248 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); 8249 if (err < 0) 8250 return err; 8251 } 8252 8253 nid = cfg->speaker_pins[0]; 8254 if (nid) { 8255 if (nid == 0x16) { 8256 err = add_control(spec, ALC_CTL_WIDGET_VOL, 8257 "Speaker Playback Volume", 8258 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, 8259 HDA_OUTPUT)); 8260 if (err < 0) 8261 return err; 8262 err = add_control(spec, ALC_CTL_WIDGET_MUTE, 8263 "Speaker Playback Switch", 8264 HDA_COMPOSE_AMP_VAL(nid, 2, 0, 8265 HDA_OUTPUT)); 8266 if (err < 0) 8267 return err; 8268 } else { 8269 err = add_control(spec, ALC_CTL_WIDGET_MUTE, 8270 "Speaker Playback Switch", 8271 HDA_COMPOSE_AMP_VAL(nid, 3, 0, 8272 HDA_OUTPUT)); 8273 if (err < 0) 8274 return err; 8275 } 8276 } 8277 nid = cfg->hp_pins[0]; 8278 if (nid) { 8279 /* spec->multiout.hp_nid = 2; */ 8280 if (nid == 0x16) { 8281 err = add_control(spec, ALC_CTL_WIDGET_VOL, 8282 "Headphone Playback Volume", 8283 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, 8284 HDA_OUTPUT)); 8285 if (err < 0) 8286 return err; 8287 err = add_control(spec, ALC_CTL_WIDGET_MUTE, 8288 "Headphone Playback Switch", 8289 HDA_COMPOSE_AMP_VAL(nid, 2, 0, 8290 HDA_OUTPUT)); 8291 if (err < 0) 8292 return err; 8293 } else { 8294 err = add_control(spec, ALC_CTL_WIDGET_MUTE, 8295 "Headphone Playback Switch", 8296 HDA_COMPOSE_AMP_VAL(nid, 3, 0, 8297 HDA_OUTPUT)); 8298 if (err < 0) 8299 return err; 8300 } 8301 } 8302 return 0; 8303} 8304 8305/* identical with ALC880 */ 8306#define alc262_auto_create_analog_input_ctls \ 8307 alc880_auto_create_analog_input_ctls 8308 8309/* 8310 * generic initialization of ADC, input mixers and output mixers 8311 */ 8312static struct hda_verb alc262_volume_init_verbs[] = { 8313 /* 8314 * Unmute ADC0-2 and set the default input to mic-in 8315 */ 8316 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 8317 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8318 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 8319 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8320 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 8321 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8322 8323 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 8324 * mixer widget 8325 * Note: PASD motherboards uses the Line In 2 as the input for 8326 * front panel mic (mic 2) 8327 */ 8328 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 8329 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8330 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8331 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 8332 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8333 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8334 8335 /* 8336 * Set up output mixers (0x0c - 0x0f) 8337 */ 8338 /* set vol=0 to output mixers */ 8339 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8340 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8341 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8342 8343 /* set up input amps for analog loopback */ 8344 /* Amp Indices: DAC = 0, mixer = 1 */ 8345 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8346 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8347 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8348 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8349 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8350 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8351 8352 /* FIXME: use matrix-type input source selection */ 8353 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 8354 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 8355 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 8356 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 8357 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 8358 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 8359 /* Input mixer2 */ 8360 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 8361 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 8362 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 8363 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 8364 /* Input mixer3 */ 8365 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 8366 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 8367 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 8368 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 8369 8370 { } 8371}; 8372 8373static struct hda_verb alc262_HP_BPC_init_verbs[] = { 8374 /* 8375 * Unmute ADC0-2 and set the default input to mic-in 8376 */ 8377 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 8378 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8379 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 8380 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8381 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 8382 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8383 8384 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 8385 * mixer widget 8386 * Note: PASD motherboards uses the Line In 2 as the input for 8387 * front panel mic (mic 2) 8388 */ 8389 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 8390 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8391 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8392 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 8393 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8394 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8395 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, 8396 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, 8397 8398 /* 8399 * Set up output mixers (0x0c - 0x0e) 8400 */ 8401 /* set vol=0 to output mixers */ 8402 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8403 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8404 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8405 8406 /* set up input amps for analog loopback */ 8407 /* Amp Indices: DAC = 0, mixer = 1 */ 8408 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8409 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8410 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8411 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8412 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8413 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8414 8415 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 8416 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 8417 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 8418 8419 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 8420 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 8421 8422 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 8423 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 8424 8425 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 8426 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 8427 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 8428 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 8429 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 8430 8431 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, 8432 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 8433 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 8434 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, 8435 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 8436 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 8437 8438 8439 /* FIXME: use matrix-type input source selection */ 8440 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 8441 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 8442 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 8443 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, 8444 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, 8445 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, 8446 /* Input mixer2 */ 8447 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 8448 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, 8449 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, 8450 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, 8451 /* Input mixer3 */ 8452 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 8453 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, 8454 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, 8455 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, 8456 8457 { } 8458}; 8459 8460static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = { 8461 /* 8462 * Unmute ADC0-2 and set the default input to mic-in 8463 */ 8464 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 8465 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8466 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 8467 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8468 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 8469 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8470 8471 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 8472 * mixer widget 8473 * Note: PASD motherboards uses the Line In 2 as the input for front 8474 * panel mic (mic 2) 8475 */ 8476 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 8477 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8478 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8479 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 8480 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8481 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8482 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, 8483 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, 8484 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, 8485 /* 8486 * Set up output mixers (0x0c - 0x0e) 8487 */ 8488 /* set vol=0 to output mixers */ 8489 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8490 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8491 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8492 8493 /* set up input amps for analog loopback */ 8494 /* Amp Indices: DAC = 0, mixer = 1 */ 8495 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8496 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8497 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8498 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8499 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8500 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8501 8502 8503 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */ 8504 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */ 8505 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */ 8506 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */ 8507 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */ 8508 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */ 8509 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */ 8510 8511 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 8512 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 8513 8514 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 8515 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 8516 8517 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */ 8518 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 8519 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 8520 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, 8521 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 8522 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 8523 8524 /* FIXME: use matrix-type input source selection */ 8525 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 8526 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 8527 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/ 8528 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/ 8529 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/ 8530 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/ 8531 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/ 8532 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */ 8533 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/ 8534 /* Input mixer2 */ 8535 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 8536 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 8537 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, 8538 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, 8539 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, 8540 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */ 8541 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, 8542 /* Input mixer3 */ 8543 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 8544 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 8545 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, 8546 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, 8547 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, 8548 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */ 8549 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, 8550 8551 { } 8552}; 8553 8554#ifdef CONFIG_SND_HDA_POWER_SAVE 8555#define alc262_loopbacks alc880_loopbacks 8556#endif 8557 8558/* pcm configuration: identiacal with ALC880 */ 8559#define alc262_pcm_analog_playback alc880_pcm_analog_playback 8560#define alc262_pcm_analog_capture alc880_pcm_analog_capture 8561#define alc262_pcm_digital_playback alc880_pcm_digital_playback 8562#define alc262_pcm_digital_capture alc880_pcm_digital_capture 8563 8564/* 8565 * BIOS auto configuration 8566 */ 8567static int alc262_parse_auto_config(struct hda_codec *codec) 8568{ 8569 struct alc_spec *spec = codec->spec; 8570 int err; 8571 static hda_nid_t alc262_ignore[] = { 0x1d, 0 }; 8572 8573 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 8574 alc262_ignore); 8575 if (err < 0) 8576 return err; 8577 if (!spec->autocfg.line_outs) 8578 return 0; /* can't find valid BIOS pin config */ 8579 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg); 8580 if (err < 0) 8581 return err; 8582 err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg); 8583 if (err < 0) 8584 return err; 8585 8586 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 8587 8588 if (spec->autocfg.dig_out_pin) 8589 spec->multiout.dig_out_nid = ALC262_DIGOUT_NID; 8590 if (spec->autocfg.dig_in_pin) 8591 spec->dig_in_nid = ALC262_DIGIN_NID; 8592 8593 if (spec->kctl_alloc) 8594 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 8595 8596 spec->init_verbs[spec->num_init_verbs++] = alc262_volume_init_verbs; 8597 spec->num_mux_defs = 1; 8598 spec->input_mux = &spec->private_imux; 8599 8600 err = alc_auto_add_mic_boost(codec); 8601 if (err < 0) 8602 return err; 8603 8604 return 1; 8605} 8606 8607#define alc262_auto_init_multi_out alc882_auto_init_multi_out 8608#define alc262_auto_init_hp_out alc882_auto_init_hp_out 8609#define alc262_auto_init_analog_input alc882_auto_init_analog_input 8610 8611 8612/* init callback for auto-configuration model -- overriding the default init */ 8613static void alc262_auto_init(struct hda_codec *codec) 8614{ 8615 alc262_auto_init_multi_out(codec); 8616 alc262_auto_init_hp_out(codec); 8617 alc262_auto_init_analog_input(codec); 8618} 8619 8620/* 8621 * configuration and preset 8622 */ 8623static const char *alc262_models[ALC262_MODEL_LAST] = { 8624 [ALC262_BASIC] = "basic", 8625 [ALC262_HIPPO] = "hippo", 8626 [ALC262_HIPPO_1] = "hippo_1", 8627 [ALC262_FUJITSU] = "fujitsu", 8628 [ALC262_HP_BPC] = "hp-bpc", 8629 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000", 8630 [ALC262_HP_TC_T5735] = "hp-tc-t5735", 8631 [ALC262_BENQ_ED8] = "benq", 8632 [ALC262_BENQ_T31] = "benq-t31", 8633 [ALC262_SONY_ASSAMD] = "sony-assamd", 8634 [ALC262_ULTRA] = "ultra", 8635 [ALC262_AUTO] = "auto", 8636}; 8637 8638static struct snd_pci_quirk alc262_cfg_tbl[] = { 8639 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO), 8640 SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC), 8641 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC), 8642 SND_PCI_QUIRK(0x103c, 0x12ff, "HP xw4550", ALC262_HP_BPC), 8643 SND_PCI_QUIRK(0x103c, 0x1308, "HP xw4600", ALC262_HP_BPC), 8644 SND_PCI_QUIRK(0x103c, 0x1309, "HP xw4*00", ALC262_HP_BPC), 8645 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC), 8646 SND_PCI_QUIRK(0x103c, 0x1307, "HP xw6600", ALC262_HP_BPC), 8647 SND_PCI_QUIRK(0x103c, 0x130a, "HP xw6*00", ALC262_HP_BPC), 8648 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC), 8649 SND_PCI_QUIRK(0x103c, 0x1306, "HP xw8600", ALC262_HP_BPC), 8650 SND_PCI_QUIRK(0x103c, 0x130b, "HP xw8*00", ALC262_HP_BPC), 8651 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL), 8652 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL), 8653 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL), 8654 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL), 8655 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF), 8656 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF), 8657 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF), 8658 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF), 8659 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735", 8660 ALC262_HP_TC_T5735), 8661 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO), 8662 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU), 8663 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1), 8664 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8), 8665 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31), 8666 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD), 8667 SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD), 8668 SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD), 8669 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD), 8670 SND_PCI_QUIRK(0x144d, 0xc032, "Samsung Q1 Ultra", ALC262_ULTRA), 8671 {} 8672}; 8673 8674static struct alc_config_preset alc262_presets[] = { 8675 [ALC262_BASIC] = { 8676 .mixers = { alc262_base_mixer }, 8677 .init_verbs = { alc262_init_verbs }, 8678 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 8679 .dac_nids = alc262_dac_nids, 8680 .hp_nid = 0x03, 8681 .num_channel_mode = ARRAY_SIZE(alc262_modes), 8682 .channel_mode = alc262_modes, 8683 .input_mux = &alc262_capture_source, 8684 }, 8685 [ALC262_HIPPO] = { 8686 .mixers = { alc262_base_mixer }, 8687 .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs}, 8688 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 8689 .dac_nids = alc262_dac_nids, 8690 .hp_nid = 0x03, 8691 .dig_out_nid = ALC262_DIGOUT_NID, 8692 .num_channel_mode = ARRAY_SIZE(alc262_modes), 8693 .channel_mode = alc262_modes, 8694 .input_mux = &alc262_capture_source, 8695 .unsol_event = alc262_hippo_unsol_event, 8696 .init_hook = alc262_hippo_automute, 8697 }, 8698 [ALC262_HIPPO_1] = { 8699 .mixers = { alc262_hippo1_mixer }, 8700 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs}, 8701 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 8702 .dac_nids = alc262_dac_nids, 8703 .hp_nid = 0x02, 8704 .dig_out_nid = ALC262_DIGOUT_NID, 8705 .num_channel_mode = ARRAY_SIZE(alc262_modes), 8706 .channel_mode = alc262_modes, 8707 .input_mux = &alc262_capture_source, 8708 .unsol_event = alc262_hippo1_unsol_event, 8709 .init_hook = alc262_hippo1_automute, 8710 }, 8711 [ALC262_FUJITSU] = { 8712 .mixers = { alc262_fujitsu_mixer }, 8713 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs, 8714 alc262_fujitsu_unsol_verbs }, 8715 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 8716 .dac_nids = alc262_dac_nids, 8717 .hp_nid = 0x03, 8718 .dig_out_nid = ALC262_DIGOUT_NID, 8719 .num_channel_mode = ARRAY_SIZE(alc262_modes), 8720 .channel_mode = alc262_modes, 8721 .input_mux = &alc262_fujitsu_capture_source, 8722 .unsol_event = alc262_fujitsu_unsol_event, 8723 }, 8724 [ALC262_HP_BPC] = { 8725 .mixers = { alc262_HP_BPC_mixer }, 8726 .init_verbs = { alc262_HP_BPC_init_verbs }, 8727 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 8728 .dac_nids = alc262_dac_nids, 8729 .hp_nid = 0x03, 8730 .num_channel_mode = ARRAY_SIZE(alc262_modes), 8731 .channel_mode = alc262_modes, 8732 .input_mux = &alc262_HP_capture_source, 8733 }, 8734 [ALC262_HP_BPC_D7000_WF] = { 8735 .mixers = { alc262_HP_BPC_WildWest_mixer }, 8736 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs }, 8737 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 8738 .dac_nids = alc262_dac_nids, 8739 .hp_nid = 0x03, 8740 .num_channel_mode = ARRAY_SIZE(alc262_modes), 8741 .channel_mode = alc262_modes, 8742 .input_mux = &alc262_HP_D7000_capture_source, 8743 }, 8744 [ALC262_HP_BPC_D7000_WL] = { 8745 .mixers = { alc262_HP_BPC_WildWest_mixer, 8746 alc262_HP_BPC_WildWest_option_mixer }, 8747 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs }, 8748 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 8749 .dac_nids = alc262_dac_nids, 8750 .hp_nid = 0x03, 8751 .num_channel_mode = ARRAY_SIZE(alc262_modes), 8752 .channel_mode = alc262_modes, 8753 .input_mux = &alc262_HP_D7000_capture_source, 8754 }, 8755 [ALC262_HP_TC_T5735] = { 8756 .mixers = { alc262_hp_t5735_mixer }, 8757 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs }, 8758 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 8759 .dac_nids = alc262_dac_nids, 8760 .hp_nid = 0x03, 8761 .num_channel_mode = ARRAY_SIZE(alc262_modes), 8762 .channel_mode = alc262_modes, 8763 .input_mux = &alc262_capture_source, 8764 .unsol_event = alc262_hp_t5735_unsol_event, 8765 .init_hook = alc262_hp_t5735_init_hook, 8766 }, 8767 [ALC262_BENQ_ED8] = { 8768 .mixers = { alc262_base_mixer }, 8769 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs }, 8770 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 8771 .dac_nids = alc262_dac_nids, 8772 .hp_nid = 0x03, 8773 .num_channel_mode = ARRAY_SIZE(alc262_modes), 8774 .channel_mode = alc262_modes, 8775 .input_mux = &alc262_capture_source, 8776 }, 8777 [ALC262_SONY_ASSAMD] = { 8778 .mixers = { alc262_sony_mixer }, 8779 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs}, 8780 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 8781 .dac_nids = alc262_dac_nids, 8782 .hp_nid = 0x02, 8783 .num_channel_mode = ARRAY_SIZE(alc262_modes), 8784 .channel_mode = alc262_modes, 8785 .input_mux = &alc262_capture_source, 8786 .unsol_event = alc262_hippo_unsol_event, 8787 .init_hook = alc262_hippo_automute, 8788 }, 8789 [ALC262_BENQ_T31] = { 8790 .mixers = { alc262_benq_t31_mixer }, 8791 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs }, 8792 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 8793 .dac_nids = alc262_dac_nids, 8794 .hp_nid = 0x03, 8795 .num_channel_mode = ARRAY_SIZE(alc262_modes), 8796 .channel_mode = alc262_modes, 8797 .input_mux = &alc262_capture_source, 8798 .unsol_event = alc262_hippo_unsol_event, 8799 .init_hook = alc262_hippo_automute, 8800 }, 8801 [ALC262_ULTRA] = { 8802 .mixers = { alc262_ultra_mixer }, 8803 .init_verbs = { alc262_init_verbs, alc262_ultra_verbs }, 8804 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 8805 .dac_nids = alc262_dac_nids, 8806 .hp_nid = 0x03, 8807 .dig_out_nid = ALC262_DIGOUT_NID, 8808 .num_channel_mode = ARRAY_SIZE(alc262_modes), 8809 .channel_mode = alc262_modes, 8810 .input_mux = &alc262_ultra_capture_source, 8811 .unsol_event = alc262_ultra_unsol_event, 8812 .init_hook = alc262_ultra_automute, 8813 }, 8814}; 8815 8816static int patch_alc262(struct hda_codec *codec) 8817{ 8818 struct alc_spec *spec; 8819 int board_config; 8820 int err; 8821 8822 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 8823 if (spec == NULL) 8824 return -ENOMEM; 8825 8826 codec->spec = spec; 8827#if 0 8828 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is 8829 * under-run 8830 */ 8831 { 8832 int tmp; 8833 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7); 8834 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0); 8835 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7); 8836 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80); 8837 } 8838#endif 8839 8840 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST, 8841 alc262_models, 8842 alc262_cfg_tbl); 8843 8844 if (board_config < 0) { 8845 printk(KERN_INFO "hda_codec: Unknown model for ALC262, " 8846 "trying auto-probe from BIOS...\n"); 8847 board_config = ALC262_AUTO; 8848 } 8849 8850 if (board_config == ALC262_AUTO) { 8851 /* automatic parse from the BIOS config */ 8852 err = alc262_parse_auto_config(codec); 8853 if (err < 0) { 8854 alc_free(codec); 8855 return err; 8856 } else if (!err) { 8857 printk(KERN_INFO 8858 "hda_codec: Cannot set up configuration " 8859 "from BIOS. Using base mode...\n"); 8860 board_config = ALC262_BASIC; 8861 } 8862 } 8863 8864 if (board_config != ALC262_AUTO) 8865 setup_preset(spec, &alc262_presets[board_config]); 8866 8867 spec->stream_name_analog = "ALC262 Analog"; 8868 spec->stream_analog_playback = &alc262_pcm_analog_playback; 8869 spec->stream_analog_capture = &alc262_pcm_analog_capture; 8870 8871 spec->stream_name_digital = "ALC262 Digital"; 8872 spec->stream_digital_playback = &alc262_pcm_digital_playback; 8873 spec->stream_digital_capture = &alc262_pcm_digital_capture; 8874 8875 if (!spec->adc_nids && spec->input_mux) { 8876 /* check whether NID 0x07 is valid */ 8877 unsigned int wcap = get_wcaps(codec, 0x07); 8878 8879 /* get type */ 8880 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; 8881 if (wcap != AC_WID_AUD_IN) { 8882 spec->adc_nids = alc262_adc_nids_alt; 8883 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt); 8884 spec->mixers[spec->num_mixers] = 8885 alc262_capture_alt_mixer; 8886 spec->num_mixers++; 8887 } else { 8888 spec->adc_nids = alc262_adc_nids; 8889 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids); 8890 spec->mixers[spec->num_mixers] = alc262_capture_mixer; 8891 spec->num_mixers++; 8892 } 8893 } 8894 8895 codec->patch_ops = alc_patch_ops; 8896 if (board_config == ALC262_AUTO) 8897 spec->init_hook = alc262_auto_init; 8898#ifdef CONFIG_SND_HDA_POWER_SAVE 8899 if (!spec->loopback.amplist) 8900 spec->loopback.amplist = alc262_loopbacks; 8901#endif 8902 8903 return 0; 8904} 8905 8906/* 8907 * ALC268 channel source setting (2 channel) 8908 */ 8909#define ALC268_DIGOUT_NID ALC880_DIGOUT_NID 8910#define alc268_modes alc260_modes 8911 8912static hda_nid_t alc268_dac_nids[2] = { 8913 /* front, hp */ 8914 0x02, 0x03 8915}; 8916 8917static hda_nid_t alc268_adc_nids[2] = { 8918 /* ADC0-1 */ 8919 0x08, 0x07 8920}; 8921 8922static hda_nid_t alc268_adc_nids_alt[1] = { 8923 /* ADC0 */ 8924 0x08 8925}; 8926 8927static struct snd_kcontrol_new alc268_base_mixer[] = { 8928 /* output mixer control */ 8929 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), 8930 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 8931 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT), 8932 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 8933 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8934 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 8935 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT), 8936 { } 8937}; 8938 8939static struct hda_verb alc268_eapd_verbs[] = { 8940 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 8941 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, 8942 { } 8943}; 8944 8945/* Toshiba specific */ 8946#define alc268_toshiba_automute alc262_hippo_automute 8947 8948static struct hda_verb alc268_toshiba_verbs[] = { 8949 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 8950 { } /* end */ 8951}; 8952 8953/* Acer specific */ 8954/* bind volumes of both NID 0x02 and 0x03 */ 8955static struct hda_bind_ctls alc268_acer_bind_master_vol = { 8956 .ops = &snd_hda_bind_vol, 8957 .values = { 8958 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), 8959 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT), 8960 0 8961 }, 8962}; 8963 8964/* mute/unmute internal speaker according to the hp jack and mute state */ 8965static void alc268_acer_automute(struct hda_codec *codec, int force) 8966{ 8967 struct alc_spec *spec = codec->spec; 8968 unsigned int mute; 8969 8970 if (force || !spec->sense_updated) { 8971 unsigned int present; 8972 present = snd_hda_codec_read(codec, 0x14, 0, 8973 AC_VERB_GET_PIN_SENSE, 0); 8974 spec->jack_present = (present & 0x80000000) != 0; 8975 spec->sense_updated = 1; 8976 } 8977 if (spec->jack_present) 8978 mute = HDA_AMP_MUTE; /* mute internal speaker */ 8979 else /* unmute internal speaker if necessary */ 8980 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0); 8981 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 8982 HDA_AMP_MUTE, mute); 8983} 8984 8985 8986/* bind hp and internal speaker mute (with plug check) */ 8987static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol, 8988 struct snd_ctl_elem_value *ucontrol) 8989{ 8990 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 8991 long *valp = ucontrol->value.integer.value; 8992 int change; 8993 8994 change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0, 8995 HDA_AMP_MUTE, 8996 valp[0] ? 0 : HDA_AMP_MUTE); 8997 change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0, 8998 HDA_AMP_MUTE, 8999 valp[1] ? 0 : HDA_AMP_MUTE); 9000 if (change) 9001 alc268_acer_automute(codec, 0); 9002 return change; 9003} 9004 9005static struct snd_kcontrol_new alc268_acer_mixer[] = { 9006 /* output mixer control */ 9007 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), 9008 { 9009 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 9010 .name = "Master Playback Switch", 9011 .info = snd_hda_mixer_amp_switch_info, 9012 .get = snd_hda_mixer_amp_switch_get, 9013 .put = alc268_acer_master_sw_put, 9014 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 9015 }, 9016 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 9017 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), 9018 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT), 9019 { } 9020}; 9021 9022static struct hda_verb alc268_acer_verbs[] = { 9023 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9024 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9025 9026 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9027 { } 9028}; 9029 9030/* unsolicited event for HP jack sensing */ 9031static void alc268_toshiba_unsol_event(struct hda_codec *codec, 9032 unsigned int res) 9033{ 9034 if ((res >> 26) != ALC880_HP_EVENT) 9035 return; 9036 alc268_toshiba_automute(codec); 9037} 9038 9039static void alc268_acer_unsol_event(struct hda_codec *codec, 9040 unsigned int res) 9041{ 9042 if ((res >> 26) != ALC880_HP_EVENT) 9043 return; 9044 alc268_acer_automute(codec, 1); 9045} 9046 9047static void alc268_acer_init_hook(struct hda_codec *codec) 9048{ 9049 alc268_acer_automute(codec, 1); 9050} 9051 9052/* 9053 * generic initialization of ADC, input mixers and output mixers 9054 */ 9055static struct hda_verb alc268_base_init_verbs[] = { 9056 /* Unmute DAC0-1 and set vol = 0 */ 9057 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 9058 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9059 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9060 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 9061 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9062 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9063 9064 /* 9065 * Set up output mixers (0x0c - 0x0e) 9066 */ 9067 /* set vol=0 to output mixers */ 9068 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9069 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9070 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 9071 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00}, 9072 9073 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9074 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9075 9076 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 9077 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 9078 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 9079 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 9080 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 9081 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 9082 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 9083 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 9084 9085 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 9086 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 9087 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 9088 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 9089 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 9090 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 9091 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 9092 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 9093 9094 /* FIXME: use matrix-type input source selection */ 9095 /* Mixer elements: 0x18, 19, 1a, 1c, 14, 15, 0b */ 9096 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 9097 /* Input mixer2 */ 9098 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 9099 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 9100 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, 9101 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, 9102 9103 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 9104 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 9105 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, 9106 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, 9107 { } 9108}; 9109 9110/* 9111 * generic initialization of ADC, input mixers and output mixers 9112 */ 9113static struct hda_verb alc268_volume_init_verbs[] = { 9114 /* set output DAC */ 9115 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9116 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9117 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9118 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9119 9120 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 9121 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 9122 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 9123 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 9124 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 9125 9126 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 9127 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9128 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9129 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9130 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9131 9132 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 9133 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 9134 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 9135 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 9136 9137 /* set PCBEEP vol = 0 */ 9138 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, (0xb000 | (0x00 << 8))}, 9139 9140 { } 9141}; 9142 9143#define alc268_mux_enum_info alc_mux_enum_info 9144#define alc268_mux_enum_get alc_mux_enum_get 9145 9146static int alc268_mux_enum_put(struct snd_kcontrol *kcontrol, 9147 struct snd_ctl_elem_value *ucontrol) 9148{ 9149 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 9150 struct alc_spec *spec = codec->spec; 9151 const struct hda_input_mux *imux = spec->input_mux; 9152 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 9153 static hda_nid_t capture_mixers[3] = { 0x23, 0x24 }; 9154 hda_nid_t nid = capture_mixers[adc_idx]; 9155 unsigned int *cur_val = &spec->cur_mux[adc_idx]; 9156 unsigned int i, idx; 9157 9158 idx = ucontrol->value.enumerated.item[0]; 9159 if (idx >= imux->num_items) 9160 idx = imux->num_items - 1; 9161 if (*cur_val == idx) 9162 return 0; 9163 for (i = 0; i < imux->num_items; i++) { 9164 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE; 9165 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 9166 imux->items[i].index, 9167 HDA_AMP_MUTE, v); 9168 snd_hda_codec_write_cache(codec, nid, 0, 9169 AC_VERB_SET_CONNECT_SEL, 9170 idx ); 9171 } 9172 *cur_val = idx; 9173 return 1; 9174} 9175 9176static struct snd_kcontrol_new alc268_capture_alt_mixer[] = { 9177 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT), 9178 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT), 9179 { 9180 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 9181 /* The multiple "Capture Source" controls confuse alsamixer 9182 * So call somewhat different.. 9183 * FIXME: the controls appear in the "playback" view! 9184 */ 9185 /* .name = "Capture Source", */ 9186 .name = "Input Source", 9187 .count = 1, 9188 .info = alc268_mux_enum_info, 9189 .get = alc268_mux_enum_get, 9190 .put = alc268_mux_enum_put, 9191 }, 9192 { } /* end */ 9193}; 9194 9195static struct snd_kcontrol_new alc268_capture_mixer[] = { 9196 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT), 9197 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT), 9198 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT), 9199 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT), 9200 { 9201 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 9202 /* The multiple "Capture Source" controls confuse alsamixer 9203 * So call somewhat different.. 9204 * FIXME: the controls appear in the "playback" view! 9205 */ 9206 /* .name = "Capture Source", */ 9207 .name = "Input Source", 9208 .count = 2, 9209 .info = alc268_mux_enum_info, 9210 .get = alc268_mux_enum_get, 9211 .put = alc268_mux_enum_put, 9212 }, 9213 { } /* end */ 9214}; 9215 9216static struct hda_input_mux alc268_capture_source = { 9217 .num_items = 4, 9218 .items = { 9219 { "Mic", 0x0 }, 9220 { "Front Mic", 0x1 }, 9221 { "Line", 0x2 }, 9222 { "CD", 0x3 }, 9223 }, 9224}; 9225 9226/* create input playback/capture controls for the given pin */ 9227static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid, 9228 const char *ctlname, int idx) 9229{ 9230 char name[32]; 9231 int err; 9232 9233 sprintf(name, "%s Playback Volume", ctlname); 9234 if (nid == 0x14) { 9235 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, 9236 HDA_COMPOSE_AMP_VAL(0x02, 3, idx, 9237 HDA_OUTPUT)); 9238 if (err < 0) 9239 return err; 9240 } else if (nid == 0x15) { 9241 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, 9242 HDA_COMPOSE_AMP_VAL(0x03, 3, idx, 9243 HDA_OUTPUT)); 9244 if (err < 0) 9245 return err; 9246 } else 9247 return -1; 9248 sprintf(name, "%s Playback Switch", ctlname); 9249 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, 9250 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT)); 9251 if (err < 0) 9252 return err; 9253 return 0; 9254} 9255 9256/* add playback controls from the parsed DAC table */ 9257static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec, 9258 const struct auto_pin_cfg *cfg) 9259{ 9260 hda_nid_t nid; 9261 int err; 9262 9263 spec->multiout.num_dacs = 2; /* only use one dac */ 9264 spec->multiout.dac_nids = spec->private_dac_nids; 9265 spec->multiout.dac_nids[0] = 2; 9266 spec->multiout.dac_nids[1] = 3; 9267 9268 nid = cfg->line_out_pins[0]; 9269 if (nid) 9270 alc268_new_analog_output(spec, nid, "Front", 0); 9271 9272 nid = cfg->speaker_pins[0]; 9273 if (nid == 0x1d) { 9274 err = add_control(spec, ALC_CTL_WIDGET_VOL, 9275 "Speaker Playback Volume", 9276 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT)); 9277 if (err < 0) 9278 return err; 9279 } 9280 nid = cfg->hp_pins[0]; 9281 if (nid) 9282 alc268_new_analog_output(spec, nid, "Headphone", 0); 9283 9284 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2]; 9285 if (nid == 0x16) { 9286 err = add_control(spec, ALC_CTL_WIDGET_MUTE, 9287 "Mono Playback Switch", 9288 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT)); 9289 if (err < 0) 9290 return err; 9291 } 9292 return 0; 9293} 9294 9295/* create playback/capture controls for input pins */ 9296static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec, 9297 const struct auto_pin_cfg *cfg) 9298{ 9299 struct hda_input_mux *imux = &spec->private_imux; 9300 int i, idx1; 9301 9302 for (i = 0; i < AUTO_PIN_LAST; i++) { 9303 switch(cfg->input_pins[i]) { 9304 case 0x18: 9305 idx1 = 0; /* Mic 1 */ 9306 break; 9307 case 0x19: 9308 idx1 = 1; /* Mic 2 */ 9309 break; 9310 case 0x1a: 9311 idx1 = 2; /* Line In */ 9312 break; 9313 case 0x1c: 9314 idx1 = 3; /* CD */ 9315 break; 9316 default: 9317 continue; 9318 } 9319 imux->items[imux->num_items].label = auto_pin_cfg_labels[i]; 9320 imux->items[imux->num_items].index = idx1; 9321 imux->num_items++; 9322 } 9323 return 0; 9324} 9325 9326static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec) 9327{ 9328 struct alc_spec *spec = codec->spec; 9329 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0]; 9330 hda_nid_t hp_nid = spec->autocfg.hp_pins[0]; 9331 hda_nid_t line_nid = spec->autocfg.line_out_pins[0]; 9332 unsigned int dac_vol1, dac_vol2; 9333 9334 if (speaker_nid) { 9335 snd_hda_codec_write(codec, speaker_nid, 0, 9336 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); 9337 snd_hda_codec_write(codec, 0x0f, 0, 9338 AC_VERB_SET_AMP_GAIN_MUTE, 9339 AMP_IN_UNMUTE(1)); 9340 snd_hda_codec_write(codec, 0x10, 0, 9341 AC_VERB_SET_AMP_GAIN_MUTE, 9342 AMP_IN_UNMUTE(1)); 9343 } else { 9344 snd_hda_codec_write(codec, 0x0f, 0, 9345 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)); 9346 snd_hda_codec_write(codec, 0x10, 0, 9347 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)); 9348 } 9349 9350 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */ 9351 if (line_nid == 0x14) 9352 dac_vol2 = AMP_OUT_ZERO; 9353 else if (line_nid == 0x15) 9354 dac_vol1 = AMP_OUT_ZERO; 9355 if (hp_nid == 0x14) 9356 dac_vol2 = AMP_OUT_ZERO; 9357 else if (hp_nid == 0x15) 9358 dac_vol1 = AMP_OUT_ZERO; 9359 if (line_nid != 0x16 || hp_nid != 0x16 || 9360 spec->autocfg.line_out_pins[1] != 0x16 || 9361 spec->autocfg.line_out_pins[2] != 0x16) 9362 dac_vol1 = dac_vol2 = AMP_OUT_ZERO; 9363 9364 snd_hda_codec_write(codec, 0x02, 0, 9365 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1); 9366 snd_hda_codec_write(codec, 0x03, 0, 9367 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2); 9368} 9369 9370/* pcm configuration: identiacal with ALC880 */ 9371#define alc268_pcm_analog_playback alc880_pcm_analog_playback 9372#define alc268_pcm_analog_capture alc880_pcm_analog_capture 9373#define alc268_pcm_digital_playback alc880_pcm_digital_playback 9374 9375/* 9376 * BIOS auto configuration 9377 */ 9378static int alc268_parse_auto_config(struct hda_codec *codec) 9379{ 9380 struct alc_spec *spec = codec->spec; 9381 int err; 9382 static hda_nid_t alc268_ignore[] = { 0 }; 9383 9384 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 9385 alc268_ignore); 9386 if (err < 0) 9387 return err; 9388 if (!spec->autocfg.line_outs) 9389 return 0; /* can't find valid BIOS pin config */ 9390 9391 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg); 9392 if (err < 0) 9393 return err; 9394 err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg); 9395 if (err < 0) 9396 return err; 9397 9398 spec->multiout.max_channels = 2; 9399 9400 /* digital only support output */ 9401 if (spec->autocfg.dig_out_pin) 9402 spec->multiout.dig_out_nid = ALC268_DIGOUT_NID; 9403 9404 if (spec->kctl_alloc) 9405 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 9406 9407 spec->init_verbs[spec->num_init_verbs++] = alc268_volume_init_verbs; 9408 spec->num_mux_defs = 1; 9409 spec->input_mux = &spec->private_imux; 9410 9411 err = alc_auto_add_mic_boost(codec); 9412 if (err < 0) 9413 return err; 9414 9415 return 1; 9416} 9417 9418#define alc268_auto_init_multi_out alc882_auto_init_multi_out 9419#define alc268_auto_init_hp_out alc882_auto_init_hp_out 9420#define alc268_auto_init_analog_input alc882_auto_init_analog_input 9421 9422/* init callback for auto-configuration model -- overriding the default init */ 9423static void alc268_auto_init(struct hda_codec *codec) 9424{ 9425 alc268_auto_init_multi_out(codec); 9426 alc268_auto_init_hp_out(codec); 9427 alc268_auto_init_mono_speaker_out(codec); 9428 alc268_auto_init_analog_input(codec); 9429} 9430 9431/* 9432 * configuration and preset 9433 */ 9434static const char *alc268_models[ALC268_MODEL_LAST] = { 9435 [ALC268_3ST] = "3stack", 9436 [ALC268_TOSHIBA] = "toshiba", 9437 [ALC268_ACER] = "acer", 9438 [ALC268_AUTO] = "auto", 9439}; 9440 9441static struct snd_pci_quirk alc268_cfg_tbl[] = { 9442 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST), 9443 SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA), 9444 SND_PCI_QUIRK(0x1179, 0xff50, "TOSHIBA A305", ALC268_TOSHIBA), 9445 SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA), 9446 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER), 9447 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER), 9448 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER), 9449 {} 9450}; 9451 9452static struct alc_config_preset alc268_presets[] = { 9453 [ALC268_3ST] = { 9454 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer }, 9455 .init_verbs = { alc268_base_init_verbs }, 9456 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 9457 .dac_nids = alc268_dac_nids, 9458 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 9459 .adc_nids = alc268_adc_nids_alt, 9460 .hp_nid = 0x03, 9461 .dig_out_nid = ALC268_DIGOUT_NID, 9462 .num_channel_mode = ARRAY_SIZE(alc268_modes), 9463 .channel_mode = alc268_modes, 9464 .input_mux = &alc268_capture_source, 9465 }, 9466 [ALC268_TOSHIBA] = { 9467 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer }, 9468 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 9469 alc268_toshiba_verbs }, 9470 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 9471 .dac_nids = alc268_dac_nids, 9472 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 9473 .adc_nids = alc268_adc_nids_alt, 9474 .hp_nid = 0x03, 9475 .num_channel_mode = ARRAY_SIZE(alc268_modes), 9476 .channel_mode = alc268_modes, 9477 .input_mux = &alc268_capture_source, 9478 .unsol_event = alc268_toshiba_unsol_event, 9479 .init_hook = alc268_toshiba_automute, 9480 }, 9481 [ALC268_ACER] = { 9482 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer }, 9483 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 9484 alc268_acer_verbs }, 9485 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 9486 .dac_nids = alc268_dac_nids, 9487 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 9488 .adc_nids = alc268_adc_nids_alt, 9489 .hp_nid = 0x02, 9490 .num_channel_mode = ARRAY_SIZE(alc268_modes), 9491 .channel_mode = alc268_modes, 9492 .input_mux = &alc268_capture_source, 9493 .unsol_event = alc268_acer_unsol_event, 9494 .init_hook = alc268_acer_init_hook, 9495 }, 9496}; 9497 9498static int patch_alc268(struct hda_codec *codec) 9499{ 9500 struct alc_spec *spec; 9501 int board_config; 9502 int err; 9503 9504 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); 9505 if (spec == NULL) 9506 return -ENOMEM; 9507 9508 codec->spec = spec; 9509 9510 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST, 9511 alc268_models, 9512 alc268_cfg_tbl); 9513 9514 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) { 9515 printk(KERN_INFO "hda_codec: Unknown model for ALC268, " 9516 "trying auto-probe from BIOS...\n"); 9517 board_config = ALC268_AUTO; 9518 } 9519 9520 if (board_config == ALC268_AUTO) { 9521 /* automatic parse from the BIOS config */ 9522 err = alc268_parse_auto_config(codec); 9523 if (err < 0) { 9524 alc_free(codec); 9525 return err; 9526 } else if (!err) { 9527 printk(KERN_INFO 9528 "hda_codec: Cannot set up configuration " 9529 "from BIOS. Using base mode...\n"); 9530 board_config = ALC268_3ST; 9531 } 9532 } 9533 9534 if (board_config != ALC268_AUTO) 9535 setup_preset(spec, &alc268_presets[board_config]); 9536 9537 spec->stream_name_analog = "ALC268 Analog"; 9538 spec->stream_analog_playback = &alc268_pcm_analog_playback; 9539 spec->stream_analog_capture = &alc268_pcm_analog_capture; 9540 9541 spec->stream_name_digital = "ALC268 Digital"; 9542 spec->stream_digital_playback = &alc268_pcm_digital_playback; 9543 9544 if (board_config == ALC268_AUTO) { 9545 if (!spec->adc_nids && spec->input_mux) { 9546 /* check whether NID 0x07 is valid */ 9547 unsigned int wcap = get_wcaps(codec, 0x07); 9548 9549 /* get type */ 9550 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; 9551 if (wcap != AC_WID_AUD_IN) { 9552 spec->adc_nids = alc268_adc_nids_alt; 9553 spec->num_adc_nids = 9554 ARRAY_SIZE(alc268_adc_nids_alt); 9555 spec->mixers[spec->num_mixers] = 9556 alc268_capture_alt_mixer; 9557 spec->num_mixers++; 9558 } else { 9559 spec->adc_nids = alc268_adc_nids; 9560 spec->num_adc_nids = 9561 ARRAY_SIZE(alc268_adc_nids); 9562 spec->mixers[spec->num_mixers] = 9563 alc268_capture_mixer; 9564 spec->num_mixers++; 9565 } 9566 } 9567 } 9568 codec->patch_ops = alc_patch_ops; 9569 if (board_config == ALC268_AUTO) 9570 spec->init_hook = alc268_auto_init; 9571 9572 return 0; 9573} 9574 9575/* 9576 * ALC861 channel source setting (2/6 channel selection for 3-stack) 9577 */ 9578 9579/* 9580 * set the path ways for 2 channel output 9581 * need to set the codec line out and mic 1 pin widgets to inputs 9582 */ 9583static struct hda_verb alc861_threestack_ch2_init[] = { 9584 /* set pin widget 1Ah (line in) for input */ 9585 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 9586 /* set pin widget 18h (mic1/2) for input, for mic also enable 9587 * the vref 9588 */ 9589 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 9590 9591 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, 9592#if 0 9593 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/ 9594 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/ 9595#endif 9596 { } /* end */ 9597}; 9598/* 9599 * 6ch mode 9600 * need to set the codec line out and mic 1 pin widgets to outputs 9601 */ 9602static struct hda_verb alc861_threestack_ch6_init[] = { 9603 /* set pin widget 1Ah (line in) for output (Back Surround)*/ 9604 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 9605 /* set pin widget 18h (mic1) for output (CLFE)*/ 9606 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 9607 9608 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 }, 9609 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 }, 9610 9611 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 }, 9612#if 0 9613 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/ 9614 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/ 9615#endif 9616 { } /* end */ 9617}; 9618 9619static struct hda_channel_mode alc861_threestack_modes[2] = { 9620 { 2, alc861_threestack_ch2_init }, 9621 { 6, alc861_threestack_ch6_init }, 9622}; 9623/* Set mic1 as input and unmute the mixer */ 9624static struct hda_verb alc861_uniwill_m31_ch2_init[] = { 9625 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 9626 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/ 9627 { } /* end */ 9628}; 9629/* Set mic1 as output and mute mixer */ 9630static struct hda_verb alc861_uniwill_m31_ch4_init[] = { 9631 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 9632 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/ 9633 { } /* end */ 9634}; 9635 9636static struct hda_channel_mode alc861_uniwill_m31_modes[2] = { 9637 { 2, alc861_uniwill_m31_ch2_init }, 9638 { 4, alc861_uniwill_m31_ch4_init }, 9639}; 9640 9641/* Set mic1 and line-in as input and unmute the mixer */ 9642static struct hda_verb alc861_asus_ch2_init[] = { 9643 /* set pin widget 1Ah (line in) for input */ 9644 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 9645 /* set pin widget 18h (mic1/2) for input, for mic also enable 9646 * the vref 9647 */ 9648 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 9649 9650 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, 9651#if 0 9652 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/ 9653 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/ 9654#endif 9655 { } /* end */ 9656}; 9657/* Set mic1 nad line-in as output and mute mixer */ 9658static struct hda_verb alc861_asus_ch6_init[] = { 9659 /* set pin widget 1Ah (line in) for output (Back Surround)*/ 9660 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 9661 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */ 9662 /* set pin widget 18h (mic1) for output (CLFE)*/ 9663 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 9664 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */ 9665 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 }, 9666 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 }, 9667 9668 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 }, 9669#if 0 9670 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/ 9671 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/ 9672#endif 9673 { } /* end */ 9674}; 9675 9676static struct hda_channel_mode alc861_asus_modes[2] = { 9677 { 2, alc861_asus_ch2_init }, 9678 { 6, alc861_asus_ch6_init }, 9679}; 9680 9681/* patch-ALC861 */ 9682 9683static struct snd_kcontrol_new alc861_base_mixer[] = { 9684 /* output mixer control */ 9685 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), 9686 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), 9687 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT), 9688 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT), 9689 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), 9690 9691 /*Input mixer control */ 9692 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT), 9693 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */ 9694 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), 9695 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), 9696 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT), 9697 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT), 9698 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), 9699 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), 9700 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), 9701 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT), 9702 9703 /* Capture mixer control */ 9704 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 9705 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 9706 { 9707 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 9708 .name = "Capture Source", 9709 .count = 1, 9710 .info = alc_mux_enum_info, 9711 .get = alc_mux_enum_get, 9712 .put = alc_mux_enum_put, 9713 }, 9714 { } /* end */ 9715}; 9716 9717static struct snd_kcontrol_new alc861_3ST_mixer[] = { 9718 /* output mixer control */ 9719 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), 9720 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), 9721 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT), 9722 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT), 9723 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */ 9724 9725 /* Input mixer control */ 9726 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT), 9727 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */ 9728 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), 9729 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), 9730 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT), 9731 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT), 9732 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), 9733 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), 9734 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), 9735 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT), 9736 9737 /* Capture mixer control */ 9738 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 9739 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 9740 { 9741 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 9742 .name = "Capture Source", 9743 .count = 1, 9744 .info = alc_mux_enum_info, 9745 .get = alc_mux_enum_get, 9746 .put = alc_mux_enum_put, 9747 }, 9748 { 9749 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 9750 .name = "Channel Mode", 9751 .info = alc_ch_mode_info, 9752 .get = alc_ch_mode_get, 9753 .put = alc_ch_mode_put, 9754 .private_value = ARRAY_SIZE(alc861_threestack_modes), 9755 }, 9756 { } /* end */ 9757}; 9758 9759static struct snd_kcontrol_new alc861_toshiba_mixer[] = { 9760 /* output mixer control */ 9761 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT), 9762 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), 9763 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), 9764 9765 /*Capture mixer control */ 9766 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 9767 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 9768 { 9769 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 9770 .name = "Capture Source", 9771 .count = 1, 9772 .info = alc_mux_enum_info, 9773 .get = alc_mux_enum_get, 9774 .put = alc_mux_enum_put, 9775 }, 9776 9777 { } /* end */ 9778}; 9779 9780static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = { 9781 /* output mixer control */ 9782 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), 9783 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), 9784 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT), 9785 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT), 9786 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */ 9787 9788 /* Input mixer control */ 9789 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT), 9790 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */ 9791 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), 9792 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), 9793 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT), 9794 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT), 9795 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), 9796 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), 9797 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), 9798 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT), 9799 9800 /* Capture mixer control */ 9801 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 9802 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 9803 { 9804 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 9805 .name = "Capture Source", 9806 .count = 1, 9807 .info = alc_mux_enum_info, 9808 .get = alc_mux_enum_get, 9809 .put = alc_mux_enum_put, 9810 }, 9811 { 9812 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 9813 .name = "Channel Mode", 9814 .info = alc_ch_mode_info, 9815 .get = alc_ch_mode_get, 9816 .put = alc_ch_mode_put, 9817 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes), 9818 }, 9819 { } /* end */ 9820}; 9821 9822static struct snd_kcontrol_new alc861_asus_mixer[] = { 9823 /* output mixer control */ 9824 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), 9825 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), 9826 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT), 9827 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT), 9828 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), 9829 9830 /* Input mixer control */ 9831 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT), 9832 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), 9833 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), 9834 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), 9835 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT), 9836 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT), 9837 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), 9838 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), 9839 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), 9840 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT), 9841 9842 /* Capture mixer control */ 9843 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 9844 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 9845 { 9846 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 9847 .name = "Capture Source", 9848 .count = 1, 9849 .info = alc_mux_enum_info, 9850 .get = alc_mux_enum_get, 9851 .put = alc_mux_enum_put, 9852 }, 9853 { 9854 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 9855 .name = "Channel Mode", 9856 .info = alc_ch_mode_info, 9857 .get = alc_ch_mode_get, 9858 .put = alc_ch_mode_put, 9859 .private_value = ARRAY_SIZE(alc861_asus_modes), 9860 }, 9861 { } 9862}; 9863 9864/* additional mixer */ 9865static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = { 9866 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), 9867 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), 9868 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x23, 0x0, HDA_OUTPUT), 9869 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x23, 0x0, HDA_OUTPUT), 9870 { } 9871}; 9872 9873/* 9874 * generic initialization of ADC, input mixers and output mixers 9875 */ 9876static struct hda_verb alc861_base_init_verbs[] = { 9877 /* 9878 * Unmute ADC0 and set the default input to mic-in 9879 */ 9880 /* port-A for surround (rear panel) */ 9881 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 9882 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 }, 9883 /* port-B for mic-in (rear panel) with vref */ 9884 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 9885 /* port-C for line-in (rear panel) */ 9886 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 9887 /* port-D for Front */ 9888 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 9889 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 }, 9890 /* port-E for HP out (front panel) */ 9891 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, 9892 /* route front PCM to HP */ 9893 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, 9894 /* port-F for mic-in (front panel) with vref */ 9895 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 9896 /* port-G for CLFE (rear panel) */ 9897 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 9898 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 }, 9899 /* port-H for side (rear panel) */ 9900 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 9901 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 }, 9902 /* CD-in */ 9903 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 9904 /* route front mic to ADC1*/ 9905 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 9906 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9907 9908 /* Unmute DAC0~3 & spdif out*/ 9909 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9910 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9911 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9912 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9913 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9914 9915 /* Unmute Mixer 14 (mic) 1c (Line in)*/ 9916 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9917 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9918 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9919 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9920 9921 /* Unmute Stereo Mixer 15 */ 9922 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9923 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9924 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 9925 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */ 9926 9927 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9928 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9929 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9930 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9931 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9932 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9933 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9934 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9935 /* hp used DAC 3 (Front) */ 9936 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 9937 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 9938 9939 { } 9940}; 9941 9942static struct hda_verb alc861_threestack_init_verbs[] = { 9943 /* 9944 * Unmute ADC0 and set the default input to mic-in 9945 */ 9946 /* port-A for surround (rear panel) */ 9947 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 9948 /* port-B for mic-in (rear panel) with vref */ 9949 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 9950 /* port-C for line-in (rear panel) */ 9951 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 9952 /* port-D for Front */ 9953 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 9954 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 }, 9955 /* port-E for HP out (front panel) */ 9956 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, 9957 /* route front PCM to HP */ 9958 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, 9959 /* port-F for mic-in (front panel) with vref */ 9960 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 9961 /* port-G for CLFE (rear panel) */ 9962 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 9963 /* port-H for side (rear panel) */ 9964 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 9965 /* CD-in */ 9966 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 9967 /* route front mic to ADC1*/ 9968 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 9969 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9970 /* Unmute DAC0~3 & spdif out*/ 9971 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9972 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9973 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9974 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9975 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9976 9977 /* Unmute Mixer 14 (mic) 1c (Line in)*/ 9978 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9979 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9980 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9981 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9982 9983 /* Unmute Stereo Mixer 15 */ 9984 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9985 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9986 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 9987 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */ 9988 9989 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9990 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9991 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9992 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9993 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9994 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9995 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9996 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9997 /* hp used DAC 3 (Front) */ 9998 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 9999 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 10000 { } 10001}; 10002 10003static struct hda_verb alc861_uniwill_m31_init_verbs[] = { 10004 /* 10005 * Unmute ADC0 and set the default input to mic-in 10006 */ 10007 /* port-A for surround (rear panel) */ 10008 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 10009 /* port-B for mic-in (rear panel) with vref */ 10010 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 10011 /* port-C for line-in (rear panel) */ 10012 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 10013 /* port-D for Front */ 10014 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 10015 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 }, 10016 /* port-E for HP out (front panel) */ 10017 /* this has to be set to VREF80 */ 10018 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 10019 /* route front PCM to HP */ 10020 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, 10021 /* port-F for mic-in (front panel) with vref */ 10022 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 10023 /* port-G for CLFE (rear panel) */ 10024 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 10025 /* port-H for side (rear panel) */ 10026 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 10027 /* CD-in */ 10028 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 10029 /* route front mic to ADC1*/ 10030 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 10031 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 10032 /* Unmute DAC0~3 & spdif out*/ 10033 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 10034 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 10035 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 10036 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 10037 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 10038 10039 /* Unmute Mixer 14 (mic) 1c (Line in)*/ 10040 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 10041 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 10042 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 10043 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 10044 10045 /* Unmute Stereo Mixer 15 */ 10046 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 10047 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 10048 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 10049 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */ 10050 10051 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 10052 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 10053 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 10054 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 10055 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 10056 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 10057 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 10058 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 10059 /* hp used DAC 3 (Front) */ 10060 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 10061 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 10062 { } 10063}; 10064 10065static struct hda_verb alc861_asus_init_verbs[] = { 10066 /* 10067 * Unmute ADC0 and set the default input to mic-in 10068 */ 10069 /* port-A for surround (rear panel) 10070 * according to codec#0 this is the HP jack 10071 */ 10072 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */ 10073 /* route front PCM to HP */ 10074 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 }, 10075 /* port-B for mic-in (rear panel) with vref */ 10076 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 10077 /* port-C for line-in (rear panel) */ 10078 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 10079 /* port-D for Front */ 10080 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 10081 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 }, 10082 /* port-E for HP out (front panel) */ 10083 /* this has to be set to VREF80 */ 10084 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 10085 /* route front PCM to HP */ 10086 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, 10087 /* port-F for mic-in (front panel) with vref */ 10088 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 10089 /* port-G for CLFE (rear panel) */ 10090 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 10091 /* port-H for side (rear panel) */ 10092 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 10093 /* CD-in */ 10094 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 10095 /* route front mic to ADC1*/ 10096 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 10097 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 10098 /* Unmute DAC0~3 & spdif out*/ 10099 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 10100 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 10101 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 10102 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 10103 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 10104 /* Unmute Mixer 14 (mic) 1c (Line in)*/ 10105 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 10106 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 10107 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 10108 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 10109 10110 /* Unmute Stereo Mixer 15 */ 10111 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 10112 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 10113 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 10114 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */ 10115 10116 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 10117 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 10118 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 10119 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 10120 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 10121 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 10122 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 10123 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 10124 /* hp used DAC 3 (Front) */ 10125 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 10126 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 10127 { } 10128}; 10129 10130/* additional init verbs for ASUS laptops */ 10131static struct hda_verb alc861_asus_laptop_init_verbs[] = { 10132 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */ 10133 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */ 10134 { } 10135}; 10136 10137/* 10138 * generic initialization of ADC, input mixers and output mixers 10139 */ 10140static struct hda_verb alc861_auto_init_verbs[] = { 10141 /* 10142 * Unmute ADC0 and set the default input to mic-in 10143 */ 10144 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */ 10145 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 10146 10147 /* Unmute DAC0~3 & spdif out*/ 10148 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 10149 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 10150 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 10151 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 10152 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 10153 10154 /* Unmute Mixer 14 (mic) 1c (Line in)*/ 10155 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 10156 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 10157 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 10158 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 10159 10160 /* Unmute Stereo Mixer 15 */ 10161 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 10162 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 10163 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 10164 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, 10165 10166 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 10167 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 10168 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 10169 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 10170 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 10171 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 10172 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 10173 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 10174 10175 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 10176 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 10177 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 10178 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 10179 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 10180 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 10181 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 10182 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 10183 10184 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */ 10185 10186 { } 10187}; 10188 10189static struct hda_verb alc861_toshiba_init_verbs[] = { 10190 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 10191 10192 { } 10193}; 10194 10195/* toggle speaker-output according to the hp-jack state */ 10196static void alc861_toshiba_automute(struct hda_codec *codec) 10197{ 10198 unsigned int present; 10199 10200 present = snd_hda_codec_read(codec, 0x0f, 0, 10201 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 10202 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0, 10203 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 10204 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3, 10205 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE); 10206} 10207 10208static void alc861_toshiba_unsol_event(struct hda_codec *codec, 10209 unsigned int res) 10210{ 10211 if ((res >> 26) == ALC880_HP_EVENT) 10212 alc861_toshiba_automute(codec); 10213} 10214 10215/* pcm configuration: identiacal with ALC880 */ 10216#define alc861_pcm_analog_playback alc880_pcm_analog_playback 10217#define alc861_pcm_analog_capture alc880_pcm_analog_capture 10218#define alc861_pcm_digital_playback alc880_pcm_digital_playback 10219#define alc861_pcm_digital_capture alc880_pcm_digital_capture 10220 10221 10222#define ALC861_DIGOUT_NID 0x07 10223 10224static struct hda_channel_mode alc861_8ch_modes[1] = { 10225 { 8, NULL } 10226}; 10227 10228static hda_nid_t alc861_dac_nids[4] = { 10229 /* front, surround, clfe, side */ 10230 0x03, 0x06, 0x05, 0x04 10231}; 10232 10233static hda_nid_t alc660_dac_nids[3] = { 10234 /* front, clfe, surround */ 10235 0x03, 0x05, 0x06 10236}; 10237 10238static hda_nid_t alc861_adc_nids[1] = { 10239 /* ADC0-2 */ 10240 0x08, 10241}; 10242 10243static struct hda_input_mux alc861_capture_source = { 10244 .num_items = 5, 10245 .items = { 10246 { "Mic", 0x0 }, 10247 { "Front Mic", 0x3 }, 10248 { "Line", 0x1 }, 10249 { "CD", 0x4 }, 10250 { "Mixer", 0x5 }, 10251 }, 10252}; 10253 10254/* fill in the dac_nids table from the parsed pin configuration */ 10255static int alc861_auto_fill_dac_nids(struct alc_spec *spec, 10256 const struct auto_pin_cfg *cfg) 10257{ 10258 int i; 10259 hda_nid_t nid; 10260 10261 spec->multiout.dac_nids = spec->private_dac_nids; 10262 for (i = 0; i < cfg->line_outs; i++) { 10263 nid = cfg->line_out_pins[i]; 10264 if (nid) { 10265 if (i >= ARRAY_SIZE(alc861_dac_nids)) 10266 continue; 10267 spec->multiout.dac_nids[i] = alc861_dac_nids[i]; 10268 } 10269 } 10270 spec->multiout.num_dacs = cfg->line_outs; 10271 return 0; 10272} 10273 10274/* add playback controls from the parsed DAC table */ 10275static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec, 10276 const struct auto_pin_cfg *cfg) 10277{ 10278 char name[32]; 10279 static const char *chname[4] = { 10280 "Front", "Surround", NULL /*CLFE*/, "Side" 10281 }; 10282 hda_nid_t nid; 10283 int i, idx, err; 10284 10285 for (i = 0; i < cfg->line_outs; i++) { 10286 nid = spec->multiout.dac_nids[i]; 10287 if (!nid) 10288 continue; 10289 if (nid == 0x05) { 10290 /* Center/LFE */ 10291 err = add_control(spec, ALC_CTL_BIND_MUTE, 10292 "Center Playback Switch", 10293 HDA_COMPOSE_AMP_VAL(nid, 1, 0, 10294 HDA_OUTPUT)); 10295 if (err < 0) 10296 return err; 10297 err = add_control(spec, ALC_CTL_BIND_MUTE, 10298 "LFE Playback Switch", 10299 HDA_COMPOSE_AMP_VAL(nid, 2, 0, 10300 HDA_OUTPUT)); 10301 if (err < 0) 10302 return err; 10303 } else { 10304 for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1; 10305 idx++) 10306 if (nid == alc861_dac_nids[idx]) 10307 break; 10308 sprintf(name, "%s Playback Switch", chname[idx]); 10309 err = add_control(spec, ALC_CTL_BIND_MUTE, name, 10310 HDA_COMPOSE_AMP_VAL(nid, 3, 0, 10311 HDA_OUTPUT)); 10312 if (err < 0) 10313 return err; 10314 } 10315 } 10316 return 0; 10317} 10318 10319static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin) 10320{ 10321 int err; 10322 hda_nid_t nid; 10323 10324 if (!pin) 10325 return 0; 10326 10327 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) { 10328 nid = 0x03; 10329 err = add_control(spec, ALC_CTL_WIDGET_MUTE, 10330 "Headphone Playback Switch", 10331 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); 10332 if (err < 0) 10333 return err; 10334 spec->multiout.hp_nid = nid; 10335 } 10336 return 0; 10337} 10338 10339/* create playback/capture controls for input pins */ 10340static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec, 10341 const struct auto_pin_cfg *cfg) 10342{ 10343 struct hda_input_mux *imux = &spec->private_imux; 10344 int i, err, idx, idx1; 10345 10346 for (i = 0; i < AUTO_PIN_LAST; i++) { 10347 switch (cfg->input_pins[i]) { 10348 case 0x0c: 10349 idx1 = 1; 10350 idx = 2; /* Line In */ 10351 break; 10352 case 0x0f: 10353 idx1 = 2; 10354 idx = 2; /* Line In */ 10355 break; 10356 case 0x0d: 10357 idx1 = 0; 10358 idx = 1; /* Mic In */ 10359 break; 10360 case 0x10: 10361 idx1 = 3; 10362 idx = 1; /* Mic In */ 10363 break; 10364 case 0x11: 10365 idx1 = 4; 10366 idx = 0; /* CD */ 10367 break; 10368 default: 10369 continue; 10370 } 10371 10372 err = new_analog_input(spec, cfg->input_pins[i], 10373 auto_pin_cfg_labels[i], idx, 0x15); 10374 if (err < 0) 10375 return err; 10376 10377 imux->items[imux->num_items].label = auto_pin_cfg_labels[i]; 10378 imux->items[imux->num_items].index = idx1; 10379 imux->num_items++; 10380 } 10381 return 0; 10382} 10383 10384static struct snd_kcontrol_new alc861_capture_mixer[] = { 10385 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 10386 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 10387 10388 { 10389 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 10390 /* The multiple "Capture Source" controls confuse alsamixer 10391 * So call somewhat different.. 10392 *FIXME: the controls appear in the "playback" view! 10393 */ 10394 /* .name = "Capture Source", */ 10395 .name = "Input Source", 10396 .count = 1, 10397 .info = alc_mux_enum_info, 10398 .get = alc_mux_enum_get, 10399 .put = alc_mux_enum_put, 10400 }, 10401 { } /* end */ 10402}; 10403 10404static void alc861_auto_set_output_and_unmute(struct hda_codec *codec, 10405 hda_nid_t nid, 10406 int pin_type, int dac_idx) 10407{ 10408 /* set as output */ 10409 10410 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 10411 pin_type); 10412 snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE, 10413 AMP_OUT_UNMUTE); 10414 10415} 10416 10417static void alc861_auto_init_multi_out(struct hda_codec *codec) 10418{ 10419 struct alc_spec *spec = codec->spec; 10420 int i; 10421 10422 alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b); 10423 for (i = 0; i < spec->autocfg.line_outs; i++) { 10424 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 10425 int pin_type = get_pin_type(spec->autocfg.line_out_type); 10426 if (nid) 10427 alc861_auto_set_output_and_unmute(codec, nid, pin_type, 10428 spec->multiout.dac_nids[i]); 10429 } 10430} 10431 10432static void alc861_auto_init_hp_out(struct hda_codec *codec) 10433{ 10434 struct alc_spec *spec = codec->spec; 10435 hda_nid_t pin; 10436 10437 pin = spec->autocfg.hp_pins[0]; 10438 if (pin) /* connect to front */ 10439 alc861_auto_set_output_and_unmute(codec, pin, PIN_HP, 10440 spec->multiout.dac_nids[0]); 10441} 10442 10443static void alc861_auto_init_analog_input(struct hda_codec *codec) 10444{ 10445 struct alc_spec *spec = codec->spec; 10446 int i; 10447 10448 for (i = 0; i < AUTO_PIN_LAST; i++) { 10449 hda_nid_t nid = spec->autocfg.input_pins[i]; 10450 if (nid >= 0x0c && nid <= 0x11) { 10451 snd_hda_codec_write(codec, nid, 0, 10452 AC_VERB_SET_PIN_WIDGET_CONTROL, 10453 i <= AUTO_PIN_FRONT_MIC ? 10454 PIN_VREF80 : PIN_IN); 10455 } 10456 } 10457} 10458 10459/* parse the BIOS configuration and set up the alc_spec */ 10460/* return 1 if successful, 0 if the proper config is not found, 10461 * or a negative error code 10462 */ 10463static int alc861_parse_auto_config(struct hda_codec *codec) 10464{ 10465 struct alc_spec *spec = codec->spec; 10466 int err; 10467 static hda_nid_t alc861_ignore[] = { 0x1d, 0 }; 10468 10469 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 10470 alc861_ignore); 10471 if (err < 0) 10472 return err; 10473 if (!spec->autocfg.line_outs) 10474 return 0; /* can't find valid BIOS pin config */ 10475 10476 err = alc861_auto_fill_dac_nids(spec, &spec->autocfg); 10477 if (err < 0) 10478 return err; 10479 err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg); 10480 if (err < 0) 10481 return err; 10482 err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]); 10483 if (err < 0) 10484 return err; 10485 err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg); 10486 if (err < 0) 10487 return err; 10488 10489 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 10490 10491 if (spec->autocfg.dig_out_pin) 10492 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID; 10493 10494 if (spec->kctl_alloc) 10495 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 10496 10497 spec->init_verbs[spec->num_init_verbs++] = alc861_auto_init_verbs; 10498 10499 spec->num_mux_defs = 1; 10500 spec->input_mux = &spec->private_imux; 10501 10502 spec->adc_nids = alc861_adc_nids; 10503 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids); 10504 spec->mixers[spec->num_mixers] = alc861_capture_mixer; 10505 spec->num_mixers++; 10506 10507 return 1; 10508} 10509 10510/* additional initialization for auto-configuration model */ 10511static void alc861_auto_init(struct hda_codec *codec) 10512{ 10513 alc861_auto_init_multi_out(codec); 10514 alc861_auto_init_hp_out(codec); 10515 alc861_auto_init_analog_input(codec); 10516} 10517 10518#ifdef CONFIG_SND_HDA_POWER_SAVE 10519static struct hda_amp_list alc861_loopbacks[] = { 10520 { 0x15, HDA_INPUT, 0 }, 10521 { 0x15, HDA_INPUT, 1 }, 10522 { 0x15, HDA_INPUT, 2 }, 10523 { 0x15, HDA_INPUT, 3 }, 10524 { } /* end */ 10525}; 10526#endif 10527 10528 10529/* 10530 * configuration and preset 10531 */ 10532static const char *alc861_models[ALC861_MODEL_LAST] = { 10533 [ALC861_3ST] = "3stack", 10534 [ALC660_3ST] = "3stack-660", 10535 [ALC861_3ST_DIG] = "3stack-dig", 10536 [ALC861_6ST_DIG] = "6stack-dig", 10537 [ALC861_UNIWILL_M31] = "uniwill-m31", 10538 [ALC861_TOSHIBA] = "toshiba", 10539 [ALC861_ASUS] = "asus", 10540 [ALC861_ASUS_LAPTOP] = "asus-laptop", 10541 [ALC861_AUTO] = "auto", 10542}; 10543 10544static struct snd_pci_quirk alc861_cfg_tbl[] = { 10545 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST), 10546 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP), 10547 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP), 10548 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP), 10549 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP), 10550 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS), 10551 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG), 10552 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA), 10553 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!) 10554 * Any other models that need this preset? 10555 */ 10556 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */ 10557 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31), 10558 SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), 10559 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31), 10560 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST), 10561 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST), 10562 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST), 10563 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST), 10564 {} 10565}; 10566 10567static struct alc_config_preset alc861_presets[] = { 10568 [ALC861_3ST] = { 10569 .mixers = { alc861_3ST_mixer }, 10570 .init_verbs = { alc861_threestack_init_verbs }, 10571 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 10572 .dac_nids = alc861_dac_nids, 10573 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes), 10574 .channel_mode = alc861_threestack_modes, 10575 .need_dac_fix = 1, 10576 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 10577 .adc_nids = alc861_adc_nids, 10578 .input_mux = &alc861_capture_source, 10579 }, 10580 [ALC861_3ST_DIG] = { 10581 .mixers = { alc861_base_mixer }, 10582 .init_verbs = { alc861_threestack_init_verbs }, 10583 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 10584 .dac_nids = alc861_dac_nids, 10585 .dig_out_nid = ALC861_DIGOUT_NID, 10586 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes), 10587 .channel_mode = alc861_threestack_modes, 10588 .need_dac_fix = 1, 10589 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 10590 .adc_nids = alc861_adc_nids, 10591 .input_mux = &alc861_capture_source, 10592 }, 10593 [ALC861_6ST_DIG] = { 10594 .mixers = { alc861_base_mixer }, 10595 .init_verbs = { alc861_base_init_verbs }, 10596 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 10597 .dac_nids = alc861_dac_nids, 10598 .dig_out_nid = ALC861_DIGOUT_NID, 10599 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes), 10600 .channel_mode = alc861_8ch_modes, 10601 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 10602 .adc_nids = alc861_adc_nids, 10603 .input_mux = &alc861_capture_source, 10604 }, 10605 [ALC660_3ST] = { 10606 .mixers = { alc861_3ST_mixer }, 10607 .init_verbs = { alc861_threestack_init_verbs }, 10608 .num_dacs = ARRAY_SIZE(alc660_dac_nids), 10609 .dac_nids = alc660_dac_nids, 10610 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes), 10611 .channel_mode = alc861_threestack_modes, 10612 .need_dac_fix = 1, 10613 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 10614 .adc_nids = alc861_adc_nids, 10615 .input_mux = &alc861_capture_source, 10616 }, 10617 [ALC861_UNIWILL_M31] = { 10618 .mixers = { alc861_uniwill_m31_mixer }, 10619 .init_verbs = { alc861_uniwill_m31_init_verbs }, 10620 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 10621 .dac_nids = alc861_dac_nids, 10622 .dig_out_nid = ALC861_DIGOUT_NID, 10623 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes), 10624 .channel_mode = alc861_uniwill_m31_modes, 10625 .need_dac_fix = 1, 10626 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 10627 .adc_nids = alc861_adc_nids, 10628 .input_mux = &alc861_capture_source, 10629 }, 10630 [ALC861_TOSHIBA] = { 10631 .mixers = { alc861_toshiba_mixer }, 10632 .init_verbs = { alc861_base_init_verbs, 10633 alc861_toshiba_init_verbs }, 10634 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 10635 .dac_nids = alc861_dac_nids, 10636 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10637 .channel_mode = alc883_3ST_2ch_modes, 10638 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 10639 .adc_nids = alc861_adc_nids, 10640 .input_mux = &alc861_capture_source, 10641 .unsol_event = alc861_toshiba_unsol_event, 10642 .init_hook = alc861_toshiba_automute, 10643 }, 10644 [ALC861_ASUS] = { 10645 .mixers = { alc861_asus_mixer }, 10646 .init_verbs = { alc861_asus_init_verbs }, 10647 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 10648 .dac_nids = alc861_dac_nids, 10649 .dig_out_nid = ALC861_DIGOUT_NID, 10650 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes), 10651 .channel_mode = alc861_asus_modes, 10652 .need_dac_fix = 1, 10653 .hp_nid = 0x06, 10654 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 10655 .adc_nids = alc861_adc_nids, 10656 .input_mux = &alc861_capture_source, 10657 }, 10658 [ALC861_ASUS_LAPTOP] = { 10659 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer }, 10660 .init_verbs = { alc861_asus_init_verbs, 10661 alc861_asus_laptop_init_verbs }, 10662 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 10663 .dac_nids = alc861_dac_nids, 10664 .dig_out_nid = ALC861_DIGOUT_NID, 10665 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10666 .channel_mode = alc883_3ST_2ch_modes, 10667 .need_dac_fix = 1, 10668 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 10669 .adc_nids = alc861_adc_nids, 10670 .input_mux = &alc861_capture_source, 10671 }, 10672}; 10673 10674 10675static int patch_alc861(struct hda_codec *codec) 10676{ 10677 struct alc_spec *spec; 10678 int board_config; 10679 int err; 10680 10681 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 10682 if (spec == NULL) 10683 return -ENOMEM; 10684 10685 codec->spec = spec; 10686 10687 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST, 10688 alc861_models, 10689 alc861_cfg_tbl); 10690 10691 if (board_config < 0) { 10692 printk(KERN_INFO "hda_codec: Unknown model for ALC861, " 10693 "trying auto-probe from BIOS...\n"); 10694 board_config = ALC861_AUTO; 10695 } 10696 10697 if (board_config == ALC861_AUTO) { 10698 /* automatic parse from the BIOS config */ 10699 err = alc861_parse_auto_config(codec); 10700 if (err < 0) { 10701 alc_free(codec); 10702 return err; 10703 } else if (!err) { 10704 printk(KERN_INFO 10705 "hda_codec: Cannot set up configuration " 10706 "from BIOS. Using base mode...\n"); 10707 board_config = ALC861_3ST_DIG; 10708 } 10709 } 10710 10711 if (board_config != ALC861_AUTO) 10712 setup_preset(spec, &alc861_presets[board_config]); 10713 10714 spec->stream_name_analog = "ALC861 Analog"; 10715 spec->stream_analog_playback = &alc861_pcm_analog_playback; 10716 spec->stream_analog_capture = &alc861_pcm_analog_capture; 10717 10718 spec->stream_name_digital = "ALC861 Digital"; 10719 spec->stream_digital_playback = &alc861_pcm_digital_playback; 10720 spec->stream_digital_capture = &alc861_pcm_digital_capture; 10721 10722 codec->patch_ops = alc_patch_ops; 10723 if (board_config == ALC861_AUTO) 10724 spec->init_hook = alc861_auto_init; 10725#ifdef CONFIG_SND_HDA_POWER_SAVE 10726 if (!spec->loopback.amplist) 10727 spec->loopback.amplist = alc861_loopbacks; 10728#endif 10729 10730 return 0; 10731} 10732 10733/* 10734 * ALC861-VD support 10735 * 10736 * Based on ALC882 10737 * 10738 * In addition, an independent DAC 10739 */ 10740#define ALC861VD_DIGOUT_NID 0x06 10741 10742static hda_nid_t alc861vd_dac_nids[4] = { 10743 /* front, surr, clfe, side surr */ 10744 0x02, 0x03, 0x04, 0x05 10745}; 10746 10747/* dac_nids for ALC660vd are in a different order - according to 10748 * Realtek's driver. 10749 * This should probably tesult in a different mixer for 6stack models 10750 * of ALC660vd codecs, but for now there is only 3stack mixer 10751 * - and it is the same as in 861vd. 10752 * adc_nids in ALC660vd are (is) the same as in 861vd 10753 */ 10754static hda_nid_t alc660vd_dac_nids[3] = { 10755 /* front, rear, clfe, rear_surr */ 10756 0x02, 0x04, 0x03 10757}; 10758 10759static hda_nid_t alc861vd_adc_nids[1] = { 10760 /* ADC0 */ 10761 0x09, 10762}; 10763 10764/* input MUX */ 10765/* FIXME: should be a matrix-type input source selection */ 10766static struct hda_input_mux alc861vd_capture_source = { 10767 .num_items = 4, 10768 .items = { 10769 { "Mic", 0x0 }, 10770 { "Front Mic", 0x1 }, 10771 { "Line", 0x2 }, 10772 { "CD", 0x4 }, 10773 }, 10774}; 10775 10776static struct hda_input_mux alc861vd_dallas_capture_source = { 10777 .num_items = 3, 10778 .items = { 10779 { "Front Mic", 0x0 }, 10780 { "ATAPI Mic", 0x1 }, 10781 { "Line In", 0x5 }, 10782 }, 10783}; 10784 10785static struct hda_input_mux alc861vd_hp_capture_source = { 10786 .num_items = 2, 10787 .items = { 10788 { "Front Mic", 0x0 }, 10789 { "ATAPI Mic", 0x1 }, 10790 }, 10791}; 10792 10793#define alc861vd_mux_enum_info alc_mux_enum_info 10794#define alc861vd_mux_enum_get alc_mux_enum_get 10795 10796static int alc861vd_mux_enum_put(struct snd_kcontrol *kcontrol, 10797 struct snd_ctl_elem_value *ucontrol) 10798{ 10799 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 10800 struct alc_spec *spec = codec->spec; 10801 const struct hda_input_mux *imux = spec->input_mux; 10802 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 10803 static hda_nid_t capture_mixers[1] = { 0x22 }; 10804 hda_nid_t nid = capture_mixers[adc_idx]; 10805 unsigned int *cur_val = &spec->cur_mux[adc_idx]; 10806 unsigned int i, idx; 10807 10808 idx = ucontrol->value.enumerated.item[0]; 10809 if (idx >= imux->num_items) 10810 idx = imux->num_items - 1; 10811 if (*cur_val == idx) 10812 return 0; 10813 for (i = 0; i < imux->num_items; i++) { 10814 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE; 10815 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 10816 imux->items[i].index, 10817 HDA_AMP_MUTE, v); 10818 } 10819 *cur_val = idx; 10820 return 1; 10821} 10822 10823/* 10824 * 2ch mode 10825 */ 10826static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = { 10827 { 2, NULL } 10828}; 10829 10830/* 10831 * 6ch mode 10832 */ 10833static struct hda_verb alc861vd_6stack_ch6_init[] = { 10834 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 10835 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 10836 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 10837 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 10838 { } /* end */ 10839}; 10840 10841/* 10842 * 8ch mode 10843 */ 10844static struct hda_verb alc861vd_6stack_ch8_init[] = { 10845 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 10846 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 10847 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 10848 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 10849 { } /* end */ 10850}; 10851 10852static struct hda_channel_mode alc861vd_6stack_modes[2] = { 10853 { 6, alc861vd_6stack_ch6_init }, 10854 { 8, alc861vd_6stack_ch8_init }, 10855}; 10856 10857static struct snd_kcontrol_new alc861vd_chmode_mixer[] = { 10858 { 10859 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 10860 .name = "Channel Mode", 10861 .info = alc_ch_mode_info, 10862 .get = alc_ch_mode_get, 10863 .put = alc_ch_mode_put, 10864 }, 10865 { } /* end */ 10866}; 10867 10868static struct snd_kcontrol_new alc861vd_capture_mixer[] = { 10869 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), 10870 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), 10871 10872 { 10873 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 10874 /* The multiple "Capture Source" controls confuse alsamixer 10875 * So call somewhat different.. 10876 *FIXME: the controls appear in the "playback" view! 10877 */ 10878 /* .name = "Capture Source", */ 10879 .name = "Input Source", 10880 .count = 1, 10881 .info = alc861vd_mux_enum_info, 10882 .get = alc861vd_mux_enum_get, 10883 .put = alc861vd_mux_enum_put, 10884 }, 10885 { } /* end */ 10886}; 10887 10888/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 10889 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b 10890 */ 10891static struct snd_kcontrol_new alc861vd_6st_mixer[] = { 10892 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 10893 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 10894 10895 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT), 10896 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 10897 10898 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, 10899 HDA_OUTPUT), 10900 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, 10901 HDA_OUTPUT), 10902 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 10903 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 10904 10905 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT), 10906 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 10907 10908 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 10909 10910 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 10911 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 10912 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 10913 10914 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 10915 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 10916 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 10917 10918 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 10919 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 10920 10921 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 10922 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 10923 10924 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 10925 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 10926 10927 { } /* end */ 10928}; 10929 10930static struct snd_kcontrol_new alc861vd_3st_mixer[] = { 10931 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 10932 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 10933 10934 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 10935 10936 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 10937 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 10938 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 10939 10940 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 10941 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 10942 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 10943 10944 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 10945 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 10946 10947 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 10948 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 10949 10950 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 10951 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 10952 10953 { } /* end */ 10954}; 10955 10956static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = { 10957 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 10958 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/ 10959 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 10960 10961 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 10962 10963 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 10964 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 10965 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 10966 10967 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 10968 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 10969 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 10970 10971 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 10972 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 10973 10974 { } /* end */ 10975}; 10976 10977/* Pin assignment: Front=0x14, HP = 0x15, 10978 * Front Mic=0x18, ATAPI Mic = 0x19, Line In = 0x1d 10979 */ 10980static struct snd_kcontrol_new alc861vd_dallas_mixer[] = { 10981 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 10982 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 10983 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 10984 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT), 10985 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 10986 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 10987 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 10988 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 10989 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x05, HDA_INPUT), 10990 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x05, HDA_INPUT), 10991 { } /* end */ 10992}; 10993 10994/* Pin assignment: Speaker=0x14, Line-out = 0x15, 10995 * Front Mic=0x18, ATAPI Mic = 0x19, 10996 */ 10997static struct snd_kcontrol_new alc861vd_hp_mixer[] = { 10998 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 10999 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 11000 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 11001 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT), 11002 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11003 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11004 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 11005 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 11006 11007 { } /* end */ 11008}; 11009 11010/* 11011 * generic initialization of ADC, input mixers and output mixers 11012 */ 11013static struct hda_verb alc861vd_volume_init_verbs[] = { 11014 /* 11015 * Unmute ADC0 and set the default input to mic-in 11016 */ 11017 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 11018 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11019 11020 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of 11021 * the analog-loopback mixer widget 11022 */ 11023 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 11024 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 11025 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 11026 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 11027 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 11028 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 11029 11030 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */ 11031 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11032 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11033 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 11034 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, 11035 11036 /* 11037 * Set up output mixers (0x02 - 0x05) 11038 */ 11039 /* set vol=0 to output mixers */ 11040 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 11041 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 11042 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 11043 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 11044 11045 /* set up input amps for analog loopback */ 11046 /* Amp Indices: DAC = 0, mixer = 1 */ 11047 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 11048 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 11049 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 11050 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 11051 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 11052 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 11053 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 11054 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 11055 11056 { } 11057}; 11058 11059/* 11060 * 3-stack pin configuration: 11061 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b 11062 */ 11063static struct hda_verb alc861vd_3stack_init_verbs[] = { 11064 /* 11065 * Set pin mode and muting 11066 */ 11067 /* set front pin widgets 0x14 for output */ 11068 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 11069 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 11070 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 11071 11072 /* Mic (rear) pin: input vref at 80% */ 11073 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 11074 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 11075 /* Front Mic pin: input vref at 80% */ 11076 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 11077 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 11078 /* Line In pin: input */ 11079 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 11080 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 11081 /* Line-2 In: Headphone output (output 0 - 0x0c) */ 11082 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11083 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 11084 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 11085 /* CD pin widget for input */ 11086 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 11087 11088 { } 11089}; 11090 11091/* 11092 * 6-stack pin configuration: 11093 */ 11094static struct hda_verb alc861vd_6stack_init_verbs[] = { 11095 /* 11096 * Set pin mode and muting 11097 */ 11098 /* set front pin widgets 0x14 for output */ 11099 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 11100 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 11101 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 11102 11103 /* Rear Pin: output 1 (0x0d) */ 11104 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 11105 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 11106 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 11107 /* CLFE Pin: output 2 (0x0e) */ 11108 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 11109 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 11110 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, 11111 /* Side Pin: output 3 (0x0f) */ 11112 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 11113 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 11114 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, 11115 11116 /* Mic (rear) pin: input vref at 80% */ 11117 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 11118 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 11119 /* Front Mic pin: input vref at 80% */ 11120 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 11121 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 11122 /* Line In pin: input */ 11123 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 11124 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 11125 /* Line-2 In: Headphone output (output 0 - 0x0c) */ 11126 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11127 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 11128 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 11129 /* CD pin widget for input */ 11130 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 11131 11132 { } 11133}; 11134 11135static struct hda_verb alc861vd_eapd_verbs[] = { 11136 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 11137 { } 11138}; 11139 11140static struct hda_verb alc861vd_lenovo_unsol_verbs[] = { 11141 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11142 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11143 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, 11144 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 11145 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 11146 {} 11147}; 11148 11149/* toggle speaker-output according to the hp-jack state */ 11150static void alc861vd_lenovo_hp_automute(struct hda_codec *codec) 11151{ 11152 unsigned int present; 11153 unsigned char bits; 11154 11155 present = snd_hda_codec_read(codec, 0x1b, 0, 11156 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 11157 bits = present ? HDA_AMP_MUTE : 0; 11158 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 11159 HDA_AMP_MUTE, bits); 11160} 11161 11162static void alc861vd_lenovo_mic_automute(struct hda_codec *codec) 11163{ 11164 unsigned int present; 11165 unsigned char bits; 11166 11167 present = snd_hda_codec_read(codec, 0x18, 0, 11168 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 11169 bits = present ? HDA_AMP_MUTE : 0; 11170 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, 11171 HDA_AMP_MUTE, bits); 11172} 11173 11174static void alc861vd_lenovo_automute(struct hda_codec *codec) 11175{ 11176 alc861vd_lenovo_hp_automute(codec); 11177 alc861vd_lenovo_mic_automute(codec); 11178} 11179 11180static void alc861vd_lenovo_unsol_event(struct hda_codec *codec, 11181 unsigned int res) 11182{ 11183 switch (res >> 26) { 11184 case ALC880_HP_EVENT: 11185 alc861vd_lenovo_hp_automute(codec); 11186 break; 11187 case ALC880_MIC_EVENT: 11188 alc861vd_lenovo_mic_automute(codec); 11189 break; 11190 } 11191} 11192 11193static struct hda_verb alc861vd_dallas_verbs[] = { 11194 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 11195 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 11196 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 11197 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 11198 11199 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11200 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11201 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 11202 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 11203 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 11204 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 11205 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 11206 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 11207 11208 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 11209 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 11210 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 11211 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 11212 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 11213 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 11214 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 11215 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 11216 11217 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, 11218 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 11219 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, 11220 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 11221 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 11222 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 11223 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 11224 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 11225 11226 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11227 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 11228 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 11229 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 11230 11231 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 11232 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 11233 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 11234 11235 { } /* end */ 11236}; 11237 11238/* toggle speaker-output according to the hp-jack state */ 11239static void alc861vd_dallas_automute(struct hda_codec *codec) 11240{ 11241 unsigned int present; 11242 11243 present = snd_hda_codec_read(codec, 0x15, 0, 11244 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 11245 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 11246 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 11247} 11248 11249static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int res) 11250{ 11251 if ((res >> 26) == ALC880_HP_EVENT) 11252 alc861vd_dallas_automute(codec); 11253} 11254 11255#ifdef CONFIG_SND_HDA_POWER_SAVE 11256#define alc861vd_loopbacks alc880_loopbacks 11257#endif 11258 11259/* pcm configuration: identiacal with ALC880 */ 11260#define alc861vd_pcm_analog_playback alc880_pcm_analog_playback 11261#define alc861vd_pcm_analog_capture alc880_pcm_analog_capture 11262#define alc861vd_pcm_digital_playback alc880_pcm_digital_playback 11263#define alc861vd_pcm_digital_capture alc880_pcm_digital_capture 11264 11265/* 11266 * configuration and preset 11267 */ 11268static const char *alc861vd_models[ALC861VD_MODEL_LAST] = { 11269 [ALC660VD_3ST] = "3stack-660", 11270 [ALC660VD_3ST_DIG] = "3stack-660-digout", 11271 [ALC861VD_3ST] = "3stack", 11272 [ALC861VD_3ST_DIG] = "3stack-digout", 11273 [ALC861VD_6ST_DIG] = "6stack-digout", 11274 [ALC861VD_LENOVO] = "lenovo", 11275 [ALC861VD_DALLAS] = "dallas", 11276 [ALC861VD_HP] = "hp", 11277 [ALC861VD_AUTO] = "auto", 11278}; 11279 11280static struct snd_pci_quirk alc861vd_cfg_tbl[] = { 11281 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST), 11282 SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST), 11283 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG), 11284 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST), 11285 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST), 11286 11287 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/ 11288 SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS), 11289 SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO), 11290 SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO), 11291 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO), 11292 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO), 11293 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG), 11294 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG), 11295 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP), 11296 {} 11297}; 11298 11299static struct alc_config_preset alc861vd_presets[] = { 11300 [ALC660VD_3ST] = { 11301 .mixers = { alc861vd_3st_mixer }, 11302 .init_verbs = { alc861vd_volume_init_verbs, 11303 alc861vd_3stack_init_verbs }, 11304 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids), 11305 .dac_nids = alc660vd_dac_nids, 11306 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids), 11307 .adc_nids = alc861vd_adc_nids, 11308 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 11309 .channel_mode = alc861vd_3stack_2ch_modes, 11310 .input_mux = &alc861vd_capture_source, 11311 }, 11312 [ALC660VD_3ST_DIG] = { 11313 .mixers = { alc861vd_3st_mixer }, 11314 .init_verbs = { alc861vd_volume_init_verbs, 11315 alc861vd_3stack_init_verbs }, 11316 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids), 11317 .dac_nids = alc660vd_dac_nids, 11318 .dig_out_nid = ALC861VD_DIGOUT_NID, 11319 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids), 11320 .adc_nids = alc861vd_adc_nids, 11321 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 11322 .channel_mode = alc861vd_3stack_2ch_modes, 11323 .input_mux = &alc861vd_capture_source, 11324 }, 11325 [ALC861VD_3ST] = { 11326 .mixers = { alc861vd_3st_mixer }, 11327 .init_verbs = { alc861vd_volume_init_verbs, 11328 alc861vd_3stack_init_verbs }, 11329 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids), 11330 .dac_nids = alc861vd_dac_nids, 11331 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 11332 .channel_mode = alc861vd_3stack_2ch_modes, 11333 .input_mux = &alc861vd_capture_source, 11334 }, 11335 [ALC861VD_3ST_DIG] = { 11336 .mixers = { alc861vd_3st_mixer }, 11337 .init_verbs = { alc861vd_volume_init_verbs, 11338 alc861vd_3stack_init_verbs }, 11339 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids), 11340 .dac_nids = alc861vd_dac_nids, 11341 .dig_out_nid = ALC861VD_DIGOUT_NID, 11342 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 11343 .channel_mode = alc861vd_3stack_2ch_modes, 11344 .input_mux = &alc861vd_capture_source, 11345 }, 11346 [ALC861VD_6ST_DIG] = { 11347 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer }, 11348 .init_verbs = { alc861vd_volume_init_verbs, 11349 alc861vd_6stack_init_verbs }, 11350 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids), 11351 .dac_nids = alc861vd_dac_nids, 11352 .dig_out_nid = ALC861VD_DIGOUT_NID, 11353 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes), 11354 .channel_mode = alc861vd_6stack_modes, 11355 .input_mux = &alc861vd_capture_source, 11356 }, 11357 [ALC861VD_LENOVO] = { 11358 .mixers = { alc861vd_lenovo_mixer }, 11359 .init_verbs = { alc861vd_volume_init_verbs, 11360 alc861vd_3stack_init_verbs, 11361 alc861vd_eapd_verbs, 11362 alc861vd_lenovo_unsol_verbs }, 11363 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids), 11364 .dac_nids = alc660vd_dac_nids, 11365 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids), 11366 .adc_nids = alc861vd_adc_nids, 11367 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 11368 .channel_mode = alc861vd_3stack_2ch_modes, 11369 .input_mux = &alc861vd_capture_source, 11370 .unsol_event = alc861vd_lenovo_unsol_event, 11371 .init_hook = alc861vd_lenovo_automute, 11372 }, 11373 [ALC861VD_DALLAS] = { 11374 .mixers = { alc861vd_dallas_mixer }, 11375 .init_verbs = { alc861vd_dallas_verbs }, 11376 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids), 11377 .dac_nids = alc861vd_dac_nids, 11378 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids), 11379 .adc_nids = alc861vd_adc_nids, 11380 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 11381 .channel_mode = alc861vd_3stack_2ch_modes, 11382 .input_mux = &alc861vd_dallas_capture_source, 11383 .unsol_event = alc861vd_dallas_unsol_event, 11384 .init_hook = alc861vd_dallas_automute, 11385 }, 11386 [ALC861VD_HP] = { 11387 .mixers = { alc861vd_hp_mixer }, 11388 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs }, 11389 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids), 11390 .dac_nids = alc861vd_dac_nids, 11391 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids), 11392 .dig_out_nid = ALC861VD_DIGOUT_NID, 11393 .adc_nids = alc861vd_adc_nids, 11394 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 11395 .channel_mode = alc861vd_3stack_2ch_modes, 11396 .input_mux = &alc861vd_hp_capture_source, 11397 .unsol_event = alc861vd_dallas_unsol_event, 11398 .init_hook = alc861vd_dallas_automute, 11399 }, 11400}; 11401 11402/* 11403 * BIOS auto configuration 11404 */ 11405static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec, 11406 hda_nid_t nid, int pin_type, int dac_idx) 11407{ 11408 /* set as output */ 11409 snd_hda_codec_write(codec, nid, 0, 11410 AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type); 11411 snd_hda_codec_write(codec, nid, 0, 11412 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); 11413} 11414 11415static void alc861vd_auto_init_multi_out(struct hda_codec *codec) 11416{ 11417 struct alc_spec *spec = codec->spec; 11418 int i; 11419 11420 alc_subsystem_id(codec, 0x15, 0x1b, 0x14); 11421 for (i = 0; i <= HDA_SIDE; i++) { 11422 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 11423 int pin_type = get_pin_type(spec->autocfg.line_out_type); 11424 if (nid) 11425 alc861vd_auto_set_output_and_unmute(codec, nid, 11426 pin_type, i); 11427 } 11428} 11429 11430 11431static void alc861vd_auto_init_hp_out(struct hda_codec *codec) 11432{ 11433 struct alc_spec *spec = codec->spec; 11434 hda_nid_t pin; 11435 11436 pin = spec->autocfg.hp_pins[0]; 11437 if (pin) /* connect to front and use dac 0 */ 11438 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); 11439} 11440 11441#define alc861vd_is_input_pin(nid) alc880_is_input_pin(nid) 11442#define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID 11443 11444static void alc861vd_auto_init_analog_input(struct hda_codec *codec) 11445{ 11446 struct alc_spec *spec = codec->spec; 11447 int i; 11448 11449 for (i = 0; i < AUTO_PIN_LAST; i++) { 11450 hda_nid_t nid = spec->autocfg.input_pins[i]; 11451 if (alc861vd_is_input_pin(nid)) { 11452 snd_hda_codec_write(codec, nid, 0, 11453 AC_VERB_SET_PIN_WIDGET_CONTROL, 11454 i <= AUTO_PIN_FRONT_MIC ? 11455 PIN_VREF80 : PIN_IN); 11456 if (nid != ALC861VD_PIN_CD_NID) 11457 snd_hda_codec_write(codec, nid, 0, 11458 AC_VERB_SET_AMP_GAIN_MUTE, 11459 AMP_OUT_MUTE); 11460 } 11461 } 11462} 11463 11464#define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02) 11465#define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c) 11466 11467/* add playback controls from the parsed DAC table */ 11468/* Based on ALC880 version. But ALC861VD has separate, 11469 * different NIDs for mute/unmute switch and volume control */ 11470static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec, 11471 const struct auto_pin_cfg *cfg) 11472{ 11473 char name[32]; 11474 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"}; 11475 hda_nid_t nid_v, nid_s; 11476 int i, err; 11477 11478 for (i = 0; i < cfg->line_outs; i++) { 11479 if (!spec->multiout.dac_nids[i]) 11480 continue; 11481 nid_v = alc861vd_idx_to_mixer_vol( 11482 alc880_dac_to_idx( 11483 spec->multiout.dac_nids[i])); 11484 nid_s = alc861vd_idx_to_mixer_switch( 11485 alc880_dac_to_idx( 11486 spec->multiout.dac_nids[i])); 11487 11488 if (i == 2) { 11489 /* Center/LFE */ 11490 err = add_control(spec, ALC_CTL_WIDGET_VOL, 11491 "Center Playback Volume", 11492 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0, 11493 HDA_OUTPUT)); 11494 if (err < 0) 11495 return err; 11496 err = add_control(spec, ALC_CTL_WIDGET_VOL, 11497 "LFE Playback Volume", 11498 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0, 11499 HDA_OUTPUT)); 11500 if (err < 0) 11501 return err; 11502 err = add_control(spec, ALC_CTL_BIND_MUTE, 11503 "Center Playback Switch", 11504 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2, 11505 HDA_INPUT)); 11506 if (err < 0) 11507 return err; 11508 err = add_control(spec, ALC_CTL_BIND_MUTE, 11509 "LFE Playback Switch", 11510 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2, 11511 HDA_INPUT)); 11512 if (err < 0) 11513 return err; 11514 } else { 11515 sprintf(name, "%s Playback Volume", chname[i]); 11516 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, 11517 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, 11518 HDA_OUTPUT)); 11519 if (err < 0) 11520 return err; 11521 sprintf(name, "%s Playback Switch", chname[i]); 11522 err = add_control(spec, ALC_CTL_BIND_MUTE, name, 11523 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, 11524 HDA_INPUT)); 11525 if (err < 0) 11526 return err; 11527 } 11528 } 11529 return 0; 11530} 11531 11532/* add playback controls for speaker and HP outputs */ 11533/* Based on ALC880 version. But ALC861VD has separate, 11534 * different NIDs for mute/unmute switch and volume control */ 11535static int alc861vd_auto_create_extra_out(struct alc_spec *spec, 11536 hda_nid_t pin, const char *pfx) 11537{ 11538 hda_nid_t nid_v, nid_s; 11539 int err; 11540 char name[32]; 11541 11542 if (!pin) 11543 return 0; 11544 11545 if (alc880_is_fixed_pin(pin)) { 11546 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); 11547 /* specify the DAC as the extra output */ 11548 if (!spec->multiout.hp_nid) 11549 spec->multiout.hp_nid = nid_v; 11550 else 11551 spec->multiout.extra_out_nid[0] = nid_v; 11552 /* control HP volume/switch on the output mixer amp */ 11553 nid_v = alc861vd_idx_to_mixer_vol( 11554 alc880_fixed_pin_idx(pin)); 11555 nid_s = alc861vd_idx_to_mixer_switch( 11556 alc880_fixed_pin_idx(pin)); 11557 11558 sprintf(name, "%s Playback Volume", pfx); 11559 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, 11560 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT)); 11561 if (err < 0) 11562 return err; 11563 sprintf(name, "%s Playback Switch", pfx); 11564 err = add_control(spec, ALC_CTL_BIND_MUTE, name, 11565 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT)); 11566 if (err < 0) 11567 return err; 11568 } else if (alc880_is_multi_pin(pin)) { 11569 /* set manual connection */ 11570 /* we have only a switch on HP-out PIN */ 11571 sprintf(name, "%s Playback Switch", pfx); 11572 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, 11573 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); 11574 if (err < 0) 11575 return err; 11576 } 11577 return 0; 11578} 11579 11580/* parse the BIOS configuration and set up the alc_spec 11581 * return 1 if successful, 0 if the proper config is not found, 11582 * or a negative error code 11583 * Based on ALC880 version - had to change it to override 11584 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */ 11585static int alc861vd_parse_auto_config(struct hda_codec *codec) 11586{ 11587 struct alc_spec *spec = codec->spec; 11588 int err; 11589 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 }; 11590 11591 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 11592 alc861vd_ignore); 11593 if (err < 0) 11594 return err; 11595 if (!spec->autocfg.line_outs) 11596 return 0; /* can't find valid BIOS pin config */ 11597 11598 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); 11599 if (err < 0) 11600 return err; 11601 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg); 11602 if (err < 0) 11603 return err; 11604 err = alc861vd_auto_create_extra_out(spec, 11605 spec->autocfg.speaker_pins[0], 11606 "Speaker"); 11607 if (err < 0) 11608 return err; 11609 err = alc861vd_auto_create_extra_out(spec, 11610 spec->autocfg.hp_pins[0], 11611 "Headphone"); 11612 if (err < 0) 11613 return err; 11614 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg); 11615 if (err < 0) 11616 return err; 11617 11618 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 11619 11620 if (spec->autocfg.dig_out_pin) 11621 spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID; 11622 11623 if (spec->kctl_alloc) 11624 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 11625 11626 spec->init_verbs[spec->num_init_verbs++] 11627 = alc861vd_volume_init_verbs; 11628 11629 spec->num_mux_defs = 1; 11630 spec->input_mux = &spec->private_imux; 11631 11632 err = alc_auto_add_mic_boost(codec); 11633 if (err < 0) 11634 return err; 11635 11636 return 1; 11637} 11638 11639/* additional initialization for auto-configuration model */ 11640static void alc861vd_auto_init(struct hda_codec *codec) 11641{ 11642 alc861vd_auto_init_multi_out(codec); 11643 alc861vd_auto_init_hp_out(codec); 11644 alc861vd_auto_init_analog_input(codec); 11645} 11646 11647static int patch_alc861vd(struct hda_codec *codec) 11648{ 11649 struct alc_spec *spec; 11650 int err, board_config; 11651 11652 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 11653 if (spec == NULL) 11654 return -ENOMEM; 11655 11656 codec->spec = spec; 11657 11658 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST, 11659 alc861vd_models, 11660 alc861vd_cfg_tbl); 11661 11662 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) { 11663 printk(KERN_INFO "hda_codec: Unknown model for ALC660VD/" 11664 "ALC861VD, trying auto-probe from BIOS...\n"); 11665 board_config = ALC861VD_AUTO; 11666 } 11667 11668 if (board_config == ALC861VD_AUTO) { 11669 /* automatic parse from the BIOS config */ 11670 err = alc861vd_parse_auto_config(codec); 11671 if (err < 0) { 11672 alc_free(codec); 11673 return err; 11674 } else if (!err) { 11675 printk(KERN_INFO 11676 "hda_codec: Cannot set up configuration " 11677 "from BIOS. Using base mode...\n"); 11678 board_config = ALC861VD_3ST; 11679 } 11680 } 11681 11682 if (board_config != ALC861VD_AUTO) 11683 setup_preset(spec, &alc861vd_presets[board_config]); 11684 11685 spec->stream_name_analog = "ALC861VD Analog"; 11686 spec->stream_analog_playback = &alc861vd_pcm_analog_playback; 11687 spec->stream_analog_capture = &alc861vd_pcm_analog_capture; 11688 11689 spec->stream_name_digital = "ALC861VD Digital"; 11690 spec->stream_digital_playback = &alc861vd_pcm_digital_playback; 11691 spec->stream_digital_capture = &alc861vd_pcm_digital_capture; 11692 11693 spec->adc_nids = alc861vd_adc_nids; 11694 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids); 11695 11696 spec->mixers[spec->num_mixers] = alc861vd_capture_mixer; 11697 spec->num_mixers++; 11698 11699 codec->patch_ops = alc_patch_ops; 11700 11701 if (board_config == ALC861VD_AUTO) 11702 spec->init_hook = alc861vd_auto_init; 11703#ifdef CONFIG_SND_HDA_POWER_SAVE 11704 if (!spec->loopback.amplist) 11705 spec->loopback.amplist = alc861vd_loopbacks; 11706#endif 11707 11708 return 0; 11709} 11710 11711/* 11712 * ALC662 support 11713 * 11714 * ALC662 is almost identical with ALC880 but has cleaner and more flexible 11715 * configuration. Each pin widget can choose any input DACs and a mixer. 11716 * Each ADC is connected from a mixer of all inputs. This makes possible 11717 * 6-channel independent captures. 11718 * 11719 * In addition, an independent DAC for the multi-playback (not used in this 11720 * driver yet). 11721 */ 11722#define ALC662_DIGOUT_NID 0x06 11723#define ALC662_DIGIN_NID 0x0a 11724 11725static hda_nid_t alc662_dac_nids[4] = { 11726 /* front, rear, clfe, rear_surr */ 11727 0x02, 0x03, 0x04 11728}; 11729 11730static hda_nid_t alc662_adc_nids[1] = { 11731 /* ADC1-2 */ 11732 0x09, 11733}; 11734/* input MUX */ 11735/* FIXME: should be a matrix-type input source selection */ 11736 11737static struct hda_input_mux alc662_capture_source = { 11738 .num_items = 4, 11739 .items = { 11740 { "Mic", 0x0 }, 11741 { "Front Mic", 0x1 }, 11742 { "Line", 0x2 }, 11743 { "CD", 0x4 }, 11744 }, 11745}; 11746 11747static struct hda_input_mux alc662_lenovo_101e_capture_source = { 11748 .num_items = 2, 11749 .items = { 11750 { "Mic", 0x1 }, 11751 { "Line", 0x2 }, 11752 }, 11753}; 11754 11755static struct hda_input_mux alc662_eeepc_capture_source = { 11756 .num_items = 2, 11757 .items = { 11758 { "i-Mic", 0x1 }, 11759 { "e-Mic", 0x0 }, 11760 }, 11761}; 11762 11763#define alc662_mux_enum_info alc_mux_enum_info 11764#define alc662_mux_enum_get alc_mux_enum_get 11765 11766static int alc662_mux_enum_put(struct snd_kcontrol *kcontrol, 11767 struct snd_ctl_elem_value *ucontrol) 11768{ 11769 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 11770 struct alc_spec *spec = codec->spec; 11771 const struct hda_input_mux *imux = spec->input_mux; 11772 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 11773 static hda_nid_t capture_mixers[2] = { 0x23, 0x22 }; 11774 hda_nid_t nid = capture_mixers[adc_idx]; 11775 unsigned int *cur_val = &spec->cur_mux[adc_idx]; 11776 unsigned int i, idx; 11777 11778 idx = ucontrol->value.enumerated.item[0]; 11779 if (idx >= imux->num_items) 11780 idx = imux->num_items - 1; 11781 if (*cur_val == idx) 11782 return 0; 11783 for (i = 0; i < imux->num_items; i++) { 11784 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE; 11785 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 11786 imux->items[i].index, 11787 HDA_AMP_MUTE, v); 11788 } 11789 *cur_val = idx; 11790 return 1; 11791} 11792/* 11793 * 2ch mode 11794 */ 11795static struct hda_channel_mode alc662_3ST_2ch_modes[1] = { 11796 { 2, NULL } 11797}; 11798 11799/* 11800 * 2ch mode 11801 */ 11802static struct hda_verb alc662_3ST_ch2_init[] = { 11803 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 11804 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 11805 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 11806 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 11807 { } /* end */ 11808}; 11809 11810/* 11811 * 6ch mode 11812 */ 11813static struct hda_verb alc662_3ST_ch6_init[] = { 11814 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 11815 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 11816 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, 11817 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 11818 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 11819 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 11820 { } /* end */ 11821}; 11822 11823static struct hda_channel_mode alc662_3ST_6ch_modes[2] = { 11824 { 2, alc662_3ST_ch2_init }, 11825 { 6, alc662_3ST_ch6_init }, 11826}; 11827 11828/* 11829 * 2ch mode 11830 */ 11831static struct hda_verb alc662_sixstack_ch6_init[] = { 11832 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 11833 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 11834 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 11835 { } /* end */ 11836}; 11837 11838/* 11839 * 6ch mode 11840 */ 11841static struct hda_verb alc662_sixstack_ch8_init[] = { 11842 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 11843 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 11844 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 11845 { } /* end */ 11846}; 11847 11848static struct hda_channel_mode alc662_5stack_modes[2] = { 11849 { 2, alc662_sixstack_ch6_init }, 11850 { 6, alc662_sixstack_ch8_init }, 11851}; 11852 11853/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 11854 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b 11855 */ 11856 11857static struct snd_kcontrol_new alc662_base_mixer[] = { 11858 /* output mixer control */ 11859 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), 11860 HDA_CODEC_MUTE("Front Playback Switch", 0x02, 0x0, HDA_OUTPUT), 11861 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT), 11862 HDA_CODEC_MUTE("Surround Playback Switch", 0x03, 0x0, HDA_OUTPUT), 11863 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT), 11864 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT), 11865 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT), 11866 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT), 11867 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 11868 11869 /*Input mixer control */ 11870 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT), 11871 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT), 11872 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT), 11873 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT), 11874 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT), 11875 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT), 11876 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT), 11877 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT), 11878 11879 /* Capture mixer control */ 11880 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), 11881 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), 11882 { 11883 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 11884 .name = "Capture Source", 11885 .count = 1, 11886 .info = alc_mux_enum_info, 11887 .get = alc_mux_enum_get, 11888 .put = alc_mux_enum_put, 11889 }, 11890 { } /* end */ 11891}; 11892 11893static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = { 11894 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 11895 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT), 11896 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 11897 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 11898 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 11899 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 11900 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 11901 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11902 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11903 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 11904 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 11905 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 11906 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 11907 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), 11908 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), 11909 { 11910 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 11911 /* .name = "Capture Source", */ 11912 .name = "Input Source", 11913 .count = 1, 11914 .info = alc662_mux_enum_info, 11915 .get = alc662_mux_enum_get, 11916 .put = alc662_mux_enum_put, 11917 }, 11918 { } /* end */ 11919}; 11920 11921static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = { 11922 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 11923 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT), 11924 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT), 11925 HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT), 11926 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT), 11927 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT), 11928 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT), 11929 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT), 11930 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 11931 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 11932 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 11933 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 11934 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 11935 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11936 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11937 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 11938 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 11939 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 11940 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 11941 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), 11942 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), 11943 { 11944 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 11945 /* .name = "Capture Source", */ 11946 .name = "Input Source", 11947 .count = 1, 11948 .info = alc662_mux_enum_info, 11949 .get = alc662_mux_enum_get, 11950 .put = alc662_mux_enum_put, 11951 }, 11952 { } /* end */ 11953}; 11954 11955static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = { 11956 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 11957 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT), 11958 HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x03, 0x0, HDA_OUTPUT), 11959 HDA_BIND_MUTE("iSpeaker Playback Switch", 0x03, 2, HDA_INPUT), 11960 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 11961 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 11962 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 11963 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 11964 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 11965 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), 11966 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), 11967 { 11968 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 11969 /* .name = "Capture Source", */ 11970 .name = "Input Source", 11971 .count = 1, 11972 .info = alc662_mux_enum_info, 11973 .get = alc662_mux_enum_get, 11974 .put = alc662_mux_enum_put, 11975 }, 11976 { } /* end */ 11977}; 11978 11979static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = { 11980 HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 11981 11982 HDA_CODEC_VOLUME("LineOut Playback Volume", 0x02, 0x0, HDA_OUTPUT), 11983 HDA_CODEC_MUTE("LineOut Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 11984 11985 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT), 11986 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11987 HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11988 11989 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT), 11990 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 11991 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 11992 { } /* end */ 11993}; 11994 11995static struct snd_kcontrol_new alc662_chmode_mixer[] = { 11996 { 11997 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 11998 .name = "Channel Mode", 11999 .info = alc_ch_mode_info, 12000 .get = alc_ch_mode_get, 12001 .put = alc_ch_mode_put, 12002 }, 12003 { } /* end */ 12004}; 12005 12006static struct hda_verb alc662_init_verbs[] = { 12007 /* ADC: mute amp left and right */ 12008 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 12009 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 12010 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 12011 12012 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 12013 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 12014 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 12015 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 12016 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 12017 12018 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12019 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12020 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12021 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12022 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12023 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12024 12025 /* Front Pin: output 0 (0x0c) */ 12026 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 12027 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 12028 12029 /* Rear Pin: output 1 (0x0d) */ 12030 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 12031 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 12032 12033 /* CLFE Pin: output 2 (0x0e) */ 12034 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 12035 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 12036 12037 /* Mic (rear) pin: input vref at 80% */ 12038 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 12039 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 12040 /* Front Mic pin: input vref at 80% */ 12041 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 12042 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 12043 /* Line In pin: input */ 12044 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 12045 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 12046 /* Line-2 In: Headphone output (output 0 - 0x0c) */ 12047 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 12048 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 12049 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 12050 /* CD pin widget for input */ 12051 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 12052 12053 /* FIXME: use matrix-type input source selection */ 12054 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 12055 /* Input mixer */ 12056 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12057 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12058 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 12059 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, 12060 12061 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12062 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12063 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 12064 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, 12065 { } 12066}; 12067 12068static struct hda_verb alc662_sue_init_verbs[] = { 12069 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT}, 12070 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT}, 12071 {} 12072}; 12073 12074static struct hda_verb alc662_eeepc_sue_init_verbs[] = { 12075 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 12076 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 12077 {} 12078}; 12079 12080/* 12081 * generic initialization of ADC, input mixers and output mixers 12082 */ 12083static struct hda_verb alc662_auto_init_verbs[] = { 12084 /* 12085 * Unmute ADC and set the default input to mic-in 12086 */ 12087 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 12088 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12089 12090 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 12091 * mixer widget 12092 * Note: PASD motherboards uses the Line In 2 as the input for front 12093 * panel mic (mic 2) 12094 */ 12095 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 12096 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 12097 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 12098 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 12099 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 12100 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 12101 12102 /* 12103 * Set up output mixers (0x0c - 0x0f) 12104 */ 12105 /* set vol=0 to output mixers */ 12106 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 12107 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 12108 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 12109 12110 /* set up input amps for analog loopback */ 12111 /* Amp Indices: DAC = 0, mixer = 1 */ 12112 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12113 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12114 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12115 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12116 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12117 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12118 12119 12120 /* FIXME: use matrix-type input source selection */ 12121 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 12122 /* Input mixer */ 12123 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12124 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12125 { } 12126}; 12127 12128/* capture mixer elements */ 12129static struct snd_kcontrol_new alc662_capture_mixer[] = { 12130 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), 12131 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), 12132 { 12133 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 12134 /* The multiple "Capture Source" controls confuse alsamixer 12135 * So call somewhat different.. 12136 * FIXME: the controls appear in the "playback" view! 12137 */ 12138 /* .name = "Capture Source", */ 12139 .name = "Input Source", 12140 .count = 1, 12141 .info = alc882_mux_enum_info, 12142 .get = alc882_mux_enum_get, 12143 .put = alc882_mux_enum_put, 12144 }, 12145 { } /* end */ 12146}; 12147 12148static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec) 12149{ 12150 unsigned int present; 12151 unsigned char bits; 12152 12153 present = snd_hda_codec_read(codec, 0x14, 0, 12154 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 12155 bits = present ? HDA_AMP_MUTE : 0; 12156 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 12157 HDA_AMP_MUTE, bits); 12158} 12159 12160static void alc662_lenovo_101e_all_automute(struct hda_codec *codec) 12161{ 12162 unsigned int present; 12163 unsigned char bits; 12164 12165 present = snd_hda_codec_read(codec, 0x1b, 0, 12166 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 12167 bits = present ? HDA_AMP_MUTE : 0; 12168 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 12169 HDA_AMP_MUTE, bits); 12170 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 12171 HDA_AMP_MUTE, bits); 12172} 12173 12174static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec, 12175 unsigned int res) 12176{ 12177 if ((res >> 26) == ALC880_HP_EVENT) 12178 alc662_lenovo_101e_all_automute(codec); 12179 if ((res >> 26) == ALC880_FRONT_EVENT) 12180 alc662_lenovo_101e_ispeaker_automute(codec); 12181} 12182 12183static void alc662_eeepc_mic_automute(struct hda_codec *codec) 12184{ 12185 unsigned int present; 12186 12187 present = snd_hda_codec_read(codec, 0x18, 0, 12188 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 12189 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE, 12190 0x7000 | (0x00 << 8) | (present ? 0 : 0x80)); 12191 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE, 12192 0x7000 | (0x00 << 8) | (present ? 0 : 0x80)); 12193 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE, 12194 0x7000 | (0x01 << 8) | (present ? 0x80 : 0)); 12195 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE, 12196 0x7000 | (0x01 << 8) | (present ? 0x80 : 0)); 12197} 12198 12199/* unsolicited event for HP jack sensing */ 12200static void alc662_eeepc_unsol_event(struct hda_codec *codec, 12201 unsigned int res) 12202{ 12203 if ((res >> 26) == ALC880_HP_EVENT) 12204 alc262_hippo1_automute( codec ); 12205 12206 if ((res >> 26) == ALC880_MIC_EVENT) 12207 alc662_eeepc_mic_automute(codec); 12208} 12209 12210static void alc662_eeepc_inithook(struct hda_codec *codec) 12211{ 12212 alc262_hippo1_automute( codec ); 12213 alc662_eeepc_mic_automute(codec); 12214} 12215 12216#ifdef CONFIG_SND_HDA_POWER_SAVE 12217#define alc662_loopbacks alc880_loopbacks 12218#endif 12219 12220 12221/* pcm configuration: identiacal with ALC880 */ 12222#define alc662_pcm_analog_playback alc880_pcm_analog_playback 12223#define alc662_pcm_analog_capture alc880_pcm_analog_capture 12224#define alc662_pcm_digital_playback alc880_pcm_digital_playback 12225#define alc662_pcm_digital_capture alc880_pcm_digital_capture 12226 12227/* 12228 * configuration and preset 12229 */ 12230static const char *alc662_models[ALC662_MODEL_LAST] = { 12231 [ALC662_3ST_2ch_DIG] = "3stack-dig", 12232 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig", 12233 [ALC662_3ST_6ch] = "3stack-6ch", 12234 [ALC662_5ST_DIG] = "6stack-dig", 12235 [ALC662_LENOVO_101E] = "lenovo-101e", 12236 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701", 12237 [ALC662_AUTO] = "auto", 12238}; 12239 12240static struct snd_pci_quirk alc662_cfg_tbl[] = { 12241 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E), 12242 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701), 12243 {} 12244}; 12245 12246static struct alc_config_preset alc662_presets[] = { 12247 [ALC662_3ST_2ch_DIG] = { 12248 .mixers = { alc662_3ST_2ch_mixer, alc662_capture_mixer }, 12249 .init_verbs = { alc662_init_verbs }, 12250 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 12251 .dac_nids = alc662_dac_nids, 12252 .dig_out_nid = ALC662_DIGOUT_NID, 12253 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids), 12254 .adc_nids = alc662_adc_nids, 12255 .dig_in_nid = ALC662_DIGIN_NID, 12256 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 12257 .channel_mode = alc662_3ST_2ch_modes, 12258 .input_mux = &alc662_capture_source, 12259 }, 12260 [ALC662_3ST_6ch_DIG] = { 12261 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer, 12262 alc662_capture_mixer }, 12263 .init_verbs = { alc662_init_verbs }, 12264 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 12265 .dac_nids = alc662_dac_nids, 12266 .dig_out_nid = ALC662_DIGOUT_NID, 12267 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids), 12268 .adc_nids = alc662_adc_nids, 12269 .dig_in_nid = ALC662_DIGIN_NID, 12270 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), 12271 .channel_mode = alc662_3ST_6ch_modes, 12272 .need_dac_fix = 1, 12273 .input_mux = &alc662_capture_source, 12274 }, 12275 [ALC662_3ST_6ch] = { 12276 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer, 12277 alc662_capture_mixer }, 12278 .init_verbs = { alc662_init_verbs }, 12279 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 12280 .dac_nids = alc662_dac_nids, 12281 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids), 12282 .adc_nids = alc662_adc_nids, 12283 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), 12284 .channel_mode = alc662_3ST_6ch_modes, 12285 .need_dac_fix = 1, 12286 .input_mux = &alc662_capture_source, 12287 }, 12288 [ALC662_5ST_DIG] = { 12289 .mixers = { alc662_base_mixer, alc662_chmode_mixer, 12290 alc662_capture_mixer }, 12291 .init_verbs = { alc662_init_verbs }, 12292 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 12293 .dac_nids = alc662_dac_nids, 12294 .dig_out_nid = ALC662_DIGOUT_NID, 12295 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids), 12296 .adc_nids = alc662_adc_nids, 12297 .dig_in_nid = ALC662_DIGIN_NID, 12298 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes), 12299 .channel_mode = alc662_5stack_modes, 12300 .input_mux = &alc662_capture_source, 12301 }, 12302 [ALC662_LENOVO_101E] = { 12303 .mixers = { alc662_lenovo_101e_mixer, alc662_capture_mixer }, 12304 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs }, 12305 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 12306 .dac_nids = alc662_dac_nids, 12307 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids), 12308 .adc_nids = alc662_adc_nids, 12309 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 12310 .channel_mode = alc662_3ST_2ch_modes, 12311 .input_mux = &alc662_lenovo_101e_capture_source, 12312 .unsol_event = alc662_lenovo_101e_unsol_event, 12313 .init_hook = alc662_lenovo_101e_all_automute, 12314 }, 12315 [ALC662_ASUS_EEEPC_P701] = { 12316 .mixers = { alc662_eeepc_p701_mixer, alc662_capture_mixer }, 12317 .init_verbs = { alc662_init_verbs, 12318 alc662_eeepc_sue_init_verbs }, 12319 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 12320 .dac_nids = alc662_dac_nids, 12321 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids), 12322 .adc_nids = alc662_adc_nids, 12323 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 12324 .channel_mode = alc662_3ST_2ch_modes, 12325 .input_mux = &alc662_eeepc_capture_source, 12326 .unsol_event = alc662_eeepc_unsol_event, 12327 .init_hook = alc662_eeepc_inithook, 12328 }, 12329 12330}; 12331 12332 12333/* 12334 * BIOS auto configuration 12335 */ 12336 12337/* add playback controls from the parsed DAC table */ 12338static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec, 12339 const struct auto_pin_cfg *cfg) 12340{ 12341 char name[32]; 12342 static const char *chname[4] = { 12343 "Front", "Surround", NULL /*CLFE*/, "Side" 12344 }; 12345 hda_nid_t nid; 12346 int i, err; 12347 12348 for (i = 0; i < cfg->line_outs; i++) { 12349 if (!spec->multiout.dac_nids[i]) 12350 continue; 12351 nid = alc880_idx_to_dac(i); 12352 if (i == 2) { 12353 /* Center/LFE */ 12354 err = add_control(spec, ALC_CTL_WIDGET_VOL, 12355 "Center Playback Volume", 12356 HDA_COMPOSE_AMP_VAL(nid, 1, 0, 12357 HDA_OUTPUT)); 12358 if (err < 0) 12359 return err; 12360 err = add_control(spec, ALC_CTL_WIDGET_VOL, 12361 "LFE Playback Volume", 12362 HDA_COMPOSE_AMP_VAL(nid, 2, 0, 12363 HDA_OUTPUT)); 12364 if (err < 0) 12365 return err; 12366 err = add_control(spec, ALC_CTL_BIND_MUTE, 12367 "Center Playback Switch", 12368 HDA_COMPOSE_AMP_VAL(nid, 1, 2, 12369 HDA_INPUT)); 12370 if (err < 0) 12371 return err; 12372 err = add_control(spec, ALC_CTL_BIND_MUTE, 12373 "LFE Playback Switch", 12374 HDA_COMPOSE_AMP_VAL(nid, 2, 2, 12375 HDA_INPUT)); 12376 if (err < 0) 12377 return err; 12378 } else { 12379 sprintf(name, "%s Playback Volume", chname[i]); 12380 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, 12381 HDA_COMPOSE_AMP_VAL(nid, 3, 0, 12382 HDA_OUTPUT)); 12383 if (err < 0) 12384 return err; 12385 sprintf(name, "%s Playback Switch", chname[i]); 12386 err = add_control(spec, ALC_CTL_BIND_MUTE, name, 12387 HDA_COMPOSE_AMP_VAL(nid, 3, 2, 12388 HDA_INPUT)); 12389 if (err < 0) 12390 return err; 12391 } 12392 } 12393 return 0; 12394} 12395 12396/* add playback controls for speaker and HP outputs */ 12397static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin, 12398 const char *pfx) 12399{ 12400 hda_nid_t nid; 12401 int err; 12402 char name[32]; 12403 12404 if (!pin) 12405 return 0; 12406 12407 if (alc880_is_fixed_pin(pin)) { 12408 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); 12409 /* printk("DAC nid=%x\n",nid); */ 12410 /* specify the DAC as the extra output */ 12411 if (!spec->multiout.hp_nid) 12412 spec->multiout.hp_nid = nid; 12413 else 12414 spec->multiout.extra_out_nid[0] = nid; 12415 /* control HP volume/switch on the output mixer amp */ 12416 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); 12417 sprintf(name, "%s Playback Volume", pfx); 12418 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, 12419 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); 12420 if (err < 0) 12421 return err; 12422 sprintf(name, "%s Playback Switch", pfx); 12423 err = add_control(spec, ALC_CTL_BIND_MUTE, name, 12424 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT)); 12425 if (err < 0) 12426 return err; 12427 } else if (alc880_is_multi_pin(pin)) { 12428 /* set manual connection */ 12429 /* we have only a switch on HP-out PIN */ 12430 sprintf(name, "%s Playback Switch", pfx); 12431 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, 12432 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); 12433 if (err < 0) 12434 return err; 12435 } 12436 return 0; 12437} 12438 12439/* create playback/capture controls for input pins */ 12440static int alc662_auto_create_analog_input_ctls(struct alc_spec *spec, 12441 const struct auto_pin_cfg *cfg) 12442{ 12443 struct hda_input_mux *imux = &spec->private_imux; 12444 int i, err, idx; 12445 12446 for (i = 0; i < AUTO_PIN_LAST; i++) { 12447 if (alc880_is_input_pin(cfg->input_pins[i])) { 12448 idx = alc880_input_pin_idx(cfg->input_pins[i]); 12449 err = new_analog_input(spec, cfg->input_pins[i], 12450 auto_pin_cfg_labels[i], 12451 idx, 0x0b); 12452 if (err < 0) 12453 return err; 12454 imux->items[imux->num_items].label = 12455 auto_pin_cfg_labels[i]; 12456 imux->items[imux->num_items].index = 12457 alc880_input_pin_idx(cfg->input_pins[i]); 12458 imux->num_items++; 12459 } 12460 } 12461 return 0; 12462} 12463 12464static void alc662_auto_set_output_and_unmute(struct hda_codec *codec, 12465 hda_nid_t nid, int pin_type, 12466 int dac_idx) 12467{ 12468 /* set as output */ 12469 snd_hda_codec_write(codec, nid, 0, 12470 AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type); 12471 snd_hda_codec_write(codec, nid, 0, 12472 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); 12473 /* need the manual connection? */ 12474 if (alc880_is_multi_pin(nid)) { 12475 struct alc_spec *spec = codec->spec; 12476 int idx = alc880_multi_pin_idx(nid); 12477 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0, 12478 AC_VERB_SET_CONNECT_SEL, 12479 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx])); 12480 } 12481} 12482 12483static void alc662_auto_init_multi_out(struct hda_codec *codec) 12484{ 12485 struct alc_spec *spec = codec->spec; 12486 int i; 12487 12488 for (i = 0; i <= HDA_SIDE; i++) { 12489 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 12490 int pin_type = get_pin_type(spec->autocfg.line_out_type); 12491 if (nid) 12492 alc662_auto_set_output_and_unmute(codec, nid, pin_type, 12493 i); 12494 } 12495} 12496 12497static void alc662_auto_init_hp_out(struct hda_codec *codec) 12498{ 12499 struct alc_spec *spec = codec->spec; 12500 hda_nid_t pin; 12501 12502 pin = spec->autocfg.hp_pins[0]; 12503 if (pin) /* connect to front */ 12504 /* use dac 0 */ 12505 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); 12506} 12507 12508#define alc662_is_input_pin(nid) alc880_is_input_pin(nid) 12509#define ALC662_PIN_CD_NID ALC880_PIN_CD_NID 12510 12511static void alc662_auto_init_analog_input(struct hda_codec *codec) 12512{ 12513 struct alc_spec *spec = codec->spec; 12514 int i; 12515 12516 for (i = 0; i < AUTO_PIN_LAST; i++) { 12517 hda_nid_t nid = spec->autocfg.input_pins[i]; 12518 if (alc662_is_input_pin(nid)) { 12519 snd_hda_codec_write(codec, nid, 0, 12520 AC_VERB_SET_PIN_WIDGET_CONTROL, 12521 (i <= AUTO_PIN_FRONT_MIC ? 12522 PIN_VREF80 : PIN_IN)); 12523 if (nid != ALC662_PIN_CD_NID) 12524 snd_hda_codec_write(codec, nid, 0, 12525 AC_VERB_SET_AMP_GAIN_MUTE, 12526 AMP_OUT_MUTE); 12527 } 12528 } 12529} 12530 12531static int alc662_parse_auto_config(struct hda_codec *codec) 12532{ 12533 struct alc_spec *spec = codec->spec; 12534 int err; 12535 static hda_nid_t alc662_ignore[] = { 0x1d, 0 }; 12536 12537 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 12538 alc662_ignore); 12539 if (err < 0) 12540 return err; 12541 if (!spec->autocfg.line_outs) 12542 return 0; /* can't find valid BIOS pin config */ 12543 12544 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); 12545 if (err < 0) 12546 return err; 12547 err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg); 12548 if (err < 0) 12549 return err; 12550 err = alc662_auto_create_extra_out(spec, 12551 spec->autocfg.speaker_pins[0], 12552 "Speaker"); 12553 if (err < 0) 12554 return err; 12555 err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0], 12556 "Headphone"); 12557 if (err < 0) 12558 return err; 12559 err = alc662_auto_create_analog_input_ctls(spec, &spec->autocfg); 12560 if (err < 0) 12561 return err; 12562 12563 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 12564 12565 if (spec->autocfg.dig_out_pin) 12566 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID; 12567 12568 if (spec->kctl_alloc) 12569 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 12570 12571 spec->num_mux_defs = 1; 12572 spec->input_mux = &spec->private_imux; 12573 12574 spec->init_verbs[spec->num_init_verbs++] = alc662_auto_init_verbs; 12575 spec->mixers[spec->num_mixers] = alc662_capture_mixer; 12576 spec->num_mixers++; 12577 return 1; 12578} 12579 12580/* additional initialization for auto-configuration model */ 12581static void alc662_auto_init(struct hda_codec *codec) 12582{ 12583 alc662_auto_init_multi_out(codec); 12584 alc662_auto_init_hp_out(codec); 12585 alc662_auto_init_analog_input(codec); 12586} 12587 12588static int patch_alc662(struct hda_codec *codec) 12589{ 12590 struct alc_spec *spec; 12591 int err, board_config; 12592 12593 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 12594 if (!spec) 12595 return -ENOMEM; 12596 12597 codec->spec = spec; 12598 12599 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST, 12600 alc662_models, 12601 alc662_cfg_tbl); 12602 if (board_config < 0) { 12603 printk(KERN_INFO "hda_codec: Unknown model for ALC662, " 12604 "trying auto-probe from BIOS...\n"); 12605 board_config = ALC662_AUTO; 12606 } 12607 12608 if (board_config == ALC662_AUTO) { 12609 /* automatic parse from the BIOS config */ 12610 err = alc662_parse_auto_config(codec); 12611 if (err < 0) { 12612 alc_free(codec); 12613 return err; 12614 } else if (!err) { 12615 printk(KERN_INFO 12616 "hda_codec: Cannot set up configuration " 12617 "from BIOS. Using base mode...\n"); 12618 board_config = ALC662_3ST_2ch_DIG; 12619 } 12620 } 12621 12622 if (board_config != ALC662_AUTO) 12623 setup_preset(spec, &alc662_presets[board_config]); 12624 12625 spec->stream_name_analog = "ALC662 Analog"; 12626 spec->stream_analog_playback = &alc662_pcm_analog_playback; 12627 spec->stream_analog_capture = &alc662_pcm_analog_capture; 12628 12629 spec->stream_name_digital = "ALC662 Digital"; 12630 spec->stream_digital_playback = &alc662_pcm_digital_playback; 12631 spec->stream_digital_capture = &alc662_pcm_digital_capture; 12632 12633 if (!spec->adc_nids && spec->input_mux) { 12634 spec->adc_nids = alc662_adc_nids; 12635 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids); 12636 } 12637 12638 codec->patch_ops = alc_patch_ops; 12639 if (board_config == ALC662_AUTO) 12640 spec->init_hook = alc662_auto_init; 12641#ifdef CONFIG_SND_HDA_POWER_SAVE 12642 if (!spec->loopback.amplist) 12643 spec->loopback.amplist = alc662_loopbacks; 12644#endif 12645 12646 return 0; 12647} 12648 12649/* 12650 * patch entries 12651 */ 12652struct hda_codec_preset snd_hda_preset_realtek[] = { 12653 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 }, 12654 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 }, 12655 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 }, 12656 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660", 12657 .patch = patch_alc861 }, 12658 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd }, 12659 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 }, 12660 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd }, 12661 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2", 12662 .patch = patch_alc883 }, 12663 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1", 12664 .patch = patch_alc662 }, 12665 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 }, 12666 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 }, 12667 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 }, 12668 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 }, 12669 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 }, 12670 {} /* terminator */ 12671}; 12672