patch_realtek.c revision 0438a00e64f38b2f655a10167f9f2d9759856069
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_BENQ_ED8, 96 ALC262_SONY_ASSAMD, 97 ALC262_BENQ_T31, 98 ALC262_AUTO, 99 ALC262_MODEL_LAST /* last tag */ 100}; 101 102/* ALC268 models */ 103enum { 104 ALC268_3ST, 105 ALC268_TOSHIBA, 106 ALC268_ACER, 107 ALC268_AUTO, 108 ALC268_MODEL_LAST /* last tag */ 109}; 110 111/* ALC861 models */ 112enum { 113 ALC861_3ST, 114 ALC660_3ST, 115 ALC861_3ST_DIG, 116 ALC861_6ST_DIG, 117 ALC861_UNIWILL_M31, 118 ALC861_TOSHIBA, 119 ALC861_ASUS, 120 ALC861_ASUS_LAPTOP, 121 ALC861_AUTO, 122 ALC861_MODEL_LAST, 123}; 124 125/* ALC861-VD models */ 126enum { 127 ALC660VD_3ST, 128 ALC660VD_3ST_DIG, 129 ALC861VD_3ST, 130 ALC861VD_3ST_DIG, 131 ALC861VD_6ST_DIG, 132 ALC861VD_LENOVO, 133 ALC861VD_DALLAS, 134 ALC861VD_HP, 135 ALC861VD_AUTO, 136 ALC861VD_MODEL_LAST, 137}; 138 139/* ALC662 models */ 140enum { 141 ALC662_3ST_2ch_DIG, 142 ALC662_3ST_6ch_DIG, 143 ALC662_3ST_6ch, 144 ALC662_5ST_DIG, 145 ALC662_LENOVO_101E, 146 ALC662_AUTO, 147 ALC662_MODEL_LAST, 148}; 149 150/* ALC882 models */ 151enum { 152 ALC882_3ST_DIG, 153 ALC882_6ST_DIG, 154 ALC882_ARIMA, 155 ALC882_W2JC, 156 ALC882_TARGA, 157 ALC882_ASUS_A7J, 158 ALC882_ASUS_A7M, 159 ALC885_MACPRO, 160 ALC885_MBP3, 161 ALC885_IMAC24, 162 ALC882_AUTO, 163 ALC882_MODEL_LAST, 164}; 165 166/* ALC883 models */ 167enum { 168 ALC883_3ST_2ch_DIG, 169 ALC883_3ST_6ch_DIG, 170 ALC883_3ST_6ch, 171 ALC883_6ST_DIG, 172 ALC883_TARGA_DIG, 173 ALC883_TARGA_2ch_DIG, 174 ALC883_ACER, 175 ALC883_ACER_ASPIRE, 176 ALC883_MEDION, 177 ALC883_MEDION_MD2, 178 ALC883_LAPTOP_EAPD, 179 ALC883_LENOVO_101E_2ch, 180 ALC883_LENOVO_NB0763, 181 ALC888_LENOVO_MS7195_DIG, 182 ALC883_HAIER_W66, 183 ALC888_6ST_HP, 184 ALC888_3ST_HP, 185 ALC883_AUTO, 186 ALC883_MODEL_LAST, 187}; 188 189/* for GPIO Poll */ 190#define GPIO_MASK 0x03 191 192struct alc_spec { 193 /* codec parameterization */ 194 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */ 195 unsigned int num_mixers; 196 197 const struct hda_verb *init_verbs[5]; /* initialization verbs 198 * don't forget NULL 199 * termination! 200 */ 201 unsigned int num_init_verbs; 202 203 char *stream_name_analog; /* analog PCM stream */ 204 struct hda_pcm_stream *stream_analog_playback; 205 struct hda_pcm_stream *stream_analog_capture; 206 207 char *stream_name_digital; /* digital PCM stream */ 208 struct hda_pcm_stream *stream_digital_playback; 209 struct hda_pcm_stream *stream_digital_capture; 210 211 /* playback */ 212 struct hda_multi_out multiout; /* playback set-up 213 * max_channels, dacs must be set 214 * dig_out_nid and hp_nid are optional 215 */ 216 217 /* capture */ 218 unsigned int num_adc_nids; 219 hda_nid_t *adc_nids; 220 hda_nid_t dig_in_nid; /* digital-in NID; optional */ 221 222 /* capture source */ 223 unsigned int num_mux_defs; 224 const struct hda_input_mux *input_mux; 225 unsigned int cur_mux[3]; 226 227 /* channel model */ 228 const struct hda_channel_mode *channel_mode; 229 int num_channel_mode; 230 int need_dac_fix; 231 232 /* PCM information */ 233 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */ 234 235 /* dynamic controls, init_verbs and input_mux */ 236 struct auto_pin_cfg autocfg; 237 unsigned int num_kctl_alloc, num_kctl_used; 238 struct snd_kcontrol_new *kctl_alloc; 239 struct hda_input_mux private_imux; 240 hda_nid_t private_dac_nids[5]; 241 242 /* hooks */ 243 void (*init_hook)(struct hda_codec *codec); 244 void (*unsol_event)(struct hda_codec *codec, unsigned int res); 245 246 /* for pin sensing */ 247 unsigned int sense_updated: 1; 248 unsigned int jack_present: 1; 249 250#ifdef CONFIG_SND_HDA_POWER_SAVE 251 struct hda_loopback_check loopback; 252#endif 253}; 254 255/* 256 * configuration template - to be copied to the spec instance 257 */ 258struct alc_config_preset { 259 struct snd_kcontrol_new *mixers[5]; /* should be identical size 260 * with spec 261 */ 262 const struct hda_verb *init_verbs[5]; 263 unsigned int num_dacs; 264 hda_nid_t *dac_nids; 265 hda_nid_t dig_out_nid; /* optional */ 266 hda_nid_t hp_nid; /* optional */ 267 unsigned int num_adc_nids; 268 hda_nid_t *adc_nids; 269 hda_nid_t dig_in_nid; 270 unsigned int num_channel_mode; 271 const struct hda_channel_mode *channel_mode; 272 int need_dac_fix; 273 unsigned int num_mux_defs; 274 const struct hda_input_mux *input_mux; 275 void (*unsol_event)(struct hda_codec *, unsigned int); 276 void (*init_hook)(struct hda_codec *); 277#ifdef CONFIG_SND_HDA_POWER_SAVE 278 struct hda_amp_list *loopbacks; 279#endif 280}; 281 282 283/* 284 * input MUX handling 285 */ 286static int alc_mux_enum_info(struct snd_kcontrol *kcontrol, 287 struct snd_ctl_elem_info *uinfo) 288{ 289 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 290 struct alc_spec *spec = codec->spec; 291 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id); 292 if (mux_idx >= spec->num_mux_defs) 293 mux_idx = 0; 294 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo); 295} 296 297static int alc_mux_enum_get(struct snd_kcontrol *kcontrol, 298 struct snd_ctl_elem_value *ucontrol) 299{ 300 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 301 struct alc_spec *spec = codec->spec; 302 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 303 304 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx]; 305 return 0; 306} 307 308static int alc_mux_enum_put(struct snd_kcontrol *kcontrol, 309 struct snd_ctl_elem_value *ucontrol) 310{ 311 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 312 struct alc_spec *spec = codec->spec; 313 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 314 unsigned int mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx; 315 return snd_hda_input_mux_put(codec, &spec->input_mux[mux_idx], ucontrol, 316 spec->adc_nids[adc_idx], 317 &spec->cur_mux[adc_idx]); 318} 319 320 321/* 322 * channel mode setting 323 */ 324static int alc_ch_mode_info(struct snd_kcontrol *kcontrol, 325 struct snd_ctl_elem_info *uinfo) 326{ 327 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 328 struct alc_spec *spec = codec->spec; 329 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode, 330 spec->num_channel_mode); 331} 332 333static int alc_ch_mode_get(struct snd_kcontrol *kcontrol, 334 struct snd_ctl_elem_value *ucontrol) 335{ 336 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 337 struct alc_spec *spec = codec->spec; 338 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode, 339 spec->num_channel_mode, 340 spec->multiout.max_channels); 341} 342 343static int alc_ch_mode_put(struct snd_kcontrol *kcontrol, 344 struct snd_ctl_elem_value *ucontrol) 345{ 346 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 347 struct alc_spec *spec = codec->spec; 348 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode, 349 spec->num_channel_mode, 350 &spec->multiout.max_channels); 351 if (err >= 0 && spec->need_dac_fix) 352 spec->multiout.num_dacs = spec->multiout.max_channels / 2; 353 return err; 354} 355 356/* 357 * Control the mode of pin widget settings via the mixer. "pc" is used 358 * instead of "%" to avoid consequences of accidently treating the % as 359 * being part of a format specifier. Maximum allowed length of a value is 360 * 63 characters plus NULL terminator. 361 * 362 * Note: some retasking pin complexes seem to ignore requests for input 363 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these 364 * are requested. Therefore order this list so that this behaviour will not 365 * cause problems when mixer clients move through the enum sequentially. 366 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of 367 * March 2006. 368 */ 369static char *alc_pin_mode_names[] = { 370 "Mic 50pc bias", "Mic 80pc bias", 371 "Line in", "Line out", "Headphone out", 372}; 373static unsigned char alc_pin_mode_values[] = { 374 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP, 375}; 376/* The control can present all 5 options, or it can limit the options based 377 * in the pin being assumed to be exclusively an input or an output pin. In 378 * addition, "input" pins may or may not process the mic bias option 379 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to 380 * accept requests for bias as of chip versions up to March 2006) and/or 381 * wiring in the computer. 382 */ 383#define ALC_PIN_DIR_IN 0x00 384#define ALC_PIN_DIR_OUT 0x01 385#define ALC_PIN_DIR_INOUT 0x02 386#define ALC_PIN_DIR_IN_NOMICBIAS 0x03 387#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04 388 389/* Info about the pin modes supported by the different pin direction modes. 390 * For each direction the minimum and maximum values are given. 391 */ 392static signed char alc_pin_mode_dir_info[5][2] = { 393 { 0, 2 }, /* ALC_PIN_DIR_IN */ 394 { 3, 4 }, /* ALC_PIN_DIR_OUT */ 395 { 0, 4 }, /* ALC_PIN_DIR_INOUT */ 396 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */ 397 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */ 398}; 399#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0]) 400#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1]) 401#define alc_pin_mode_n_items(_dir) \ 402 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1) 403 404static int alc_pin_mode_info(struct snd_kcontrol *kcontrol, 405 struct snd_ctl_elem_info *uinfo) 406{ 407 unsigned int item_num = uinfo->value.enumerated.item; 408 unsigned char dir = (kcontrol->private_value >> 16) & 0xff; 409 410 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 411 uinfo->count = 1; 412 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir); 413 414 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir)) 415 item_num = alc_pin_mode_min(dir); 416 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]); 417 return 0; 418} 419 420static int alc_pin_mode_get(struct snd_kcontrol *kcontrol, 421 struct snd_ctl_elem_value *ucontrol) 422{ 423 unsigned int i; 424 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 425 hda_nid_t nid = kcontrol->private_value & 0xffff; 426 unsigned char dir = (kcontrol->private_value >> 16) & 0xff; 427 long *valp = ucontrol->value.integer.value; 428 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0, 429 AC_VERB_GET_PIN_WIDGET_CONTROL, 430 0x00); 431 432 /* Find enumerated value for current pinctl setting */ 433 i = alc_pin_mode_min(dir); 434 while (alc_pin_mode_values[i] != pinctl && i <= alc_pin_mode_max(dir)) 435 i++; 436 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir); 437 return 0; 438} 439 440static int alc_pin_mode_put(struct snd_kcontrol *kcontrol, 441 struct snd_ctl_elem_value *ucontrol) 442{ 443 signed int change; 444 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 445 hda_nid_t nid = kcontrol->private_value & 0xffff; 446 unsigned char dir = (kcontrol->private_value >> 16) & 0xff; 447 long val = *ucontrol->value.integer.value; 448 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0, 449 AC_VERB_GET_PIN_WIDGET_CONTROL, 450 0x00); 451 452 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir)) 453 val = alc_pin_mode_min(dir); 454 455 change = pinctl != alc_pin_mode_values[val]; 456 if (change) { 457 /* Set pin mode to that requested */ 458 snd_hda_codec_write_cache(codec, nid, 0, 459 AC_VERB_SET_PIN_WIDGET_CONTROL, 460 alc_pin_mode_values[val]); 461 462 /* Also enable the retasking pin's input/output as required 463 * for the requested pin mode. Enum values of 2 or less are 464 * input modes. 465 * 466 * Dynamically switching the input/output buffers probably 467 * reduces noise slightly (particularly on input) so we'll 468 * do it. However, having both input and output buffers 469 * enabled simultaneously doesn't seem to be problematic if 470 * this turns out to be necessary in the future. 471 */ 472 if (val <= 2) { 473 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, 474 HDA_AMP_MUTE, HDA_AMP_MUTE); 475 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0, 476 HDA_AMP_MUTE, 0); 477 } else { 478 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0, 479 HDA_AMP_MUTE, HDA_AMP_MUTE); 480 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, 481 HDA_AMP_MUTE, 0); 482 } 483 } 484 return change; 485} 486 487#define ALC_PIN_MODE(xname, nid, dir) \ 488 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 489 .info = alc_pin_mode_info, \ 490 .get = alc_pin_mode_get, \ 491 .put = alc_pin_mode_put, \ 492 .private_value = nid | (dir<<16) } 493 494/* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged 495 * together using a mask with more than one bit set. This control is 496 * currently used only by the ALC260 test model. At this stage they are not 497 * needed for any "production" models. 498 */ 499#ifdef CONFIG_SND_DEBUG 500#define alc_gpio_data_info snd_ctl_boolean_mono_info 501 502static int alc_gpio_data_get(struct snd_kcontrol *kcontrol, 503 struct snd_ctl_elem_value *ucontrol) 504{ 505 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 506 hda_nid_t nid = kcontrol->private_value & 0xffff; 507 unsigned char mask = (kcontrol->private_value >> 16) & 0xff; 508 long *valp = ucontrol->value.integer.value; 509 unsigned int val = snd_hda_codec_read(codec, nid, 0, 510 AC_VERB_GET_GPIO_DATA, 0x00); 511 512 *valp = (val & mask) != 0; 513 return 0; 514} 515static int alc_gpio_data_put(struct snd_kcontrol *kcontrol, 516 struct snd_ctl_elem_value *ucontrol) 517{ 518 signed int change; 519 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 520 hda_nid_t nid = kcontrol->private_value & 0xffff; 521 unsigned char mask = (kcontrol->private_value >> 16) & 0xff; 522 long val = *ucontrol->value.integer.value; 523 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0, 524 AC_VERB_GET_GPIO_DATA, 525 0x00); 526 527 /* Set/unset the masked GPIO bit(s) as needed */ 528 change = (val == 0 ? 0 : mask) != (gpio_data & mask); 529 if (val == 0) 530 gpio_data &= ~mask; 531 else 532 gpio_data |= mask; 533 snd_hda_codec_write_cache(codec, nid, 0, 534 AC_VERB_SET_GPIO_DATA, gpio_data); 535 536 return change; 537} 538#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \ 539 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 540 .info = alc_gpio_data_info, \ 541 .get = alc_gpio_data_get, \ 542 .put = alc_gpio_data_put, \ 543 .private_value = nid | (mask<<16) } 544#endif /* CONFIG_SND_DEBUG */ 545 546/* A switch control to allow the enabling of the digital IO pins on the 547 * ALC260. This is incredibly simplistic; the intention of this control is 548 * to provide something in the test model allowing digital outputs to be 549 * identified if present. If models are found which can utilise these 550 * outputs a more complete mixer control can be devised for those models if 551 * necessary. 552 */ 553#ifdef CONFIG_SND_DEBUG 554#define alc_spdif_ctrl_info snd_ctl_boolean_mono_info 555 556static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol, 557 struct snd_ctl_elem_value *ucontrol) 558{ 559 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 560 hda_nid_t nid = kcontrol->private_value & 0xffff; 561 unsigned char mask = (kcontrol->private_value >> 16) & 0xff; 562 long *valp = ucontrol->value.integer.value; 563 unsigned int val = snd_hda_codec_read(codec, nid, 0, 564 AC_VERB_GET_DIGI_CONVERT, 0x00); 565 566 *valp = (val & mask) != 0; 567 return 0; 568} 569static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol, 570 struct snd_ctl_elem_value *ucontrol) 571{ 572 signed int change; 573 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 574 hda_nid_t nid = kcontrol->private_value & 0xffff; 575 unsigned char mask = (kcontrol->private_value >> 16) & 0xff; 576 long val = *ucontrol->value.integer.value; 577 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0, 578 AC_VERB_GET_DIGI_CONVERT, 579 0x00); 580 581 /* Set/unset the masked control bit(s) as needed */ 582 change = (val == 0 ? 0 : mask) != (ctrl_data & mask); 583 if (val==0) 584 ctrl_data &= ~mask; 585 else 586 ctrl_data |= mask; 587 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, 588 ctrl_data); 589 590 return change; 591} 592#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \ 593 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 594 .info = alc_spdif_ctrl_info, \ 595 .get = alc_spdif_ctrl_get, \ 596 .put = alc_spdif_ctrl_put, \ 597 .private_value = nid | (mask<<16) } 598#endif /* CONFIG_SND_DEBUG */ 599 600/* 601 * set up from the preset table 602 */ 603static void setup_preset(struct alc_spec *spec, 604 const struct alc_config_preset *preset) 605{ 606 int i; 607 608 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++) 609 spec->mixers[spec->num_mixers++] = preset->mixers[i]; 610 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i]; 611 i++) 612 spec->init_verbs[spec->num_init_verbs++] = 613 preset->init_verbs[i]; 614 615 spec->channel_mode = preset->channel_mode; 616 spec->num_channel_mode = preset->num_channel_mode; 617 spec->need_dac_fix = preset->need_dac_fix; 618 619 spec->multiout.max_channels = spec->channel_mode[0].channels; 620 621 spec->multiout.num_dacs = preset->num_dacs; 622 spec->multiout.dac_nids = preset->dac_nids; 623 spec->multiout.dig_out_nid = preset->dig_out_nid; 624 spec->multiout.hp_nid = preset->hp_nid; 625 626 spec->num_mux_defs = preset->num_mux_defs; 627 if (!spec->num_mux_defs) 628 spec->num_mux_defs = 1; 629 spec->input_mux = preset->input_mux; 630 631 spec->num_adc_nids = preset->num_adc_nids; 632 spec->adc_nids = preset->adc_nids; 633 spec->dig_in_nid = preset->dig_in_nid; 634 635 spec->unsol_event = preset->unsol_event; 636 spec->init_hook = preset->init_hook; 637#ifdef CONFIG_SND_HDA_POWER_SAVE 638 spec->loopback.amplist = preset->loopbacks; 639#endif 640} 641 642/* Enable GPIO mask and set output */ 643static struct hda_verb alc_gpio1_init_verbs[] = { 644 {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, 645 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, 646 {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, 647 { } 648}; 649 650static struct hda_verb alc_gpio2_init_verbs[] = { 651 {0x01, AC_VERB_SET_GPIO_MASK, 0x02}, 652 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02}, 653 {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, 654 { } 655}; 656 657static struct hda_verb alc_gpio3_init_verbs[] = { 658 {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, 659 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03}, 660 {0x01, AC_VERB_SET_GPIO_DATA, 0x03}, 661 { } 662}; 663 664/* 32-bit subsystem ID for BIOS loading in HD Audio codec. 665 * 31 ~ 16 : Manufacture ID 666 * 15 ~ 8 : SKU ID 667 * 7 ~ 0 : Assembly ID 668 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36 669 */ 670static void alc_subsystem_id(struct hda_codec *codec, 671 unsigned int porta, unsigned int porte, 672 unsigned int portd) 673{ 674 unsigned int ass, tmp; 675 676 ass = codec->subsystem_id; 677 if (!(ass & 1)) 678 return; 679 680 /* Override */ 681 tmp = (ass & 0x38) >> 3; /* external Amp control */ 682 switch (tmp) { 683 case 1: 684 snd_hda_sequence_write(codec, alc_gpio1_init_verbs); 685 break; 686 case 3: 687 snd_hda_sequence_write(codec, alc_gpio2_init_verbs); 688 break; 689 case 7: 690 snd_hda_sequence_write(codec, alc_gpio3_init_verbs); 691 break; 692 case 5: 693 switch (codec->vendor_id) { 694 case 0x10ec0862: 695 case 0x10ec0660: 696 case 0x10ec0662: 697 case 0x10ec0267: 698 case 0x10ec0268: 699 snd_hda_codec_write(codec, 0x14, 0, 700 AC_VERB_SET_EAPD_BTLENABLE, 2); 701 snd_hda_codec_write(codec, 0x15, 0, 702 AC_VERB_SET_EAPD_BTLENABLE, 2); 703 return; 704 } 705 case 6: 706 if (ass & 4) { /* bit 2 : 0 = Desktop, 1 = Laptop */ 707 hda_nid_t port = 0; 708 tmp = (ass & 0x1800) >> 11; 709 switch (tmp) { 710 case 0: port = porta; break; 711 case 1: port = porte; break; 712 case 2: port = portd; break; 713 } 714 if (port) 715 snd_hda_codec_write(codec, port, 0, 716 AC_VERB_SET_EAPD_BTLENABLE, 717 2); 718 } 719 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7); 720 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, 721 (tmp == 5 ? 0x3040 : 0x3050)); 722 break; 723 } 724} 725 726/* 727 * Fix-up pin default configurations 728 */ 729 730struct alc_pincfg { 731 hda_nid_t nid; 732 u32 val; 733}; 734 735static void alc_fix_pincfg(struct hda_codec *codec, 736 const struct snd_pci_quirk *quirk, 737 const struct alc_pincfg **pinfix) 738{ 739 const struct alc_pincfg *cfg; 740 741 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk); 742 if (!quirk) 743 return; 744 745 cfg = pinfix[quirk->value]; 746 for (; cfg->nid; cfg++) { 747 int i; 748 u32 val = cfg->val; 749 for (i = 0; i < 4; i++) { 750 snd_hda_codec_write(codec, cfg->nid, 0, 751 AC_VERB_SET_CONFIG_DEFAULT_BYTES_0 + i, 752 val & 0xff); 753 val >>= 8; 754 } 755 } 756} 757 758/* 759 * ALC880 3-stack model 760 * 761 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e) 762 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18, 763 * F-Mic = 0x1b, HP = 0x19 764 */ 765 766static hda_nid_t alc880_dac_nids[4] = { 767 /* front, rear, clfe, rear_surr */ 768 0x02, 0x05, 0x04, 0x03 769}; 770 771static hda_nid_t alc880_adc_nids[3] = { 772 /* ADC0-2 */ 773 0x07, 0x08, 0x09, 774}; 775 776/* The datasheet says the node 0x07 is connected from inputs, 777 * but it shows zero connection in the real implementation on some devices. 778 * Note: this is a 915GAV bug, fixed on 915GLV 779 */ 780static hda_nid_t alc880_adc_nids_alt[2] = { 781 /* ADC1-2 */ 782 0x08, 0x09, 783}; 784 785#define ALC880_DIGOUT_NID 0x06 786#define ALC880_DIGIN_NID 0x0a 787 788static struct hda_input_mux alc880_capture_source = { 789 .num_items = 4, 790 .items = { 791 { "Mic", 0x0 }, 792 { "Front Mic", 0x3 }, 793 { "Line", 0x2 }, 794 { "CD", 0x4 }, 795 }, 796}; 797 798/* channel source setting (2/6 channel selection for 3-stack) */ 799/* 2ch mode */ 800static struct hda_verb alc880_threestack_ch2_init[] = { 801 /* set line-in to input, mute it */ 802 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 803 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 804 /* set mic-in to input vref 80%, mute it */ 805 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 806 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 807 { } /* end */ 808}; 809 810/* 6ch mode */ 811static struct hda_verb alc880_threestack_ch6_init[] = { 812 /* set line-in to output, unmute it */ 813 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 814 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 815 /* set mic-in to output, unmute it */ 816 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 817 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 818 { } /* end */ 819}; 820 821static struct hda_channel_mode alc880_threestack_modes[2] = { 822 { 2, alc880_threestack_ch2_init }, 823 { 6, alc880_threestack_ch6_init }, 824}; 825 826static struct snd_kcontrol_new alc880_three_stack_mixer[] = { 827 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 828 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 829 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 830 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT), 831 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 832 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 833 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 834 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 835 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 836 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 837 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 838 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 839 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 840 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 841 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT), 842 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT), 843 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 844 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 845 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT), 846 { 847 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 848 .name = "Channel Mode", 849 .info = alc_ch_mode_info, 850 .get = alc_ch_mode_get, 851 .put = alc_ch_mode_put, 852 }, 853 { } /* end */ 854}; 855 856/* capture mixer elements */ 857static struct snd_kcontrol_new alc880_capture_mixer[] = { 858 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT), 859 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT), 860 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT), 861 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT), 862 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT), 863 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT), 864 { 865 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 866 /* The multiple "Capture Source" controls confuse alsamixer 867 * So call somewhat different.. 868 * FIXME: the controls appear in the "playback" view! 869 */ 870 /* .name = "Capture Source", */ 871 .name = "Input Source", 872 .count = 3, 873 .info = alc_mux_enum_info, 874 .get = alc_mux_enum_get, 875 .put = alc_mux_enum_put, 876 }, 877 { } /* end */ 878}; 879 880/* capture mixer elements (in case NID 0x07 not available) */ 881static struct snd_kcontrol_new alc880_capture_alt_mixer[] = { 882 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 883 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 884 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), 885 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), 886 { 887 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 888 /* The multiple "Capture Source" controls confuse alsamixer 889 * So call somewhat different.. 890 * FIXME: the controls appear in the "playback" view! 891 */ 892 /* .name = "Capture Source", */ 893 .name = "Input Source", 894 .count = 2, 895 .info = alc_mux_enum_info, 896 .get = alc_mux_enum_get, 897 .put = alc_mux_enum_put, 898 }, 899 { } /* end */ 900}; 901 902 903 904/* 905 * ALC880 5-stack model 906 * 907 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d), 908 * Side = 0x02 (0xd) 909 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16 910 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19 911 */ 912 913/* additional mixers to alc880_three_stack_mixer */ 914static struct snd_kcontrol_new alc880_five_stack_mixer[] = { 915 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 916 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT), 917 { } /* end */ 918}; 919 920/* channel source setting (6/8 channel selection for 5-stack) */ 921/* 6ch mode */ 922static struct hda_verb alc880_fivestack_ch6_init[] = { 923 /* set line-in to input, mute it */ 924 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 925 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 926 { } /* end */ 927}; 928 929/* 8ch mode */ 930static struct hda_verb alc880_fivestack_ch8_init[] = { 931 /* set line-in to output, unmute it */ 932 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 933 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 934 { } /* end */ 935}; 936 937static struct hda_channel_mode alc880_fivestack_modes[2] = { 938 { 6, alc880_fivestack_ch6_init }, 939 { 8, alc880_fivestack_ch8_init }, 940}; 941 942 943/* 944 * ALC880 6-stack model 945 * 946 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e), 947 * Side = 0x05 (0x0f) 948 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17, 949 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b 950 */ 951 952static hda_nid_t alc880_6st_dac_nids[4] = { 953 /* front, rear, clfe, rear_surr */ 954 0x02, 0x03, 0x04, 0x05 955}; 956 957static struct hda_input_mux alc880_6stack_capture_source = { 958 .num_items = 4, 959 .items = { 960 { "Mic", 0x0 }, 961 { "Front Mic", 0x1 }, 962 { "Line", 0x2 }, 963 { "CD", 0x4 }, 964 }, 965}; 966 967/* fixed 8-channels */ 968static struct hda_channel_mode alc880_sixstack_modes[1] = { 969 { 8, NULL }, 970}; 971 972static struct snd_kcontrol_new alc880_six_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", 0x0d, 0x0, HDA_OUTPUT), 976 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 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("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 982 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 983 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 984 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 985 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 986 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 987 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 988 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 989 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 990 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 991 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 992 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 993 { 994 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 995 .name = "Channel Mode", 996 .info = alc_ch_mode_info, 997 .get = alc_ch_mode_get, 998 .put = alc_ch_mode_put, 999 }, 1000 { } /* end */ 1001}; 1002 1003 1004/* 1005 * ALC880 W810 model 1006 * 1007 * W810 has rear IO for: 1008 * Front (DAC 02) 1009 * Surround (DAC 03) 1010 * Center/LFE (DAC 04) 1011 * Digital out (06) 1012 * 1013 * The system also has a pair of internal speakers, and a headphone jack. 1014 * These are both connected to Line2 on the codec, hence to DAC 02. 1015 * 1016 * There is a variable resistor to control the speaker or headphone 1017 * volume. This is a hardware-only device without a software API. 1018 * 1019 * Plugging headphones in will disable the internal speakers. This is 1020 * implemented in hardware, not via the driver using jack sense. In 1021 * a similar fashion, plugging into the rear socket marked "front" will 1022 * disable both the speakers and headphones. 1023 * 1024 * For input, there's a microphone jack, and an "audio in" jack. 1025 * These may not do anything useful with this driver yet, because I 1026 * haven't setup any initialization verbs for these yet... 1027 */ 1028 1029static hda_nid_t alc880_w810_dac_nids[3] = { 1030 /* front, rear/surround, clfe */ 1031 0x02, 0x03, 0x04 1032}; 1033 1034/* fixed 6 channels */ 1035static struct hda_channel_mode alc880_w810_modes[1] = { 1036 { 6, NULL } 1037}; 1038 1039/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */ 1040static struct snd_kcontrol_new alc880_w810_base_mixer[] = { 1041 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 1042 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 1043 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 1044 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 1045 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 1046 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 1047 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 1048 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 1049 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 1050 { } /* end */ 1051}; 1052 1053 1054/* 1055 * Z710V model 1056 * 1057 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d) 1058 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?), 1059 * Line = 0x1a 1060 */ 1061 1062static hda_nid_t alc880_z71v_dac_nids[1] = { 1063 0x02 1064}; 1065#define ALC880_Z71V_HP_DAC 0x03 1066 1067/* fixed 2 channels */ 1068static struct hda_channel_mode alc880_2_jack_modes[1] = { 1069 { 2, NULL } 1070}; 1071 1072static struct snd_kcontrol_new alc880_z71v_mixer[] = { 1073 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 1074 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 1075 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 1076 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT), 1077 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 1078 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 1079 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 1080 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 1081 { } /* end */ 1082}; 1083 1084 1085/* FIXME! */ 1086/* 1087 * ALC880 F1734 model 1088 * 1089 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d) 1090 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18 1091 */ 1092 1093static hda_nid_t alc880_f1734_dac_nids[1] = { 1094 0x03 1095}; 1096#define ALC880_F1734_HP_DAC 0x02 1097 1098static struct snd_kcontrol_new alc880_f1734_mixer[] = { 1099 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 1100 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), 1101 HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 1102 HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 1103 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 1104 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 1105 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 1106 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 1107 { } /* end */ 1108}; 1109 1110 1111/* FIXME! */ 1112/* 1113 * ALC880 ASUS model 1114 * 1115 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e) 1116 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16, 1117 * Mic = 0x18, Line = 0x1a 1118 */ 1119 1120#define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */ 1121#define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */ 1122 1123static struct snd_kcontrol_new alc880_asus_mixer[] = { 1124 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 1125 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 1126 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 1127 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 1128 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 1129 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 1130 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 1131 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 1132 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 1133 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 1134 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 1135 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 1136 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 1137 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 1138 { 1139 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1140 .name = "Channel Mode", 1141 .info = alc_ch_mode_info, 1142 .get = alc_ch_mode_get, 1143 .put = alc_ch_mode_put, 1144 }, 1145 { } /* end */ 1146}; 1147 1148/* FIXME! */ 1149/* 1150 * ALC880 ASUS W1V model 1151 * 1152 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e) 1153 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16, 1154 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b 1155 */ 1156 1157/* additional mixers to alc880_asus_mixer */ 1158static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = { 1159 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT), 1160 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT), 1161 { } /* end */ 1162}; 1163 1164/* additional mixers to alc880_asus_mixer */ 1165static struct snd_kcontrol_new alc880_pcbeep_mixer[] = { 1166 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 1167 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 1168 { } /* end */ 1169}; 1170 1171/* TCL S700 */ 1172static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = { 1173 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 1174 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 1175 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 1176 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT), 1177 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT), 1178 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT), 1179 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT), 1180 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 1181 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 1182 { 1183 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1184 /* The multiple "Capture Source" controls confuse alsamixer 1185 * So call somewhat different.. 1186 * FIXME: the controls appear in the "playback" view! 1187 */ 1188 /* .name = "Capture Source", */ 1189 .name = "Input Source", 1190 .count = 1, 1191 .info = alc_mux_enum_info, 1192 .get = alc_mux_enum_get, 1193 .put = alc_mux_enum_put, 1194 }, 1195 { } /* end */ 1196}; 1197 1198/* Uniwill */ 1199static struct snd_kcontrol_new alc880_uniwill_mixer[] = { 1200 HDA_CODEC_VOLUME("HPhone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 1201 HDA_BIND_MUTE("HPhone Playback Switch", 0x0c, 2, HDA_INPUT), 1202 HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 1203 HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT), 1204 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 1205 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 1206 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 1207 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 1208 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 1209 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 1210 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 1211 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 1212 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 1213 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 1214 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 1215 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 1216 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 1217 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 1218 { 1219 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1220 .name = "Channel Mode", 1221 .info = alc_ch_mode_info, 1222 .get = alc_ch_mode_get, 1223 .put = alc_ch_mode_put, 1224 }, 1225 { } /* end */ 1226}; 1227 1228static struct snd_kcontrol_new alc880_fujitsu_mixer[] = { 1229 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 1230 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), 1231 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 1232 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 1233 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 1234 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 1235 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 1236 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 1237 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 1238 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 1239 { } /* end */ 1240}; 1241 1242static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = { 1243 HDA_CODEC_VOLUME("HPhone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 1244 HDA_BIND_MUTE("HPhone Playback Switch", 0x0c, 2, HDA_INPUT), 1245 HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 1246 HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT), 1247 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 1248 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 1249 { } /* end */ 1250}; 1251 1252/* 1253 * build control elements 1254 */ 1255static int alc_build_controls(struct hda_codec *codec) 1256{ 1257 struct alc_spec *spec = codec->spec; 1258 int err; 1259 int i; 1260 1261 for (i = 0; i < spec->num_mixers; i++) { 1262 err = snd_hda_add_new_ctls(codec, spec->mixers[i]); 1263 if (err < 0) 1264 return err; 1265 } 1266 1267 if (spec->multiout.dig_out_nid) { 1268 err = snd_hda_create_spdif_out_ctls(codec, 1269 spec->multiout.dig_out_nid); 1270 if (err < 0) 1271 return err; 1272 } 1273 if (spec->dig_in_nid) { 1274 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid); 1275 if (err < 0) 1276 return err; 1277 } 1278 return 0; 1279} 1280 1281 1282/* 1283 * initialize the codec volumes, etc 1284 */ 1285 1286/* 1287 * generic initialization of ADC, input mixers and output mixers 1288 */ 1289static struct hda_verb alc880_volume_init_verbs[] = { 1290 /* 1291 * Unmute ADC0-2 and set the default input to mic-in 1292 */ 1293 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 1294 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1295 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 1296 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1297 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 1298 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1299 1300 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 1301 * mixer widget 1302 * Note: PASD motherboards uses the Line In 2 as the input for front 1303 * panel mic (mic 2) 1304 */ 1305 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 1306 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 1307 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 1308 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 1309 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 1310 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 1311 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, 1312 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, 1313 1314 /* 1315 * Set up output mixers (0x0c - 0x0f) 1316 */ 1317 /* set vol=0 to output mixers */ 1318 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 1319 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 1320 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 1321 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 1322 /* set up input amps for analog loopback */ 1323 /* Amp Indices: DAC = 0, mixer = 1 */ 1324 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 1325 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 1326 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 1327 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 1328 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 1329 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 1330 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 1331 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 1332 1333 { } 1334}; 1335 1336/* 1337 * 3-stack pin configuration: 1338 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b 1339 */ 1340static struct hda_verb alc880_pin_3stack_init_verbs[] = { 1341 /* 1342 * preset connection lists of input pins 1343 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround 1344 */ 1345 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ 1346 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 1347 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */ 1348 1349 /* 1350 * Set pin mode and muting 1351 */ 1352 /* set front pin widgets 0x14 for output */ 1353 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1354 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1355 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 1356 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1357 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1358 /* Mic2 (as headphone out) for HP output */ 1359 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1360 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1361 /* Line In pin widget for input */ 1362 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1363 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1364 /* Line2 (as front mic) pin widget for input and vref at 80% */ 1365 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1366 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1367 /* CD pin widget for input */ 1368 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1369 1370 { } 1371}; 1372 1373/* 1374 * 5-stack pin configuration: 1375 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19, 1376 * line-in/side = 0x1a, f-mic = 0x1b 1377 */ 1378static struct hda_verb alc880_pin_5stack_init_verbs[] = { 1379 /* 1380 * preset connection lists of input pins 1381 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround 1382 */ 1383 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 1384 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */ 1385 1386 /* 1387 * Set pin mode and muting 1388 */ 1389 /* set pin widgets 0x14-0x17 for output */ 1390 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1391 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1392 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1393 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1394 /* unmute pins for output (no gain on this amp) */ 1395 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1396 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1397 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1398 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1399 1400 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 1401 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1402 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1403 /* Mic2 (as headphone out) for HP output */ 1404 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1405 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1406 /* Line In pin widget for input */ 1407 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1408 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1409 /* Line2 (as front mic) pin widget for input and vref at 80% */ 1410 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1411 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1412 /* CD pin widget for input */ 1413 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1414 1415 { } 1416}; 1417 1418/* 1419 * W810 pin configuration: 1420 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b 1421 */ 1422static struct hda_verb alc880_pin_w810_init_verbs[] = { 1423 /* hphone/speaker input selector: front DAC */ 1424 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0}, 1425 1426 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1427 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1428 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1429 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1430 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1431 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1432 1433 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1434 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1435 1436 { } 1437}; 1438 1439/* 1440 * Z71V pin configuration: 1441 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?) 1442 */ 1443static struct hda_verb alc880_pin_z71v_init_verbs[] = { 1444 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1445 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1446 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1447 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1448 1449 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1450 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1451 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1452 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1453 1454 { } 1455}; 1456 1457/* 1458 * 6-stack pin configuration: 1459 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18, 1460 * f-mic = 0x19, line = 0x1a, HP = 0x1b 1461 */ 1462static struct hda_verb alc880_pin_6stack_init_verbs[] = { 1463 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 1464 1465 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1466 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1467 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1468 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1469 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1470 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1471 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1472 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1473 1474 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1475 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1476 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1477 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1478 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1479 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1480 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1481 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1482 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1483 1484 { } 1485}; 1486 1487/* 1488 * Uniwill pin configuration: 1489 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19, 1490 * line = 0x1a 1491 */ 1492static struct hda_verb alc880_uniwill_init_verbs[] = { 1493 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 1494 1495 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1496 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1497 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1498 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1499 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1500 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1501 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1502 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1503 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 1504 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 1505 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 1506 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 1507 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 1508 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 1509 1510 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1511 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1512 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1513 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1514 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1515 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1516 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */ 1517 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */ 1518 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1519 1520 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 1521 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 1522 1523 { } 1524}; 1525 1526/* 1527* Uniwill P53 1528* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19, 1529 */ 1530static struct hda_verb alc880_uniwill_p53_init_verbs[] = { 1531 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 1532 1533 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1534 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1535 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1536 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1537 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1538 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1539 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 1540 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 1541 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 1542 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 1543 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 1544 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 1545 1546 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1547 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1548 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1549 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1550 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1551 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1552 1553 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 1554 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT}, 1555 1556 { } 1557}; 1558 1559static struct hda_verb alc880_beep_init_verbs[] = { 1560 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) }, 1561 { } 1562}; 1563 1564/* toggle speaker-output according to the hp-jack state */ 1565static void alc880_uniwill_hp_automute(struct hda_codec *codec) 1566{ 1567 unsigned int present; 1568 unsigned char bits; 1569 1570 present = snd_hda_codec_read(codec, 0x14, 0, 1571 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 1572 bits = present ? HDA_AMP_MUTE : 0; 1573 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 1574 HDA_AMP_MUTE, bits); 1575 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0, 1576 HDA_AMP_MUTE, bits); 1577} 1578 1579/* auto-toggle front mic */ 1580static void alc880_uniwill_mic_automute(struct hda_codec *codec) 1581{ 1582 unsigned int present; 1583 unsigned char bits; 1584 1585 present = snd_hda_codec_read(codec, 0x18, 0, 1586 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 1587 bits = present ? HDA_AMP_MUTE : 0; 1588 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits); 1589} 1590 1591static void alc880_uniwill_automute(struct hda_codec *codec) 1592{ 1593 alc880_uniwill_hp_automute(codec); 1594 alc880_uniwill_mic_automute(codec); 1595} 1596 1597static void alc880_uniwill_unsol_event(struct hda_codec *codec, 1598 unsigned int res) 1599{ 1600 /* Looks like the unsol event is incompatible with the standard 1601 * definition. 4bit tag is placed at 28 bit! 1602 */ 1603 switch (res >> 28) { 1604 case ALC880_HP_EVENT: 1605 alc880_uniwill_hp_automute(codec); 1606 break; 1607 case ALC880_MIC_EVENT: 1608 alc880_uniwill_mic_automute(codec); 1609 break; 1610 } 1611} 1612 1613static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec) 1614{ 1615 unsigned int present; 1616 unsigned char bits; 1617 1618 present = snd_hda_codec_read(codec, 0x14, 0, 1619 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 1620 bits = present ? HDA_AMP_MUTE : 0; 1621 snd_hda_codec_amp_stereo(codec, 0x15, HDA_INPUT, 0, HDA_AMP_MUTE, bits); 1622} 1623 1624static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec) 1625{ 1626 unsigned int present; 1627 1628 present = snd_hda_codec_read(codec, 0x21, 0, 1629 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0); 1630 present &= HDA_AMP_VOLMASK; 1631 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0, 1632 HDA_AMP_VOLMASK, present); 1633 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0, 1634 HDA_AMP_VOLMASK, present); 1635} 1636 1637static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec, 1638 unsigned int res) 1639{ 1640 /* Looks like the unsol event is incompatible with the standard 1641 * definition. 4bit tag is placed at 28 bit! 1642 */ 1643 if ((res >> 28) == ALC880_HP_EVENT) 1644 alc880_uniwill_p53_hp_automute(codec); 1645 if ((res >> 28) == ALC880_DCVOL_EVENT) 1646 alc880_uniwill_p53_dcvol_automute(codec); 1647} 1648 1649/* FIXME! */ 1650/* 1651 * F1734 pin configuration: 1652 * HP = 0x14, speaker-out = 0x15, mic = 0x18 1653 */ 1654static struct hda_verb alc880_pin_f1734_init_verbs[] = { 1655 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, 1656 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, 1657 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, 1658 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, 1659 1660 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1661 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1662 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1663 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1664 1665 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1666 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1667 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1668 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1669 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1670 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1671 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1672 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1673 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1674 1675 { } 1676}; 1677 1678/* FIXME! */ 1679/* 1680 * ASUS pin configuration: 1681 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a 1682 */ 1683static struct hda_verb alc880_pin_asus_init_verbs[] = { 1684 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, 1685 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, 1686 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, 1687 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, 1688 1689 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1690 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1691 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1692 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1693 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1694 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1695 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1696 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1697 1698 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1699 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1700 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1701 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1702 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1703 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1704 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1705 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1706 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1707 1708 { } 1709}; 1710 1711/* Enable GPIO mask and set output */ 1712#define alc880_gpio1_init_verbs alc_gpio1_init_verbs 1713#define alc880_gpio2_init_verbs alc_gpio2_init_verbs 1714 1715/* Clevo m520g init */ 1716static struct hda_verb alc880_pin_clevo_init_verbs[] = { 1717 /* headphone output */ 1718 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01}, 1719 /* line-out */ 1720 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1721 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1722 /* Line-in */ 1723 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1724 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1725 /* CD */ 1726 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1727 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1728 /* Mic1 (rear panel) */ 1729 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1730 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1731 /* Mic2 (front panel) */ 1732 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1733 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1734 /* headphone */ 1735 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1736 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1737 /* change to EAPD mode */ 1738 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 1739 {0x20, AC_VERB_SET_PROC_COEF, 0x3060}, 1740 1741 { } 1742}; 1743 1744static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = { 1745 /* change to EAPD mode */ 1746 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 1747 {0x20, AC_VERB_SET_PROC_COEF, 0x3060}, 1748 1749 /* Headphone output */ 1750 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1751 /* Front output*/ 1752 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1753 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 1754 1755 /* Line In pin widget for input */ 1756 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1757 /* CD pin widget for input */ 1758 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1759 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 1760 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1761 1762 /* change to EAPD mode */ 1763 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 1764 {0x20, AC_VERB_SET_PROC_COEF, 0x3070}, 1765 1766 { } 1767}; 1768 1769/* 1770 * LG m1 express dual 1771 * 1772 * Pin assignment: 1773 * Rear Line-In/Out (blue): 0x14 1774 * Build-in Mic-In: 0x15 1775 * Speaker-out: 0x17 1776 * HP-Out (green): 0x1b 1777 * Mic-In/Out (red): 0x19 1778 * SPDIF-Out: 0x1e 1779 */ 1780 1781/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */ 1782static hda_nid_t alc880_lg_dac_nids[3] = { 1783 0x05, 0x02, 0x03 1784}; 1785 1786/* seems analog CD is not working */ 1787static struct hda_input_mux alc880_lg_capture_source = { 1788 .num_items = 3, 1789 .items = { 1790 { "Mic", 0x1 }, 1791 { "Line", 0x5 }, 1792 { "Internal Mic", 0x6 }, 1793 }, 1794}; 1795 1796/* 2,4,6 channel modes */ 1797static struct hda_verb alc880_lg_ch2_init[] = { 1798 /* set line-in and mic-in to input */ 1799 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 1800 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 1801 { } 1802}; 1803 1804static struct hda_verb alc880_lg_ch4_init[] = { 1805 /* set line-in to out and mic-in to input */ 1806 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, 1807 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 1808 { } 1809}; 1810 1811static struct hda_verb alc880_lg_ch6_init[] = { 1812 /* set line-in and mic-in to output */ 1813 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, 1814 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, 1815 { } 1816}; 1817 1818static struct hda_channel_mode alc880_lg_ch_modes[3] = { 1819 { 2, alc880_lg_ch2_init }, 1820 { 4, alc880_lg_ch4_init }, 1821 { 6, alc880_lg_ch6_init }, 1822}; 1823 1824static struct snd_kcontrol_new alc880_lg_mixer[] = { 1825 /* FIXME: it's not really "master" but front channels */ 1826 HDA_CODEC_VOLUME("Master Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 1827 HDA_BIND_MUTE("Master Playback Switch", 0x0f, 2, HDA_INPUT), 1828 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 1829 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT), 1830 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT), 1831 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT), 1832 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT), 1833 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT), 1834 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 1835 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 1836 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT), 1837 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT), 1838 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT), 1839 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT), 1840 { 1841 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1842 .name = "Channel Mode", 1843 .info = alc_ch_mode_info, 1844 .get = alc_ch_mode_get, 1845 .put = alc_ch_mode_put, 1846 }, 1847 { } /* end */ 1848}; 1849 1850static struct hda_verb alc880_lg_init_verbs[] = { 1851 /* set capture source to mic-in */ 1852 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 1853 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 1854 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 1855 /* mute all amp mixer inputs */ 1856 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)}, 1857 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, 1858 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, 1859 /* line-in to input */ 1860 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1861 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1862 /* built-in mic */ 1863 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1864 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1865 /* speaker-out */ 1866 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1867 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1868 /* mic-in to input */ 1869 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01}, 1870 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1871 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1872 /* HP-out */ 1873 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03}, 1874 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1875 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1876 /* jack sense */ 1877 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1}, 1878 { } 1879}; 1880 1881/* toggle speaker-output according to the hp-jack state */ 1882static void alc880_lg_automute(struct hda_codec *codec) 1883{ 1884 unsigned int present; 1885 unsigned char bits; 1886 1887 present = snd_hda_codec_read(codec, 0x1b, 0, 1888 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 1889 bits = present ? HDA_AMP_MUTE : 0; 1890 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0, 1891 HDA_AMP_MUTE, bits); 1892} 1893 1894static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res) 1895{ 1896 /* Looks like the unsol event is incompatible with the standard 1897 * definition. 4bit tag is placed at 28 bit! 1898 */ 1899 if ((res >> 28) == 0x01) 1900 alc880_lg_automute(codec); 1901} 1902 1903/* 1904 * LG LW20 1905 * 1906 * Pin assignment: 1907 * Speaker-out: 0x14 1908 * Mic-In: 0x18 1909 * Built-in Mic-In: 0x19 1910 * Line-In: 0x1b 1911 * HP-Out: 0x1a 1912 * SPDIF-Out: 0x1e 1913 */ 1914 1915static struct hda_input_mux alc880_lg_lw_capture_source = { 1916 .num_items = 3, 1917 .items = { 1918 { "Mic", 0x0 }, 1919 { "Internal Mic", 0x1 }, 1920 { "Line In", 0x2 }, 1921 }, 1922}; 1923 1924#define alc880_lg_lw_modes alc880_threestack_modes 1925 1926static struct snd_kcontrol_new alc880_lg_lw_mixer[] = { 1927 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 1928 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 1929 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 1930 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT), 1931 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 1932 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 1933 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 1934 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 1935 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 1936 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 1937 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 1938 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 1939 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 1940 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 1941 { 1942 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1943 .name = "Channel Mode", 1944 .info = alc_ch_mode_info, 1945 .get = alc_ch_mode_get, 1946 .put = alc_ch_mode_put, 1947 }, 1948 { } /* end */ 1949}; 1950 1951static struct hda_verb alc880_lg_lw_init_verbs[] = { 1952 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 1953 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ 1954 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */ 1955 1956 /* set capture source to mic-in */ 1957 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1958 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1959 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1960 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, 1961 /* speaker-out */ 1962 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1963 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1964 /* HP-out */ 1965 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1966 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1967 /* mic-in to input */ 1968 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1969 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1970 /* built-in mic */ 1971 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1972 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1973 /* jack sense */ 1974 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1}, 1975 { } 1976}; 1977 1978/* toggle speaker-output according to the hp-jack state */ 1979static void alc880_lg_lw_automute(struct hda_codec *codec) 1980{ 1981 unsigned int present; 1982 unsigned char bits; 1983 1984 present = snd_hda_codec_read(codec, 0x1b, 0, 1985 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 1986 bits = present ? HDA_AMP_MUTE : 0; 1987 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 1988 HDA_AMP_MUTE, bits); 1989} 1990 1991static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res) 1992{ 1993 /* Looks like the unsol event is incompatible with the standard 1994 * definition. 4bit tag is placed at 28 bit! 1995 */ 1996 if ((res >> 28) == 0x01) 1997 alc880_lg_lw_automute(codec); 1998} 1999 2000#ifdef CONFIG_SND_HDA_POWER_SAVE 2001static struct hda_amp_list alc880_loopbacks[] = { 2002 { 0x0b, HDA_INPUT, 0 }, 2003 { 0x0b, HDA_INPUT, 1 }, 2004 { 0x0b, HDA_INPUT, 2 }, 2005 { 0x0b, HDA_INPUT, 3 }, 2006 { 0x0b, HDA_INPUT, 4 }, 2007 { } /* end */ 2008}; 2009 2010static struct hda_amp_list alc880_lg_loopbacks[] = { 2011 { 0x0b, HDA_INPUT, 1 }, 2012 { 0x0b, HDA_INPUT, 6 }, 2013 { 0x0b, HDA_INPUT, 7 }, 2014 { } /* end */ 2015}; 2016#endif 2017 2018/* 2019 * Common callbacks 2020 */ 2021 2022static int alc_init(struct hda_codec *codec) 2023{ 2024 struct alc_spec *spec = codec->spec; 2025 unsigned int i; 2026 2027 for (i = 0; i < spec->num_init_verbs; i++) 2028 snd_hda_sequence_write(codec, spec->init_verbs[i]); 2029 2030 if (spec->init_hook) 2031 spec->init_hook(codec); 2032 2033 return 0; 2034} 2035 2036static void alc_unsol_event(struct hda_codec *codec, unsigned int res) 2037{ 2038 struct alc_spec *spec = codec->spec; 2039 2040 if (spec->unsol_event) 2041 spec->unsol_event(codec, res); 2042} 2043 2044#ifdef CONFIG_SND_HDA_POWER_SAVE 2045static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid) 2046{ 2047 struct alc_spec *spec = codec->spec; 2048 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid); 2049} 2050#endif 2051 2052/* 2053 * Analog playback callbacks 2054 */ 2055static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo, 2056 struct hda_codec *codec, 2057 struct snd_pcm_substream *substream) 2058{ 2059 struct alc_spec *spec = codec->spec; 2060 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream); 2061} 2062 2063static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo, 2064 struct hda_codec *codec, 2065 unsigned int stream_tag, 2066 unsigned int format, 2067 struct snd_pcm_substream *substream) 2068{ 2069 struct alc_spec *spec = codec->spec; 2070 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, 2071 stream_tag, format, substream); 2072} 2073 2074static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, 2075 struct hda_codec *codec, 2076 struct snd_pcm_substream *substream) 2077{ 2078 struct alc_spec *spec = codec->spec; 2079 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); 2080} 2081 2082/* 2083 * Digital out 2084 */ 2085static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo, 2086 struct hda_codec *codec, 2087 struct snd_pcm_substream *substream) 2088{ 2089 struct alc_spec *spec = codec->spec; 2090 return snd_hda_multi_out_dig_open(codec, &spec->multiout); 2091} 2092 2093static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, 2094 struct hda_codec *codec, 2095 unsigned int stream_tag, 2096 unsigned int format, 2097 struct snd_pcm_substream *substream) 2098{ 2099 struct alc_spec *spec = codec->spec; 2100 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, 2101 stream_tag, format, substream); 2102} 2103 2104static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, 2105 struct hda_codec *codec, 2106 struct snd_pcm_substream *substream) 2107{ 2108 struct alc_spec *spec = codec->spec; 2109 return snd_hda_multi_out_dig_close(codec, &spec->multiout); 2110} 2111 2112/* 2113 * Analog capture 2114 */ 2115static int alc880_capture_pcm_prepare(struct hda_pcm_stream *hinfo, 2116 struct hda_codec *codec, 2117 unsigned int stream_tag, 2118 unsigned int format, 2119 struct snd_pcm_substream *substream) 2120{ 2121 struct alc_spec *spec = codec->spec; 2122 2123 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number], 2124 stream_tag, 0, format); 2125 return 0; 2126} 2127 2128static int alc880_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, 2129 struct hda_codec *codec, 2130 struct snd_pcm_substream *substream) 2131{ 2132 struct alc_spec *spec = codec->spec; 2133 2134 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number], 2135 0, 0, 0); 2136 return 0; 2137} 2138 2139 2140/* 2141 */ 2142static struct hda_pcm_stream alc880_pcm_analog_playback = { 2143 .substreams = 1, 2144 .channels_min = 2, 2145 .channels_max = 8, 2146 /* NID is set in alc_build_pcms */ 2147 .ops = { 2148 .open = alc880_playback_pcm_open, 2149 .prepare = alc880_playback_pcm_prepare, 2150 .cleanup = alc880_playback_pcm_cleanup 2151 }, 2152}; 2153 2154static struct hda_pcm_stream alc880_pcm_analog_capture = { 2155 .substreams = 2, 2156 .channels_min = 2, 2157 .channels_max = 2, 2158 /* NID is set in alc_build_pcms */ 2159 .ops = { 2160 .prepare = alc880_capture_pcm_prepare, 2161 .cleanup = alc880_capture_pcm_cleanup 2162 }, 2163}; 2164 2165static struct hda_pcm_stream alc880_pcm_digital_playback = { 2166 .substreams = 1, 2167 .channels_min = 2, 2168 .channels_max = 2, 2169 /* NID is set in alc_build_pcms */ 2170 .ops = { 2171 .open = alc880_dig_playback_pcm_open, 2172 .close = alc880_dig_playback_pcm_close, 2173 .prepare = alc880_dig_playback_pcm_prepare 2174 }, 2175}; 2176 2177static struct hda_pcm_stream alc880_pcm_digital_capture = { 2178 .substreams = 1, 2179 .channels_min = 2, 2180 .channels_max = 2, 2181 /* NID is set in alc_build_pcms */ 2182}; 2183 2184/* Used by alc_build_pcms to flag that a PCM has no playback stream */ 2185static struct hda_pcm_stream alc_pcm_null_playback = { 2186 .substreams = 0, 2187 .channels_min = 0, 2188 .channels_max = 0, 2189}; 2190 2191static int alc_build_pcms(struct hda_codec *codec) 2192{ 2193 struct alc_spec *spec = codec->spec; 2194 struct hda_pcm *info = spec->pcm_rec; 2195 int i; 2196 2197 codec->num_pcms = 1; 2198 codec->pcm_info = info; 2199 2200 info->name = spec->stream_name_analog; 2201 if (spec->stream_analog_playback) { 2202 snd_assert(spec->multiout.dac_nids, return -EINVAL); 2203 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback); 2204 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0]; 2205 } 2206 if (spec->stream_analog_capture) { 2207 snd_assert(spec->adc_nids, return -EINVAL); 2208 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture); 2209 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0]; 2210 } 2211 2212 if (spec->channel_mode) { 2213 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0; 2214 for (i = 0; i < spec->num_channel_mode; i++) { 2215 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) { 2216 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels; 2217 } 2218 } 2219 } 2220 2221 /* SPDIF for stream index #1 */ 2222 if (spec->multiout.dig_out_nid || spec->dig_in_nid) { 2223 codec->num_pcms = 2; 2224 info = spec->pcm_rec + 1; 2225 info->name = spec->stream_name_digital; 2226 if (spec->multiout.dig_out_nid && 2227 spec->stream_digital_playback) { 2228 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback); 2229 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid; 2230 } 2231 if (spec->dig_in_nid && 2232 spec->stream_digital_capture) { 2233 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture); 2234 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid; 2235 } 2236 } 2237 2238 /* If the use of more than one ADC is requested for the current 2239 * model, configure a second analog capture-only PCM. 2240 */ 2241 /* Additional Analaog capture for index #2 */ 2242 if (spec->num_adc_nids > 1 && spec->stream_analog_capture && 2243 spec->adc_nids) { 2244 codec->num_pcms = 3; 2245 info = spec->pcm_rec + 2; 2246 info->name = spec->stream_name_analog; 2247 /* No playback stream for second PCM */ 2248 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = alc_pcm_null_playback; 2249 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0; 2250 if (spec->stream_analog_capture) { 2251 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture); 2252 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[1]; 2253 } 2254 } 2255 2256 return 0; 2257} 2258 2259static void alc_free(struct hda_codec *codec) 2260{ 2261 struct alc_spec *spec = codec->spec; 2262 unsigned int i; 2263 2264 if (!spec) 2265 return; 2266 2267 if (spec->kctl_alloc) { 2268 for (i = 0; i < spec->num_kctl_used; i++) 2269 kfree(spec->kctl_alloc[i].name); 2270 kfree(spec->kctl_alloc); 2271 } 2272 kfree(spec); 2273} 2274 2275/* 2276 */ 2277static struct hda_codec_ops alc_patch_ops = { 2278 .build_controls = alc_build_controls, 2279 .build_pcms = alc_build_pcms, 2280 .init = alc_init, 2281 .free = alc_free, 2282 .unsol_event = alc_unsol_event, 2283#ifdef CONFIG_SND_HDA_POWER_SAVE 2284 .check_power_status = alc_check_power_status, 2285#endif 2286}; 2287 2288 2289/* 2290 * Test configuration for debugging 2291 * 2292 * Almost all inputs/outputs are enabled. I/O pins can be configured via 2293 * enum controls. 2294 */ 2295#ifdef CONFIG_SND_DEBUG 2296static hda_nid_t alc880_test_dac_nids[4] = { 2297 0x02, 0x03, 0x04, 0x05 2298}; 2299 2300static struct hda_input_mux alc880_test_capture_source = { 2301 .num_items = 7, 2302 .items = { 2303 { "In-1", 0x0 }, 2304 { "In-2", 0x1 }, 2305 { "In-3", 0x2 }, 2306 { "In-4", 0x3 }, 2307 { "CD", 0x4 }, 2308 { "Front", 0x5 }, 2309 { "Surround", 0x6 }, 2310 }, 2311}; 2312 2313static struct hda_channel_mode alc880_test_modes[4] = { 2314 { 2, NULL }, 2315 { 4, NULL }, 2316 { 6, NULL }, 2317 { 8, NULL }, 2318}; 2319 2320static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol, 2321 struct snd_ctl_elem_info *uinfo) 2322{ 2323 static char *texts[] = { 2324 "N/A", "Line Out", "HP Out", 2325 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%" 2326 }; 2327 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 2328 uinfo->count = 1; 2329 uinfo->value.enumerated.items = 8; 2330 if (uinfo->value.enumerated.item >= 8) 2331 uinfo->value.enumerated.item = 7; 2332 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); 2333 return 0; 2334} 2335 2336static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol, 2337 struct snd_ctl_elem_value *ucontrol) 2338{ 2339 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2340 hda_nid_t nid = (hda_nid_t)kcontrol->private_value; 2341 unsigned int pin_ctl, item = 0; 2342 2343 pin_ctl = snd_hda_codec_read(codec, nid, 0, 2344 AC_VERB_GET_PIN_WIDGET_CONTROL, 0); 2345 if (pin_ctl & AC_PINCTL_OUT_EN) { 2346 if (pin_ctl & AC_PINCTL_HP_EN) 2347 item = 2; 2348 else 2349 item = 1; 2350 } else if (pin_ctl & AC_PINCTL_IN_EN) { 2351 switch (pin_ctl & AC_PINCTL_VREFEN) { 2352 case AC_PINCTL_VREF_HIZ: item = 3; break; 2353 case AC_PINCTL_VREF_50: item = 4; break; 2354 case AC_PINCTL_VREF_GRD: item = 5; break; 2355 case AC_PINCTL_VREF_80: item = 6; break; 2356 case AC_PINCTL_VREF_100: item = 7; break; 2357 } 2358 } 2359 ucontrol->value.enumerated.item[0] = item; 2360 return 0; 2361} 2362 2363static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol, 2364 struct snd_ctl_elem_value *ucontrol) 2365{ 2366 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2367 hda_nid_t nid = (hda_nid_t)kcontrol->private_value; 2368 static unsigned int ctls[] = { 2369 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN, 2370 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ, 2371 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50, 2372 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD, 2373 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80, 2374 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100, 2375 }; 2376 unsigned int old_ctl, new_ctl; 2377 2378 old_ctl = snd_hda_codec_read(codec, nid, 0, 2379 AC_VERB_GET_PIN_WIDGET_CONTROL, 0); 2380 new_ctl = ctls[ucontrol->value.enumerated.item[0]]; 2381 if (old_ctl != new_ctl) { 2382 int val; 2383 snd_hda_codec_write_cache(codec, nid, 0, 2384 AC_VERB_SET_PIN_WIDGET_CONTROL, 2385 new_ctl); 2386 val = ucontrol->value.enumerated.item[0] >= 3 ? 2387 HDA_AMP_MUTE : 0; 2388 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, 2389 HDA_AMP_MUTE, val); 2390 return 1; 2391 } 2392 return 0; 2393} 2394 2395static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol, 2396 struct snd_ctl_elem_info *uinfo) 2397{ 2398 static char *texts[] = { 2399 "Front", "Surround", "CLFE", "Side" 2400 }; 2401 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 2402 uinfo->count = 1; 2403 uinfo->value.enumerated.items = 4; 2404 if (uinfo->value.enumerated.item >= 4) 2405 uinfo->value.enumerated.item = 3; 2406 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); 2407 return 0; 2408} 2409 2410static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol, 2411 struct snd_ctl_elem_value *ucontrol) 2412{ 2413 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2414 hda_nid_t nid = (hda_nid_t)kcontrol->private_value; 2415 unsigned int sel; 2416 2417 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0); 2418 ucontrol->value.enumerated.item[0] = sel & 3; 2419 return 0; 2420} 2421 2422static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol, 2423 struct snd_ctl_elem_value *ucontrol) 2424{ 2425 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2426 hda_nid_t nid = (hda_nid_t)kcontrol->private_value; 2427 unsigned int sel; 2428 2429 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3; 2430 if (ucontrol->value.enumerated.item[0] != sel) { 2431 sel = ucontrol->value.enumerated.item[0] & 3; 2432 snd_hda_codec_write_cache(codec, nid, 0, 2433 AC_VERB_SET_CONNECT_SEL, sel); 2434 return 1; 2435 } 2436 return 0; 2437} 2438 2439#define PIN_CTL_TEST(xname,nid) { \ 2440 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 2441 .name = xname, \ 2442 .info = alc_test_pin_ctl_info, \ 2443 .get = alc_test_pin_ctl_get, \ 2444 .put = alc_test_pin_ctl_put, \ 2445 .private_value = nid \ 2446 } 2447 2448#define PIN_SRC_TEST(xname,nid) { \ 2449 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 2450 .name = xname, \ 2451 .info = alc_test_pin_src_info, \ 2452 .get = alc_test_pin_src_get, \ 2453 .put = alc_test_pin_src_put, \ 2454 .private_value = nid \ 2455 } 2456 2457static struct snd_kcontrol_new alc880_test_mixer[] = { 2458 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2459 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2460 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT), 2461 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 2462 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 2463 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 2464 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT), 2465 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 2466 PIN_CTL_TEST("Front Pin Mode", 0x14), 2467 PIN_CTL_TEST("Surround Pin Mode", 0x15), 2468 PIN_CTL_TEST("CLFE Pin Mode", 0x16), 2469 PIN_CTL_TEST("Side Pin Mode", 0x17), 2470 PIN_CTL_TEST("In-1 Pin Mode", 0x18), 2471 PIN_CTL_TEST("In-2 Pin Mode", 0x19), 2472 PIN_CTL_TEST("In-3 Pin Mode", 0x1a), 2473 PIN_CTL_TEST("In-4 Pin Mode", 0x1b), 2474 PIN_SRC_TEST("In-1 Pin Source", 0x18), 2475 PIN_SRC_TEST("In-2 Pin Source", 0x19), 2476 PIN_SRC_TEST("In-3 Pin Source", 0x1a), 2477 PIN_SRC_TEST("In-4 Pin Source", 0x1b), 2478 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT), 2479 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT), 2480 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT), 2481 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT), 2482 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT), 2483 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT), 2484 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT), 2485 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT), 2486 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT), 2487 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT), 2488 { 2489 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2490 .name = "Channel Mode", 2491 .info = alc_ch_mode_info, 2492 .get = alc_ch_mode_get, 2493 .put = alc_ch_mode_put, 2494 }, 2495 { } /* end */ 2496}; 2497 2498static struct hda_verb alc880_test_init_verbs[] = { 2499 /* Unmute inputs of 0x0c - 0x0f */ 2500 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 2501 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 2502 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 2503 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 2504 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 2505 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 2506 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 2507 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 2508 /* Vol output for 0x0c-0x0f */ 2509 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 2510 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 2511 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 2512 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 2513 /* Set output pins 0x14-0x17 */ 2514 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2515 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2516 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2517 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2518 /* Unmute output pins 0x14-0x17 */ 2519 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2520 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2521 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2522 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2523 /* Set input pins 0x18-0x1c */ 2524 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2525 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2526 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2527 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2528 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2529 /* Mute input pins 0x18-0x1b */ 2530 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2531 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2532 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2533 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2534 /* ADC set up */ 2535 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 2536 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 2537 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 2538 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 2539 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 2540 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 2541 /* Analog input/passthru */ 2542 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 2543 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 2544 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 2545 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 2546 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 2547 { } 2548}; 2549#endif 2550 2551/* 2552 */ 2553 2554static const char *alc880_models[ALC880_MODEL_LAST] = { 2555 [ALC880_3ST] = "3stack", 2556 [ALC880_TCL_S700] = "tcl", 2557 [ALC880_3ST_DIG] = "3stack-digout", 2558 [ALC880_CLEVO] = "clevo", 2559 [ALC880_5ST] = "5stack", 2560 [ALC880_5ST_DIG] = "5stack-digout", 2561 [ALC880_W810] = "w810", 2562 [ALC880_Z71V] = "z71v", 2563 [ALC880_6ST] = "6stack", 2564 [ALC880_6ST_DIG] = "6stack-digout", 2565 [ALC880_ASUS] = "asus", 2566 [ALC880_ASUS_W1V] = "asus-w1v", 2567 [ALC880_ASUS_DIG] = "asus-dig", 2568 [ALC880_ASUS_DIG2] = "asus-dig2", 2569 [ALC880_UNIWILL_DIG] = "uniwill", 2570 [ALC880_UNIWILL_P53] = "uniwill-p53", 2571 [ALC880_FUJITSU] = "fujitsu", 2572 [ALC880_F1734] = "F1734", 2573 [ALC880_LG] = "lg", 2574 [ALC880_LG_LW] = "lg-lw", 2575#ifdef CONFIG_SND_DEBUG 2576 [ALC880_TEST] = "test", 2577#endif 2578 [ALC880_AUTO] = "auto", 2579}; 2580 2581static struct snd_pci_quirk alc880_cfg_tbl[] = { 2582 /* Broken BIOS configuration */ 2583 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), 2584 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG), 2585 2586 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG), 2587 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST), 2588 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810), 2589 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG), 2590 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG), 2591 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG), 2592 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG), 2593 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG), 2594 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST), 2595 2596 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG), 2597 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST), 2598 2599 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V), 2600 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG), 2601 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG), 2602 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG), 2603 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG), 2604 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG), 2605 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V), 2606 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */ 2607 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG), 2608 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG), 2609 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS", ALC880_ASUS), 2610 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG), 2611 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST), 2612 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST), 2613 SND_PCI_QUIRK(0x1043, 0, "ASUS", ALC880_ASUS), 2614 2615 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST), 2616 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST), 2617 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST), 2618 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST), 2619 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST), 2620 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO), 2621 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO), 2622 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG), 2623 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810), 2624 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG), 2625 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700), 2626 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG), 2627 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG), 2628 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG), 2629 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG), 2630 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG), 2631 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG), 2632 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2), 2633 2634 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG), 2635 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL), 2636 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53), 2637 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734), 2638 2639 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG), 2640 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL), 2641 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734), 2642 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU), 2643 2644 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG), 2645 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG), 2646 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW), 2647 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW), 2648 2649 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG), 2650 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG), 2651 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG), 2652 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG), 2653 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG), 2654 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG), 2655 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG), 2656 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG), 2657 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG), 2658 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG), 2659 SND_PCI_QUIRK(0x8086, 0, "Intel mobo", ALC880_3ST), 2660 2661 {} 2662}; 2663 2664/* 2665 * ALC880 codec presets 2666 */ 2667static struct alc_config_preset alc880_presets[] = { 2668 [ALC880_3ST] = { 2669 .mixers = { alc880_three_stack_mixer }, 2670 .init_verbs = { alc880_volume_init_verbs, 2671 alc880_pin_3stack_init_verbs }, 2672 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 2673 .dac_nids = alc880_dac_nids, 2674 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), 2675 .channel_mode = alc880_threestack_modes, 2676 .need_dac_fix = 1, 2677 .input_mux = &alc880_capture_source, 2678 }, 2679 [ALC880_3ST_DIG] = { 2680 .mixers = { alc880_three_stack_mixer }, 2681 .init_verbs = { alc880_volume_init_verbs, 2682 alc880_pin_3stack_init_verbs }, 2683 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 2684 .dac_nids = alc880_dac_nids, 2685 .dig_out_nid = ALC880_DIGOUT_NID, 2686 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), 2687 .channel_mode = alc880_threestack_modes, 2688 .need_dac_fix = 1, 2689 .input_mux = &alc880_capture_source, 2690 }, 2691 [ALC880_TCL_S700] = { 2692 .mixers = { alc880_tcl_s700_mixer }, 2693 .init_verbs = { alc880_volume_init_verbs, 2694 alc880_pin_tcl_S700_init_verbs, 2695 alc880_gpio2_init_verbs }, 2696 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 2697 .dac_nids = alc880_dac_nids, 2698 .hp_nid = 0x03, 2699 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), 2700 .channel_mode = alc880_2_jack_modes, 2701 .input_mux = &alc880_capture_source, 2702 }, 2703 [ALC880_5ST] = { 2704 .mixers = { alc880_three_stack_mixer, 2705 alc880_five_stack_mixer}, 2706 .init_verbs = { alc880_volume_init_verbs, 2707 alc880_pin_5stack_init_verbs }, 2708 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 2709 .dac_nids = alc880_dac_nids, 2710 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes), 2711 .channel_mode = alc880_fivestack_modes, 2712 .input_mux = &alc880_capture_source, 2713 }, 2714 [ALC880_5ST_DIG] = { 2715 .mixers = { alc880_three_stack_mixer, 2716 alc880_five_stack_mixer }, 2717 .init_verbs = { alc880_volume_init_verbs, 2718 alc880_pin_5stack_init_verbs }, 2719 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 2720 .dac_nids = alc880_dac_nids, 2721 .dig_out_nid = ALC880_DIGOUT_NID, 2722 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes), 2723 .channel_mode = alc880_fivestack_modes, 2724 .input_mux = &alc880_capture_source, 2725 }, 2726 [ALC880_6ST] = { 2727 .mixers = { alc880_six_stack_mixer }, 2728 .init_verbs = { alc880_volume_init_verbs, 2729 alc880_pin_6stack_init_verbs }, 2730 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids), 2731 .dac_nids = alc880_6st_dac_nids, 2732 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes), 2733 .channel_mode = alc880_sixstack_modes, 2734 .input_mux = &alc880_6stack_capture_source, 2735 }, 2736 [ALC880_6ST_DIG] = { 2737 .mixers = { alc880_six_stack_mixer }, 2738 .init_verbs = { alc880_volume_init_verbs, 2739 alc880_pin_6stack_init_verbs }, 2740 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids), 2741 .dac_nids = alc880_6st_dac_nids, 2742 .dig_out_nid = ALC880_DIGOUT_NID, 2743 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes), 2744 .channel_mode = alc880_sixstack_modes, 2745 .input_mux = &alc880_6stack_capture_source, 2746 }, 2747 [ALC880_W810] = { 2748 .mixers = { alc880_w810_base_mixer }, 2749 .init_verbs = { alc880_volume_init_verbs, 2750 alc880_pin_w810_init_verbs, 2751 alc880_gpio2_init_verbs }, 2752 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids), 2753 .dac_nids = alc880_w810_dac_nids, 2754 .dig_out_nid = ALC880_DIGOUT_NID, 2755 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes), 2756 .channel_mode = alc880_w810_modes, 2757 .input_mux = &alc880_capture_source, 2758 }, 2759 [ALC880_Z71V] = { 2760 .mixers = { alc880_z71v_mixer }, 2761 .init_verbs = { alc880_volume_init_verbs, 2762 alc880_pin_z71v_init_verbs }, 2763 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids), 2764 .dac_nids = alc880_z71v_dac_nids, 2765 .dig_out_nid = ALC880_DIGOUT_NID, 2766 .hp_nid = 0x03, 2767 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), 2768 .channel_mode = alc880_2_jack_modes, 2769 .input_mux = &alc880_capture_source, 2770 }, 2771 [ALC880_F1734] = { 2772 .mixers = { alc880_f1734_mixer }, 2773 .init_verbs = { alc880_volume_init_verbs, 2774 alc880_pin_f1734_init_verbs }, 2775 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids), 2776 .dac_nids = alc880_f1734_dac_nids, 2777 .hp_nid = 0x02, 2778 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), 2779 .channel_mode = alc880_2_jack_modes, 2780 .input_mux = &alc880_capture_source, 2781 }, 2782 [ALC880_ASUS] = { 2783 .mixers = { alc880_asus_mixer }, 2784 .init_verbs = { alc880_volume_init_verbs, 2785 alc880_pin_asus_init_verbs, 2786 alc880_gpio1_init_verbs }, 2787 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 2788 .dac_nids = alc880_asus_dac_nids, 2789 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), 2790 .channel_mode = alc880_asus_modes, 2791 .need_dac_fix = 1, 2792 .input_mux = &alc880_capture_source, 2793 }, 2794 [ALC880_ASUS_DIG] = { 2795 .mixers = { alc880_asus_mixer }, 2796 .init_verbs = { alc880_volume_init_verbs, 2797 alc880_pin_asus_init_verbs, 2798 alc880_gpio1_init_verbs }, 2799 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 2800 .dac_nids = alc880_asus_dac_nids, 2801 .dig_out_nid = ALC880_DIGOUT_NID, 2802 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), 2803 .channel_mode = alc880_asus_modes, 2804 .need_dac_fix = 1, 2805 .input_mux = &alc880_capture_source, 2806 }, 2807 [ALC880_ASUS_DIG2] = { 2808 .mixers = { alc880_asus_mixer }, 2809 .init_verbs = { alc880_volume_init_verbs, 2810 alc880_pin_asus_init_verbs, 2811 alc880_gpio2_init_verbs }, /* use GPIO2 */ 2812 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 2813 .dac_nids = alc880_asus_dac_nids, 2814 .dig_out_nid = ALC880_DIGOUT_NID, 2815 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), 2816 .channel_mode = alc880_asus_modes, 2817 .need_dac_fix = 1, 2818 .input_mux = &alc880_capture_source, 2819 }, 2820 [ALC880_ASUS_W1V] = { 2821 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer }, 2822 .init_verbs = { alc880_volume_init_verbs, 2823 alc880_pin_asus_init_verbs, 2824 alc880_gpio1_init_verbs }, 2825 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 2826 .dac_nids = alc880_asus_dac_nids, 2827 .dig_out_nid = ALC880_DIGOUT_NID, 2828 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), 2829 .channel_mode = alc880_asus_modes, 2830 .need_dac_fix = 1, 2831 .input_mux = &alc880_capture_source, 2832 }, 2833 [ALC880_UNIWILL_DIG] = { 2834 .mixers = { alc880_asus_mixer, alc880_pcbeep_mixer }, 2835 .init_verbs = { alc880_volume_init_verbs, 2836 alc880_pin_asus_init_verbs }, 2837 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 2838 .dac_nids = alc880_asus_dac_nids, 2839 .dig_out_nid = ALC880_DIGOUT_NID, 2840 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), 2841 .channel_mode = alc880_asus_modes, 2842 .need_dac_fix = 1, 2843 .input_mux = &alc880_capture_source, 2844 }, 2845 [ALC880_UNIWILL] = { 2846 .mixers = { alc880_uniwill_mixer }, 2847 .init_verbs = { alc880_volume_init_verbs, 2848 alc880_uniwill_init_verbs }, 2849 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 2850 .dac_nids = alc880_asus_dac_nids, 2851 .dig_out_nid = ALC880_DIGOUT_NID, 2852 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), 2853 .channel_mode = alc880_threestack_modes, 2854 .need_dac_fix = 1, 2855 .input_mux = &alc880_capture_source, 2856 .unsol_event = alc880_uniwill_unsol_event, 2857 .init_hook = alc880_uniwill_automute, 2858 }, 2859 [ALC880_UNIWILL_P53] = { 2860 .mixers = { alc880_uniwill_p53_mixer }, 2861 .init_verbs = { alc880_volume_init_verbs, 2862 alc880_uniwill_p53_init_verbs }, 2863 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 2864 .dac_nids = alc880_asus_dac_nids, 2865 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes), 2866 .channel_mode = alc880_threestack_modes, 2867 .input_mux = &alc880_capture_source, 2868 .unsol_event = alc880_uniwill_p53_unsol_event, 2869 .init_hook = alc880_uniwill_p53_hp_automute, 2870 }, 2871 [ALC880_FUJITSU] = { 2872 .mixers = { alc880_fujitsu_mixer, 2873 alc880_pcbeep_mixer, }, 2874 .init_verbs = { alc880_volume_init_verbs, 2875 alc880_uniwill_p53_init_verbs, 2876 alc880_beep_init_verbs }, 2877 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 2878 .dac_nids = alc880_dac_nids, 2879 .dig_out_nid = ALC880_DIGOUT_NID, 2880 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), 2881 .channel_mode = alc880_2_jack_modes, 2882 .input_mux = &alc880_capture_source, 2883 .unsol_event = alc880_uniwill_p53_unsol_event, 2884 .init_hook = alc880_uniwill_p53_hp_automute, 2885 }, 2886 [ALC880_CLEVO] = { 2887 .mixers = { alc880_three_stack_mixer }, 2888 .init_verbs = { alc880_volume_init_verbs, 2889 alc880_pin_clevo_init_verbs }, 2890 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 2891 .dac_nids = alc880_dac_nids, 2892 .hp_nid = 0x03, 2893 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), 2894 .channel_mode = alc880_threestack_modes, 2895 .need_dac_fix = 1, 2896 .input_mux = &alc880_capture_source, 2897 }, 2898 [ALC880_LG] = { 2899 .mixers = { alc880_lg_mixer }, 2900 .init_verbs = { alc880_volume_init_verbs, 2901 alc880_lg_init_verbs }, 2902 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids), 2903 .dac_nids = alc880_lg_dac_nids, 2904 .dig_out_nid = ALC880_DIGOUT_NID, 2905 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes), 2906 .channel_mode = alc880_lg_ch_modes, 2907 .need_dac_fix = 1, 2908 .input_mux = &alc880_lg_capture_source, 2909 .unsol_event = alc880_lg_unsol_event, 2910 .init_hook = alc880_lg_automute, 2911#ifdef CONFIG_SND_HDA_POWER_SAVE 2912 .loopbacks = alc880_lg_loopbacks, 2913#endif 2914 }, 2915 [ALC880_LG_LW] = { 2916 .mixers = { alc880_lg_lw_mixer }, 2917 .init_verbs = { alc880_volume_init_verbs, 2918 alc880_lg_lw_init_verbs }, 2919 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 2920 .dac_nids = alc880_dac_nids, 2921 .dig_out_nid = ALC880_DIGOUT_NID, 2922 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes), 2923 .channel_mode = alc880_lg_lw_modes, 2924 .input_mux = &alc880_lg_lw_capture_source, 2925 .unsol_event = alc880_lg_lw_unsol_event, 2926 .init_hook = alc880_lg_lw_automute, 2927 }, 2928#ifdef CONFIG_SND_DEBUG 2929 [ALC880_TEST] = { 2930 .mixers = { alc880_test_mixer }, 2931 .init_verbs = { alc880_test_init_verbs }, 2932 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids), 2933 .dac_nids = alc880_test_dac_nids, 2934 .dig_out_nid = ALC880_DIGOUT_NID, 2935 .num_channel_mode = ARRAY_SIZE(alc880_test_modes), 2936 .channel_mode = alc880_test_modes, 2937 .input_mux = &alc880_test_capture_source, 2938 }, 2939#endif 2940}; 2941 2942/* 2943 * Automatic parse of I/O pins from the BIOS configuration 2944 */ 2945 2946#define NUM_CONTROL_ALLOC 32 2947#define NUM_VERB_ALLOC 32 2948 2949enum { 2950 ALC_CTL_WIDGET_VOL, 2951 ALC_CTL_WIDGET_MUTE, 2952 ALC_CTL_BIND_MUTE, 2953}; 2954static struct snd_kcontrol_new alc880_control_templates[] = { 2955 HDA_CODEC_VOLUME(NULL, 0, 0, 0), 2956 HDA_CODEC_MUTE(NULL, 0, 0, 0), 2957 HDA_BIND_MUTE(NULL, 0, 0, 0), 2958}; 2959 2960/* add dynamic controls */ 2961static int add_control(struct alc_spec *spec, int type, const char *name, 2962 unsigned long val) 2963{ 2964 struct snd_kcontrol_new *knew; 2965 2966 if (spec->num_kctl_used >= spec->num_kctl_alloc) { 2967 int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC; 2968 2969 /* array + terminator */ 2970 knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL); 2971 if (!knew) 2972 return -ENOMEM; 2973 if (spec->kctl_alloc) { 2974 memcpy(knew, spec->kctl_alloc, 2975 sizeof(*knew) * spec->num_kctl_alloc); 2976 kfree(spec->kctl_alloc); 2977 } 2978 spec->kctl_alloc = knew; 2979 spec->num_kctl_alloc = num; 2980 } 2981 2982 knew = &spec->kctl_alloc[spec->num_kctl_used]; 2983 *knew = alc880_control_templates[type]; 2984 knew->name = kstrdup(name, GFP_KERNEL); 2985 if (!knew->name) 2986 return -ENOMEM; 2987 knew->private_value = val; 2988 spec->num_kctl_used++; 2989 return 0; 2990} 2991 2992#define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17) 2993#define alc880_fixed_pin_idx(nid) ((nid) - 0x14) 2994#define alc880_is_multi_pin(nid) ((nid) >= 0x18) 2995#define alc880_multi_pin_idx(nid) ((nid) - 0x18) 2996#define alc880_is_input_pin(nid) ((nid) >= 0x18) 2997#define alc880_input_pin_idx(nid) ((nid) - 0x18) 2998#define alc880_idx_to_dac(nid) ((nid) + 0x02) 2999#define alc880_dac_to_idx(nid) ((nid) - 0x02) 3000#define alc880_idx_to_mixer(nid) ((nid) + 0x0c) 3001#define alc880_idx_to_selector(nid) ((nid) + 0x10) 3002#define ALC880_PIN_CD_NID 0x1c 3003 3004/* fill in the dac_nids table from the parsed pin configuration */ 3005static int alc880_auto_fill_dac_nids(struct alc_spec *spec, 3006 const struct auto_pin_cfg *cfg) 3007{ 3008 hda_nid_t nid; 3009 int assigned[4]; 3010 int i, j; 3011 3012 memset(assigned, 0, sizeof(assigned)); 3013 spec->multiout.dac_nids = spec->private_dac_nids; 3014 3015 /* check the pins hardwired to audio widget */ 3016 for (i = 0; i < cfg->line_outs; i++) { 3017 nid = cfg->line_out_pins[i]; 3018 if (alc880_is_fixed_pin(nid)) { 3019 int idx = alc880_fixed_pin_idx(nid); 3020 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx); 3021 assigned[idx] = 1; 3022 } 3023 } 3024 /* left pins can be connect to any audio widget */ 3025 for (i = 0; i < cfg->line_outs; i++) { 3026 nid = cfg->line_out_pins[i]; 3027 if (alc880_is_fixed_pin(nid)) 3028 continue; 3029 /* search for an empty channel */ 3030 for (j = 0; j < cfg->line_outs; j++) { 3031 if (!assigned[j]) { 3032 spec->multiout.dac_nids[i] = 3033 alc880_idx_to_dac(j); 3034 assigned[j] = 1; 3035 break; 3036 } 3037 } 3038 } 3039 spec->multiout.num_dacs = cfg->line_outs; 3040 return 0; 3041} 3042 3043/* add playback controls from the parsed DAC table */ 3044static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec, 3045 const struct auto_pin_cfg *cfg) 3046{ 3047 char name[32]; 3048 static const char *chname[4] = { 3049 "Front", "Surround", NULL /*CLFE*/, "Side" 3050 }; 3051 hda_nid_t nid; 3052 int i, err; 3053 3054 for (i = 0; i < cfg->line_outs; i++) { 3055 if (!spec->multiout.dac_nids[i]) 3056 continue; 3057 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i])); 3058 if (i == 2) { 3059 /* Center/LFE */ 3060 err = add_control(spec, ALC_CTL_WIDGET_VOL, 3061 "Center Playback Volume", 3062 HDA_COMPOSE_AMP_VAL(nid, 1, 0, 3063 HDA_OUTPUT)); 3064 if (err < 0) 3065 return err; 3066 err = add_control(spec, ALC_CTL_WIDGET_VOL, 3067 "LFE Playback Volume", 3068 HDA_COMPOSE_AMP_VAL(nid, 2, 0, 3069 HDA_OUTPUT)); 3070 if (err < 0) 3071 return err; 3072 err = add_control(spec, ALC_CTL_BIND_MUTE, 3073 "Center Playback Switch", 3074 HDA_COMPOSE_AMP_VAL(nid, 1, 2, 3075 HDA_INPUT)); 3076 if (err < 0) 3077 return err; 3078 err = add_control(spec, ALC_CTL_BIND_MUTE, 3079 "LFE Playback Switch", 3080 HDA_COMPOSE_AMP_VAL(nid, 2, 2, 3081 HDA_INPUT)); 3082 if (err < 0) 3083 return err; 3084 } else { 3085 sprintf(name, "%s Playback Volume", chname[i]); 3086 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, 3087 HDA_COMPOSE_AMP_VAL(nid, 3, 0, 3088 HDA_OUTPUT)); 3089 if (err < 0) 3090 return err; 3091 sprintf(name, "%s Playback Switch", chname[i]); 3092 err = add_control(spec, ALC_CTL_BIND_MUTE, name, 3093 HDA_COMPOSE_AMP_VAL(nid, 3, 2, 3094 HDA_INPUT)); 3095 if (err < 0) 3096 return err; 3097 } 3098 } 3099 return 0; 3100} 3101 3102/* add playback controls for speaker and HP outputs */ 3103static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin, 3104 const char *pfx) 3105{ 3106 hda_nid_t nid; 3107 int err; 3108 char name[32]; 3109 3110 if (!pin) 3111 return 0; 3112 3113 if (alc880_is_fixed_pin(pin)) { 3114 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); 3115 /* specify the DAC as the extra output */ 3116 if (!spec->multiout.hp_nid) 3117 spec->multiout.hp_nid = nid; 3118 else 3119 spec->multiout.extra_out_nid[0] = nid; 3120 /* control HP volume/switch on the output mixer amp */ 3121 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin)); 3122 sprintf(name, "%s Playback Volume", pfx); 3123 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, 3124 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); 3125 if (err < 0) 3126 return err; 3127 sprintf(name, "%s Playback Switch", pfx); 3128 err = add_control(spec, ALC_CTL_BIND_MUTE, name, 3129 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT)); 3130 if (err < 0) 3131 return err; 3132 } else if (alc880_is_multi_pin(pin)) { 3133 /* set manual connection */ 3134 /* we have only a switch on HP-out PIN */ 3135 sprintf(name, "%s Playback Switch", pfx); 3136 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, 3137 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); 3138 if (err < 0) 3139 return err; 3140 } 3141 return 0; 3142} 3143 3144/* create input playback/capture controls for the given pin */ 3145static int new_analog_input(struct alc_spec *spec, hda_nid_t pin, 3146 const char *ctlname, 3147 int idx, hda_nid_t mix_nid) 3148{ 3149 char name[32]; 3150 int err; 3151 3152 sprintf(name, "%s Playback Volume", ctlname); 3153 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, 3154 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT)); 3155 if (err < 0) 3156 return err; 3157 sprintf(name, "%s Playback Switch", ctlname); 3158 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, 3159 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT)); 3160 if (err < 0) 3161 return err; 3162 return 0; 3163} 3164 3165/* create playback/capture controls for input pins */ 3166static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec, 3167 const struct auto_pin_cfg *cfg) 3168{ 3169 struct hda_input_mux *imux = &spec->private_imux; 3170 int i, err, idx; 3171 3172 for (i = 0; i < AUTO_PIN_LAST; i++) { 3173 if (alc880_is_input_pin(cfg->input_pins[i])) { 3174 idx = alc880_input_pin_idx(cfg->input_pins[i]); 3175 err = new_analog_input(spec, cfg->input_pins[i], 3176 auto_pin_cfg_labels[i], 3177 idx, 0x0b); 3178 if (err < 0) 3179 return err; 3180 imux->items[imux->num_items].label = 3181 auto_pin_cfg_labels[i]; 3182 imux->items[imux->num_items].index = 3183 alc880_input_pin_idx(cfg->input_pins[i]); 3184 imux->num_items++; 3185 } 3186 } 3187 return 0; 3188} 3189 3190static void alc880_auto_set_output_and_unmute(struct hda_codec *codec, 3191 hda_nid_t nid, int pin_type, 3192 int dac_idx) 3193{ 3194 /* set as output */ 3195 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 3196 pin_type); 3197 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, 3198 AMP_OUT_UNMUTE); 3199 /* need the manual connection? */ 3200 if (alc880_is_multi_pin(nid)) { 3201 struct alc_spec *spec = codec->spec; 3202 int idx = alc880_multi_pin_idx(nid); 3203 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0, 3204 AC_VERB_SET_CONNECT_SEL, 3205 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx])); 3206 } 3207} 3208 3209static int get_pin_type(int line_out_type) 3210{ 3211 if (line_out_type == AUTO_PIN_HP_OUT) 3212 return PIN_HP; 3213 else 3214 return PIN_OUT; 3215} 3216 3217static void alc880_auto_init_multi_out(struct hda_codec *codec) 3218{ 3219 struct alc_spec *spec = codec->spec; 3220 int i; 3221 3222 alc_subsystem_id(codec, 0x15, 0x1b, 0x14); 3223 for (i = 0; i < spec->autocfg.line_outs; i++) { 3224 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 3225 int pin_type = get_pin_type(spec->autocfg.line_out_type); 3226 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i); 3227 } 3228} 3229 3230static void alc880_auto_init_extra_out(struct hda_codec *codec) 3231{ 3232 struct alc_spec *spec = codec->spec; 3233 hda_nid_t pin; 3234 3235 pin = spec->autocfg.speaker_pins[0]; 3236 if (pin) /* connect to front */ 3237 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0); 3238 pin = spec->autocfg.hp_pins[0]; 3239 if (pin) /* connect to front */ 3240 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); 3241} 3242 3243static void alc880_auto_init_analog_input(struct hda_codec *codec) 3244{ 3245 struct alc_spec *spec = codec->spec; 3246 int i; 3247 3248 for (i = 0; i < AUTO_PIN_LAST; i++) { 3249 hda_nid_t nid = spec->autocfg.input_pins[i]; 3250 if (alc880_is_input_pin(nid)) { 3251 snd_hda_codec_write(codec, nid, 0, 3252 AC_VERB_SET_PIN_WIDGET_CONTROL, 3253 i <= AUTO_PIN_FRONT_MIC ? 3254 PIN_VREF80 : PIN_IN); 3255 if (nid != ALC880_PIN_CD_NID) 3256 snd_hda_codec_write(codec, nid, 0, 3257 AC_VERB_SET_AMP_GAIN_MUTE, 3258 AMP_OUT_MUTE); 3259 } 3260 } 3261} 3262 3263/* parse the BIOS configuration and set up the alc_spec */ 3264/* return 1 if successful, 0 if the proper config is not found, 3265 * or a negative error code 3266 */ 3267static int alc880_parse_auto_config(struct hda_codec *codec) 3268{ 3269 struct alc_spec *spec = codec->spec; 3270 int err; 3271 static hda_nid_t alc880_ignore[] = { 0x1d, 0 }; 3272 3273 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 3274 alc880_ignore); 3275 if (err < 0) 3276 return err; 3277 if (!spec->autocfg.line_outs) 3278 return 0; /* can't find valid BIOS pin config */ 3279 3280 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); 3281 if (err < 0) 3282 return err; 3283 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg); 3284 if (err < 0) 3285 return err; 3286 err = alc880_auto_create_extra_out(spec, 3287 spec->autocfg.speaker_pins[0], 3288 "Speaker"); 3289 if (err < 0) 3290 return err; 3291 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0], 3292 "Headphone"); 3293 if (err < 0) 3294 return err; 3295 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg); 3296 if (err < 0) 3297 return err; 3298 3299 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 3300 3301 if (spec->autocfg.dig_out_pin) 3302 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID; 3303 if (spec->autocfg.dig_in_pin) 3304 spec->dig_in_nid = ALC880_DIGIN_NID; 3305 3306 if (spec->kctl_alloc) 3307 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 3308 3309 spec->init_verbs[spec->num_init_verbs++] = alc880_volume_init_verbs; 3310 3311 spec->num_mux_defs = 1; 3312 spec->input_mux = &spec->private_imux; 3313 3314 return 1; 3315} 3316 3317/* additional initialization for auto-configuration model */ 3318static void alc880_auto_init(struct hda_codec *codec) 3319{ 3320 alc880_auto_init_multi_out(codec); 3321 alc880_auto_init_extra_out(codec); 3322 alc880_auto_init_analog_input(codec); 3323} 3324 3325/* 3326 * OK, here we have finally the patch for ALC880 3327 */ 3328 3329static int patch_alc880(struct hda_codec *codec) 3330{ 3331 struct alc_spec *spec; 3332 int board_config; 3333 int err; 3334 3335 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 3336 if (spec == NULL) 3337 return -ENOMEM; 3338 3339 codec->spec = spec; 3340 3341 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST, 3342 alc880_models, 3343 alc880_cfg_tbl); 3344 if (board_config < 0) { 3345 printk(KERN_INFO "hda_codec: Unknown model for ALC880, " 3346 "trying auto-probe from BIOS...\n"); 3347 board_config = ALC880_AUTO; 3348 } 3349 3350 if (board_config == ALC880_AUTO) { 3351 /* automatic parse from the BIOS config */ 3352 err = alc880_parse_auto_config(codec); 3353 if (err < 0) { 3354 alc_free(codec); 3355 return err; 3356 } else if (!err) { 3357 printk(KERN_INFO 3358 "hda_codec: Cannot set up configuration " 3359 "from BIOS. Using 3-stack mode...\n"); 3360 board_config = ALC880_3ST; 3361 } 3362 } 3363 3364 if (board_config != ALC880_AUTO) 3365 setup_preset(spec, &alc880_presets[board_config]); 3366 3367 spec->stream_name_analog = "ALC880 Analog"; 3368 spec->stream_analog_playback = &alc880_pcm_analog_playback; 3369 spec->stream_analog_capture = &alc880_pcm_analog_capture; 3370 3371 spec->stream_name_digital = "ALC880 Digital"; 3372 spec->stream_digital_playback = &alc880_pcm_digital_playback; 3373 spec->stream_digital_capture = &alc880_pcm_digital_capture; 3374 3375 if (!spec->adc_nids && spec->input_mux) { 3376 /* check whether NID 0x07 is valid */ 3377 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]); 3378 /* get type */ 3379 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; 3380 if (wcap != AC_WID_AUD_IN) { 3381 spec->adc_nids = alc880_adc_nids_alt; 3382 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt); 3383 spec->mixers[spec->num_mixers] = 3384 alc880_capture_alt_mixer; 3385 spec->num_mixers++; 3386 } else { 3387 spec->adc_nids = alc880_adc_nids; 3388 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids); 3389 spec->mixers[spec->num_mixers] = alc880_capture_mixer; 3390 spec->num_mixers++; 3391 } 3392 } 3393 3394 codec->patch_ops = alc_patch_ops; 3395 if (board_config == ALC880_AUTO) 3396 spec->init_hook = alc880_auto_init; 3397#ifdef CONFIG_SND_HDA_POWER_SAVE 3398 if (!spec->loopback.amplist) 3399 spec->loopback.amplist = alc880_loopbacks; 3400#endif 3401 3402 return 0; 3403} 3404 3405 3406/* 3407 * ALC260 support 3408 */ 3409 3410static hda_nid_t alc260_dac_nids[1] = { 3411 /* front */ 3412 0x02, 3413}; 3414 3415static hda_nid_t alc260_adc_nids[1] = { 3416 /* ADC0 */ 3417 0x04, 3418}; 3419 3420static hda_nid_t alc260_adc_nids_alt[1] = { 3421 /* ADC1 */ 3422 0x05, 3423}; 3424 3425static hda_nid_t alc260_hp_adc_nids[2] = { 3426 /* ADC1, 0 */ 3427 0x05, 0x04 3428}; 3429 3430/* NIDs used when simultaneous access to both ADCs makes sense. Note that 3431 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC. 3432 */ 3433static hda_nid_t alc260_dual_adc_nids[2] = { 3434 /* ADC0, ADC1 */ 3435 0x04, 0x05 3436}; 3437 3438#define ALC260_DIGOUT_NID 0x03 3439#define ALC260_DIGIN_NID 0x06 3440 3441static struct hda_input_mux alc260_capture_source = { 3442 .num_items = 4, 3443 .items = { 3444 { "Mic", 0x0 }, 3445 { "Front Mic", 0x1 }, 3446 { "Line", 0x2 }, 3447 { "CD", 0x4 }, 3448 }, 3449}; 3450 3451/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack, 3452 * headphone jack and the internal CD lines since these are the only pins at 3453 * which audio can appear. For flexibility, also allow the option of 3454 * recording the mixer output on the second ADC (ADC0 doesn't have a 3455 * connection to the mixer output). 3456 */ 3457static struct hda_input_mux alc260_fujitsu_capture_sources[2] = { 3458 { 3459 .num_items = 3, 3460 .items = { 3461 { "Mic/Line", 0x0 }, 3462 { "CD", 0x4 }, 3463 { "Headphone", 0x2 }, 3464 }, 3465 }, 3466 { 3467 .num_items = 4, 3468 .items = { 3469 { "Mic/Line", 0x0 }, 3470 { "CD", 0x4 }, 3471 { "Headphone", 0x2 }, 3472 { "Mixer", 0x5 }, 3473 }, 3474 }, 3475 3476}; 3477 3478/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to 3479 * the Fujitsu S702x, but jacks are marked differently. 3480 */ 3481static struct hda_input_mux alc260_acer_capture_sources[2] = { 3482 { 3483 .num_items = 4, 3484 .items = { 3485 { "Mic", 0x0 }, 3486 { "Line", 0x2 }, 3487 { "CD", 0x4 }, 3488 { "Headphone", 0x5 }, 3489 }, 3490 }, 3491 { 3492 .num_items = 5, 3493 .items = { 3494 { "Mic", 0x0 }, 3495 { "Line", 0x2 }, 3496 { "CD", 0x4 }, 3497 { "Headphone", 0x6 }, 3498 { "Mixer", 0x5 }, 3499 }, 3500 }, 3501}; 3502/* 3503 * This is just place-holder, so there's something for alc_build_pcms to look 3504 * at when it calculates the maximum number of channels. ALC260 has no mixer 3505 * element which allows changing the channel mode, so the verb list is 3506 * never used. 3507 */ 3508static struct hda_channel_mode alc260_modes[1] = { 3509 { 2, NULL }, 3510}; 3511 3512 3513/* Mixer combinations 3514 * 3515 * basic: base_output + input + pc_beep + capture 3516 * HP: base_output + input + capture_alt 3517 * HP_3013: hp_3013 + input + capture 3518 * fujitsu: fujitsu + capture 3519 * acer: acer + capture 3520 */ 3521 3522static struct snd_kcontrol_new alc260_base_output_mixer[] = { 3523 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT), 3524 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT), 3525 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT), 3526 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT), 3527 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), 3528 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT), 3529 { } /* end */ 3530}; 3531 3532static struct snd_kcontrol_new alc260_input_mixer[] = { 3533 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), 3534 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), 3535 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), 3536 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT), 3537 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), 3538 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT), 3539 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT), 3540 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT), 3541 { } /* end */ 3542}; 3543 3544static struct snd_kcontrol_new alc260_pc_beep_mixer[] = { 3545 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT), 3546 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT), 3547 { } /* end */ 3548}; 3549 3550static struct snd_kcontrol_new alc260_hp_3013_mixer[] = { 3551 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT), 3552 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT), 3553 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT), 3554 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT), 3555 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT), 3556 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 3557 HDA_CODEC_VOLUME_MONO("iSpeaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), 3558 HDA_CODEC_MUTE_MONO("iSpeaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT), 3559 { } /* end */ 3560}; 3561 3562/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12, 3563 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10. 3564 */ 3565static struct snd_kcontrol_new alc260_fujitsu_mixer[] = { 3566 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT), 3567 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT), 3568 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT), 3569 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), 3570 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), 3571 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT), 3572 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT), 3573 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN), 3574 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT), 3575 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT), 3576 HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT), 3577 HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x09, 2, HDA_INPUT), 3578 { } /* end */ 3579}; 3580 3581/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current 3582 * versions of the ALC260 don't act on requests to enable mic bias from NID 3583 * 0x0f (used to drive the headphone jack in these laptops). The ALC260 3584 * datasheet doesn't mention this restriction. At this stage it's not clear 3585 * whether this behaviour is intentional or is a hardware bug in chip 3586 * revisions available in early 2006. Therefore for now allow the 3587 * "Headphone Jack Mode" control to span all choices, but if it turns out 3588 * that the lack of mic bias for this NID is intentional we could change the 3589 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS. 3590 * 3591 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006 3592 * don't appear to make the mic bias available from the "line" jack, even 3593 * though the NID used for this jack (0x14) can supply it. The theory is 3594 * that perhaps Acer have included blocking capacitors between the ALC260 3595 * and the output jack. If this turns out to be the case for all such 3596 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT 3597 * to ALC_PIN_DIR_INOUT_NOMICBIAS. 3598 * 3599 * The C20x Tablet series have a mono internal speaker which is controlled 3600 * via the chip's Mono sum widget and pin complex, so include the necessary 3601 * controls for such models. On models without a "mono speaker" the control 3602 * won't do anything. 3603 */ 3604static struct snd_kcontrol_new alc260_acer_mixer[] = { 3605 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), 3606 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT), 3607 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT), 3608 HDA_CODEC_VOLUME_MONO("Mono Speaker Playback Volume", 0x0a, 1, 0x0, 3609 HDA_OUTPUT), 3610 HDA_BIND_MUTE_MONO("Mono Speaker Playback Switch", 0x0a, 1, 2, 3611 HDA_INPUT), 3612 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), 3613 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), 3614 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), 3615 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT), 3616 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN), 3617 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), 3618 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT), 3619 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT), 3620 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT), 3621 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT), 3622 { } /* end */ 3623}; 3624 3625/* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12, 3626 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17. 3627 */ 3628static struct snd_kcontrol_new alc260_will_mixer[] = { 3629 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), 3630 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT), 3631 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), 3632 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT), 3633 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN), 3634 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), 3635 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT), 3636 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT), 3637 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), 3638 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), 3639 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT), 3640 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT), 3641 { } /* end */ 3642}; 3643 3644/* Replacer 672V ALC260 pin usage: Mic jack = 0x12, 3645 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f. 3646 */ 3647static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = { 3648 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), 3649 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT), 3650 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), 3651 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT), 3652 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN), 3653 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT), 3654 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT), 3655 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), 3656 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT), 3657 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT), 3658 { } /* end */ 3659}; 3660 3661/* capture mixer elements */ 3662static struct snd_kcontrol_new alc260_capture_mixer[] = { 3663 HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT), 3664 HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT), 3665 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x05, 0x0, HDA_INPUT), 3666 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x05, 0x0, HDA_INPUT), 3667 { 3668 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 3669 /* The multiple "Capture Source" controls confuse alsamixer 3670 * So call somewhat different.. 3671 * FIXME: the controls appear in the "playback" view! 3672 */ 3673 /* .name = "Capture Source", */ 3674 .name = "Input Source", 3675 .count = 2, 3676 .info = alc_mux_enum_info, 3677 .get = alc_mux_enum_get, 3678 .put = alc_mux_enum_put, 3679 }, 3680 { } /* end */ 3681}; 3682 3683static struct snd_kcontrol_new alc260_capture_alt_mixer[] = { 3684 HDA_CODEC_VOLUME("Capture Volume", 0x05, 0x0, HDA_INPUT), 3685 HDA_CODEC_MUTE("Capture Switch", 0x05, 0x0, HDA_INPUT), 3686 { 3687 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 3688 /* The multiple "Capture Source" controls confuse alsamixer 3689 * So call somewhat different.. 3690 * FIXME: the controls appear in the "playback" view! 3691 */ 3692 /* .name = "Capture Source", */ 3693 .name = "Input Source", 3694 .count = 1, 3695 .info = alc_mux_enum_info, 3696 .get = alc_mux_enum_get, 3697 .put = alc_mux_enum_put, 3698 }, 3699 { } /* end */ 3700}; 3701 3702/* 3703 * initialization verbs 3704 */ 3705static struct hda_verb alc260_init_verbs[] = { 3706 /* Line In pin widget for input */ 3707 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3708 /* CD pin widget for input */ 3709 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3710 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 3711 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3712 /* Mic2 (front panel) pin widget for input and vref at 80% */ 3713 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3714 /* LINE-2 is used for line-out in rear */ 3715 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3716 /* select line-out */ 3717 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00}, 3718 /* LINE-OUT pin */ 3719 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3720 /* enable HP */ 3721 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3722 /* enable Mono */ 3723 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3724 /* mute capture amp left and right */ 3725 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3726 /* set connection select to line in (default select for this ADC) */ 3727 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02}, 3728 /* mute capture amp left and right */ 3729 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3730 /* set connection select to line in (default select for this ADC) */ 3731 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02}, 3732 /* set vol=0 Line-Out mixer amp left and right */ 3733 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3734 /* unmute pin widget amp left and right (no gain on this amp) */ 3735 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3736 /* set vol=0 HP mixer amp left and right */ 3737 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3738 /* unmute pin widget amp left and right (no gain on this amp) */ 3739 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3740 /* set vol=0 Mono mixer amp left and right */ 3741 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3742 /* unmute pin widget amp left and right (no gain on this amp) */ 3743 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3744 /* unmute LINE-2 out pin */ 3745 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3746 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & 3747 * Line In 2 = 0x03 3748 */ 3749 /* mute analog inputs */ 3750 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3751 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 3752 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 3753 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 3754 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 3755 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */ 3756 /* mute Front out path */ 3757 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3758 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 3759 /* mute Headphone out path */ 3760 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3761 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 3762 /* mute Mono out path */ 3763 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3764 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 3765 { } 3766}; 3767 3768#if 0 /* should be identical with alc260_init_verbs? */ 3769static struct hda_verb alc260_hp_init_verbs[] = { 3770 /* Headphone and output */ 3771 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 3772 /* mono output */ 3773 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 3774 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 3775 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 3776 /* Mic2 (front panel) pin widget for input and vref at 80% */ 3777 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 3778 /* Line In pin widget for input */ 3779 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 3780 /* Line-2 pin widget for output */ 3781 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 3782 /* CD pin widget for input */ 3783 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 3784 /* unmute amp left and right */ 3785 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000}, 3786 /* set connection select to line in (default select for this ADC) */ 3787 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02}, 3788 /* unmute Line-Out mixer amp left and right (volume = 0) */ 3789 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 3790 /* mute pin widget amp left and right (no gain on this amp) */ 3791 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 3792 /* unmute HP mixer amp left and right (volume = 0) */ 3793 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 3794 /* mute pin widget amp left and right (no gain on this amp) */ 3795 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 3796 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & 3797 * Line In 2 = 0x03 3798 */ 3799 /* mute analog inputs */ 3800 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3801 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 3802 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 3803 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 3804 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 3805 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */ 3806 /* Unmute Front out path */ 3807 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 3808 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 3809 /* Unmute Headphone out path */ 3810 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 3811 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 3812 /* Unmute Mono out path */ 3813 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 3814 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 3815 { } 3816}; 3817#endif 3818 3819static struct hda_verb alc260_hp_3013_init_verbs[] = { 3820 /* Line out and output */ 3821 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 3822 /* mono output */ 3823 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 3824 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 3825 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 3826 /* Mic2 (front panel) pin widget for input and vref at 80% */ 3827 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 3828 /* Line In pin widget for input */ 3829 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 3830 /* Headphone pin widget for output */ 3831 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 3832 /* CD pin widget for input */ 3833 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 3834 /* unmute amp left and right */ 3835 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000}, 3836 /* set connection select to line in (default select for this ADC) */ 3837 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02}, 3838 /* unmute Line-Out mixer amp left and right (volume = 0) */ 3839 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 3840 /* mute pin widget amp left and right (no gain on this amp) */ 3841 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 3842 /* unmute HP mixer amp left and right (volume = 0) */ 3843 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 3844 /* mute pin widget amp left and right (no gain on this amp) */ 3845 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 3846 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & 3847 * Line In 2 = 0x03 3848 */ 3849 /* mute analog inputs */ 3850 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3851 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 3852 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 3853 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 3854 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 3855 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */ 3856 /* Unmute Front out path */ 3857 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 3858 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 3859 /* Unmute Headphone out path */ 3860 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 3861 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 3862 /* Unmute Mono out path */ 3863 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 3864 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 3865 { } 3866}; 3867 3868/* Initialisation sequence for ALC260 as configured in Fujitsu S702x 3869 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD 3870 * audio = 0x16, internal speaker = 0x10. 3871 */ 3872static struct hda_verb alc260_fujitsu_init_verbs[] = { 3873 /* Disable all GPIOs */ 3874 {0x01, AC_VERB_SET_GPIO_MASK, 0}, 3875 /* Internal speaker is connected to headphone pin */ 3876 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3877 /* Headphone/Line-out jack connects to Line1 pin; make it an output */ 3878 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3879 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */ 3880 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3881 /* Ensure all other unused pins are disabled and muted. */ 3882 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 3883 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3884 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 3885 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3886 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 3887 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3888 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 3889 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3890 3891 /* Disable digital (SPDIF) pins */ 3892 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0}, 3893 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0}, 3894 3895 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus 3896 * when acting as an output. 3897 */ 3898 {0x0d, AC_VERB_SET_CONNECT_SEL, 0}, 3899 3900 /* Start with output sum widgets muted and their output gains at min */ 3901 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3902 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 3903 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3904 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3905 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 3906 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3907 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3908 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 3909 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3910 3911 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */ 3912 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3913 /* Unmute Line1 pin widget output buffer since it starts as an output. 3914 * If the pin mode is changed by the user the pin mode control will 3915 * take care of enabling the pin's input/output buffers as needed. 3916 * Therefore there's no need to enable the input buffer at this 3917 * stage. 3918 */ 3919 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3920 /* Unmute input buffer of pin widget used for Line-in (no equiv 3921 * mixer ctrl) 3922 */ 3923 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3924 3925 /* Mute capture amp left and right */ 3926 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3927 /* Set ADC connection select to match default mixer setting - line 3928 * in (on mic1 pin) 3929 */ 3930 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, 3931 3932 /* Do the same for the second ADC: mute capture input amp and 3933 * set ADC connection to line in (on mic1 pin) 3934 */ 3935 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3936 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, 3937 3938 /* Mute all inputs to mixer widget (even unconnected ones) */ 3939 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */ 3940 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */ 3941 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */ 3942 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */ 3943 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */ 3944 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */ 3945 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */ 3946 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */ 3947 3948 { } 3949}; 3950 3951/* Initialisation sequence for ALC260 as configured in Acer TravelMate and 3952 * similar laptops (adapted from Fujitsu init verbs). 3953 */ 3954static struct hda_verb alc260_acer_init_verbs[] = { 3955 /* On TravelMate laptops, GPIO 0 enables the internal speaker and 3956 * the headphone jack. Turn this on and rely on the standard mute 3957 * methods whenever the user wants to turn these outputs off. 3958 */ 3959 {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, 3960 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, 3961 {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, 3962 /* Internal speaker/Headphone jack is connected to Line-out pin */ 3963 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3964 /* Internal microphone/Mic jack is connected to Mic1 pin */ 3965 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, 3966 /* Line In jack is connected to Line1 pin */ 3967 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3968 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */ 3969 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3970 /* Ensure all other unused pins are disabled and muted. */ 3971 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 3972 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3973 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 3974 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3975 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 3976 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3977 /* Disable digital (SPDIF) pins */ 3978 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0}, 3979 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0}, 3980 3981 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum 3982 * bus when acting as outputs. 3983 */ 3984 {0x0b, AC_VERB_SET_CONNECT_SEL, 0}, 3985 {0x0d, AC_VERB_SET_CONNECT_SEL, 0}, 3986 3987 /* Start with output sum widgets muted and their output gains at min */ 3988 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3989 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 3990 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3991 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3992 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 3993 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3994 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3995 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 3996 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3997 3998 /* Unmute Line-out pin widget amp left and right 3999 * (no equiv mixer ctrl) 4000 */ 4001 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4002 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */ 4003 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4004 /* Unmute Mic1 and Line1 pin widget input buffers since they start as 4005 * inputs. If the pin mode is changed by the user the pin mode control 4006 * will take care of enabling the pin's input/output buffers as needed. 4007 * Therefore there's no need to enable the input buffer at this 4008 * stage. 4009 */ 4010 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4011 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4012 4013 /* Mute capture amp left and right */ 4014 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4015 /* Set ADC connection select to match default mixer setting - mic 4016 * (on mic1 pin) 4017 */ 4018 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, 4019 4020 /* Do similar with the second ADC: mute capture input amp and 4021 * set ADC connection to mic to match ALSA's default state. 4022 */ 4023 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4024 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, 4025 4026 /* Mute all inputs to mixer widget (even unconnected ones) */ 4027 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */ 4028 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */ 4029 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */ 4030 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */ 4031 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */ 4032 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */ 4033 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */ 4034 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */ 4035 4036 { } 4037}; 4038 4039static struct hda_verb alc260_will_verbs[] = { 4040 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 4041 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00}, 4042 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00}, 4043 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02}, 4044 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07}, 4045 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040}, 4046 {} 4047}; 4048 4049static struct hda_verb alc260_replacer_672v_verbs[] = { 4050 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02}, 4051 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07}, 4052 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050}, 4053 4054 {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, 4055 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, 4056 {0x01, AC_VERB_SET_GPIO_DATA, 0x00}, 4057 4058 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 4059 {} 4060}; 4061 4062/* toggle speaker-output according to the hp-jack state */ 4063static void alc260_replacer_672v_automute(struct hda_codec *codec) 4064{ 4065 unsigned int present; 4066 4067 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */ 4068 present = snd_hda_codec_read(codec, 0x0f, 0, 4069 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 4070 if (present) { 4071 snd_hda_codec_write_cache(codec, 0x01, 0, 4072 AC_VERB_SET_GPIO_DATA, 1); 4073 snd_hda_codec_write_cache(codec, 0x0f, 0, 4074 AC_VERB_SET_PIN_WIDGET_CONTROL, 4075 PIN_HP); 4076 } else { 4077 snd_hda_codec_write_cache(codec, 0x01, 0, 4078 AC_VERB_SET_GPIO_DATA, 0); 4079 snd_hda_codec_write_cache(codec, 0x0f, 0, 4080 AC_VERB_SET_PIN_WIDGET_CONTROL, 4081 PIN_OUT); 4082 } 4083} 4084 4085static void alc260_replacer_672v_unsol_event(struct hda_codec *codec, 4086 unsigned int res) 4087{ 4088 if ((res >> 26) == ALC880_HP_EVENT) 4089 alc260_replacer_672v_automute(codec); 4090} 4091 4092/* Test configuration for debugging, modelled after the ALC880 test 4093 * configuration. 4094 */ 4095#ifdef CONFIG_SND_DEBUG 4096static hda_nid_t alc260_test_dac_nids[1] = { 4097 0x02, 4098}; 4099static hda_nid_t alc260_test_adc_nids[2] = { 4100 0x04, 0x05, 4101}; 4102/* For testing the ALC260, each input MUX needs its own definition since 4103 * the signal assignments are different. This assumes that the first ADC 4104 * is NID 0x04. 4105 */ 4106static struct hda_input_mux alc260_test_capture_sources[2] = { 4107 { 4108 .num_items = 7, 4109 .items = { 4110 { "MIC1 pin", 0x0 }, 4111 { "MIC2 pin", 0x1 }, 4112 { "LINE1 pin", 0x2 }, 4113 { "LINE2 pin", 0x3 }, 4114 { "CD pin", 0x4 }, 4115 { "LINE-OUT pin", 0x5 }, 4116 { "HP-OUT pin", 0x6 }, 4117 }, 4118 }, 4119 { 4120 .num_items = 8, 4121 .items = { 4122 { "MIC1 pin", 0x0 }, 4123 { "MIC2 pin", 0x1 }, 4124 { "LINE1 pin", 0x2 }, 4125 { "LINE2 pin", 0x3 }, 4126 { "CD pin", 0x4 }, 4127 { "Mixer", 0x5 }, 4128 { "LINE-OUT pin", 0x6 }, 4129 { "HP-OUT pin", 0x7 }, 4130 }, 4131 }, 4132}; 4133static struct snd_kcontrol_new alc260_test_mixer[] = { 4134 /* Output driver widgets */ 4135 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), 4136 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT), 4137 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT), 4138 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT), 4139 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT), 4140 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT), 4141 4142 /* Modes for retasking pin widgets 4143 * Note: the ALC260 doesn't seem to act on requests to enable mic 4144 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't 4145 * mention this restriction. At this stage it's not clear whether 4146 * this behaviour is intentional or is a hardware bug in chip 4147 * revisions available at least up until early 2006. Therefore for 4148 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all 4149 * choices, but if it turns out that the lack of mic bias for these 4150 * NIDs is intentional we could change their modes from 4151 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS. 4152 */ 4153 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT), 4154 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT), 4155 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT), 4156 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT), 4157 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT), 4158 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT), 4159 4160 /* Loopback mixer controls */ 4161 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT), 4162 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT), 4163 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT), 4164 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT), 4165 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT), 4166 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT), 4167 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT), 4168 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT), 4169 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), 4170 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), 4171 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT), 4172 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT), 4173 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT), 4174 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT), 4175 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT), 4176 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT), 4177 4178 /* Controls for GPIO pins, assuming they are configured as outputs */ 4179 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01), 4180 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02), 4181 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04), 4182 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08), 4183 4184 /* Switches to allow the digital IO pins to be enabled. The datasheet 4185 * is ambigious as to which NID is which; testing on laptops which 4186 * make this output available should provide clarification. 4187 */ 4188 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01), 4189 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01), 4190 4191 { } /* end */ 4192}; 4193static struct hda_verb alc260_test_init_verbs[] = { 4194 /* Enable all GPIOs as outputs with an initial value of 0 */ 4195 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f}, 4196 {0x01, AC_VERB_SET_GPIO_DATA, 0x00}, 4197 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f}, 4198 4199 /* Enable retasking pins as output, initially without power amp */ 4200 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4201 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4202 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4203 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4204 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4205 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4206 4207 /* Disable digital (SPDIF) pins initially, but users can enable 4208 * them via a mixer switch. In the case of SPDIF-out, this initverb 4209 * payload also sets the generation to 0, output to be in "consumer" 4210 * PCM format, copyright asserted, no pre-emphasis and no validity 4211 * control. 4212 */ 4213 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0}, 4214 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0}, 4215 4216 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the 4217 * OUT1 sum bus when acting as an output. 4218 */ 4219 {0x0b, AC_VERB_SET_CONNECT_SEL, 0}, 4220 {0x0c, AC_VERB_SET_CONNECT_SEL, 0}, 4221 {0x0d, AC_VERB_SET_CONNECT_SEL, 0}, 4222 {0x0e, AC_VERB_SET_CONNECT_SEL, 0}, 4223 4224 /* Start with output sum widgets muted and their output gains at min */ 4225 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4226 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4227 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4228 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4229 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4230 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4231 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4232 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4233 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4234 4235 /* Unmute retasking pin widget output buffers since the default 4236 * state appears to be output. As the pin mode is changed by the 4237 * user the pin mode control will take care of enabling the pin's 4238 * input/output buffers as needed. 4239 */ 4240 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4241 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4242 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4243 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4244 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4245 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4246 /* Also unmute the mono-out pin widget */ 4247 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4248 4249 /* Mute capture amp left and right */ 4250 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4251 /* Set ADC connection select to match default mixer setting (mic1 4252 * pin) 4253 */ 4254 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, 4255 4256 /* Do the same for the second ADC: mute capture input amp and 4257 * set ADC connection to mic1 pin 4258 */ 4259 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4260 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, 4261 4262 /* Mute all inputs to mixer widget (even unconnected ones) */ 4263 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */ 4264 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */ 4265 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */ 4266 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */ 4267 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */ 4268 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */ 4269 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */ 4270 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */ 4271 4272 { } 4273}; 4274#endif 4275 4276static struct hda_pcm_stream alc260_pcm_analog_playback = { 4277 .substreams = 1, 4278 .channels_min = 2, 4279 .channels_max = 2, 4280}; 4281 4282static struct hda_pcm_stream alc260_pcm_analog_capture = { 4283 .substreams = 1, 4284 .channels_min = 2, 4285 .channels_max = 2, 4286}; 4287 4288#define alc260_pcm_digital_playback alc880_pcm_digital_playback 4289#define alc260_pcm_digital_capture alc880_pcm_digital_capture 4290 4291/* 4292 * for BIOS auto-configuration 4293 */ 4294 4295static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid, 4296 const char *pfx) 4297{ 4298 hda_nid_t nid_vol; 4299 unsigned long vol_val, sw_val; 4300 char name[32]; 4301 int err; 4302 4303 if (nid >= 0x0f && nid < 0x11) { 4304 nid_vol = nid - 0x7; 4305 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT); 4306 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT); 4307 } else if (nid == 0x11) { 4308 nid_vol = nid - 0x7; 4309 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT); 4310 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT); 4311 } else if (nid >= 0x12 && nid <= 0x15) { 4312 nid_vol = 0x08; 4313 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT); 4314 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT); 4315 } else 4316 return 0; /* N/A */ 4317 4318 snprintf(name, sizeof(name), "%s Playback Volume", pfx); 4319 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val); 4320 if (err < 0) 4321 return err; 4322 snprintf(name, sizeof(name), "%s Playback Switch", pfx); 4323 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val); 4324 if (err < 0) 4325 return err; 4326 return 1; 4327} 4328 4329/* add playback controls from the parsed DAC table */ 4330static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec, 4331 const struct auto_pin_cfg *cfg) 4332{ 4333 hda_nid_t nid; 4334 int err; 4335 4336 spec->multiout.num_dacs = 1; 4337 spec->multiout.dac_nids = spec->private_dac_nids; 4338 spec->multiout.dac_nids[0] = 0x02; 4339 4340 nid = cfg->line_out_pins[0]; 4341 if (nid) { 4342 err = alc260_add_playback_controls(spec, nid, "Front"); 4343 if (err < 0) 4344 return err; 4345 } 4346 4347 nid = cfg->speaker_pins[0]; 4348 if (nid) { 4349 err = alc260_add_playback_controls(spec, nid, "Speaker"); 4350 if (err < 0) 4351 return err; 4352 } 4353 4354 nid = cfg->hp_pins[0]; 4355 if (nid) { 4356 err = alc260_add_playback_controls(spec, nid, "Headphone"); 4357 if (err < 0) 4358 return err; 4359 } 4360 return 0; 4361} 4362 4363/* create playback/capture controls for input pins */ 4364static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec, 4365 const struct auto_pin_cfg *cfg) 4366{ 4367 struct hda_input_mux *imux = &spec->private_imux; 4368 int i, err, idx; 4369 4370 for (i = 0; i < AUTO_PIN_LAST; i++) { 4371 if (cfg->input_pins[i] >= 0x12) { 4372 idx = cfg->input_pins[i] - 0x12; 4373 err = new_analog_input(spec, cfg->input_pins[i], 4374 auto_pin_cfg_labels[i], idx, 4375 0x07); 4376 if (err < 0) 4377 return err; 4378 imux->items[imux->num_items].label = 4379 auto_pin_cfg_labels[i]; 4380 imux->items[imux->num_items].index = idx; 4381 imux->num_items++; 4382 } 4383 if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){ 4384 idx = cfg->input_pins[i] - 0x09; 4385 err = new_analog_input(spec, cfg->input_pins[i], 4386 auto_pin_cfg_labels[i], idx, 4387 0x07); 4388 if (err < 0) 4389 return err; 4390 imux->items[imux->num_items].label = 4391 auto_pin_cfg_labels[i]; 4392 imux->items[imux->num_items].index = idx; 4393 imux->num_items++; 4394 } 4395 } 4396 return 0; 4397} 4398 4399static void alc260_auto_set_output_and_unmute(struct hda_codec *codec, 4400 hda_nid_t nid, int pin_type, 4401 int sel_idx) 4402{ 4403 /* set as output */ 4404 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 4405 pin_type); 4406 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, 4407 AMP_OUT_UNMUTE); 4408 /* need the manual connection? */ 4409 if (nid >= 0x12) { 4410 int idx = nid - 0x12; 4411 snd_hda_codec_write(codec, idx + 0x0b, 0, 4412 AC_VERB_SET_CONNECT_SEL, sel_idx); 4413 } 4414} 4415 4416static void alc260_auto_init_multi_out(struct hda_codec *codec) 4417{ 4418 struct alc_spec *spec = codec->spec; 4419 hda_nid_t nid; 4420 4421 alc_subsystem_id(codec, 0x10, 0x15, 0x0f); 4422 nid = spec->autocfg.line_out_pins[0]; 4423 if (nid) { 4424 int pin_type = get_pin_type(spec->autocfg.line_out_type); 4425 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0); 4426 } 4427 4428 nid = spec->autocfg.speaker_pins[0]; 4429 if (nid) 4430 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0); 4431 4432 nid = spec->autocfg.hp_pins[0]; 4433 if (nid) 4434 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0); 4435} 4436 4437#define ALC260_PIN_CD_NID 0x16 4438static void alc260_auto_init_analog_input(struct hda_codec *codec) 4439{ 4440 struct alc_spec *spec = codec->spec; 4441 int i; 4442 4443 for (i = 0; i < AUTO_PIN_LAST; i++) { 4444 hda_nid_t nid = spec->autocfg.input_pins[i]; 4445 if (nid >= 0x12) { 4446 snd_hda_codec_write(codec, nid, 0, 4447 AC_VERB_SET_PIN_WIDGET_CONTROL, 4448 i <= AUTO_PIN_FRONT_MIC ? 4449 PIN_VREF80 : PIN_IN); 4450 if (nid != ALC260_PIN_CD_NID) 4451 snd_hda_codec_write(codec, nid, 0, 4452 AC_VERB_SET_AMP_GAIN_MUTE, 4453 AMP_OUT_MUTE); 4454 } 4455 } 4456} 4457 4458/* 4459 * generic initialization of ADC, input mixers and output mixers 4460 */ 4461static struct hda_verb alc260_volume_init_verbs[] = { 4462 /* 4463 * Unmute ADC0-1 and set the default input to mic-in 4464 */ 4465 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, 4466 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4467 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, 4468 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4469 4470 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 4471 * mixer widget 4472 * Note: PASD motherboards uses the Line In 2 as the input for 4473 * front panel mic (mic 2) 4474 */ 4475 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 4476 /* mute analog inputs */ 4477 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4478 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4479 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 4480 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 4481 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 4482 4483 /* 4484 * Set up output mixers (0x08 - 0x0a) 4485 */ 4486 /* set vol=0 to output mixers */ 4487 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4488 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4489 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4490 /* set up input amps for analog loopback */ 4491 /* Amp Indices: DAC = 0, mixer = 1 */ 4492 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4493 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4494 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4495 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4496 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4497 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4498 4499 { } 4500}; 4501 4502static int alc260_parse_auto_config(struct hda_codec *codec) 4503{ 4504 struct alc_spec *spec = codec->spec; 4505 unsigned int wcap; 4506 int err; 4507 static hda_nid_t alc260_ignore[] = { 0x17, 0 }; 4508 4509 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 4510 alc260_ignore); 4511 if (err < 0) 4512 return err; 4513 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg); 4514 if (err < 0) 4515 return err; 4516 if (!spec->kctl_alloc) 4517 return 0; /* can't find valid BIOS pin config */ 4518 err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg); 4519 if (err < 0) 4520 return err; 4521 4522 spec->multiout.max_channels = 2; 4523 4524 if (spec->autocfg.dig_out_pin) 4525 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID; 4526 if (spec->kctl_alloc) 4527 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 4528 4529 spec->init_verbs[spec->num_init_verbs++] = alc260_volume_init_verbs; 4530 4531 spec->num_mux_defs = 1; 4532 spec->input_mux = &spec->private_imux; 4533 4534 /* check whether NID 0x04 is valid */ 4535 wcap = get_wcaps(codec, 0x04); 4536 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */ 4537 if (wcap != AC_WID_AUD_IN) { 4538 spec->adc_nids = alc260_adc_nids_alt; 4539 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt); 4540 spec->mixers[spec->num_mixers] = alc260_capture_alt_mixer; 4541 } else { 4542 spec->adc_nids = alc260_adc_nids; 4543 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids); 4544 spec->mixers[spec->num_mixers] = alc260_capture_mixer; 4545 } 4546 spec->num_mixers++; 4547 4548 return 1; 4549} 4550 4551/* additional initialization for auto-configuration model */ 4552static void alc260_auto_init(struct hda_codec *codec) 4553{ 4554 alc260_auto_init_multi_out(codec); 4555 alc260_auto_init_analog_input(codec); 4556} 4557 4558#ifdef CONFIG_SND_HDA_POWER_SAVE 4559static struct hda_amp_list alc260_loopbacks[] = { 4560 { 0x07, HDA_INPUT, 0 }, 4561 { 0x07, HDA_INPUT, 1 }, 4562 { 0x07, HDA_INPUT, 2 }, 4563 { 0x07, HDA_INPUT, 3 }, 4564 { 0x07, HDA_INPUT, 4 }, 4565 { } /* end */ 4566}; 4567#endif 4568 4569/* 4570 * ALC260 configurations 4571 */ 4572static const char *alc260_models[ALC260_MODEL_LAST] = { 4573 [ALC260_BASIC] = "basic", 4574 [ALC260_HP] = "hp", 4575 [ALC260_HP_3013] = "hp-3013", 4576 [ALC260_FUJITSU_S702X] = "fujitsu", 4577 [ALC260_ACER] = "acer", 4578 [ALC260_WILL] = "will", 4579 [ALC260_REPLACER_672V] = "replacer", 4580#ifdef CONFIG_SND_DEBUG 4581 [ALC260_TEST] = "test", 4582#endif 4583 [ALC260_AUTO] = "auto", 4584}; 4585 4586static struct snd_pci_quirk alc260_cfg_tbl[] = { 4587 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER), 4588 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER), 4589 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013), 4590 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013), 4591 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013), 4592 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP), 4593 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_3013), 4594 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013), 4595 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP), 4596 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP), 4597 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP), 4598 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC), 4599 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC), 4600 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC), 4601 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X), 4602 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC), 4603 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL), 4604 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V), 4605 {} 4606}; 4607 4608static struct alc_config_preset alc260_presets[] = { 4609 [ALC260_BASIC] = { 4610 .mixers = { alc260_base_output_mixer, 4611 alc260_input_mixer, 4612 alc260_pc_beep_mixer, 4613 alc260_capture_mixer }, 4614 .init_verbs = { alc260_init_verbs }, 4615 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 4616 .dac_nids = alc260_dac_nids, 4617 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids), 4618 .adc_nids = alc260_adc_nids, 4619 .num_channel_mode = ARRAY_SIZE(alc260_modes), 4620 .channel_mode = alc260_modes, 4621 .input_mux = &alc260_capture_source, 4622 }, 4623 [ALC260_HP] = { 4624 .mixers = { alc260_base_output_mixer, 4625 alc260_input_mixer, 4626 alc260_capture_alt_mixer }, 4627 .init_verbs = { alc260_init_verbs }, 4628 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 4629 .dac_nids = alc260_dac_nids, 4630 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids), 4631 .adc_nids = alc260_hp_adc_nids, 4632 .num_channel_mode = ARRAY_SIZE(alc260_modes), 4633 .channel_mode = alc260_modes, 4634 .input_mux = &alc260_capture_source, 4635 }, 4636 [ALC260_HP_3013] = { 4637 .mixers = { alc260_hp_3013_mixer, 4638 alc260_input_mixer, 4639 alc260_capture_alt_mixer }, 4640 .init_verbs = { alc260_hp_3013_init_verbs }, 4641 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 4642 .dac_nids = alc260_dac_nids, 4643 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids), 4644 .adc_nids = alc260_hp_adc_nids, 4645 .num_channel_mode = ARRAY_SIZE(alc260_modes), 4646 .channel_mode = alc260_modes, 4647 .input_mux = &alc260_capture_source, 4648 }, 4649 [ALC260_FUJITSU_S702X] = { 4650 .mixers = { alc260_fujitsu_mixer, 4651 alc260_capture_mixer }, 4652 .init_verbs = { alc260_fujitsu_init_verbs }, 4653 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 4654 .dac_nids = alc260_dac_nids, 4655 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids), 4656 .adc_nids = alc260_dual_adc_nids, 4657 .num_channel_mode = ARRAY_SIZE(alc260_modes), 4658 .channel_mode = alc260_modes, 4659 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources), 4660 .input_mux = alc260_fujitsu_capture_sources, 4661 }, 4662 [ALC260_ACER] = { 4663 .mixers = { alc260_acer_mixer, 4664 alc260_capture_mixer }, 4665 .init_verbs = { alc260_acer_init_verbs }, 4666 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 4667 .dac_nids = alc260_dac_nids, 4668 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids), 4669 .adc_nids = alc260_dual_adc_nids, 4670 .num_channel_mode = ARRAY_SIZE(alc260_modes), 4671 .channel_mode = alc260_modes, 4672 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources), 4673 .input_mux = alc260_acer_capture_sources, 4674 }, 4675 [ALC260_WILL] = { 4676 .mixers = { alc260_will_mixer, 4677 alc260_capture_mixer }, 4678 .init_verbs = { alc260_init_verbs, alc260_will_verbs }, 4679 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 4680 .dac_nids = alc260_dac_nids, 4681 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids), 4682 .adc_nids = alc260_adc_nids, 4683 .dig_out_nid = ALC260_DIGOUT_NID, 4684 .num_channel_mode = ARRAY_SIZE(alc260_modes), 4685 .channel_mode = alc260_modes, 4686 .input_mux = &alc260_capture_source, 4687 }, 4688 [ALC260_REPLACER_672V] = { 4689 .mixers = { alc260_replacer_672v_mixer, 4690 alc260_capture_mixer }, 4691 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs }, 4692 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 4693 .dac_nids = alc260_dac_nids, 4694 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids), 4695 .adc_nids = alc260_adc_nids, 4696 .dig_out_nid = ALC260_DIGOUT_NID, 4697 .num_channel_mode = ARRAY_SIZE(alc260_modes), 4698 .channel_mode = alc260_modes, 4699 .input_mux = &alc260_capture_source, 4700 .unsol_event = alc260_replacer_672v_unsol_event, 4701 .init_hook = alc260_replacer_672v_automute, 4702 }, 4703#ifdef CONFIG_SND_DEBUG 4704 [ALC260_TEST] = { 4705 .mixers = { alc260_test_mixer, 4706 alc260_capture_mixer }, 4707 .init_verbs = { alc260_test_init_verbs }, 4708 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids), 4709 .dac_nids = alc260_test_dac_nids, 4710 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids), 4711 .adc_nids = alc260_test_adc_nids, 4712 .num_channel_mode = ARRAY_SIZE(alc260_modes), 4713 .channel_mode = alc260_modes, 4714 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources), 4715 .input_mux = alc260_test_capture_sources, 4716 }, 4717#endif 4718}; 4719 4720static int patch_alc260(struct hda_codec *codec) 4721{ 4722 struct alc_spec *spec; 4723 int err, board_config; 4724 4725 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 4726 if (spec == NULL) 4727 return -ENOMEM; 4728 4729 codec->spec = spec; 4730 4731 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST, 4732 alc260_models, 4733 alc260_cfg_tbl); 4734 if (board_config < 0) { 4735 snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, " 4736 "trying auto-probe from BIOS...\n"); 4737 board_config = ALC260_AUTO; 4738 } 4739 4740 if (board_config == ALC260_AUTO) { 4741 /* automatic parse from the BIOS config */ 4742 err = alc260_parse_auto_config(codec); 4743 if (err < 0) { 4744 alc_free(codec); 4745 return err; 4746 } else if (!err) { 4747 printk(KERN_INFO 4748 "hda_codec: Cannot set up configuration " 4749 "from BIOS. Using base mode...\n"); 4750 board_config = ALC260_BASIC; 4751 } 4752 } 4753 4754 if (board_config != ALC260_AUTO) 4755 setup_preset(spec, &alc260_presets[board_config]); 4756 4757 spec->stream_name_analog = "ALC260 Analog"; 4758 spec->stream_analog_playback = &alc260_pcm_analog_playback; 4759 spec->stream_analog_capture = &alc260_pcm_analog_capture; 4760 4761 spec->stream_name_digital = "ALC260 Digital"; 4762 spec->stream_digital_playback = &alc260_pcm_digital_playback; 4763 spec->stream_digital_capture = &alc260_pcm_digital_capture; 4764 4765 codec->patch_ops = alc_patch_ops; 4766 if (board_config == ALC260_AUTO) 4767 spec->init_hook = alc260_auto_init; 4768#ifdef CONFIG_SND_HDA_POWER_SAVE 4769 if (!spec->loopback.amplist) 4770 spec->loopback.amplist = alc260_loopbacks; 4771#endif 4772 4773 return 0; 4774} 4775 4776 4777/* 4778 * ALC882 support 4779 * 4780 * ALC882 is almost identical with ALC880 but has cleaner and more flexible 4781 * configuration. Each pin widget can choose any input DACs and a mixer. 4782 * Each ADC is connected from a mixer of all inputs. This makes possible 4783 * 6-channel independent captures. 4784 * 4785 * In addition, an independent DAC for the multi-playback (not used in this 4786 * driver yet). 4787 */ 4788#define ALC882_DIGOUT_NID 0x06 4789#define ALC882_DIGIN_NID 0x0a 4790 4791static struct hda_channel_mode alc882_ch_modes[1] = { 4792 { 8, NULL } 4793}; 4794 4795static hda_nid_t alc882_dac_nids[4] = { 4796 /* front, rear, clfe, rear_surr */ 4797 0x02, 0x03, 0x04, 0x05 4798}; 4799 4800/* identical with ALC880 */ 4801#define alc882_adc_nids alc880_adc_nids 4802#define alc882_adc_nids_alt alc880_adc_nids_alt 4803 4804/* input MUX */ 4805/* FIXME: should be a matrix-type input source selection */ 4806 4807static struct hda_input_mux alc882_capture_source = { 4808 .num_items = 4, 4809 .items = { 4810 { "Mic", 0x0 }, 4811 { "Front Mic", 0x1 }, 4812 { "Line", 0x2 }, 4813 { "CD", 0x4 }, 4814 }, 4815}; 4816#define alc882_mux_enum_info alc_mux_enum_info 4817#define alc882_mux_enum_get alc_mux_enum_get 4818 4819static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol, 4820 struct snd_ctl_elem_value *ucontrol) 4821{ 4822 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 4823 struct alc_spec *spec = codec->spec; 4824 const struct hda_input_mux *imux = spec->input_mux; 4825 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 4826 static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 }; 4827 hda_nid_t nid = capture_mixers[adc_idx]; 4828 unsigned int *cur_val = &spec->cur_mux[adc_idx]; 4829 unsigned int i, idx; 4830 4831 idx = ucontrol->value.enumerated.item[0]; 4832 if (idx >= imux->num_items) 4833 idx = imux->num_items - 1; 4834 if (*cur_val == idx) 4835 return 0; 4836 for (i = 0; i < imux->num_items; i++) { 4837 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE; 4838 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 4839 imux->items[i].index, 4840 HDA_AMP_MUTE, v); 4841 } 4842 *cur_val = idx; 4843 return 1; 4844} 4845 4846/* 4847 * 2ch mode 4848 */ 4849static struct hda_verb alc882_3ST_ch2_init[] = { 4850 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 4851 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 4852 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 4853 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 4854 { } /* end */ 4855}; 4856 4857/* 4858 * 6ch mode 4859 */ 4860static struct hda_verb alc882_3ST_ch6_init[] = { 4861 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 4862 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 4863 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, 4864 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 4865 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 4866 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 4867 { } /* end */ 4868}; 4869 4870static struct hda_channel_mode alc882_3ST_6ch_modes[2] = { 4871 { 2, alc882_3ST_ch2_init }, 4872 { 6, alc882_3ST_ch6_init }, 4873}; 4874 4875/* 4876 * 6ch mode 4877 */ 4878static struct hda_verb alc882_sixstack_ch6_init[] = { 4879 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 4880 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 4881 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 4882 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 4883 { } /* end */ 4884}; 4885 4886/* 4887 * 8ch mode 4888 */ 4889static struct hda_verb alc882_sixstack_ch8_init[] = { 4890 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 4891 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 4892 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 4893 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 4894 { } /* end */ 4895}; 4896 4897static struct hda_channel_mode alc882_sixstack_modes[2] = { 4898 { 6, alc882_sixstack_ch6_init }, 4899 { 8, alc882_sixstack_ch8_init }, 4900}; 4901 4902/* 4903 * macbook pro ALC885 can switch LineIn to LineOut without loosing Mic 4904 */ 4905 4906/* 4907 * 2ch mode 4908 */ 4909static struct hda_verb alc885_mbp_ch2_init[] = { 4910 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 4911 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4912 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4913 { } /* end */ 4914}; 4915 4916/* 4917 * 6ch mode 4918 */ 4919static struct hda_verb alc885_mbp_ch6_init[] = { 4920 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 4921 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4922 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 4923 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4924 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4925 { } /* end */ 4926}; 4927 4928static struct hda_channel_mode alc885_mbp_6ch_modes[2] = { 4929 { 2, alc885_mbp_ch2_init }, 4930 { 6, alc885_mbp_ch6_init }, 4931}; 4932 4933 4934/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 4935 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b 4936 */ 4937static struct snd_kcontrol_new alc882_base_mixer[] = { 4938 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 4939 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 4940 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 4941 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 4942 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 4943 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 4944 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 4945 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 4946 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 4947 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 4948 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 4949 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 4950 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 4951 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 4952 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 4953 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 4954 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 4955 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 4956 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 4957 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 4958 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 4959 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 4960 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 4961 { } /* end */ 4962}; 4963 4964static struct snd_kcontrol_new alc885_mbp3_mixer[] = { 4965 HDA_CODEC_VOLUME("Master Volume", 0x0c, 0x00, HDA_OUTPUT), 4966 HDA_BIND_MUTE ("Master Switch", 0x0c, 0x02, HDA_INPUT), 4967 HDA_CODEC_MUTE ("Speaker Switch", 0x14, 0x00, HDA_OUTPUT), 4968 HDA_CODEC_VOLUME("Line Out Volume", 0x0d,0x00, HDA_OUTPUT), 4969 HDA_CODEC_VOLUME("Line In Playback Volume", 0x0b, 0x02, HDA_INPUT), 4970 HDA_CODEC_MUTE ("Line In Playback Switch", 0x0b, 0x02, HDA_INPUT), 4971 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT), 4972 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT), 4973 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0x00, HDA_INPUT), 4974 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT), 4975 { } /* end */ 4976}; 4977static struct snd_kcontrol_new alc882_w2jc_mixer[] = { 4978 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 4979 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 4980 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 4981 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 4982 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 4983 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 4984 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 4985 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 4986 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 4987 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 4988 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 4989 { } /* end */ 4990}; 4991 4992static struct snd_kcontrol_new alc882_targa_mixer[] = { 4993 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 4994 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 4995 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 4996 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 4997 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 4998 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 4999 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 5000 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 5001 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 5002 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 5003 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 5004 { } /* end */ 5005}; 5006 5007/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ??? 5008 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c 5009 */ 5010static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = { 5011 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 5012 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 5013 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 5014 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT), 5015 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 5016 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 5017 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 5018 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 5019 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT), 5020 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT), 5021 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 5022 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 5023 { } /* end */ 5024}; 5025 5026static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = { 5027 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 5028 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 5029 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 5030 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 5031 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 5032 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 5033 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 5034 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 5035 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 5036 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 5037 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 5038 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 5039 { } /* end */ 5040}; 5041 5042static struct snd_kcontrol_new alc882_chmode_mixer[] = { 5043 { 5044 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 5045 .name = "Channel Mode", 5046 .info = alc_ch_mode_info, 5047 .get = alc_ch_mode_get, 5048 .put = alc_ch_mode_put, 5049 }, 5050 { } /* end */ 5051}; 5052 5053static struct hda_verb alc882_init_verbs[] = { 5054 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 5055 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5056 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5057 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 5058 /* Rear mixer */ 5059 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5060 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5061 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 5062 /* CLFE mixer */ 5063 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5064 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5065 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 5066 /* Side mixer */ 5067 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5068 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5069 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 5070 5071 /* Front Pin: output 0 (0x0c) */ 5072 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5073 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5074 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 5075 /* Rear Pin: output 1 (0x0d) */ 5076 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5077 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5078 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 5079 /* CLFE Pin: output 2 (0x0e) */ 5080 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5081 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5082 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, 5083 /* Side Pin: output 3 (0x0f) */ 5084 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5085 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5086 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, 5087 /* Mic (rear) pin: input vref at 80% */ 5088 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 5089 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 5090 /* Front Mic pin: input vref at 80% */ 5091 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 5092 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 5093 /* Line In pin: input */ 5094 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 5095 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 5096 /* Line-2 In: Headphone output (output 0 - 0x0c) */ 5097 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 5098 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5099 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 5100 /* CD pin widget for input */ 5101 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 5102 5103 /* FIXME: use matrix-type input source selection */ 5104 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 5105 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 5106 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5107 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 5108 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 5109 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 5110 /* Input mixer2 */ 5111 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5112 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 5113 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 5114 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 5115 /* Input mixer3 */ 5116 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5117 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 5118 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 5119 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 5120 /* ADC1: mute amp left and right */ 5121 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5122 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 5123 /* ADC2: mute amp left and right */ 5124 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5125 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 5126 /* ADC3: mute amp left and right */ 5127 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5128 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 5129 5130 { } 5131}; 5132 5133static struct hda_verb alc882_eapd_verbs[] = { 5134 /* change to EAPD mode */ 5135 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 5136 {0x20, AC_VERB_SET_PROC_COEF, 0x3060}, 5137 { } 5138}; 5139 5140/* Mac Pro test */ 5141static struct snd_kcontrol_new alc882_macpro_mixer[] = { 5142 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 5143 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 5144 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT), 5145 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT), 5146 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT), 5147 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT), 5148 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT), 5149 { } /* end */ 5150}; 5151 5152static struct hda_verb alc882_macpro_init_verbs[] = { 5153 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 5154 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5155 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5156 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 5157 /* Front Pin: output 0 (0x0c) */ 5158 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5159 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5160 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 5161 /* Front Mic pin: input vref at 80% */ 5162 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 5163 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 5164 /* Speaker: output */ 5165 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5166 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5167 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04}, 5168 /* Headphone output (output 0 - 0x0c) */ 5169 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 5170 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5171 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00}, 5172 5173 /* FIXME: use matrix-type input source selection */ 5174 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 5175 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 5176 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5177 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 5178 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 5179 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 5180 /* Input mixer2 */ 5181 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5182 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 5183 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 5184 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 5185 /* Input mixer3 */ 5186 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5187 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 5188 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 5189 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 5190 /* ADC1: mute amp left and right */ 5191 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5192 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 5193 /* ADC2: mute amp left and right */ 5194 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5195 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 5196 /* ADC3: mute amp left and right */ 5197 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5198 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 5199 5200 { } 5201}; 5202 5203/* Macbook Pro rev3 */ 5204static struct hda_verb alc885_mbp3_init_verbs[] = { 5205 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 5206 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5207 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5208 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 5209 /* Rear mixer */ 5210 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5211 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5212 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 5213 /* Front Pin: output 0 (0x0c) */ 5214 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5215 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5216 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 5217 /* HP Pin: output 0 (0x0d) */ 5218 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, 5219 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 5220 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 5221 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 5222 /* Mic (rear) pin: input vref at 80% */ 5223 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 5224 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 5225 /* Front Mic pin: input vref at 80% */ 5226 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 5227 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 5228 /* Line In pin: use output 1 when in LineOut mode */ 5229 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 5230 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 5231 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, 5232 5233 /* FIXME: use matrix-type input source selection */ 5234 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 5235 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 5236 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5237 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 5238 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 5239 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 5240 /* Input mixer2 */ 5241 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5242 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 5243 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 5244 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 5245 /* Input mixer3 */ 5246 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5247 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 5248 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 5249 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 5250 /* ADC1: mute amp left and right */ 5251 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5252 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 5253 /* ADC2: mute amp left and right */ 5254 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5255 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 5256 /* ADC3: mute amp left and right */ 5257 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5258 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 5259 5260 { } 5261}; 5262 5263/* iMac 24 mixer. */ 5264static struct snd_kcontrol_new alc885_imac24_mixer[] = { 5265 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 5266 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT), 5267 { } /* end */ 5268}; 5269 5270/* iMac 24 init verbs. */ 5271static struct hda_verb alc885_imac24_init_verbs[] = { 5272 /* Internal speakers: output 0 (0x0c) */ 5273 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5274 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5275 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00}, 5276 /* Internal speakers: output 0 (0x0c) */ 5277 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5278 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5279 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00}, 5280 /* Headphone: output 0 (0x0c) */ 5281 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 5282 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5283 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 5284 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 5285 /* Front Mic: input vref at 80% */ 5286 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 5287 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 5288 { } 5289}; 5290 5291/* Toggle speaker-output according to the hp-jack state */ 5292static void alc885_imac24_automute(struct hda_codec *codec) 5293{ 5294 unsigned int present; 5295 5296 present = snd_hda_codec_read(codec, 0x14, 0, 5297 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 5298 snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0, 5299 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 5300 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0, 5301 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 5302} 5303 5304/* Processes unsolicited events. */ 5305static void alc885_imac24_unsol_event(struct hda_codec *codec, 5306 unsigned int res) 5307{ 5308 /* Headphone insertion or removal. */ 5309 if ((res >> 26) == ALC880_HP_EVENT) 5310 alc885_imac24_automute(codec); 5311} 5312 5313static void alc885_mbp3_automute(struct hda_codec *codec) 5314{ 5315 unsigned int present; 5316 5317 present = snd_hda_codec_read(codec, 0x15, 0, 5318 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 5319 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 5320 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 5321 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 5322 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE); 5323 5324} 5325static void alc885_mbp3_unsol_event(struct hda_codec *codec, 5326 unsigned int res) 5327{ 5328 /* Headphone insertion or removal. */ 5329 if ((res >> 26) == ALC880_HP_EVENT) 5330 alc885_mbp3_automute(codec); 5331} 5332 5333 5334static struct hda_verb alc882_targa_verbs[] = { 5335 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5336 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 5337 5338 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 5339 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5340 5341 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ 5342 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */ 5343 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 5344 5345 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 5346 {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, 5347 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03}, 5348 {0x01, AC_VERB_SET_GPIO_DATA, 0x03}, 5349 { } /* end */ 5350}; 5351 5352/* toggle speaker-output according to the hp-jack state */ 5353static void alc882_targa_automute(struct hda_codec *codec) 5354{ 5355 unsigned int present; 5356 5357 present = snd_hda_codec_read(codec, 0x14, 0, 5358 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 5359 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0, 5360 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 5361 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA, 5362 present ? 1 : 3); 5363} 5364 5365static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res) 5366{ 5367 /* Looks like the unsol event is incompatible with the standard 5368 * definition. 4bit tag is placed at 26 bit! 5369 */ 5370 if (((res >> 26) == ALC880_HP_EVENT)) { 5371 alc882_targa_automute(codec); 5372 } 5373} 5374 5375static struct hda_verb alc882_asus_a7j_verbs[] = { 5376 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5377 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 5378 5379 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 5380 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5381 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5382 5383 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */ 5384 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 5385 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */ 5386 5387 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ 5388 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */ 5389 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 5390 { } /* end */ 5391}; 5392 5393static struct hda_verb alc882_asus_a7m_verbs[] = { 5394 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5395 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 5396 5397 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 5398 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5399 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5400 5401 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */ 5402 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 5403 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */ 5404 5405 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ 5406 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */ 5407 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 5408 { } /* end */ 5409}; 5410 5411static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted) 5412{ 5413 unsigned int gpiostate, gpiomask, gpiodir; 5414 5415 gpiostate = snd_hda_codec_read(codec, codec->afg, 0, 5416 AC_VERB_GET_GPIO_DATA, 0); 5417 5418 if (!muted) 5419 gpiostate |= (1 << pin); 5420 else 5421 gpiostate &= ~(1 << pin); 5422 5423 gpiomask = snd_hda_codec_read(codec, codec->afg, 0, 5424 AC_VERB_GET_GPIO_MASK, 0); 5425 gpiomask |= (1 << pin); 5426 5427 gpiodir = snd_hda_codec_read(codec, codec->afg, 0, 5428 AC_VERB_GET_GPIO_DIRECTION, 0); 5429 gpiodir |= (1 << pin); 5430 5431 5432 snd_hda_codec_write(codec, codec->afg, 0, 5433 AC_VERB_SET_GPIO_MASK, gpiomask); 5434 snd_hda_codec_write(codec, codec->afg, 0, 5435 AC_VERB_SET_GPIO_DIRECTION, gpiodir); 5436 5437 msleep(1); 5438 5439 snd_hda_codec_write(codec, codec->afg, 0, 5440 AC_VERB_SET_GPIO_DATA, gpiostate); 5441} 5442 5443/* set up GPIO at initialization */ 5444static void alc885_macpro_init_hook(struct hda_codec *codec) 5445{ 5446 alc882_gpio_mute(codec, 0, 0); 5447 alc882_gpio_mute(codec, 1, 0); 5448} 5449 5450/* set up GPIO and update auto-muting at initialization */ 5451static void alc885_imac24_init_hook(struct hda_codec *codec) 5452{ 5453 alc885_macpro_init_hook(codec); 5454 alc885_imac24_automute(codec); 5455} 5456 5457/* 5458 * generic initialization of ADC, input mixers and output mixers 5459 */ 5460static struct hda_verb alc882_auto_init_verbs[] = { 5461 /* 5462 * Unmute ADC0-2 and set the default input to mic-in 5463 */ 5464 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 5465 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5466 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 5467 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5468 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 5469 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5470 5471 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 5472 * mixer widget 5473 * Note: PASD motherboards uses the Line In 2 as the input for 5474 * front panel mic (mic 2) 5475 */ 5476 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 5477 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5478 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 5479 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 5480 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 5481 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 5482 5483 /* 5484 * Set up output mixers (0x0c - 0x0f) 5485 */ 5486 /* set vol=0 to output mixers */ 5487 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5488 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5489 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5490 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5491 /* set up input amps for analog loopback */ 5492 /* Amp Indices: DAC = 0, mixer = 1 */ 5493 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5494 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 5495 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5496 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 5497 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5498 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 5499 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5500 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 5501 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5502 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 5503 5504 /* FIXME: use matrix-type input source selection */ 5505 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 5506 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 5507 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 5508 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 5509 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 5510 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 5511 /* Input mixer2 */ 5512 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 5513 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 5514 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 5515 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 5516 /* Input mixer3 */ 5517 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 5518 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 5519 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 5520 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 5521 5522 { } 5523}; 5524 5525/* capture mixer elements */ 5526static struct snd_kcontrol_new alc882_capture_alt_mixer[] = { 5527 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 5528 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 5529 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), 5530 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), 5531 { 5532 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 5533 /* The multiple "Capture Source" controls confuse alsamixer 5534 * So call somewhat different.. 5535 * FIXME: the controls appear in the "playback" view! 5536 */ 5537 /* .name = "Capture Source", */ 5538 .name = "Input Source", 5539 .count = 2, 5540 .info = alc882_mux_enum_info, 5541 .get = alc882_mux_enum_get, 5542 .put = alc882_mux_enum_put, 5543 }, 5544 { } /* end */ 5545}; 5546 5547static struct snd_kcontrol_new alc882_capture_mixer[] = { 5548 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT), 5549 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT), 5550 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT), 5551 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT), 5552 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT), 5553 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT), 5554 { 5555 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 5556 /* The multiple "Capture Source" controls confuse alsamixer 5557 * So call somewhat different.. 5558 * FIXME: the controls appear in the "playback" view! 5559 */ 5560 /* .name = "Capture Source", */ 5561 .name = "Input Source", 5562 .count = 3, 5563 .info = alc882_mux_enum_info, 5564 .get = alc882_mux_enum_get, 5565 .put = alc882_mux_enum_put, 5566 }, 5567 { } /* end */ 5568}; 5569 5570#ifdef CONFIG_SND_HDA_POWER_SAVE 5571#define alc882_loopbacks alc880_loopbacks 5572#endif 5573 5574/* pcm configuration: identiacal with ALC880 */ 5575#define alc882_pcm_analog_playback alc880_pcm_analog_playback 5576#define alc882_pcm_analog_capture alc880_pcm_analog_capture 5577#define alc882_pcm_digital_playback alc880_pcm_digital_playback 5578#define alc882_pcm_digital_capture alc880_pcm_digital_capture 5579 5580/* 5581 * configuration and preset 5582 */ 5583static const char *alc882_models[ALC882_MODEL_LAST] = { 5584 [ALC882_3ST_DIG] = "3stack-dig", 5585 [ALC882_6ST_DIG] = "6stack-dig", 5586 [ALC882_ARIMA] = "arima", 5587 [ALC882_W2JC] = "w2jc", 5588 [ALC882_TARGA] = "targa", 5589 [ALC882_ASUS_A7J] = "asus-a7j", 5590 [ALC882_ASUS_A7M] = "asus-a7m", 5591 [ALC885_MACPRO] = "macpro", 5592 [ALC885_MBP3] = "mbp3", 5593 [ALC885_IMAC24] = "imac24", 5594 [ALC882_AUTO] = "auto", 5595}; 5596 5597static struct snd_pci_quirk alc882_cfg_tbl[] = { 5598 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG), 5599 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG), 5600 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG), 5601 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */ 5602 SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), 5603 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J), 5604 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M), 5605 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG), 5606 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG), 5607 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC), 5608 {} 5609}; 5610 5611static struct alc_config_preset alc882_presets[] = { 5612 [ALC882_3ST_DIG] = { 5613 .mixers = { alc882_base_mixer }, 5614 .init_verbs = { alc882_init_verbs }, 5615 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 5616 .dac_nids = alc882_dac_nids, 5617 .dig_out_nid = ALC882_DIGOUT_NID, 5618 .dig_in_nid = ALC882_DIGIN_NID, 5619 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes), 5620 .channel_mode = alc882_ch_modes, 5621 .need_dac_fix = 1, 5622 .input_mux = &alc882_capture_source, 5623 }, 5624 [ALC882_6ST_DIG] = { 5625 .mixers = { alc882_base_mixer, alc882_chmode_mixer }, 5626 .init_verbs = { alc882_init_verbs }, 5627 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 5628 .dac_nids = alc882_dac_nids, 5629 .dig_out_nid = ALC882_DIGOUT_NID, 5630 .dig_in_nid = ALC882_DIGIN_NID, 5631 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes), 5632 .channel_mode = alc882_sixstack_modes, 5633 .input_mux = &alc882_capture_source, 5634 }, 5635 [ALC882_ARIMA] = { 5636 .mixers = { alc882_base_mixer, alc882_chmode_mixer }, 5637 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs }, 5638 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 5639 .dac_nids = alc882_dac_nids, 5640 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes), 5641 .channel_mode = alc882_sixstack_modes, 5642 .input_mux = &alc882_capture_source, 5643 }, 5644 [ALC882_W2JC] = { 5645 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer }, 5646 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs, 5647 alc880_gpio1_init_verbs }, 5648 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 5649 .dac_nids = alc882_dac_nids, 5650 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), 5651 .channel_mode = alc880_threestack_modes, 5652 .need_dac_fix = 1, 5653 .input_mux = &alc882_capture_source, 5654 .dig_out_nid = ALC882_DIGOUT_NID, 5655 }, 5656 [ALC885_MBP3] = { 5657 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer }, 5658 .init_verbs = { alc885_mbp3_init_verbs, 5659 alc880_gpio1_init_verbs }, 5660 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 5661 .dac_nids = alc882_dac_nids, 5662 .channel_mode = alc885_mbp_6ch_modes, 5663 .num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes), 5664 .input_mux = &alc882_capture_source, 5665 .dig_out_nid = ALC882_DIGOUT_NID, 5666 .dig_in_nid = ALC882_DIGIN_NID, 5667 .unsol_event = alc885_mbp3_unsol_event, 5668 .init_hook = alc885_mbp3_automute, 5669 }, 5670 [ALC885_MACPRO] = { 5671 .mixers = { alc882_macpro_mixer }, 5672 .init_verbs = { alc882_macpro_init_verbs }, 5673 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 5674 .dac_nids = alc882_dac_nids, 5675 .dig_out_nid = ALC882_DIGOUT_NID, 5676 .dig_in_nid = ALC882_DIGIN_NID, 5677 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes), 5678 .channel_mode = alc882_ch_modes, 5679 .input_mux = &alc882_capture_source, 5680 .init_hook = alc885_macpro_init_hook, 5681 }, 5682 [ALC885_IMAC24] = { 5683 .mixers = { alc885_imac24_mixer }, 5684 .init_verbs = { alc885_imac24_init_verbs }, 5685 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 5686 .dac_nids = alc882_dac_nids, 5687 .dig_out_nid = ALC882_DIGOUT_NID, 5688 .dig_in_nid = ALC882_DIGIN_NID, 5689 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes), 5690 .channel_mode = alc882_ch_modes, 5691 .input_mux = &alc882_capture_source, 5692 .unsol_event = alc885_imac24_unsol_event, 5693 .init_hook = alc885_imac24_init_hook, 5694 }, 5695 [ALC882_TARGA] = { 5696 .mixers = { alc882_targa_mixer, alc882_chmode_mixer, 5697 alc882_capture_mixer }, 5698 .init_verbs = { alc882_init_verbs, alc882_targa_verbs}, 5699 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 5700 .dac_nids = alc882_dac_nids, 5701 .dig_out_nid = ALC882_DIGOUT_NID, 5702 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids), 5703 .adc_nids = alc882_adc_nids, 5704 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes), 5705 .channel_mode = alc882_3ST_6ch_modes, 5706 .need_dac_fix = 1, 5707 .input_mux = &alc882_capture_source, 5708 .unsol_event = alc882_targa_unsol_event, 5709 .init_hook = alc882_targa_automute, 5710 }, 5711 [ALC882_ASUS_A7J] = { 5712 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer, 5713 alc882_capture_mixer }, 5714 .init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs}, 5715 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 5716 .dac_nids = alc882_dac_nids, 5717 .dig_out_nid = ALC882_DIGOUT_NID, 5718 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids), 5719 .adc_nids = alc882_adc_nids, 5720 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes), 5721 .channel_mode = alc882_3ST_6ch_modes, 5722 .need_dac_fix = 1, 5723 .input_mux = &alc882_capture_source, 5724 }, 5725 [ALC882_ASUS_A7M] = { 5726 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer }, 5727 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs, 5728 alc880_gpio1_init_verbs, 5729 alc882_asus_a7m_verbs }, 5730 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 5731 .dac_nids = alc882_dac_nids, 5732 .dig_out_nid = ALC882_DIGOUT_NID, 5733 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), 5734 .channel_mode = alc880_threestack_modes, 5735 .need_dac_fix = 1, 5736 .input_mux = &alc882_capture_source, 5737 }, 5738}; 5739 5740 5741/* 5742 * Pin config fixes 5743 */ 5744enum { 5745 PINFIX_ABIT_AW9D_MAX 5746}; 5747 5748static struct alc_pincfg alc882_abit_aw9d_pinfix[] = { 5749 { 0x15, 0x01080104 }, /* side */ 5750 { 0x16, 0x01011012 }, /* rear */ 5751 { 0x17, 0x01016011 }, /* clfe */ 5752 { } 5753}; 5754 5755static const struct alc_pincfg *alc882_pin_fixes[] = { 5756 [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix, 5757}; 5758 5759static struct snd_pci_quirk alc882_pinfix_tbl[] = { 5760 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX), 5761 {} 5762}; 5763 5764/* 5765 * BIOS auto configuration 5766 */ 5767static void alc882_auto_set_output_and_unmute(struct hda_codec *codec, 5768 hda_nid_t nid, int pin_type, 5769 int dac_idx) 5770{ 5771 /* set as output */ 5772 struct alc_spec *spec = codec->spec; 5773 int idx; 5774 5775 if (spec->multiout.dac_nids[dac_idx] == 0x25) 5776 idx = 4; 5777 else 5778 idx = spec->multiout.dac_nids[dac_idx] - 2; 5779 5780 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 5781 pin_type); 5782 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, 5783 AMP_OUT_UNMUTE); 5784 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx); 5785 5786} 5787 5788static void alc882_auto_init_multi_out(struct hda_codec *codec) 5789{ 5790 struct alc_spec *spec = codec->spec; 5791 int i; 5792 5793 alc_subsystem_id(codec, 0x15, 0x1b, 0x14); 5794 for (i = 0; i <= HDA_SIDE; i++) { 5795 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 5796 int pin_type = get_pin_type(spec->autocfg.line_out_type); 5797 if (nid) 5798 alc882_auto_set_output_and_unmute(codec, nid, pin_type, 5799 i); 5800 } 5801} 5802 5803static void alc882_auto_init_hp_out(struct hda_codec *codec) 5804{ 5805 struct alc_spec *spec = codec->spec; 5806 hda_nid_t pin; 5807 5808 pin = spec->autocfg.hp_pins[0]; 5809 if (pin) /* connect to front */ 5810 /* use dac 0 */ 5811 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); 5812} 5813 5814#define alc882_is_input_pin(nid) alc880_is_input_pin(nid) 5815#define ALC882_PIN_CD_NID ALC880_PIN_CD_NID 5816 5817static void alc882_auto_init_analog_input(struct hda_codec *codec) 5818{ 5819 struct alc_spec *spec = codec->spec; 5820 int i; 5821 5822 for (i = 0; i < AUTO_PIN_LAST; i++) { 5823 hda_nid_t nid = spec->autocfg.input_pins[i]; 5824 if (alc882_is_input_pin(nid)) { 5825 snd_hda_codec_write(codec, nid, 0, 5826 AC_VERB_SET_PIN_WIDGET_CONTROL, 5827 i <= AUTO_PIN_FRONT_MIC ? 5828 PIN_VREF80 : PIN_IN); 5829 if (nid != ALC882_PIN_CD_NID) 5830 snd_hda_codec_write(codec, nid, 0, 5831 AC_VERB_SET_AMP_GAIN_MUTE, 5832 AMP_OUT_MUTE); 5833 } 5834 } 5835} 5836 5837/* add mic boosts if needed */ 5838static int alc_auto_add_mic_boost(struct hda_codec *codec) 5839{ 5840 struct alc_spec *spec = codec->spec; 5841 int err; 5842 hda_nid_t nid; 5843 5844 nid = spec->autocfg.input_pins[AUTO_PIN_MIC]; 5845 if (nid) { 5846 err = add_control(spec, ALC_CTL_WIDGET_VOL, 5847 "Mic Boost", 5848 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT)); 5849 if (err < 0) 5850 return err; 5851 } 5852 nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC]; 5853 if (nid) { 5854 err = add_control(spec, ALC_CTL_WIDGET_VOL, 5855 "Front Mic Boost", 5856 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT)); 5857 if (err < 0) 5858 return err; 5859 } 5860 return 0; 5861} 5862 5863/* almost identical with ALC880 parser... */ 5864static int alc882_parse_auto_config(struct hda_codec *codec) 5865{ 5866 struct alc_spec *spec = codec->spec; 5867 int err = alc880_parse_auto_config(codec); 5868 5869 if (err < 0) 5870 return err; 5871 else if (!err) 5872 return 0; /* no config found */ 5873 5874 err = alc_auto_add_mic_boost(codec); 5875 if (err < 0) 5876 return err; 5877 5878 /* hack - override the init verbs */ 5879 spec->init_verbs[0] = alc882_auto_init_verbs; 5880 5881 return 1; /* config found */ 5882} 5883 5884/* additional initialization for auto-configuration model */ 5885static void alc882_auto_init(struct hda_codec *codec) 5886{ 5887 alc882_auto_init_multi_out(codec); 5888 alc882_auto_init_hp_out(codec); 5889 alc882_auto_init_analog_input(codec); 5890} 5891 5892static int patch_alc882(struct hda_codec *codec) 5893{ 5894 struct alc_spec *spec; 5895 int err, board_config; 5896 5897 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 5898 if (spec == NULL) 5899 return -ENOMEM; 5900 5901 codec->spec = spec; 5902 5903 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST, 5904 alc882_models, 5905 alc882_cfg_tbl); 5906 5907 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) { 5908 /* Pick up systems that don't supply PCI SSID */ 5909 switch (codec->subsystem_id) { 5910 case 0x106b0c00: /* Mac Pro */ 5911 board_config = ALC885_MACPRO; 5912 break; 5913 case 0x106b1000: /* iMac 24 */ 5914 board_config = ALC885_IMAC24; 5915 break; 5916 case 0x106b2c00: /* Macbook Pro rev3 */ 5917 board_config = ALC885_MBP3; 5918 break; 5919 default: 5920 printk(KERN_INFO "hda_codec: Unknown model for ALC882, " 5921 "trying auto-probe from BIOS...\n"); 5922 board_config = ALC882_AUTO; 5923 } 5924 } 5925 5926 alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes); 5927 5928 if (board_config == ALC882_AUTO) { 5929 /* automatic parse from the BIOS config */ 5930 err = alc882_parse_auto_config(codec); 5931 if (err < 0) { 5932 alc_free(codec); 5933 return err; 5934 } else if (!err) { 5935 printk(KERN_INFO 5936 "hda_codec: Cannot set up configuration " 5937 "from BIOS. Using base mode...\n"); 5938 board_config = ALC882_3ST_DIG; 5939 } 5940 } 5941 5942 if (board_config != ALC882_AUTO) 5943 setup_preset(spec, &alc882_presets[board_config]); 5944 5945 spec->stream_name_analog = "ALC882 Analog"; 5946 spec->stream_analog_playback = &alc882_pcm_analog_playback; 5947 spec->stream_analog_capture = &alc882_pcm_analog_capture; 5948 5949 spec->stream_name_digital = "ALC882 Digital"; 5950 spec->stream_digital_playback = &alc882_pcm_digital_playback; 5951 spec->stream_digital_capture = &alc882_pcm_digital_capture; 5952 5953 if (!spec->adc_nids && spec->input_mux) { 5954 /* check whether NID 0x07 is valid */ 5955 unsigned int wcap = get_wcaps(codec, 0x07); 5956 /* get type */ 5957 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; 5958 if (wcap != AC_WID_AUD_IN) { 5959 spec->adc_nids = alc882_adc_nids_alt; 5960 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt); 5961 spec->mixers[spec->num_mixers] = 5962 alc882_capture_alt_mixer; 5963 spec->num_mixers++; 5964 } else { 5965 spec->adc_nids = alc882_adc_nids; 5966 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids); 5967 spec->mixers[spec->num_mixers] = alc882_capture_mixer; 5968 spec->num_mixers++; 5969 } 5970 } 5971 5972 codec->patch_ops = alc_patch_ops; 5973 if (board_config == ALC882_AUTO) 5974 spec->init_hook = alc882_auto_init; 5975#ifdef CONFIG_SND_HDA_POWER_SAVE 5976 if (!spec->loopback.amplist) 5977 spec->loopback.amplist = alc882_loopbacks; 5978#endif 5979 5980 return 0; 5981} 5982 5983/* 5984 * ALC883 support 5985 * 5986 * ALC883 is almost identical with ALC880 but has cleaner and more flexible 5987 * configuration. Each pin widget can choose any input DACs and a mixer. 5988 * Each ADC is connected from a mixer of all inputs. This makes possible 5989 * 6-channel independent captures. 5990 * 5991 * In addition, an independent DAC for the multi-playback (not used in this 5992 * driver yet). 5993 */ 5994#define ALC883_DIGOUT_NID 0x06 5995#define ALC883_DIGIN_NID 0x0a 5996 5997static hda_nid_t alc883_dac_nids[4] = { 5998 /* front, rear, clfe, rear_surr */ 5999 0x02, 0x04, 0x03, 0x05 6000}; 6001 6002static hda_nid_t alc883_adc_nids[2] = { 6003 /* ADC1-2 */ 6004 0x08, 0x09, 6005}; 6006 6007/* input MUX */ 6008/* FIXME: should be a matrix-type input source selection */ 6009 6010static struct hda_input_mux alc883_capture_source = { 6011 .num_items = 4, 6012 .items = { 6013 { "Mic", 0x0 }, 6014 { "Front Mic", 0x1 }, 6015 { "Line", 0x2 }, 6016 { "CD", 0x4 }, 6017 }, 6018}; 6019 6020static struct hda_input_mux alc883_lenovo_101e_capture_source = { 6021 .num_items = 2, 6022 .items = { 6023 { "Mic", 0x1 }, 6024 { "Line", 0x2 }, 6025 }, 6026}; 6027 6028static struct hda_input_mux alc883_lenovo_nb0763_capture_source = { 6029 .num_items = 4, 6030 .items = { 6031 { "Mic", 0x0 }, 6032 { "iMic", 0x1 }, 6033 { "Line", 0x2 }, 6034 { "CD", 0x4 }, 6035 }, 6036}; 6037 6038#define alc883_mux_enum_info alc_mux_enum_info 6039#define alc883_mux_enum_get alc_mux_enum_get 6040 6041static int alc883_mux_enum_put(struct snd_kcontrol *kcontrol, 6042 struct snd_ctl_elem_value *ucontrol) 6043{ 6044 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 6045 struct alc_spec *spec = codec->spec; 6046 const struct hda_input_mux *imux = spec->input_mux; 6047 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 6048 static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 }; 6049 hda_nid_t nid = capture_mixers[adc_idx]; 6050 unsigned int *cur_val = &spec->cur_mux[adc_idx]; 6051 unsigned int i, idx; 6052 6053 idx = ucontrol->value.enumerated.item[0]; 6054 if (idx >= imux->num_items) 6055 idx = imux->num_items - 1; 6056 if (*cur_val == idx) 6057 return 0; 6058 for (i = 0; i < imux->num_items; i++) { 6059 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE; 6060 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 6061 imux->items[i].index, 6062 HDA_AMP_MUTE, v); 6063 } 6064 *cur_val = idx; 6065 return 1; 6066} 6067 6068/* 6069 * 2ch mode 6070 */ 6071static struct hda_channel_mode alc883_3ST_2ch_modes[1] = { 6072 { 2, NULL } 6073}; 6074 6075/* 6076 * 2ch mode 6077 */ 6078static struct hda_verb alc883_3ST_ch2_init[] = { 6079 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 6080 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 6081 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 6082 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 6083 { } /* end */ 6084}; 6085 6086/* 6087 * 6ch mode 6088 */ 6089static struct hda_verb alc883_3ST_ch6_init[] = { 6090 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 6091 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 6092 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, 6093 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 6094 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 6095 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 6096 { } /* end */ 6097}; 6098 6099static struct hda_channel_mode alc883_3ST_6ch_modes[2] = { 6100 { 2, alc883_3ST_ch2_init }, 6101 { 6, alc883_3ST_ch6_init }, 6102}; 6103 6104/* 6105 * 6ch mode 6106 */ 6107static struct hda_verb alc883_sixstack_ch6_init[] = { 6108 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 6109 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 6110 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 6111 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 6112 { } /* end */ 6113}; 6114 6115/* 6116 * 8ch mode 6117 */ 6118static struct hda_verb alc883_sixstack_ch8_init[] = { 6119 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 6120 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 6121 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 6122 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 6123 { } /* end */ 6124}; 6125 6126static struct hda_channel_mode alc883_sixstack_modes[2] = { 6127 { 6, alc883_sixstack_ch6_init }, 6128 { 8, alc883_sixstack_ch8_init }, 6129}; 6130 6131static struct hda_verb alc883_medion_eapd_verbs[] = { 6132 /* eanable EAPD on medion laptop */ 6133 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 6134 {0x20, AC_VERB_SET_PROC_COEF, 0x3070}, 6135 { } 6136}; 6137 6138/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 6139 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b 6140 */ 6141 6142static struct snd_kcontrol_new alc883_base_mixer[] = { 6143 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 6144 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 6145 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 6146 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 6147 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 6148 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 6149 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 6150 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 6151 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 6152 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 6153 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 6154 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 6155 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 6156 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 6157 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 6158 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 6159 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 6160 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 6161 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 6162 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 6163 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 6164 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 6165 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 6166 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 6167 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 6168 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), 6169 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), 6170 { 6171 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 6172 /* .name = "Capture Source", */ 6173 .name = "Input Source", 6174 .count = 2, 6175 .info = alc883_mux_enum_info, 6176 .get = alc883_mux_enum_get, 6177 .put = alc883_mux_enum_put, 6178 }, 6179 { } /* end */ 6180}; 6181 6182static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = { 6183 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 6184 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 6185 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 6186 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 6187 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 6188 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 6189 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 6190 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 6191 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 6192 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 6193 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 6194 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 6195 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 6196 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 6197 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 6198 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 6199 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 6200 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), 6201 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), 6202 { 6203 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 6204 /* .name = "Capture Source", */ 6205 .name = "Input Source", 6206 .count = 2, 6207 .info = alc883_mux_enum_info, 6208 .get = alc883_mux_enum_get, 6209 .put = alc883_mux_enum_put, 6210 }, 6211 { } /* end */ 6212}; 6213 6214static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = { 6215 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 6216 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 6217 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 6218 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 6219 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 6220 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 6221 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 6222 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 6223 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 6224 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 6225 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 6226 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 6227 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 6228 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 6229 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 6230 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 6231 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 6232 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 6233 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 6234 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 6235 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 6236 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 6237 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 6238 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), 6239 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), 6240 { 6241 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 6242 /* .name = "Capture Source", */ 6243 .name = "Input Source", 6244 .count = 2, 6245 .info = alc883_mux_enum_info, 6246 .get = alc883_mux_enum_get, 6247 .put = alc883_mux_enum_put, 6248 }, 6249 { } /* end */ 6250}; 6251 6252static struct snd_kcontrol_new alc883_fivestack_mixer[] = { 6253 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 6254 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 6255 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 6256 HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT), 6257 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 6258 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 6259 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x16, 1, 0x0, HDA_OUTPUT), 6260 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT), 6261 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 6262 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 6263 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 6264 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 6265 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 6266 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 6267 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 6268 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 6269 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 6270 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 6271 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 6272 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 6273 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 6274 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 6275 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 6276 6277 { 6278 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 6279 /* .name = "Capture Source", */ 6280 .name = "Input Source", 6281 .count = 1, 6282 .info = alc883_mux_enum_info, 6283 .get = alc883_mux_enum_get, 6284 .put = alc883_mux_enum_put, 6285 }, 6286 { } /* end */ 6287}; 6288 6289static struct snd_kcontrol_new alc883_tagra_mixer[] = { 6290 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 6291 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 6292 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 6293 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 6294 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 6295 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 6296 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 6297 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 6298 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 6299 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 6300 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 6301 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 6302 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 6303 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 6304 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 6305 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 6306 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 6307 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 6308 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), 6309 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), 6310 { 6311 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 6312 /* .name = "Capture Source", */ 6313 .name = "Input Source", 6314 .count = 2, 6315 .info = alc883_mux_enum_info, 6316 .get = alc883_mux_enum_get, 6317 .put = alc883_mux_enum_put, 6318 }, 6319 { } /* end */ 6320}; 6321 6322static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = { 6323 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 6324 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 6325 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 6326 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 6327 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 6328 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 6329 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 6330 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 6331 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 6332 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 6333 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), 6334 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), 6335 { 6336 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 6337 /* .name = "Capture Source", */ 6338 .name = "Input Source", 6339 .count = 2, 6340 .info = alc883_mux_enum_info, 6341 .get = alc883_mux_enum_get, 6342 .put = alc883_mux_enum_put, 6343 }, 6344 { } /* end */ 6345}; 6346 6347static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = { 6348 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 6349 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 6350 HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 6351 HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT), 6352 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 6353 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 6354 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 6355 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 6356 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 6357 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 6358 { 6359 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 6360 /* .name = "Capture Source", */ 6361 .name = "Input Source", 6362 .count = 1, 6363 .info = alc883_mux_enum_info, 6364 .get = alc883_mux_enum_get, 6365 .put = alc883_mux_enum_put, 6366 }, 6367 { } /* end */ 6368}; 6369 6370static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = { 6371 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 6372 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT), 6373 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 6374 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 6375 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 6376 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 6377 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 6378 HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT), 6379 HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT), 6380 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 6381 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 6382 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), 6383 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), 6384 { 6385 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 6386 /* .name = "Capture Source", */ 6387 .name = "Input Source", 6388 .count = 2, 6389 .info = alc883_mux_enum_info, 6390 .get = alc883_mux_enum_get, 6391 .put = alc883_mux_enum_put, 6392 }, 6393 { } /* end */ 6394}; 6395 6396static struct snd_kcontrol_new alc883_medion_md2_mixer[] = { 6397 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 6398 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 6399 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT), 6400 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 6401 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 6402 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 6403 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 6404 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 6405 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 6406 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 6407 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 6408 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), 6409 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), 6410 { 6411 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 6412 /* .name = "Capture Source", */ 6413 .name = "Input Source", 6414 .count = 2, 6415 .info = alc883_mux_enum_info, 6416 .get = alc883_mux_enum_get, 6417 .put = alc883_mux_enum_put, 6418 }, 6419 { } /* end */ 6420}; 6421 6422static struct snd_kcontrol_new alc888_6st_hp_mixer[] = { 6423 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 6424 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 6425 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT), 6426 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT), 6427 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT), 6428 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT), 6429 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT), 6430 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT), 6431 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 6432 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 6433 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 6434 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 6435 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 6436 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 6437 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 6438 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 6439 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 6440 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 6441 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 6442 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 6443 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 6444 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 6445 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 6446 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 6447 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 6448 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), 6449 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), 6450 { 6451 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 6452 /* .name = "Capture Source", */ 6453 .name = "Input Source", 6454 .count = 2, 6455 .info = alc883_mux_enum_info, 6456 .get = alc883_mux_enum_get, 6457 .put = alc883_mux_enum_put, 6458 }, 6459 { } /* end */ 6460}; 6461 6462static struct snd_kcontrol_new alc888_3st_hp_mixer[] = { 6463 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 6464 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 6465 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT), 6466 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT), 6467 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT), 6468 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT), 6469 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT), 6470 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT), 6471 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 6472 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 6473 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 6474 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 6475 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 6476 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 6477 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 6478 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 6479 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 6480 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 6481 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 6482 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 6483 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 6484 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 6485 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 6486 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), 6487 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), 6488 { 6489 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 6490 /* .name = "Capture Source", */ 6491 .name = "Input Source", 6492 .count = 2, 6493 .info = alc883_mux_enum_info, 6494 .get = alc883_mux_enum_get, 6495 .put = alc883_mux_enum_put, 6496 }, 6497 { } /* end */ 6498}; 6499 6500static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = { 6501 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 6502 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 6503 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 6504 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 6505 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 6506 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 6507 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 6508 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 6509 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 6510 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 6511 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), 6512 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), 6513 { 6514 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 6515 /* .name = "Capture Source", */ 6516 .name = "Input Source", 6517 .count = 2, 6518 .info = alc883_mux_enum_info, 6519 .get = alc883_mux_enum_get, 6520 .put = alc883_mux_enum_put, 6521 }, 6522 { } /* end */ 6523}; 6524 6525static struct snd_kcontrol_new alc883_chmode_mixer[] = { 6526 { 6527 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 6528 .name = "Channel Mode", 6529 .info = alc_ch_mode_info, 6530 .get = alc_ch_mode_get, 6531 .put = alc_ch_mode_put, 6532 }, 6533 { } /* end */ 6534}; 6535 6536static struct hda_verb alc883_init_verbs[] = { 6537 /* ADC1: mute amp left and right */ 6538 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6539 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 6540 /* ADC2: mute amp left and right */ 6541 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6542 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 6543 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 6544 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6545 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6546 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6547 /* Rear mixer */ 6548 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6549 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6550 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6551 /* CLFE mixer */ 6552 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6553 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6554 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6555 /* Side mixer */ 6556 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6557 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6558 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6559 6560 /* mute analog input loopbacks */ 6561 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6562 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6563 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 6564 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 6565 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 6566 6567 /* Front Pin: output 0 (0x0c) */ 6568 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6569 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6570 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 6571 /* Rear Pin: output 1 (0x0d) */ 6572 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6573 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6574 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 6575 /* CLFE Pin: output 2 (0x0e) */ 6576 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6577 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6578 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, 6579 /* Side Pin: output 3 (0x0f) */ 6580 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6581 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6582 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, 6583 /* Mic (rear) pin: input vref at 80% */ 6584 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 6585 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 6586 /* Front Mic pin: input vref at 80% */ 6587 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 6588 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 6589 /* Line In pin: input */ 6590 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 6591 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 6592 /* Line-2 In: Headphone output (output 0 - 0x0c) */ 6593 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6594 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6595 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 6596 /* CD pin widget for input */ 6597 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 6598 6599 /* FIXME: use matrix-type input source selection */ 6600 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 6601 /* Input mixer2 */ 6602 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6603 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 6604 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 6605 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, 6606 /* Input mixer3 */ 6607 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6608 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 6609 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 6610 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, 6611 { } 6612}; 6613 6614static struct hda_verb alc883_tagra_verbs[] = { 6615 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6616 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 6617 6618 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6619 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6620 6621 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ 6622 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */ 6623 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 6624 6625 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 6626 {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, 6627 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03}, 6628 {0x01, AC_VERB_SET_GPIO_DATA, 0x03}, 6629 6630 { } /* end */ 6631}; 6632 6633static struct hda_verb alc883_lenovo_101e_verbs[] = { 6634 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 6635 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN}, 6636 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN}, 6637 { } /* end */ 6638}; 6639 6640static struct hda_verb alc883_lenovo_nb0763_verbs[] = { 6641 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 6642 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6643 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 6644 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6645 { } /* end */ 6646}; 6647 6648static struct hda_verb alc888_lenovo_ms7195_verbs[] = { 6649 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6650 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 6651 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 6652 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN}, 6653 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 6654 { } /* end */ 6655}; 6656 6657static struct hda_verb alc883_haier_w66_verbs[] = { 6658 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6659 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 6660 6661 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6662 6663 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 6664 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6665 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 6666 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6667 { } /* end */ 6668}; 6669 6670static struct hda_verb alc888_6st_hp_verbs[] = { 6671 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */ 6672 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Rear : output 2 (0x0e) */ 6673 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* CLFE : output 1 (0x0d) */ 6674 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, /* Side : output 3 (0x0f) */ 6675 { } 6676}; 6677 6678static struct hda_verb alc888_3st_hp_verbs[] = { 6679 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */ 6680 {0x18, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */ 6681 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */ 6682 { } 6683}; 6684 6685static struct hda_verb alc888_3st_hp_2ch_init[] = { 6686 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 6687 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 6688 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 6689 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 6690 { } 6691}; 6692 6693static struct hda_verb alc888_3st_hp_6ch_init[] = { 6694 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 6695 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 6696 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 6697 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 6698 { } 6699}; 6700 6701static struct hda_channel_mode alc888_3st_hp_modes[2] = { 6702 { 2, alc888_3st_hp_2ch_init }, 6703 { 6, alc888_3st_hp_6ch_init }, 6704}; 6705 6706/* toggle front-jack and RCA according to the hp-jack state */ 6707static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec) 6708{ 6709 unsigned int present; 6710 6711 present = snd_hda_codec_read(codec, 0x1b, 0, 6712 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 6713 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 6714 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 6715 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 6716 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 6717} 6718 6719/* toggle RCA according to the front-jack state */ 6720static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec) 6721{ 6722 unsigned int present; 6723 6724 present = snd_hda_codec_read(codec, 0x14, 0, 6725 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 6726 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 6727 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 6728} 6729 6730static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec, 6731 unsigned int res) 6732{ 6733 if ((res >> 26) == ALC880_HP_EVENT) 6734 alc888_lenovo_ms7195_front_automute(codec); 6735 if ((res >> 26) == ALC880_FRONT_EVENT) 6736 alc888_lenovo_ms7195_rca_automute(codec); 6737} 6738 6739static struct hda_verb alc883_medion_md2_verbs[] = { 6740 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6741 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 6742 6743 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6744 6745 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 6746 { } /* end */ 6747}; 6748 6749/* toggle speaker-output according to the hp-jack state */ 6750static void alc883_medion_md2_automute(struct hda_codec *codec) 6751{ 6752 unsigned int present; 6753 6754 present = snd_hda_codec_read(codec, 0x14, 0, 6755 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 6756 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 6757 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 6758} 6759 6760static void alc883_medion_md2_unsol_event(struct hda_codec *codec, 6761 unsigned int res) 6762{ 6763 if ((res >> 26) == ALC880_HP_EVENT) 6764 alc883_medion_md2_automute(codec); 6765} 6766 6767/* toggle speaker-output according to the hp-jack state */ 6768static void alc883_tagra_automute(struct hda_codec *codec) 6769{ 6770 unsigned int present; 6771 unsigned char bits; 6772 6773 present = snd_hda_codec_read(codec, 0x14, 0, 6774 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 6775 bits = present ? HDA_AMP_MUTE : 0; 6776 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0, 6777 HDA_AMP_MUTE, bits); 6778 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA, 6779 present ? 1 : 3); 6780} 6781 6782static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res) 6783{ 6784 if ((res >> 26) == ALC880_HP_EVENT) 6785 alc883_tagra_automute(codec); 6786} 6787 6788static void alc883_haier_w66_automute(struct hda_codec *codec) 6789{ 6790 unsigned int present; 6791 unsigned char bits; 6792 6793 present = snd_hda_codec_read(codec, 0x1b, 0, 6794 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 6795 bits = present ? 0x80 : 0; 6796 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 6797 0x80, bits); 6798} 6799 6800static void alc883_haier_w66_unsol_event(struct hda_codec *codec, 6801 unsigned int res) 6802{ 6803 if ((res >> 26) == ALC880_HP_EVENT) 6804 alc883_haier_w66_automute(codec); 6805} 6806 6807static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec) 6808{ 6809 unsigned int present; 6810 unsigned char bits; 6811 6812 present = snd_hda_codec_read(codec, 0x14, 0, 6813 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 6814 bits = present ? HDA_AMP_MUTE : 0; 6815 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 6816 HDA_AMP_MUTE, bits); 6817} 6818 6819static void alc883_lenovo_101e_all_automute(struct hda_codec *codec) 6820{ 6821 unsigned int present; 6822 unsigned char bits; 6823 6824 present = snd_hda_codec_read(codec, 0x1b, 0, 6825 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 6826 bits = present ? HDA_AMP_MUTE : 0; 6827 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 6828 HDA_AMP_MUTE, bits); 6829 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 6830 HDA_AMP_MUTE, bits); 6831} 6832 6833static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec, 6834 unsigned int res) 6835{ 6836 if ((res >> 26) == ALC880_HP_EVENT) 6837 alc883_lenovo_101e_all_automute(codec); 6838 if ((res >> 26) == ALC880_FRONT_EVENT) 6839 alc883_lenovo_101e_ispeaker_automute(codec); 6840} 6841 6842/* toggle speaker-output according to the hp-jack state */ 6843static void alc883_acer_aspire_automute(struct hda_codec *codec) 6844{ 6845 unsigned int present; 6846 6847 present = snd_hda_codec_read(codec, 0x14, 0, 6848 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 6849 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 6850 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 6851 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0, 6852 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 6853} 6854 6855static void alc883_acer_aspire_unsol_event(struct hda_codec *codec, 6856 unsigned int res) 6857{ 6858 if ((res >> 26) == ALC880_HP_EVENT) 6859 alc883_acer_aspire_automute(codec); 6860} 6861 6862static struct hda_verb alc883_acer_eapd_verbs[] = { 6863 /* HP Pin: output 0 (0x0c) */ 6864 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6865 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6866 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 6867 /* Front Pin: output 0 (0x0c) */ 6868 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6869 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 6870 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6871 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, 6872 /* eanable EAPD on medion laptop */ 6873 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 6874 {0x20, AC_VERB_SET_PROC_COEF, 0x3050}, 6875 /* enable unsolicited event */ 6876 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 6877 { } 6878}; 6879 6880/* 6881 * generic initialization of ADC, input mixers and output mixers 6882 */ 6883static struct hda_verb alc883_auto_init_verbs[] = { 6884 /* 6885 * Unmute ADC0-2 and set the default input to mic-in 6886 */ 6887 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 6888 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6889 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 6890 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6891 6892 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 6893 * mixer widget 6894 * Note: PASD motherboards uses the Line In 2 as the input for 6895 * front panel mic (mic 2) 6896 */ 6897 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 6898 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6899 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6900 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 6901 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 6902 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 6903 6904 /* 6905 * Set up output mixers (0x0c - 0x0f) 6906 */ 6907 /* set vol=0 to output mixers */ 6908 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6909 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6910 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6911 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6912 /* set up input amps for analog loopback */ 6913 /* Amp Indices: DAC = 0, mixer = 1 */ 6914 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6915 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 6916 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6917 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 6918 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6919 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 6920 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6921 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 6922 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6923 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 6924 6925 /* FIXME: use matrix-type input source selection */ 6926 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 6927 /* Input mixer1 */ 6928 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6929 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 6930 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 6931 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */ 6932 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, 6933 /* Input mixer2 */ 6934 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6935 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 6936 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 6937 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */ 6938 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, 6939 6940 { } 6941}; 6942 6943/* capture mixer elements */ 6944static struct snd_kcontrol_new alc883_capture_mixer[] = { 6945 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 6946 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 6947 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), 6948 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), 6949 { 6950 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 6951 /* The multiple "Capture Source" controls confuse alsamixer 6952 * So call somewhat different.. 6953 * FIXME: the controls appear in the "playback" view! 6954 */ 6955 /* .name = "Capture Source", */ 6956 .name = "Input Source", 6957 .count = 2, 6958 .info = alc882_mux_enum_info, 6959 .get = alc882_mux_enum_get, 6960 .put = alc882_mux_enum_put, 6961 }, 6962 { } /* end */ 6963}; 6964 6965#ifdef CONFIG_SND_HDA_POWER_SAVE 6966#define alc883_loopbacks alc880_loopbacks 6967#endif 6968 6969/* pcm configuration: identiacal with ALC880 */ 6970#define alc883_pcm_analog_playback alc880_pcm_analog_playback 6971#define alc883_pcm_analog_capture alc880_pcm_analog_capture 6972#define alc883_pcm_digital_playback alc880_pcm_digital_playback 6973#define alc883_pcm_digital_capture alc880_pcm_digital_capture 6974 6975/* 6976 * configuration and preset 6977 */ 6978static const char *alc883_models[ALC883_MODEL_LAST] = { 6979 [ALC883_3ST_2ch_DIG] = "3stack-dig", 6980 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig", 6981 [ALC883_3ST_6ch] = "3stack-6ch", 6982 [ALC883_6ST_DIG] = "6stack-dig", 6983 [ALC883_TARGA_DIG] = "targa-dig", 6984 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig", 6985 [ALC883_ACER] = "acer", 6986 [ALC883_ACER_ASPIRE] = "acer-aspire", 6987 [ALC883_MEDION] = "medion", 6988 [ALC883_MEDION_MD2] = "medion-md2", 6989 [ALC883_LAPTOP_EAPD] = "laptop-eapd", 6990 [ALC883_LENOVO_101E_2ch] = "lenovo-101e", 6991 [ALC883_LENOVO_NB0763] = "lenovo-nb0763", 6992 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig", 6993 [ALC883_HAIER_W66] = "haier-w66", 6994 [ALC888_6ST_HP] = "6stack-hp", 6995 [ALC888_3ST_HP] = "3stack-hp", 6996 [ALC883_AUTO] = "auto", 6997}; 6998 6999static struct snd_pci_quirk alc883_cfg_tbl[] = { 7000 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG), 7001 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG), 7002 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch), 7003 SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD), 7004 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG), 7005 SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG), 7006 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG), 7007 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG), 7008 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG), 7009 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG), 7010 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG), 7011 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG), 7012 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG), 7013 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG), 7014 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG), 7015 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG), 7016 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG), 7017 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG), 7018 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG), 7019 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG), 7020 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG), 7021 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG), 7022 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG), 7023 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG), 7024 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE), 7025 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE), 7026 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE), 7027 SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER), 7028 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch), 7029 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION), 7030 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD), 7031 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch), 7032 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch), 7033 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763), 7034 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763), 7035 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC888_6ST_HP), 7036 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP), 7037 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP), 7038 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2), 7039 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66), 7040 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763), 7041 {} 7042}; 7043 7044static struct alc_config_preset alc883_presets[] = { 7045 [ALC883_3ST_2ch_DIG] = { 7046 .mixers = { alc883_3ST_2ch_mixer }, 7047 .init_verbs = { alc883_init_verbs }, 7048 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 7049 .dac_nids = alc883_dac_nids, 7050 .dig_out_nid = ALC883_DIGOUT_NID, 7051 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 7052 .adc_nids = alc883_adc_nids, 7053 .dig_in_nid = ALC883_DIGIN_NID, 7054 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 7055 .channel_mode = alc883_3ST_2ch_modes, 7056 .input_mux = &alc883_capture_source, 7057 }, 7058 [ALC883_3ST_6ch_DIG] = { 7059 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, 7060 .init_verbs = { alc883_init_verbs }, 7061 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 7062 .dac_nids = alc883_dac_nids, 7063 .dig_out_nid = ALC883_DIGOUT_NID, 7064 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 7065 .adc_nids = alc883_adc_nids, 7066 .dig_in_nid = ALC883_DIGIN_NID, 7067 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 7068 .channel_mode = alc883_3ST_6ch_modes, 7069 .need_dac_fix = 1, 7070 .input_mux = &alc883_capture_source, 7071 }, 7072 [ALC883_3ST_6ch] = { 7073 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, 7074 .init_verbs = { alc883_init_verbs }, 7075 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 7076 .dac_nids = alc883_dac_nids, 7077 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 7078 .adc_nids = alc883_adc_nids, 7079 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 7080 .channel_mode = alc883_3ST_6ch_modes, 7081 .need_dac_fix = 1, 7082 .input_mux = &alc883_capture_source, 7083 }, 7084 [ALC883_6ST_DIG] = { 7085 .mixers = { alc883_base_mixer, alc883_chmode_mixer }, 7086 .init_verbs = { alc883_init_verbs }, 7087 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 7088 .dac_nids = alc883_dac_nids, 7089 .dig_out_nid = ALC883_DIGOUT_NID, 7090 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 7091 .adc_nids = alc883_adc_nids, 7092 .dig_in_nid = ALC883_DIGIN_NID, 7093 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), 7094 .channel_mode = alc883_sixstack_modes, 7095 .input_mux = &alc883_capture_source, 7096 }, 7097 [ALC883_TARGA_DIG] = { 7098 .mixers = { alc883_tagra_mixer, alc883_chmode_mixer }, 7099 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs}, 7100 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 7101 .dac_nids = alc883_dac_nids, 7102 .dig_out_nid = ALC883_DIGOUT_NID, 7103 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 7104 .adc_nids = alc883_adc_nids, 7105 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 7106 .channel_mode = alc883_3ST_6ch_modes, 7107 .need_dac_fix = 1, 7108 .input_mux = &alc883_capture_source, 7109 .unsol_event = alc883_tagra_unsol_event, 7110 .init_hook = alc883_tagra_automute, 7111 }, 7112 [ALC883_TARGA_2ch_DIG] = { 7113 .mixers = { alc883_tagra_2ch_mixer}, 7114 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs}, 7115 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 7116 .dac_nids = alc883_dac_nids, 7117 .dig_out_nid = ALC883_DIGOUT_NID, 7118 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 7119 .adc_nids = alc883_adc_nids, 7120 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 7121 .channel_mode = alc883_3ST_2ch_modes, 7122 .input_mux = &alc883_capture_source, 7123 .unsol_event = alc883_tagra_unsol_event, 7124 .init_hook = alc883_tagra_automute, 7125 }, 7126 [ALC883_ACER] = { 7127 .mixers = { alc883_base_mixer }, 7128 /* On TravelMate laptops, GPIO 0 enables the internal speaker 7129 * and the headphone jack. Turn this on and rely on the 7130 * standard mute methods whenever the user wants to turn 7131 * these outputs off. 7132 */ 7133 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs }, 7134 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 7135 .dac_nids = alc883_dac_nids, 7136 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 7137 .adc_nids = alc883_adc_nids, 7138 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 7139 .channel_mode = alc883_3ST_2ch_modes, 7140 .input_mux = &alc883_capture_source, 7141 }, 7142 [ALC883_ACER_ASPIRE] = { 7143 .mixers = { alc883_acer_aspire_mixer }, 7144 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs }, 7145 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 7146 .dac_nids = alc883_dac_nids, 7147 .dig_out_nid = ALC883_DIGOUT_NID, 7148 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 7149 .adc_nids = alc883_adc_nids, 7150 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 7151 .channel_mode = alc883_3ST_2ch_modes, 7152 .input_mux = &alc883_capture_source, 7153 .unsol_event = alc883_acer_aspire_unsol_event, 7154 .init_hook = alc883_acer_aspire_automute, 7155 }, 7156 [ALC883_MEDION] = { 7157 .mixers = { alc883_fivestack_mixer, 7158 alc883_chmode_mixer }, 7159 .init_verbs = { alc883_init_verbs, 7160 alc883_medion_eapd_verbs }, 7161 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 7162 .dac_nids = alc883_dac_nids, 7163 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 7164 .adc_nids = alc883_adc_nids, 7165 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), 7166 .channel_mode = alc883_sixstack_modes, 7167 .input_mux = &alc883_capture_source, 7168 }, 7169 [ALC883_MEDION_MD2] = { 7170 .mixers = { alc883_medion_md2_mixer}, 7171 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs}, 7172 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 7173 .dac_nids = alc883_dac_nids, 7174 .dig_out_nid = ALC883_DIGOUT_NID, 7175 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 7176 .adc_nids = alc883_adc_nids, 7177 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 7178 .channel_mode = alc883_3ST_2ch_modes, 7179 .input_mux = &alc883_capture_source, 7180 .unsol_event = alc883_medion_md2_unsol_event, 7181 .init_hook = alc883_medion_md2_automute, 7182 }, 7183 [ALC883_LAPTOP_EAPD] = { 7184 .mixers = { alc883_base_mixer }, 7185 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs }, 7186 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 7187 .dac_nids = alc883_dac_nids, 7188 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 7189 .adc_nids = alc883_adc_nids, 7190 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 7191 .channel_mode = alc883_3ST_2ch_modes, 7192 .input_mux = &alc883_capture_source, 7193 }, 7194 [ALC883_LENOVO_101E_2ch] = { 7195 .mixers = { alc883_lenovo_101e_2ch_mixer}, 7196 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs}, 7197 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 7198 .dac_nids = alc883_dac_nids, 7199 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 7200 .adc_nids = alc883_adc_nids, 7201 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 7202 .channel_mode = alc883_3ST_2ch_modes, 7203 .input_mux = &alc883_lenovo_101e_capture_source, 7204 .unsol_event = alc883_lenovo_101e_unsol_event, 7205 .init_hook = alc883_lenovo_101e_all_automute, 7206 }, 7207 [ALC883_LENOVO_NB0763] = { 7208 .mixers = { alc883_lenovo_nb0763_mixer }, 7209 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs}, 7210 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 7211 .dac_nids = alc883_dac_nids, 7212 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 7213 .adc_nids = alc883_adc_nids, 7214 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 7215 .channel_mode = alc883_3ST_2ch_modes, 7216 .need_dac_fix = 1, 7217 .input_mux = &alc883_lenovo_nb0763_capture_source, 7218 .unsol_event = alc883_medion_md2_unsol_event, 7219 .init_hook = alc883_medion_md2_automute, 7220 }, 7221 [ALC888_LENOVO_MS7195_DIG] = { 7222 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, 7223 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs}, 7224 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 7225 .dac_nids = alc883_dac_nids, 7226 .dig_out_nid = ALC883_DIGOUT_NID, 7227 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 7228 .adc_nids = alc883_adc_nids, 7229 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 7230 .channel_mode = alc883_3ST_6ch_modes, 7231 .need_dac_fix = 1, 7232 .input_mux = &alc883_capture_source, 7233 .unsol_event = alc883_lenovo_ms7195_unsol_event, 7234 .init_hook = alc888_lenovo_ms7195_front_automute, 7235 }, 7236 [ALC883_HAIER_W66] = { 7237 .mixers = { alc883_tagra_2ch_mixer}, 7238 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs}, 7239 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 7240 .dac_nids = alc883_dac_nids, 7241 .dig_out_nid = ALC883_DIGOUT_NID, 7242 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 7243 .adc_nids = alc883_adc_nids, 7244 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 7245 .channel_mode = alc883_3ST_2ch_modes, 7246 .input_mux = &alc883_capture_source, 7247 .unsol_event = alc883_haier_w66_unsol_event, 7248 .init_hook = alc883_haier_w66_automute, 7249 }, 7250 [ALC888_6ST_HP] = { 7251 .mixers = { alc888_6st_hp_mixer, alc883_chmode_mixer }, 7252 .init_verbs = { alc883_init_verbs, alc888_6st_hp_verbs }, 7253 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 7254 .dac_nids = alc883_dac_nids, 7255 .dig_out_nid = ALC883_DIGOUT_NID, 7256 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 7257 .adc_nids = alc883_adc_nids, 7258 .dig_in_nid = ALC883_DIGIN_NID, 7259 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), 7260 .channel_mode = alc883_sixstack_modes, 7261 .input_mux = &alc883_capture_source, 7262 }, 7263 [ALC888_3ST_HP] = { 7264 .mixers = { alc888_3st_hp_mixer, alc883_chmode_mixer }, 7265 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs }, 7266 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 7267 .dac_nids = alc883_dac_nids, 7268 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 7269 .adc_nids = alc883_adc_nids, 7270 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes), 7271 .channel_mode = alc888_3st_hp_modes, 7272 .need_dac_fix = 1, 7273 .input_mux = &alc883_capture_source, 7274 }, 7275}; 7276 7277 7278/* 7279 * BIOS auto configuration 7280 */ 7281static void alc883_auto_set_output_and_unmute(struct hda_codec *codec, 7282 hda_nid_t nid, int pin_type, 7283 int dac_idx) 7284{ 7285 /* set as output */ 7286 struct alc_spec *spec = codec->spec; 7287 int idx; 7288 7289 if (spec->multiout.dac_nids[dac_idx] == 0x25) 7290 idx = 4; 7291 else 7292 idx = spec->multiout.dac_nids[dac_idx] - 2; 7293 7294 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 7295 pin_type); 7296 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, 7297 AMP_OUT_UNMUTE); 7298 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx); 7299 7300} 7301 7302static void alc883_auto_init_multi_out(struct hda_codec *codec) 7303{ 7304 struct alc_spec *spec = codec->spec; 7305 int i; 7306 7307 alc_subsystem_id(codec, 0x15, 0x1b, 0x14); 7308 for (i = 0; i <= HDA_SIDE; i++) { 7309 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 7310 int pin_type = get_pin_type(spec->autocfg.line_out_type); 7311 if (nid) 7312 alc883_auto_set_output_and_unmute(codec, nid, pin_type, 7313 i); 7314 } 7315} 7316 7317static void alc883_auto_init_hp_out(struct hda_codec *codec) 7318{ 7319 struct alc_spec *spec = codec->spec; 7320 hda_nid_t pin; 7321 7322 pin = spec->autocfg.hp_pins[0]; 7323 if (pin) /* connect to front */ 7324 /* use dac 0 */ 7325 alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); 7326} 7327 7328#define alc883_is_input_pin(nid) alc880_is_input_pin(nid) 7329#define ALC883_PIN_CD_NID ALC880_PIN_CD_NID 7330 7331static void alc883_auto_init_analog_input(struct hda_codec *codec) 7332{ 7333 struct alc_spec *spec = codec->spec; 7334 int i; 7335 7336 for (i = 0; i < AUTO_PIN_LAST; i++) { 7337 hda_nid_t nid = spec->autocfg.input_pins[i]; 7338 if (alc883_is_input_pin(nid)) { 7339 snd_hda_codec_write(codec, nid, 0, 7340 AC_VERB_SET_PIN_WIDGET_CONTROL, 7341 (i <= AUTO_PIN_FRONT_MIC ? 7342 PIN_VREF80 : PIN_IN)); 7343 if (nid != ALC883_PIN_CD_NID) 7344 snd_hda_codec_write(codec, nid, 0, 7345 AC_VERB_SET_AMP_GAIN_MUTE, 7346 AMP_OUT_MUTE); 7347 } 7348 } 7349} 7350 7351/* almost identical with ALC880 parser... */ 7352static int alc883_parse_auto_config(struct hda_codec *codec) 7353{ 7354 struct alc_spec *spec = codec->spec; 7355 int err = alc880_parse_auto_config(codec); 7356 7357 if (err < 0) 7358 return err; 7359 else if (!err) 7360 return 0; /* no config found */ 7361 7362 err = alc_auto_add_mic_boost(codec); 7363 if (err < 0) 7364 return err; 7365 7366 /* hack - override the init verbs */ 7367 spec->init_verbs[0] = alc883_auto_init_verbs; 7368 spec->mixers[spec->num_mixers] = alc883_capture_mixer; 7369 spec->num_mixers++; 7370 7371 return 1; /* config found */ 7372} 7373 7374/* additional initialization for auto-configuration model */ 7375static void alc883_auto_init(struct hda_codec *codec) 7376{ 7377 alc883_auto_init_multi_out(codec); 7378 alc883_auto_init_hp_out(codec); 7379 alc883_auto_init_analog_input(codec); 7380} 7381 7382static int patch_alc883(struct hda_codec *codec) 7383{ 7384 struct alc_spec *spec; 7385 int err, board_config; 7386 7387 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 7388 if (spec == NULL) 7389 return -ENOMEM; 7390 7391 codec->spec = spec; 7392 7393 board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST, 7394 alc883_models, 7395 alc883_cfg_tbl); 7396 if (board_config < 0) { 7397 printk(KERN_INFO "hda_codec: Unknown model for ALC883, " 7398 "trying auto-probe from BIOS...\n"); 7399 board_config = ALC883_AUTO; 7400 } 7401 7402 if (board_config == ALC883_AUTO) { 7403 /* automatic parse from the BIOS config */ 7404 err = alc883_parse_auto_config(codec); 7405 if (err < 0) { 7406 alc_free(codec); 7407 return err; 7408 } else if (!err) { 7409 printk(KERN_INFO 7410 "hda_codec: Cannot set up configuration " 7411 "from BIOS. Using base mode...\n"); 7412 board_config = ALC883_3ST_2ch_DIG; 7413 } 7414 } 7415 7416 if (board_config != ALC883_AUTO) 7417 setup_preset(spec, &alc883_presets[board_config]); 7418 7419 spec->stream_name_analog = "ALC883 Analog"; 7420 spec->stream_analog_playback = &alc883_pcm_analog_playback; 7421 spec->stream_analog_capture = &alc883_pcm_analog_capture; 7422 7423 spec->stream_name_digital = "ALC883 Digital"; 7424 spec->stream_digital_playback = &alc883_pcm_digital_playback; 7425 spec->stream_digital_capture = &alc883_pcm_digital_capture; 7426 7427 if (!spec->adc_nids && spec->input_mux) { 7428 spec->adc_nids = alc883_adc_nids; 7429 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids); 7430 } 7431 7432 codec->patch_ops = alc_patch_ops; 7433 if (board_config == ALC883_AUTO) 7434 spec->init_hook = alc883_auto_init; 7435#ifdef CONFIG_SND_HDA_POWER_SAVE 7436 if (!spec->loopback.amplist) 7437 spec->loopback.amplist = alc883_loopbacks; 7438#endif 7439 7440 return 0; 7441} 7442 7443/* 7444 * ALC262 support 7445 */ 7446 7447#define ALC262_DIGOUT_NID ALC880_DIGOUT_NID 7448#define ALC262_DIGIN_NID ALC880_DIGIN_NID 7449 7450#define alc262_dac_nids alc260_dac_nids 7451#define alc262_adc_nids alc882_adc_nids 7452#define alc262_adc_nids_alt alc882_adc_nids_alt 7453 7454#define alc262_modes alc260_modes 7455#define alc262_capture_source alc882_capture_source 7456 7457static struct snd_kcontrol_new alc262_base_mixer[] = { 7458 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7459 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 7460 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 7461 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 7462 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 7463 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 7464 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7465 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7466 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 7467 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 7468 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 7469 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 7470 /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT), 7471 HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */ 7472 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT), 7473 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 7474 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 7475 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT), 7476 { } /* end */ 7477}; 7478 7479static struct snd_kcontrol_new alc262_hippo1_mixer[] = { 7480 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7481 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 7482 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 7483 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 7484 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 7485 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 7486 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7487 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7488 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 7489 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 7490 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 7491 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 7492 /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT), 7493 HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */ 7494 /*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/ 7495 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 7496 { } /* end */ 7497}; 7498 7499static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = { 7500 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7501 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT), 7502 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 7503 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 7504 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT), 7505 7506 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7507 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7508 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 7509 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 7510 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 7511 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 7512 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 7513 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 7514 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 7515 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 7516 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT), 7517 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), 7518 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT), 7519 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT), 7520 { } /* end */ 7521}; 7522 7523static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = { 7524 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7525 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 7526 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 7527 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 7528 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 7529 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT), 7530 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT), 7531 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT), 7532 HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT), 7533 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT), 7534 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT), 7535 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 7536 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 7537 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT), 7538 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), 7539 { } /* end */ 7540}; 7541 7542static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = { 7543 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7544 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7545 HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT), 7546 { } /* end */ 7547}; 7548 7549/* bind hp and internal speaker mute (with plug check) */ 7550static int alc262_sony_master_sw_put(struct snd_kcontrol *kcontrol, 7551 struct snd_ctl_elem_value *ucontrol) 7552{ 7553 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 7554 long *valp = ucontrol->value.integer.value; 7555 int change; 7556 7557 /* change hp mute */ 7558 change = snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0, 7559 HDA_AMP_MUTE, 7560 valp[0] ? 0 : HDA_AMP_MUTE); 7561 change |= snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0, 7562 HDA_AMP_MUTE, 7563 valp[1] ? 0 : HDA_AMP_MUTE); 7564 if (change) { 7565 /* change speaker according to HP jack state */ 7566 struct alc_spec *spec = codec->spec; 7567 unsigned int mute; 7568 if (spec->jack_present) 7569 mute = HDA_AMP_MUTE; 7570 else 7571 mute = snd_hda_codec_amp_read(codec, 0x15, 0, 7572 HDA_OUTPUT, 0); 7573 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 7574 HDA_AMP_MUTE, mute); 7575 } 7576 return change; 7577} 7578 7579static struct snd_kcontrol_new alc262_sony_mixer[] = { 7580 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7581 { 7582 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 7583 .name = "Master Playback Switch", 7584 .info = snd_hda_mixer_amp_switch_info, 7585 .get = snd_hda_mixer_amp_switch_get, 7586 .put = alc262_sony_master_sw_put, 7587 .private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT), 7588 }, 7589 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7590 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7591 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 7592 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 7593 { } /* end */ 7594}; 7595 7596static struct snd_kcontrol_new alc262_benq_t31_mixer[] = { 7597 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7598 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 7599 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 7600 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7601 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7602 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 7603 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 7604 { } /* end */ 7605}; 7606 7607#define alc262_capture_mixer alc882_capture_mixer 7608#define alc262_capture_alt_mixer alc882_capture_alt_mixer 7609 7610/* 7611 * generic initialization of ADC, input mixers and output mixers 7612 */ 7613static struct hda_verb alc262_init_verbs[] = { 7614 /* 7615 * Unmute ADC0-2 and set the default input to mic-in 7616 */ 7617 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 7618 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7619 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 7620 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7621 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 7622 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7623 7624 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 7625 * mixer widget 7626 * Note: PASD motherboards uses the Line In 2 as the input for 7627 * front panel mic (mic 2) 7628 */ 7629 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 7630 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7631 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7632 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 7633 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 7634 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 7635 7636 /* 7637 * Set up output mixers (0x0c - 0x0e) 7638 */ 7639 /* set vol=0 to output mixers */ 7640 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 7641 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 7642 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 7643 /* set up input amps for analog loopback */ 7644 /* Amp Indices: DAC = 0, mixer = 1 */ 7645 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7646 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 7647 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7648 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 7649 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7650 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 7651 7652 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 7653 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 7654 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 7655 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 7656 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 7657 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 7658 7659 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 7660 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 7661 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 7662 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 7663 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 7664 7665 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 7666 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 7667 7668 /* FIXME: use matrix-type input source selection */ 7669 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 7670 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 7671 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 7672 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 7673 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 7674 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 7675 /* Input mixer2 */ 7676 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 7677 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 7678 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 7679 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 7680 /* Input mixer3 */ 7681 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 7682 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 7683 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 7684 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 7685 7686 { } 7687}; 7688 7689static struct hda_verb alc262_hippo_unsol_verbs[] = { 7690 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 7691 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 7692 {} 7693}; 7694 7695static struct hda_verb alc262_hippo1_unsol_verbs[] = { 7696 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 7697 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 7698 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 7699 7700 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 7701 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 7702 {} 7703}; 7704 7705static struct hda_verb alc262_sony_unsol_verbs[] = { 7706 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 7707 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 7708 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic 7709 7710 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 7711 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 7712}; 7713 7714/* mute/unmute internal speaker according to the hp jack and mute state */ 7715static void alc262_hippo_automute(struct hda_codec *codec) 7716{ 7717 struct alc_spec *spec = codec->spec; 7718 unsigned int mute; 7719 unsigned int present; 7720 7721 /* need to execute and sync at first */ 7722 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0); 7723 present = snd_hda_codec_read(codec, 0x15, 0, 7724 AC_VERB_GET_PIN_SENSE, 0); 7725 spec->jack_present = (present & 0x80000000) != 0; 7726 if (spec->jack_present) { 7727 /* mute internal speaker */ 7728 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 7729 HDA_AMP_MUTE, HDA_AMP_MUTE); 7730 } else { 7731 /* unmute internal speaker if necessary */ 7732 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0); 7733 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 7734 HDA_AMP_MUTE, mute); 7735 } 7736} 7737 7738/* unsolicited event for HP jack sensing */ 7739static void alc262_hippo_unsol_event(struct hda_codec *codec, 7740 unsigned int res) 7741{ 7742 if ((res >> 26) != ALC880_HP_EVENT) 7743 return; 7744 alc262_hippo_automute(codec); 7745} 7746 7747static void alc262_hippo1_automute(struct hda_codec *codec) 7748{ 7749 unsigned int mute; 7750 unsigned int present; 7751 7752 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0); 7753 present = snd_hda_codec_read(codec, 0x1b, 0, 7754 AC_VERB_GET_PIN_SENSE, 0); 7755 present = (present & 0x80000000) != 0; 7756 if (present) { 7757 /* mute internal speaker */ 7758 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 7759 HDA_AMP_MUTE, HDA_AMP_MUTE); 7760 } else { 7761 /* unmute internal speaker if necessary */ 7762 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0); 7763 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 7764 HDA_AMP_MUTE, mute); 7765 } 7766} 7767 7768/* unsolicited event for HP jack sensing */ 7769static void alc262_hippo1_unsol_event(struct hda_codec *codec, 7770 unsigned int res) 7771{ 7772 if ((res >> 26) != ALC880_HP_EVENT) 7773 return; 7774 alc262_hippo1_automute(codec); 7775} 7776 7777/* 7778 * fujitsu model 7779 * 0x14 = headphone/spdif-out, 0x15 = internal speaker 7780 */ 7781 7782#define ALC_HP_EVENT 0x37 7783 7784static struct hda_verb alc262_fujitsu_unsol_verbs[] = { 7785 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, 7786 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 7787 {} 7788}; 7789 7790static struct hda_input_mux alc262_fujitsu_capture_source = { 7791 .num_items = 2, 7792 .items = { 7793 { "Mic", 0x0 }, 7794 { "CD", 0x4 }, 7795 }, 7796}; 7797 7798static struct hda_input_mux alc262_HP_capture_source = { 7799 .num_items = 5, 7800 .items = { 7801 { "Mic", 0x0 }, 7802 { "Front Mic", 0x1 }, 7803 { "Line", 0x2 }, 7804 { "CD", 0x4 }, 7805 { "AUX IN", 0x6 }, 7806 }, 7807}; 7808 7809static struct hda_input_mux alc262_HP_D7000_capture_source = { 7810 .num_items = 4, 7811 .items = { 7812 { "Mic", 0x0 }, 7813 { "Front Mic", 0x2 }, 7814 { "Line", 0x1 }, 7815 { "CD", 0x4 }, 7816 }, 7817}; 7818 7819/* mute/unmute internal speaker according to the hp jack and mute state */ 7820static void alc262_fujitsu_automute(struct hda_codec *codec, int force) 7821{ 7822 struct alc_spec *spec = codec->spec; 7823 unsigned int mute; 7824 7825 if (force || !spec->sense_updated) { 7826 unsigned int present; 7827 /* need to execute and sync at first */ 7828 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0); 7829 present = snd_hda_codec_read(codec, 0x14, 0, 7830 AC_VERB_GET_PIN_SENSE, 0); 7831 spec->jack_present = (present & 0x80000000) != 0; 7832 spec->sense_updated = 1; 7833 } 7834 if (spec->jack_present) { 7835 /* mute internal speaker */ 7836 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 7837 HDA_AMP_MUTE, HDA_AMP_MUTE); 7838 } else { 7839 /* unmute internal speaker if necessary */ 7840 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0); 7841 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 7842 HDA_AMP_MUTE, mute); 7843 } 7844} 7845 7846/* unsolicited event for HP jack sensing */ 7847static void alc262_fujitsu_unsol_event(struct hda_codec *codec, 7848 unsigned int res) 7849{ 7850 if ((res >> 26) != ALC_HP_EVENT) 7851 return; 7852 alc262_fujitsu_automute(codec, 1); 7853} 7854 7855/* bind volumes of both NID 0x0c and 0x0d */ 7856static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = { 7857 .ops = &snd_hda_bind_vol, 7858 .values = { 7859 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT), 7860 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT), 7861 0 7862 }, 7863}; 7864 7865/* bind hp and internal speaker mute (with plug check) */ 7866static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol, 7867 struct snd_ctl_elem_value *ucontrol) 7868{ 7869 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 7870 long *valp = ucontrol->value.integer.value; 7871 int change; 7872 7873 change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0, 7874 HDA_AMP_MUTE, 7875 valp[0] ? 0 : HDA_AMP_MUTE); 7876 change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0, 7877 HDA_AMP_MUTE, 7878 valp[1] ? 0 : HDA_AMP_MUTE); 7879 if (change) 7880 alc262_fujitsu_automute(codec, 0); 7881 return change; 7882} 7883 7884static struct snd_kcontrol_new alc262_fujitsu_mixer[] = { 7885 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol), 7886 { 7887 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 7888 .name = "Master Playback Switch", 7889 .info = snd_hda_mixer_amp_switch_info, 7890 .get = snd_hda_mixer_amp_switch_get, 7891 .put = alc262_fujitsu_master_sw_put, 7892 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 7893 }, 7894 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 7895 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 7896 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 7897 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7898 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7899 { } /* end */ 7900}; 7901 7902/* additional init verbs for Benq laptops */ 7903static struct hda_verb alc262_EAPD_verbs[] = { 7904 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 7905 {0x20, AC_VERB_SET_PROC_COEF, 0x3070}, 7906 {} 7907}; 7908 7909static struct hda_verb alc262_benq_t31_EAPD_verbs[] = { 7910 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 7911 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 7912 7913 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 7914 {0x20, AC_VERB_SET_PROC_COEF, 0x3050}, 7915 {} 7916}; 7917 7918/* add playback controls from the parsed DAC table */ 7919static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, 7920 const struct auto_pin_cfg *cfg) 7921{ 7922 hda_nid_t nid; 7923 int err; 7924 7925 spec->multiout.num_dacs = 1; /* only use one dac */ 7926 spec->multiout.dac_nids = spec->private_dac_nids; 7927 spec->multiout.dac_nids[0] = 2; 7928 7929 nid = cfg->line_out_pins[0]; 7930 if (nid) { 7931 err = add_control(spec, ALC_CTL_WIDGET_VOL, 7932 "Front Playback Volume", 7933 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT)); 7934 if (err < 0) 7935 return err; 7936 err = add_control(spec, ALC_CTL_WIDGET_MUTE, 7937 "Front Playback Switch", 7938 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); 7939 if (err < 0) 7940 return err; 7941 } 7942 7943 nid = cfg->speaker_pins[0]; 7944 if (nid) { 7945 if (nid == 0x16) { 7946 err = add_control(spec, ALC_CTL_WIDGET_VOL, 7947 "Speaker Playback Volume", 7948 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, 7949 HDA_OUTPUT)); 7950 if (err < 0) 7951 return err; 7952 err = add_control(spec, ALC_CTL_WIDGET_MUTE, 7953 "Speaker Playback Switch", 7954 HDA_COMPOSE_AMP_VAL(nid, 2, 0, 7955 HDA_OUTPUT)); 7956 if (err < 0) 7957 return err; 7958 } else { 7959 err = add_control(spec, ALC_CTL_WIDGET_MUTE, 7960 "Speaker Playback Switch", 7961 HDA_COMPOSE_AMP_VAL(nid, 3, 0, 7962 HDA_OUTPUT)); 7963 if (err < 0) 7964 return err; 7965 } 7966 } 7967 nid = cfg->hp_pins[0]; 7968 if (nid) { 7969 /* spec->multiout.hp_nid = 2; */ 7970 if (nid == 0x16) { 7971 err = add_control(spec, ALC_CTL_WIDGET_VOL, 7972 "Headphone Playback Volume", 7973 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, 7974 HDA_OUTPUT)); 7975 if (err < 0) 7976 return err; 7977 err = add_control(spec, ALC_CTL_WIDGET_MUTE, 7978 "Headphone Playback Switch", 7979 HDA_COMPOSE_AMP_VAL(nid, 2, 0, 7980 HDA_OUTPUT)); 7981 if (err < 0) 7982 return err; 7983 } else { 7984 err = add_control(spec, ALC_CTL_WIDGET_MUTE, 7985 "Headphone Playback Switch", 7986 HDA_COMPOSE_AMP_VAL(nid, 3, 0, 7987 HDA_OUTPUT)); 7988 if (err < 0) 7989 return err; 7990 } 7991 } 7992 return 0; 7993} 7994 7995/* identical with ALC880 */ 7996#define alc262_auto_create_analog_input_ctls \ 7997 alc880_auto_create_analog_input_ctls 7998 7999/* 8000 * generic initialization of ADC, input mixers and output mixers 8001 */ 8002static struct hda_verb alc262_volume_init_verbs[] = { 8003 /* 8004 * Unmute ADC0-2 and set the default input to mic-in 8005 */ 8006 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 8007 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8008 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 8009 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8010 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 8011 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8012 8013 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 8014 * mixer widget 8015 * Note: PASD motherboards uses the Line In 2 as the input for 8016 * front panel mic (mic 2) 8017 */ 8018 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 8019 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8020 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8021 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 8022 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8023 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8024 8025 /* 8026 * Set up output mixers (0x0c - 0x0f) 8027 */ 8028 /* set vol=0 to output mixers */ 8029 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8030 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8031 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8032 8033 /* set up input amps for analog loopback */ 8034 /* Amp Indices: DAC = 0, mixer = 1 */ 8035 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8036 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8037 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8038 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8039 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8040 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8041 8042 /* FIXME: use matrix-type input source selection */ 8043 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 8044 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 8045 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 8046 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 8047 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 8048 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 8049 /* Input mixer2 */ 8050 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 8051 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 8052 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 8053 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 8054 /* Input mixer3 */ 8055 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 8056 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 8057 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 8058 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 8059 8060 { } 8061}; 8062 8063static struct hda_verb alc262_HP_BPC_init_verbs[] = { 8064 /* 8065 * Unmute ADC0-2 and set the default input to mic-in 8066 */ 8067 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 8068 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8069 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 8070 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8071 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 8072 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8073 8074 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 8075 * mixer widget 8076 * Note: PASD motherboards uses the Line In 2 as the input for 8077 * front panel mic (mic 2) 8078 */ 8079 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 8080 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8081 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8082 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 8083 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8084 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8085 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, 8086 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, 8087 8088 /* 8089 * Set up output mixers (0x0c - 0x0e) 8090 */ 8091 /* set vol=0 to output mixers */ 8092 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8093 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8094 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8095 8096 /* set up input amps for analog loopback */ 8097 /* Amp Indices: DAC = 0, mixer = 1 */ 8098 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8099 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8100 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8101 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8102 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8103 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8104 8105 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 8106 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 8107 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 8108 8109 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 8110 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 8111 8112 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 8113 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 8114 8115 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 8116 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 8117 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 8118 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 8119 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 8120 8121 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, 8122 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 8123 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 8124 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, 8125 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 8126 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 8127 8128 8129 /* FIXME: use matrix-type input source selection */ 8130 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 8131 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 8132 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 8133 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, 8134 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, 8135 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, 8136 /* Input mixer2 */ 8137 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 8138 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, 8139 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, 8140 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, 8141 /* Input mixer3 */ 8142 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 8143 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, 8144 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, 8145 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, 8146 8147 { } 8148}; 8149 8150static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = { 8151 /* 8152 * Unmute ADC0-2 and set the default input to mic-in 8153 */ 8154 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 8155 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8156 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 8157 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8158 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 8159 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8160 8161 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 8162 * mixer widget 8163 * Note: PASD motherboards uses the Line In 2 as the input for front 8164 * panel mic (mic 2) 8165 */ 8166 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 8167 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8168 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8169 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 8170 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8171 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8172 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, 8173 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, 8174 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, 8175 /* 8176 * Set up output mixers (0x0c - 0x0e) 8177 */ 8178 /* set vol=0 to output mixers */ 8179 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8180 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8181 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8182 8183 /* set up input amps for analog loopback */ 8184 /* Amp Indices: DAC = 0, mixer = 1 */ 8185 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8186 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8187 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8188 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8189 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8190 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8191 8192 8193 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */ 8194 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */ 8195 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */ 8196 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */ 8197 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */ 8198 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */ 8199 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */ 8200 8201 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 8202 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 8203 8204 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 8205 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 8206 8207 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */ 8208 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 8209 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 8210 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, 8211 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 8212 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 8213 8214 /* FIXME: use matrix-type input source selection */ 8215 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 8216 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 8217 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/ 8218 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/ 8219 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/ 8220 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/ 8221 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/ 8222 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */ 8223 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/ 8224 /* Input mixer2 */ 8225 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 8226 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 8227 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, 8228 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, 8229 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, 8230 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */ 8231 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, 8232 /* Input mixer3 */ 8233 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 8234 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 8235 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, 8236 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, 8237 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, 8238 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */ 8239 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, 8240 8241 { } 8242}; 8243 8244#ifdef CONFIG_SND_HDA_POWER_SAVE 8245#define alc262_loopbacks alc880_loopbacks 8246#endif 8247 8248/* pcm configuration: identiacal with ALC880 */ 8249#define alc262_pcm_analog_playback alc880_pcm_analog_playback 8250#define alc262_pcm_analog_capture alc880_pcm_analog_capture 8251#define alc262_pcm_digital_playback alc880_pcm_digital_playback 8252#define alc262_pcm_digital_capture alc880_pcm_digital_capture 8253 8254/* 8255 * BIOS auto configuration 8256 */ 8257static int alc262_parse_auto_config(struct hda_codec *codec) 8258{ 8259 struct alc_spec *spec = codec->spec; 8260 int err; 8261 static hda_nid_t alc262_ignore[] = { 0x1d, 0 }; 8262 8263 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 8264 alc262_ignore); 8265 if (err < 0) 8266 return err; 8267 if (!spec->autocfg.line_outs) 8268 return 0; /* can't find valid BIOS pin config */ 8269 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg); 8270 if (err < 0) 8271 return err; 8272 err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg); 8273 if (err < 0) 8274 return err; 8275 8276 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 8277 8278 if (spec->autocfg.dig_out_pin) 8279 spec->multiout.dig_out_nid = ALC262_DIGOUT_NID; 8280 if (spec->autocfg.dig_in_pin) 8281 spec->dig_in_nid = ALC262_DIGIN_NID; 8282 8283 if (spec->kctl_alloc) 8284 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 8285 8286 spec->init_verbs[spec->num_init_verbs++] = alc262_volume_init_verbs; 8287 spec->num_mux_defs = 1; 8288 spec->input_mux = &spec->private_imux; 8289 8290 err = alc_auto_add_mic_boost(codec); 8291 if (err < 0) 8292 return err; 8293 8294 return 1; 8295} 8296 8297#define alc262_auto_init_multi_out alc882_auto_init_multi_out 8298#define alc262_auto_init_hp_out alc882_auto_init_hp_out 8299#define alc262_auto_init_analog_input alc882_auto_init_analog_input 8300 8301 8302/* init callback for auto-configuration model -- overriding the default init */ 8303static void alc262_auto_init(struct hda_codec *codec) 8304{ 8305 alc262_auto_init_multi_out(codec); 8306 alc262_auto_init_hp_out(codec); 8307 alc262_auto_init_analog_input(codec); 8308} 8309 8310/* 8311 * configuration and preset 8312 */ 8313static const char *alc262_models[ALC262_MODEL_LAST] = { 8314 [ALC262_BASIC] = "basic", 8315 [ALC262_HIPPO] = "hippo", 8316 [ALC262_HIPPO_1] = "hippo_1", 8317 [ALC262_FUJITSU] = "fujitsu", 8318 [ALC262_HP_BPC] = "hp-bpc", 8319 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000", 8320 [ALC262_BENQ_ED8] = "benq", 8321 [ALC262_BENQ_T31] = "benq-t31", 8322 [ALC262_SONY_ASSAMD] = "sony-assamd", 8323 [ALC262_AUTO] = "auto", 8324}; 8325 8326static struct snd_pci_quirk alc262_cfg_tbl[] = { 8327 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO), 8328 SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC), 8329 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC), 8330 SND_PCI_QUIRK(0x103c, 0x12ff, "HP xw4550", ALC262_HP_BPC), 8331 SND_PCI_QUIRK(0x103c, 0x1308, "HP xw4600", ALC262_HP_BPC), 8332 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC), 8333 SND_PCI_QUIRK(0x103c, 0x1307, "HP xw6600", ALC262_HP_BPC), 8334 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC), 8335 SND_PCI_QUIRK(0x103c, 0x1306, "HP xw8600", ALC262_HP_BPC), 8336 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL), 8337 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL), 8338 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL), 8339 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL), 8340 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF), 8341 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF), 8342 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF), 8343 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF), 8344 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO), 8345 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU), 8346 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1), 8347 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8), 8348 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31), 8349 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD), 8350 SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD), 8351 SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD), 8352 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD), 8353 {} 8354}; 8355 8356static struct alc_config_preset alc262_presets[] = { 8357 [ALC262_BASIC] = { 8358 .mixers = { alc262_base_mixer }, 8359 .init_verbs = { alc262_init_verbs }, 8360 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 8361 .dac_nids = alc262_dac_nids, 8362 .hp_nid = 0x03, 8363 .num_channel_mode = ARRAY_SIZE(alc262_modes), 8364 .channel_mode = alc262_modes, 8365 .input_mux = &alc262_capture_source, 8366 }, 8367 [ALC262_HIPPO] = { 8368 .mixers = { alc262_base_mixer }, 8369 .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs}, 8370 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 8371 .dac_nids = alc262_dac_nids, 8372 .hp_nid = 0x03, 8373 .dig_out_nid = ALC262_DIGOUT_NID, 8374 .num_channel_mode = ARRAY_SIZE(alc262_modes), 8375 .channel_mode = alc262_modes, 8376 .input_mux = &alc262_capture_source, 8377 .unsol_event = alc262_hippo_unsol_event, 8378 .init_hook = alc262_hippo_automute, 8379 }, 8380 [ALC262_HIPPO_1] = { 8381 .mixers = { alc262_hippo1_mixer }, 8382 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs}, 8383 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 8384 .dac_nids = alc262_dac_nids, 8385 .hp_nid = 0x02, 8386 .dig_out_nid = ALC262_DIGOUT_NID, 8387 .num_channel_mode = ARRAY_SIZE(alc262_modes), 8388 .channel_mode = alc262_modes, 8389 .input_mux = &alc262_capture_source, 8390 .unsol_event = alc262_hippo1_unsol_event, 8391 .init_hook = alc262_hippo1_automute, 8392 }, 8393 [ALC262_FUJITSU] = { 8394 .mixers = { alc262_fujitsu_mixer }, 8395 .init_verbs = { alc262_init_verbs, alc262_fujitsu_unsol_verbs }, 8396 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 8397 .dac_nids = alc262_dac_nids, 8398 .hp_nid = 0x03, 8399 .dig_out_nid = ALC262_DIGOUT_NID, 8400 .num_channel_mode = ARRAY_SIZE(alc262_modes), 8401 .channel_mode = alc262_modes, 8402 .input_mux = &alc262_fujitsu_capture_source, 8403 .unsol_event = alc262_fujitsu_unsol_event, 8404 }, 8405 [ALC262_HP_BPC] = { 8406 .mixers = { alc262_HP_BPC_mixer }, 8407 .init_verbs = { alc262_HP_BPC_init_verbs }, 8408 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 8409 .dac_nids = alc262_dac_nids, 8410 .hp_nid = 0x03, 8411 .num_channel_mode = ARRAY_SIZE(alc262_modes), 8412 .channel_mode = alc262_modes, 8413 .input_mux = &alc262_HP_capture_source, 8414 }, 8415 [ALC262_HP_BPC_D7000_WF] = { 8416 .mixers = { alc262_HP_BPC_WildWest_mixer }, 8417 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs }, 8418 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 8419 .dac_nids = alc262_dac_nids, 8420 .hp_nid = 0x03, 8421 .num_channel_mode = ARRAY_SIZE(alc262_modes), 8422 .channel_mode = alc262_modes, 8423 .input_mux = &alc262_HP_D7000_capture_source, 8424 }, 8425 [ALC262_HP_BPC_D7000_WL] = { 8426 .mixers = { alc262_HP_BPC_WildWest_mixer, 8427 alc262_HP_BPC_WildWest_option_mixer }, 8428 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs }, 8429 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 8430 .dac_nids = alc262_dac_nids, 8431 .hp_nid = 0x03, 8432 .num_channel_mode = ARRAY_SIZE(alc262_modes), 8433 .channel_mode = alc262_modes, 8434 .input_mux = &alc262_HP_D7000_capture_source, 8435 }, 8436 [ALC262_BENQ_ED8] = { 8437 .mixers = { alc262_base_mixer }, 8438 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs }, 8439 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 8440 .dac_nids = alc262_dac_nids, 8441 .hp_nid = 0x03, 8442 .num_channel_mode = ARRAY_SIZE(alc262_modes), 8443 .channel_mode = alc262_modes, 8444 .input_mux = &alc262_capture_source, 8445 }, 8446 [ALC262_SONY_ASSAMD] = { 8447 .mixers = { alc262_sony_mixer }, 8448 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs}, 8449 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 8450 .dac_nids = alc262_dac_nids, 8451 .hp_nid = 0x02, 8452 .num_channel_mode = ARRAY_SIZE(alc262_modes), 8453 .channel_mode = alc262_modes, 8454 .input_mux = &alc262_capture_source, 8455 .unsol_event = alc262_hippo_unsol_event, 8456 .init_hook = alc262_hippo_automute, 8457 }, 8458 [ALC262_BENQ_T31] = { 8459 .mixers = { alc262_benq_t31_mixer }, 8460 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs }, 8461 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 8462 .dac_nids = alc262_dac_nids, 8463 .hp_nid = 0x03, 8464 .num_channel_mode = ARRAY_SIZE(alc262_modes), 8465 .channel_mode = alc262_modes, 8466 .input_mux = &alc262_capture_source, 8467 .unsol_event = alc262_hippo_unsol_event, 8468 .init_hook = alc262_hippo_automute, 8469 }, 8470}; 8471 8472static int patch_alc262(struct hda_codec *codec) 8473{ 8474 struct alc_spec *spec; 8475 int board_config; 8476 int err; 8477 8478 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 8479 if (spec == NULL) 8480 return -ENOMEM; 8481 8482 codec->spec = spec; 8483#if 0 8484 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is 8485 * under-run 8486 */ 8487 { 8488 int tmp; 8489 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7); 8490 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0); 8491 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7); 8492 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80); 8493 } 8494#endif 8495 8496 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST, 8497 alc262_models, 8498 alc262_cfg_tbl); 8499 8500 if (board_config < 0) { 8501 printk(KERN_INFO "hda_codec: Unknown model for ALC262, " 8502 "trying auto-probe from BIOS...\n"); 8503 board_config = ALC262_AUTO; 8504 } 8505 8506 if (board_config == ALC262_AUTO) { 8507 /* automatic parse from the BIOS config */ 8508 err = alc262_parse_auto_config(codec); 8509 if (err < 0) { 8510 alc_free(codec); 8511 return err; 8512 } else if (!err) { 8513 printk(KERN_INFO 8514 "hda_codec: Cannot set up configuration " 8515 "from BIOS. Using base mode...\n"); 8516 board_config = ALC262_BASIC; 8517 } 8518 } 8519 8520 if (board_config != ALC262_AUTO) 8521 setup_preset(spec, &alc262_presets[board_config]); 8522 8523 spec->stream_name_analog = "ALC262 Analog"; 8524 spec->stream_analog_playback = &alc262_pcm_analog_playback; 8525 spec->stream_analog_capture = &alc262_pcm_analog_capture; 8526 8527 spec->stream_name_digital = "ALC262 Digital"; 8528 spec->stream_digital_playback = &alc262_pcm_digital_playback; 8529 spec->stream_digital_capture = &alc262_pcm_digital_capture; 8530 8531 if (!spec->adc_nids && spec->input_mux) { 8532 /* check whether NID 0x07 is valid */ 8533 unsigned int wcap = get_wcaps(codec, 0x07); 8534 8535 /* get type */ 8536 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; 8537 if (wcap != AC_WID_AUD_IN) { 8538 spec->adc_nids = alc262_adc_nids_alt; 8539 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt); 8540 spec->mixers[spec->num_mixers] = 8541 alc262_capture_alt_mixer; 8542 spec->num_mixers++; 8543 } else { 8544 spec->adc_nids = alc262_adc_nids; 8545 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids); 8546 spec->mixers[spec->num_mixers] = alc262_capture_mixer; 8547 spec->num_mixers++; 8548 } 8549 } 8550 8551 codec->patch_ops = alc_patch_ops; 8552 if (board_config == ALC262_AUTO) 8553 spec->init_hook = alc262_auto_init; 8554#ifdef CONFIG_SND_HDA_POWER_SAVE 8555 if (!spec->loopback.amplist) 8556 spec->loopback.amplist = alc262_loopbacks; 8557#endif 8558 8559 return 0; 8560} 8561 8562/* 8563 * ALC268 channel source setting (2 channel) 8564 */ 8565#define ALC268_DIGOUT_NID ALC880_DIGOUT_NID 8566#define alc268_modes alc260_modes 8567 8568static hda_nid_t alc268_dac_nids[2] = { 8569 /* front, hp */ 8570 0x02, 0x03 8571}; 8572 8573static hda_nid_t alc268_adc_nids[2] = { 8574 /* ADC0-1 */ 8575 0x08, 0x07 8576}; 8577 8578static hda_nid_t alc268_adc_nids_alt[1] = { 8579 /* ADC0 */ 8580 0x08 8581}; 8582 8583static struct snd_kcontrol_new alc268_base_mixer[] = { 8584 /* output mixer control */ 8585 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), 8586 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 8587 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT), 8588 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 8589 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8590 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 8591 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT), 8592 { } 8593}; 8594 8595static struct hda_verb alc268_eapd_verbs[] = { 8596 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 8597 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, 8598 { } 8599}; 8600 8601/* Toshiba specific */ 8602#define alc268_toshiba_automute alc262_hippo_automute 8603 8604static struct hda_verb alc268_toshiba_verbs[] = { 8605 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 8606 { } /* end */ 8607}; 8608 8609/* Acer specific */ 8610/* bind volumes of both NID 0x02 and 0x03 */ 8611static struct hda_bind_ctls alc268_acer_bind_master_vol = { 8612 .ops = &snd_hda_bind_vol, 8613 .values = { 8614 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), 8615 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT), 8616 0 8617 }, 8618}; 8619 8620/* mute/unmute internal speaker according to the hp jack and mute state */ 8621static void alc268_acer_automute(struct hda_codec *codec, int force) 8622{ 8623 struct alc_spec *spec = codec->spec; 8624 unsigned int mute; 8625 8626 if (force || !spec->sense_updated) { 8627 unsigned int present; 8628 present = snd_hda_codec_read(codec, 0x14, 0, 8629 AC_VERB_GET_PIN_SENSE, 0); 8630 spec->jack_present = (present & 0x80000000) != 0; 8631 spec->sense_updated = 1; 8632 } 8633 if (spec->jack_present) 8634 mute = HDA_AMP_MUTE; /* mute internal speaker */ 8635 else /* unmute internal speaker if necessary */ 8636 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0); 8637 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 8638 HDA_AMP_MUTE, mute); 8639} 8640 8641 8642/* bind hp and internal speaker mute (with plug check) */ 8643static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol, 8644 struct snd_ctl_elem_value *ucontrol) 8645{ 8646 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 8647 long *valp = ucontrol->value.integer.value; 8648 int change; 8649 8650 change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0, 8651 HDA_AMP_MUTE, 8652 valp[0] ? 0 : HDA_AMP_MUTE); 8653 change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0, 8654 HDA_AMP_MUTE, 8655 valp[1] ? 0 : HDA_AMP_MUTE); 8656 if (change) 8657 alc268_acer_automute(codec, 0); 8658 return change; 8659} 8660 8661static struct snd_kcontrol_new alc268_acer_mixer[] = { 8662 /* output mixer control */ 8663 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), 8664 { 8665 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 8666 .name = "Master Playback Switch", 8667 .info = snd_hda_mixer_amp_switch_info, 8668 .get = snd_hda_mixer_amp_switch_get, 8669 .put = alc268_acer_master_sw_put, 8670 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 8671 }, 8672 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8673 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), 8674 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT), 8675 { } 8676}; 8677 8678static struct hda_verb alc268_acer_verbs[] = { 8679 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8680 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8681 8682 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 8683 { } 8684}; 8685 8686/* unsolicited event for HP jack sensing */ 8687static void alc268_toshiba_unsol_event(struct hda_codec *codec, 8688 unsigned int res) 8689{ 8690 if ((res >> 26) != ALC880_HP_EVENT) 8691 return; 8692 alc268_toshiba_automute(codec); 8693} 8694 8695static void alc268_acer_unsol_event(struct hda_codec *codec, 8696 unsigned int res) 8697{ 8698 if ((res >> 26) != ALC880_HP_EVENT) 8699 return; 8700 alc268_acer_automute(codec, 1); 8701} 8702 8703static void alc268_acer_init_hook(struct hda_codec *codec) 8704{ 8705 alc268_acer_automute(codec, 1); 8706} 8707 8708/* 8709 * generic initialization of ADC, input mixers and output mixers 8710 */ 8711static struct hda_verb alc268_base_init_verbs[] = { 8712 /* Unmute DAC0-1 and set vol = 0 */ 8713 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8714 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8715 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8716 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8717 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8718 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8719 8720 /* 8721 * Set up output mixers (0x0c - 0x0e) 8722 */ 8723 /* set vol=0 to output mixers */ 8724 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8725 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8726 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8727 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00}, 8728 8729 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8730 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8731 8732 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 8733 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 8734 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 8735 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 8736 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 8737 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 8738 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 8739 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 8740 8741 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8742 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8743 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8744 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8745 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8746 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8747 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8748 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 8749 8750 /* FIXME: use matrix-type input source selection */ 8751 /* Mixer elements: 0x18, 19, 1a, 1c, 14, 15, 0b */ 8752 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 8753 /* Input mixer2 */ 8754 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 8755 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 8756 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, 8757 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, 8758 8759 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 8760 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 8761 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, 8762 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, 8763 { } 8764}; 8765 8766/* 8767 * generic initialization of ADC, input mixers and output mixers 8768 */ 8769static struct hda_verb alc268_volume_init_verbs[] = { 8770 /* set output DAC */ 8771 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8772 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8773 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8774 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8775 8776 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 8777 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 8778 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 8779 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 8780 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 8781 8782 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8783 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8784 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8785 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8786 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8787 8788 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8789 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8790 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8791 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8792 8793 /* set PCBEEP vol = 0 */ 8794 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, (0xb000 | (0x00 << 8))}, 8795 8796 { } 8797}; 8798 8799#define alc268_mux_enum_info alc_mux_enum_info 8800#define alc268_mux_enum_get alc_mux_enum_get 8801 8802static int alc268_mux_enum_put(struct snd_kcontrol *kcontrol, 8803 struct snd_ctl_elem_value *ucontrol) 8804{ 8805 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 8806 struct alc_spec *spec = codec->spec; 8807 const struct hda_input_mux *imux = spec->input_mux; 8808 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 8809 static hda_nid_t capture_mixers[3] = { 0x23, 0x24 }; 8810 hda_nid_t nid = capture_mixers[adc_idx]; 8811 unsigned int *cur_val = &spec->cur_mux[adc_idx]; 8812 unsigned int i, idx; 8813 8814 idx = ucontrol->value.enumerated.item[0]; 8815 if (idx >= imux->num_items) 8816 idx = imux->num_items - 1; 8817 if (*cur_val == idx) 8818 return 0; 8819 for (i = 0; i < imux->num_items; i++) { 8820 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE; 8821 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 8822 imux->items[i].index, 8823 HDA_AMP_MUTE, v); 8824 snd_hda_codec_write_cache(codec, nid, 0, 8825 AC_VERB_SET_CONNECT_SEL, 8826 idx ); 8827 } 8828 *cur_val = idx; 8829 return 1; 8830} 8831 8832static struct snd_kcontrol_new alc268_capture_alt_mixer[] = { 8833 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT), 8834 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT), 8835 { 8836 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 8837 /* The multiple "Capture Source" controls confuse alsamixer 8838 * So call somewhat different.. 8839 * FIXME: the controls appear in the "playback" view! 8840 */ 8841 /* .name = "Capture Source", */ 8842 .name = "Input Source", 8843 .count = 1, 8844 .info = alc268_mux_enum_info, 8845 .get = alc268_mux_enum_get, 8846 .put = alc268_mux_enum_put, 8847 }, 8848 { } /* end */ 8849}; 8850 8851static struct snd_kcontrol_new alc268_capture_mixer[] = { 8852 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT), 8853 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT), 8854 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT), 8855 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT), 8856 { 8857 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 8858 /* The multiple "Capture Source" controls confuse alsamixer 8859 * So call somewhat different.. 8860 * FIXME: the controls appear in the "playback" view! 8861 */ 8862 /* .name = "Capture Source", */ 8863 .name = "Input Source", 8864 .count = 2, 8865 .info = alc268_mux_enum_info, 8866 .get = alc268_mux_enum_get, 8867 .put = alc268_mux_enum_put, 8868 }, 8869 { } /* end */ 8870}; 8871 8872static struct hda_input_mux alc268_capture_source = { 8873 .num_items = 4, 8874 .items = { 8875 { "Mic", 0x0 }, 8876 { "Front Mic", 0x1 }, 8877 { "Line", 0x2 }, 8878 { "CD", 0x3 }, 8879 }, 8880}; 8881 8882/* create input playback/capture controls for the given pin */ 8883static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid, 8884 const char *ctlname, int idx) 8885{ 8886 char name[32]; 8887 int err; 8888 8889 sprintf(name, "%s Playback Volume", ctlname); 8890 if (nid == 0x14) { 8891 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, 8892 HDA_COMPOSE_AMP_VAL(0x02, 3, idx, 8893 HDA_OUTPUT)); 8894 if (err < 0) 8895 return err; 8896 } else if (nid == 0x15) { 8897 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, 8898 HDA_COMPOSE_AMP_VAL(0x03, 3, idx, 8899 HDA_OUTPUT)); 8900 if (err < 0) 8901 return err; 8902 } else 8903 return -1; 8904 sprintf(name, "%s Playback Switch", ctlname); 8905 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, 8906 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT)); 8907 if (err < 0) 8908 return err; 8909 return 0; 8910} 8911 8912/* add playback controls from the parsed DAC table */ 8913static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec, 8914 const struct auto_pin_cfg *cfg) 8915{ 8916 hda_nid_t nid; 8917 int err; 8918 8919 spec->multiout.num_dacs = 2; /* only use one dac */ 8920 spec->multiout.dac_nids = spec->private_dac_nids; 8921 spec->multiout.dac_nids[0] = 2; 8922 spec->multiout.dac_nids[1] = 3; 8923 8924 nid = cfg->line_out_pins[0]; 8925 if (nid) 8926 alc268_new_analog_output(spec, nid, "Front", 0); 8927 8928 nid = cfg->speaker_pins[0]; 8929 if (nid == 0x1d) { 8930 err = add_control(spec, ALC_CTL_WIDGET_VOL, 8931 "Speaker Playback Volume", 8932 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT)); 8933 if (err < 0) 8934 return err; 8935 } 8936 nid = cfg->hp_pins[0]; 8937 if (nid) 8938 alc268_new_analog_output(spec, nid, "Headphone", 0); 8939 8940 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2]; 8941 if (nid == 0x16) { 8942 err = add_control(spec, ALC_CTL_WIDGET_MUTE, 8943 "Mono Playback Switch", 8944 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT)); 8945 if (err < 0) 8946 return err; 8947 } 8948 return 0; 8949} 8950 8951/* create playback/capture controls for input pins */ 8952static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec, 8953 const struct auto_pin_cfg *cfg) 8954{ 8955 struct hda_input_mux *imux = &spec->private_imux; 8956 int i, idx1; 8957 8958 for (i = 0; i < AUTO_PIN_LAST; i++) { 8959 switch(cfg->input_pins[i]) { 8960 case 0x18: 8961 idx1 = 0; /* Mic 1 */ 8962 break; 8963 case 0x19: 8964 idx1 = 1; /* Mic 2 */ 8965 break; 8966 case 0x1a: 8967 idx1 = 2; /* Line In */ 8968 break; 8969 case 0x1c: 8970 idx1 = 3; /* CD */ 8971 break; 8972 default: 8973 continue; 8974 } 8975 imux->items[imux->num_items].label = auto_pin_cfg_labels[i]; 8976 imux->items[imux->num_items].index = idx1; 8977 imux->num_items++; 8978 } 8979 return 0; 8980} 8981 8982static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec) 8983{ 8984 struct alc_spec *spec = codec->spec; 8985 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0]; 8986 hda_nid_t hp_nid = spec->autocfg.hp_pins[0]; 8987 hda_nid_t line_nid = spec->autocfg.line_out_pins[0]; 8988 unsigned int dac_vol1, dac_vol2; 8989 8990 if (speaker_nid) { 8991 snd_hda_codec_write(codec, speaker_nid, 0, 8992 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); 8993 snd_hda_codec_write(codec, 0x0f, 0, 8994 AC_VERB_SET_AMP_GAIN_MUTE, 8995 AMP_IN_UNMUTE(1)); 8996 snd_hda_codec_write(codec, 0x10, 0, 8997 AC_VERB_SET_AMP_GAIN_MUTE, 8998 AMP_IN_UNMUTE(1)); 8999 } else { 9000 snd_hda_codec_write(codec, 0x0f, 0, 9001 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)); 9002 snd_hda_codec_write(codec, 0x10, 0, 9003 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)); 9004 } 9005 9006 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */ 9007 if (line_nid == 0x14) 9008 dac_vol2 = AMP_OUT_ZERO; 9009 else if (line_nid == 0x15) 9010 dac_vol1 = AMP_OUT_ZERO; 9011 if (hp_nid == 0x14) 9012 dac_vol2 = AMP_OUT_ZERO; 9013 else if (hp_nid == 0x15) 9014 dac_vol1 = AMP_OUT_ZERO; 9015 if (line_nid != 0x16 || hp_nid != 0x16 || 9016 spec->autocfg.line_out_pins[1] != 0x16 || 9017 spec->autocfg.line_out_pins[2] != 0x16) 9018 dac_vol1 = dac_vol2 = AMP_OUT_ZERO; 9019 9020 snd_hda_codec_write(codec, 0x02, 0, 9021 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1); 9022 snd_hda_codec_write(codec, 0x03, 0, 9023 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2); 9024} 9025 9026/* pcm configuration: identiacal with ALC880 */ 9027#define alc268_pcm_analog_playback alc880_pcm_analog_playback 9028#define alc268_pcm_analog_capture alc880_pcm_analog_capture 9029#define alc268_pcm_digital_playback alc880_pcm_digital_playback 9030 9031/* 9032 * BIOS auto configuration 9033 */ 9034static int alc268_parse_auto_config(struct hda_codec *codec) 9035{ 9036 struct alc_spec *spec = codec->spec; 9037 int err; 9038 static hda_nid_t alc268_ignore[] = { 0 }; 9039 9040 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 9041 alc268_ignore); 9042 if (err < 0) 9043 return err; 9044 if (!spec->autocfg.line_outs) 9045 return 0; /* can't find valid BIOS pin config */ 9046 9047 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg); 9048 if (err < 0) 9049 return err; 9050 err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg); 9051 if (err < 0) 9052 return err; 9053 9054 spec->multiout.max_channels = 2; 9055 9056 /* digital only support output */ 9057 if (spec->autocfg.dig_out_pin) 9058 spec->multiout.dig_out_nid = ALC268_DIGOUT_NID; 9059 9060 if (spec->kctl_alloc) 9061 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 9062 9063 spec->init_verbs[spec->num_init_verbs++] = alc268_volume_init_verbs; 9064 spec->num_mux_defs = 1; 9065 spec->input_mux = &spec->private_imux; 9066 9067 err = alc_auto_add_mic_boost(codec); 9068 if (err < 0) 9069 return err; 9070 9071 return 1; 9072} 9073 9074#define alc268_auto_init_multi_out alc882_auto_init_multi_out 9075#define alc268_auto_init_hp_out alc882_auto_init_hp_out 9076#define alc268_auto_init_analog_input alc882_auto_init_analog_input 9077 9078/* init callback for auto-configuration model -- overriding the default init */ 9079static void alc268_auto_init(struct hda_codec *codec) 9080{ 9081 alc268_auto_init_multi_out(codec); 9082 alc268_auto_init_hp_out(codec); 9083 alc268_auto_init_mono_speaker_out(codec); 9084 alc268_auto_init_analog_input(codec); 9085} 9086 9087/* 9088 * configuration and preset 9089 */ 9090static const char *alc268_models[ALC268_MODEL_LAST] = { 9091 [ALC268_3ST] = "3stack", 9092 [ALC268_TOSHIBA] = "toshiba", 9093 [ALC268_ACER] = "acer", 9094 [ALC268_AUTO] = "auto", 9095}; 9096 9097static struct snd_pci_quirk alc268_cfg_tbl[] = { 9098 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST), 9099 SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA), 9100 SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA), 9101 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER), 9102 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER), 9103 {} 9104}; 9105 9106static struct alc_config_preset alc268_presets[] = { 9107 [ALC268_3ST] = { 9108 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer }, 9109 .init_verbs = { alc268_base_init_verbs }, 9110 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 9111 .dac_nids = alc268_dac_nids, 9112 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 9113 .adc_nids = alc268_adc_nids_alt, 9114 .hp_nid = 0x03, 9115 .dig_out_nid = ALC268_DIGOUT_NID, 9116 .num_channel_mode = ARRAY_SIZE(alc268_modes), 9117 .channel_mode = alc268_modes, 9118 .input_mux = &alc268_capture_source, 9119 }, 9120 [ALC268_TOSHIBA] = { 9121 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer }, 9122 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 9123 alc268_toshiba_verbs }, 9124 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 9125 .dac_nids = alc268_dac_nids, 9126 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 9127 .adc_nids = alc268_adc_nids_alt, 9128 .hp_nid = 0x03, 9129 .num_channel_mode = ARRAY_SIZE(alc268_modes), 9130 .channel_mode = alc268_modes, 9131 .input_mux = &alc268_capture_source, 9132 .input_mux = &alc268_capture_source, 9133 .unsol_event = alc268_toshiba_unsol_event, 9134 .init_hook = alc268_toshiba_automute, 9135 }, 9136 [ALC268_ACER] = { 9137 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer }, 9138 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 9139 alc268_acer_verbs }, 9140 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 9141 .dac_nids = alc268_dac_nids, 9142 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 9143 .adc_nids = alc268_adc_nids_alt, 9144 .hp_nid = 0x02, 9145 .num_channel_mode = ARRAY_SIZE(alc268_modes), 9146 .channel_mode = alc268_modes, 9147 .input_mux = &alc268_capture_source, 9148 .unsol_event = alc268_acer_unsol_event, 9149 .init_hook = alc268_acer_init_hook, 9150 }, 9151}; 9152 9153static int patch_alc268(struct hda_codec *codec) 9154{ 9155 struct alc_spec *spec; 9156 int board_config; 9157 int err; 9158 9159 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); 9160 if (spec == NULL) 9161 return -ENOMEM; 9162 9163 codec->spec = spec; 9164 9165 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST, 9166 alc268_models, 9167 alc268_cfg_tbl); 9168 9169 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) { 9170 printk(KERN_INFO "hda_codec: Unknown model for ALC268, " 9171 "trying auto-probe from BIOS...\n"); 9172 board_config = ALC268_AUTO; 9173 } 9174 9175 if (board_config == ALC268_AUTO) { 9176 /* automatic parse from the BIOS config */ 9177 err = alc268_parse_auto_config(codec); 9178 if (err < 0) { 9179 alc_free(codec); 9180 return err; 9181 } else if (!err) { 9182 printk(KERN_INFO 9183 "hda_codec: Cannot set up configuration " 9184 "from BIOS. Using base mode...\n"); 9185 board_config = ALC268_3ST; 9186 } 9187 } 9188 9189 if (board_config != ALC268_AUTO) 9190 setup_preset(spec, &alc268_presets[board_config]); 9191 9192 spec->stream_name_analog = "ALC268 Analog"; 9193 spec->stream_analog_playback = &alc268_pcm_analog_playback; 9194 spec->stream_analog_capture = &alc268_pcm_analog_capture; 9195 9196 spec->stream_name_digital = "ALC268 Digital"; 9197 spec->stream_digital_playback = &alc268_pcm_digital_playback; 9198 9199 if (board_config == ALC268_AUTO) { 9200 if (!spec->adc_nids && spec->input_mux) { 9201 /* check whether NID 0x07 is valid */ 9202 unsigned int wcap = get_wcaps(codec, 0x07); 9203 9204 /* get type */ 9205 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; 9206 if (wcap != AC_WID_AUD_IN) { 9207 spec->adc_nids = alc268_adc_nids_alt; 9208 spec->num_adc_nids = 9209 ARRAY_SIZE(alc268_adc_nids_alt); 9210 spec->mixers[spec->num_mixers] = 9211 alc268_capture_alt_mixer; 9212 spec->num_mixers++; 9213 } else { 9214 spec->adc_nids = alc268_adc_nids; 9215 spec->num_adc_nids = 9216 ARRAY_SIZE(alc268_adc_nids); 9217 spec->mixers[spec->num_mixers] = 9218 alc268_capture_mixer; 9219 spec->num_mixers++; 9220 } 9221 } 9222 } 9223 codec->patch_ops = alc_patch_ops; 9224 if (board_config == ALC268_AUTO) 9225 spec->init_hook = alc268_auto_init; 9226 9227 return 0; 9228} 9229 9230/* 9231 * ALC861 channel source setting (2/6 channel selection for 3-stack) 9232 */ 9233 9234/* 9235 * set the path ways for 2 channel output 9236 * need to set the codec line out and mic 1 pin widgets to inputs 9237 */ 9238static struct hda_verb alc861_threestack_ch2_init[] = { 9239 /* set pin widget 1Ah (line in) for input */ 9240 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 9241 /* set pin widget 18h (mic1/2) for input, for mic also enable 9242 * the vref 9243 */ 9244 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 9245 9246 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, 9247#if 0 9248 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/ 9249 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/ 9250#endif 9251 { } /* end */ 9252}; 9253/* 9254 * 6ch mode 9255 * need to set the codec line out and mic 1 pin widgets to outputs 9256 */ 9257static struct hda_verb alc861_threestack_ch6_init[] = { 9258 /* set pin widget 1Ah (line in) for output (Back Surround)*/ 9259 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 9260 /* set pin widget 18h (mic1) for output (CLFE)*/ 9261 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 9262 9263 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 }, 9264 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 }, 9265 9266 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 }, 9267#if 0 9268 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/ 9269 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/ 9270#endif 9271 { } /* end */ 9272}; 9273 9274static struct hda_channel_mode alc861_threestack_modes[2] = { 9275 { 2, alc861_threestack_ch2_init }, 9276 { 6, alc861_threestack_ch6_init }, 9277}; 9278/* Set mic1 as input and unmute the mixer */ 9279static struct hda_verb alc861_uniwill_m31_ch2_init[] = { 9280 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 9281 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/ 9282 { } /* end */ 9283}; 9284/* Set mic1 as output and mute mixer */ 9285static struct hda_verb alc861_uniwill_m31_ch4_init[] = { 9286 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 9287 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/ 9288 { } /* end */ 9289}; 9290 9291static struct hda_channel_mode alc861_uniwill_m31_modes[2] = { 9292 { 2, alc861_uniwill_m31_ch2_init }, 9293 { 4, alc861_uniwill_m31_ch4_init }, 9294}; 9295 9296/* Set mic1 and line-in as input and unmute the mixer */ 9297static struct hda_verb alc861_asus_ch2_init[] = { 9298 /* set pin widget 1Ah (line in) for input */ 9299 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 9300 /* set pin widget 18h (mic1/2) for input, for mic also enable 9301 * the vref 9302 */ 9303 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 9304 9305 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, 9306#if 0 9307 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/ 9308 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/ 9309#endif 9310 { } /* end */ 9311}; 9312/* Set mic1 nad line-in as output and mute mixer */ 9313static struct hda_verb alc861_asus_ch6_init[] = { 9314 /* set pin widget 1Ah (line in) for output (Back Surround)*/ 9315 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 9316 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */ 9317 /* set pin widget 18h (mic1) for output (CLFE)*/ 9318 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 9319 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */ 9320 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 }, 9321 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 }, 9322 9323 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 }, 9324#if 0 9325 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/ 9326 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/ 9327#endif 9328 { } /* end */ 9329}; 9330 9331static struct hda_channel_mode alc861_asus_modes[2] = { 9332 { 2, alc861_asus_ch2_init }, 9333 { 6, alc861_asus_ch6_init }, 9334}; 9335 9336/* patch-ALC861 */ 9337 9338static struct snd_kcontrol_new alc861_base_mixer[] = { 9339 /* output mixer control */ 9340 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), 9341 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), 9342 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT), 9343 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT), 9344 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), 9345 9346 /*Input mixer control */ 9347 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT), 9348 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */ 9349 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), 9350 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), 9351 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT), 9352 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT), 9353 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), 9354 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), 9355 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), 9356 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT), 9357 9358 /* Capture mixer control */ 9359 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 9360 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 9361 { 9362 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 9363 .name = "Capture Source", 9364 .count = 1, 9365 .info = alc_mux_enum_info, 9366 .get = alc_mux_enum_get, 9367 .put = alc_mux_enum_put, 9368 }, 9369 { } /* end */ 9370}; 9371 9372static struct snd_kcontrol_new alc861_3ST_mixer[] = { 9373 /* output mixer control */ 9374 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), 9375 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), 9376 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT), 9377 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT), 9378 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */ 9379 9380 /* Input mixer control */ 9381 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT), 9382 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */ 9383 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), 9384 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), 9385 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT), 9386 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT), 9387 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), 9388 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), 9389 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), 9390 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT), 9391 9392 /* Capture mixer control */ 9393 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 9394 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 9395 { 9396 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 9397 .name = "Capture Source", 9398 .count = 1, 9399 .info = alc_mux_enum_info, 9400 .get = alc_mux_enum_get, 9401 .put = alc_mux_enum_put, 9402 }, 9403 { 9404 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 9405 .name = "Channel Mode", 9406 .info = alc_ch_mode_info, 9407 .get = alc_ch_mode_get, 9408 .put = alc_ch_mode_put, 9409 .private_value = ARRAY_SIZE(alc861_threestack_modes), 9410 }, 9411 { } /* end */ 9412}; 9413 9414static struct snd_kcontrol_new alc861_toshiba_mixer[] = { 9415 /* output mixer control */ 9416 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT), 9417 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), 9418 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), 9419 9420 /*Capture mixer control */ 9421 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 9422 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 9423 { 9424 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 9425 .name = "Capture Source", 9426 .count = 1, 9427 .info = alc_mux_enum_info, 9428 .get = alc_mux_enum_get, 9429 .put = alc_mux_enum_put, 9430 }, 9431 9432 { } /* end */ 9433}; 9434 9435static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = { 9436 /* output mixer control */ 9437 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), 9438 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), 9439 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT), 9440 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT), 9441 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */ 9442 9443 /* Input mixer control */ 9444 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT), 9445 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */ 9446 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), 9447 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), 9448 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT), 9449 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT), 9450 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), 9451 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), 9452 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), 9453 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT), 9454 9455 /* Capture mixer control */ 9456 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 9457 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 9458 { 9459 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 9460 .name = "Capture Source", 9461 .count = 1, 9462 .info = alc_mux_enum_info, 9463 .get = alc_mux_enum_get, 9464 .put = alc_mux_enum_put, 9465 }, 9466 { 9467 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 9468 .name = "Channel Mode", 9469 .info = alc_ch_mode_info, 9470 .get = alc_ch_mode_get, 9471 .put = alc_ch_mode_put, 9472 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes), 9473 }, 9474 { } /* end */ 9475}; 9476 9477static struct snd_kcontrol_new alc861_asus_mixer[] = { 9478 /* output mixer control */ 9479 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), 9480 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), 9481 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT), 9482 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT), 9483 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), 9484 9485 /* Input mixer control */ 9486 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT), 9487 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), 9488 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), 9489 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), 9490 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT), 9491 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT), 9492 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), 9493 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), 9494 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), 9495 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT), 9496 9497 /* Capture mixer control */ 9498 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 9499 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 9500 { 9501 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 9502 .name = "Capture Source", 9503 .count = 1, 9504 .info = alc_mux_enum_info, 9505 .get = alc_mux_enum_get, 9506 .put = alc_mux_enum_put, 9507 }, 9508 { 9509 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 9510 .name = "Channel Mode", 9511 .info = alc_ch_mode_info, 9512 .get = alc_ch_mode_get, 9513 .put = alc_ch_mode_put, 9514 .private_value = ARRAY_SIZE(alc861_asus_modes), 9515 }, 9516 { } 9517}; 9518 9519/* additional mixer */ 9520static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = { 9521 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), 9522 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), 9523 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x23, 0x0, HDA_OUTPUT), 9524 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x23, 0x0, HDA_OUTPUT), 9525 { } 9526}; 9527 9528/* 9529 * generic initialization of ADC, input mixers and output mixers 9530 */ 9531static struct hda_verb alc861_base_init_verbs[] = { 9532 /* 9533 * Unmute ADC0 and set the default input to mic-in 9534 */ 9535 /* port-A for surround (rear panel) */ 9536 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 9537 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 }, 9538 /* port-B for mic-in (rear panel) with vref */ 9539 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 9540 /* port-C for line-in (rear panel) */ 9541 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 9542 /* port-D for Front */ 9543 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 9544 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 }, 9545 /* port-E for HP out (front panel) */ 9546 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, 9547 /* route front PCM to HP */ 9548 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, 9549 /* port-F for mic-in (front panel) with vref */ 9550 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 9551 /* port-G for CLFE (rear panel) */ 9552 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 9553 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 }, 9554 /* port-H for side (rear panel) */ 9555 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 9556 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 }, 9557 /* CD-in */ 9558 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 9559 /* route front mic to ADC1*/ 9560 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 9561 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9562 9563 /* Unmute DAC0~3 & spdif out*/ 9564 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9565 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9566 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9567 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9568 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9569 9570 /* Unmute Mixer 14 (mic) 1c (Line in)*/ 9571 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9572 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9573 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9574 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9575 9576 /* Unmute Stereo Mixer 15 */ 9577 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9578 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9579 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 9580 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */ 9581 9582 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9583 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9584 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9585 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9586 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9587 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9588 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9589 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9590 /* hp used DAC 3 (Front) */ 9591 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 9592 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 9593 9594 { } 9595}; 9596 9597static struct hda_verb alc861_threestack_init_verbs[] = { 9598 /* 9599 * Unmute ADC0 and set the default input to mic-in 9600 */ 9601 /* port-A for surround (rear panel) */ 9602 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 9603 /* port-B for mic-in (rear panel) with vref */ 9604 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 9605 /* port-C for line-in (rear panel) */ 9606 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 9607 /* port-D for Front */ 9608 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 9609 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 }, 9610 /* port-E for HP out (front panel) */ 9611 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, 9612 /* route front PCM to HP */ 9613 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, 9614 /* port-F for mic-in (front panel) with vref */ 9615 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 9616 /* port-G for CLFE (rear panel) */ 9617 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 9618 /* port-H for side (rear panel) */ 9619 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 9620 /* CD-in */ 9621 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 9622 /* route front mic to ADC1*/ 9623 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 9624 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9625 /* Unmute DAC0~3 & spdif out*/ 9626 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9627 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9628 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9629 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9630 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9631 9632 /* Unmute Mixer 14 (mic) 1c (Line in)*/ 9633 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9634 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9635 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9636 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9637 9638 /* Unmute Stereo Mixer 15 */ 9639 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9640 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9641 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 9642 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */ 9643 9644 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9645 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9646 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9647 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9648 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9649 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9650 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9651 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9652 /* hp used DAC 3 (Front) */ 9653 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 9654 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 9655 { } 9656}; 9657 9658static struct hda_verb alc861_uniwill_m31_init_verbs[] = { 9659 /* 9660 * Unmute ADC0 and set the default input to mic-in 9661 */ 9662 /* port-A for surround (rear panel) */ 9663 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 9664 /* port-B for mic-in (rear panel) with vref */ 9665 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 9666 /* port-C for line-in (rear panel) */ 9667 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 9668 /* port-D for Front */ 9669 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 9670 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 }, 9671 /* port-E for HP out (front panel) */ 9672 /* this has to be set to VREF80 */ 9673 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 9674 /* route front PCM to HP */ 9675 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, 9676 /* port-F for mic-in (front panel) with vref */ 9677 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 9678 /* port-G for CLFE (rear panel) */ 9679 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 9680 /* port-H for side (rear panel) */ 9681 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 9682 /* CD-in */ 9683 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 9684 /* route front mic to ADC1*/ 9685 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 9686 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9687 /* Unmute DAC0~3 & spdif out*/ 9688 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9689 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9690 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9691 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9692 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9693 9694 /* Unmute Mixer 14 (mic) 1c (Line in)*/ 9695 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9696 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9697 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9698 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9699 9700 /* Unmute Stereo Mixer 15 */ 9701 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9702 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9703 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 9704 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */ 9705 9706 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9707 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9708 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9709 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9710 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9711 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9712 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9713 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9714 /* hp used DAC 3 (Front) */ 9715 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 9716 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 9717 { } 9718}; 9719 9720static struct hda_verb alc861_asus_init_verbs[] = { 9721 /* 9722 * Unmute ADC0 and set the default input to mic-in 9723 */ 9724 /* port-A for surround (rear panel) 9725 * according to codec#0 this is the HP jack 9726 */ 9727 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */ 9728 /* route front PCM to HP */ 9729 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 }, 9730 /* port-B for mic-in (rear panel) with vref */ 9731 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 9732 /* port-C for line-in (rear panel) */ 9733 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 9734 /* port-D for Front */ 9735 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 9736 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 }, 9737 /* port-E for HP out (front panel) */ 9738 /* this has to be set to VREF80 */ 9739 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 9740 /* route front PCM to HP */ 9741 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, 9742 /* port-F for mic-in (front panel) with vref */ 9743 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 9744 /* port-G for CLFE (rear panel) */ 9745 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 9746 /* port-H for side (rear panel) */ 9747 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 9748 /* CD-in */ 9749 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 9750 /* route front mic to ADC1*/ 9751 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 9752 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9753 /* Unmute DAC0~3 & spdif out*/ 9754 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9755 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9756 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9757 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9758 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9759 /* Unmute Mixer 14 (mic) 1c (Line in)*/ 9760 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9761 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9762 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9763 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9764 9765 /* Unmute Stereo Mixer 15 */ 9766 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9767 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9768 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 9769 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */ 9770 9771 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9772 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9773 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9774 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9775 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9776 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9777 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9778 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9779 /* hp used DAC 3 (Front) */ 9780 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 9781 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 9782 { } 9783}; 9784 9785/* additional init verbs for ASUS laptops */ 9786static struct hda_verb alc861_asus_laptop_init_verbs[] = { 9787 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */ 9788 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */ 9789 { } 9790}; 9791 9792/* 9793 * generic initialization of ADC, input mixers and output mixers 9794 */ 9795static struct hda_verb alc861_auto_init_verbs[] = { 9796 /* 9797 * Unmute ADC0 and set the default input to mic-in 9798 */ 9799 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */ 9800 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9801 9802 /* Unmute DAC0~3 & spdif out*/ 9803 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 9804 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 9805 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 9806 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 9807 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9808 9809 /* Unmute Mixer 14 (mic) 1c (Line in)*/ 9810 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9811 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9812 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9813 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9814 9815 /* Unmute Stereo Mixer 15 */ 9816 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9817 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9818 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 9819 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, 9820 9821 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9822 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9823 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9824 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9825 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9826 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9827 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9828 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9829 9830 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 9831 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 9832 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 9833 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 9834 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 9835 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 9836 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 9837 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 9838 9839 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */ 9840 9841 { } 9842}; 9843 9844static struct hda_verb alc861_toshiba_init_verbs[] = { 9845 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 9846 9847 { } 9848}; 9849 9850/* toggle speaker-output according to the hp-jack state */ 9851static void alc861_toshiba_automute(struct hda_codec *codec) 9852{ 9853 unsigned int present; 9854 9855 present = snd_hda_codec_read(codec, 0x0f, 0, 9856 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 9857 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0, 9858 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 9859 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3, 9860 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE); 9861} 9862 9863static void alc861_toshiba_unsol_event(struct hda_codec *codec, 9864 unsigned int res) 9865{ 9866 if ((res >> 26) == ALC880_HP_EVENT) 9867 alc861_toshiba_automute(codec); 9868} 9869 9870/* pcm configuration: identiacal with ALC880 */ 9871#define alc861_pcm_analog_playback alc880_pcm_analog_playback 9872#define alc861_pcm_analog_capture alc880_pcm_analog_capture 9873#define alc861_pcm_digital_playback alc880_pcm_digital_playback 9874#define alc861_pcm_digital_capture alc880_pcm_digital_capture 9875 9876 9877#define ALC861_DIGOUT_NID 0x07 9878 9879static struct hda_channel_mode alc861_8ch_modes[1] = { 9880 { 8, NULL } 9881}; 9882 9883static hda_nid_t alc861_dac_nids[4] = { 9884 /* front, surround, clfe, side */ 9885 0x03, 0x06, 0x05, 0x04 9886}; 9887 9888static hda_nid_t alc660_dac_nids[3] = { 9889 /* front, clfe, surround */ 9890 0x03, 0x05, 0x06 9891}; 9892 9893static hda_nid_t alc861_adc_nids[1] = { 9894 /* ADC0-2 */ 9895 0x08, 9896}; 9897 9898static struct hda_input_mux alc861_capture_source = { 9899 .num_items = 5, 9900 .items = { 9901 { "Mic", 0x0 }, 9902 { "Front Mic", 0x3 }, 9903 { "Line", 0x1 }, 9904 { "CD", 0x4 }, 9905 { "Mixer", 0x5 }, 9906 }, 9907}; 9908 9909/* fill in the dac_nids table from the parsed pin configuration */ 9910static int alc861_auto_fill_dac_nids(struct alc_spec *spec, 9911 const struct auto_pin_cfg *cfg) 9912{ 9913 int i; 9914 hda_nid_t nid; 9915 9916 spec->multiout.dac_nids = spec->private_dac_nids; 9917 for (i = 0; i < cfg->line_outs; i++) { 9918 nid = cfg->line_out_pins[i]; 9919 if (nid) { 9920 if (i >= ARRAY_SIZE(alc861_dac_nids)) 9921 continue; 9922 spec->multiout.dac_nids[i] = alc861_dac_nids[i]; 9923 } 9924 } 9925 spec->multiout.num_dacs = cfg->line_outs; 9926 return 0; 9927} 9928 9929/* add playback controls from the parsed DAC table */ 9930static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec, 9931 const struct auto_pin_cfg *cfg) 9932{ 9933 char name[32]; 9934 static const char *chname[4] = { 9935 "Front", "Surround", NULL /*CLFE*/, "Side" 9936 }; 9937 hda_nid_t nid; 9938 int i, idx, err; 9939 9940 for (i = 0; i < cfg->line_outs; i++) { 9941 nid = spec->multiout.dac_nids[i]; 9942 if (!nid) 9943 continue; 9944 if (nid == 0x05) { 9945 /* Center/LFE */ 9946 err = add_control(spec, ALC_CTL_BIND_MUTE, 9947 "Center Playback Switch", 9948 HDA_COMPOSE_AMP_VAL(nid, 1, 0, 9949 HDA_OUTPUT)); 9950 if (err < 0) 9951 return err; 9952 err = add_control(spec, ALC_CTL_BIND_MUTE, 9953 "LFE Playback Switch", 9954 HDA_COMPOSE_AMP_VAL(nid, 2, 0, 9955 HDA_OUTPUT)); 9956 if (err < 0) 9957 return err; 9958 } else { 9959 for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1; 9960 idx++) 9961 if (nid == alc861_dac_nids[idx]) 9962 break; 9963 sprintf(name, "%s Playback Switch", chname[idx]); 9964 err = add_control(spec, ALC_CTL_BIND_MUTE, name, 9965 HDA_COMPOSE_AMP_VAL(nid, 3, 0, 9966 HDA_OUTPUT)); 9967 if (err < 0) 9968 return err; 9969 } 9970 } 9971 return 0; 9972} 9973 9974static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin) 9975{ 9976 int err; 9977 hda_nid_t nid; 9978 9979 if (!pin) 9980 return 0; 9981 9982 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) { 9983 nid = 0x03; 9984 err = add_control(spec, ALC_CTL_WIDGET_MUTE, 9985 "Headphone Playback Switch", 9986 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); 9987 if (err < 0) 9988 return err; 9989 spec->multiout.hp_nid = nid; 9990 } 9991 return 0; 9992} 9993 9994/* create playback/capture controls for input pins */ 9995static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec, 9996 const struct auto_pin_cfg *cfg) 9997{ 9998 struct hda_input_mux *imux = &spec->private_imux; 9999 int i, err, idx, idx1; 10000 10001 for (i = 0; i < AUTO_PIN_LAST; i++) { 10002 switch (cfg->input_pins[i]) { 10003 case 0x0c: 10004 idx1 = 1; 10005 idx = 2; /* Line In */ 10006 break; 10007 case 0x0f: 10008 idx1 = 2; 10009 idx = 2; /* Line In */ 10010 break; 10011 case 0x0d: 10012 idx1 = 0; 10013 idx = 1; /* Mic In */ 10014 break; 10015 case 0x10: 10016 idx1 = 3; 10017 idx = 1; /* Mic In */ 10018 break; 10019 case 0x11: 10020 idx1 = 4; 10021 idx = 0; /* CD */ 10022 break; 10023 default: 10024 continue; 10025 } 10026 10027 err = new_analog_input(spec, cfg->input_pins[i], 10028 auto_pin_cfg_labels[i], idx, 0x15); 10029 if (err < 0) 10030 return err; 10031 10032 imux->items[imux->num_items].label = auto_pin_cfg_labels[i]; 10033 imux->items[imux->num_items].index = idx1; 10034 imux->num_items++; 10035 } 10036 return 0; 10037} 10038 10039static struct snd_kcontrol_new alc861_capture_mixer[] = { 10040 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 10041 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 10042 10043 { 10044 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 10045 /* The multiple "Capture Source" controls confuse alsamixer 10046 * So call somewhat different.. 10047 *FIXME: the controls appear in the "playback" view! 10048 */ 10049 /* .name = "Capture Source", */ 10050 .name = "Input Source", 10051 .count = 1, 10052 .info = alc_mux_enum_info, 10053 .get = alc_mux_enum_get, 10054 .put = alc_mux_enum_put, 10055 }, 10056 { } /* end */ 10057}; 10058 10059static void alc861_auto_set_output_and_unmute(struct hda_codec *codec, 10060 hda_nid_t nid, 10061 int pin_type, int dac_idx) 10062{ 10063 /* set as output */ 10064 10065 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 10066 pin_type); 10067 snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE, 10068 AMP_OUT_UNMUTE); 10069 10070} 10071 10072static void alc861_auto_init_multi_out(struct hda_codec *codec) 10073{ 10074 struct alc_spec *spec = codec->spec; 10075 int i; 10076 10077 alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b); 10078 for (i = 0; i < spec->autocfg.line_outs; i++) { 10079 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 10080 int pin_type = get_pin_type(spec->autocfg.line_out_type); 10081 if (nid) 10082 alc861_auto_set_output_and_unmute(codec, nid, pin_type, 10083 spec->multiout.dac_nids[i]); 10084 } 10085} 10086 10087static void alc861_auto_init_hp_out(struct hda_codec *codec) 10088{ 10089 struct alc_spec *spec = codec->spec; 10090 hda_nid_t pin; 10091 10092 pin = spec->autocfg.hp_pins[0]; 10093 if (pin) /* connect to front */ 10094 alc861_auto_set_output_and_unmute(codec, pin, PIN_HP, 10095 spec->multiout.dac_nids[0]); 10096} 10097 10098static void alc861_auto_init_analog_input(struct hda_codec *codec) 10099{ 10100 struct alc_spec *spec = codec->spec; 10101 int i; 10102 10103 for (i = 0; i < AUTO_PIN_LAST; i++) { 10104 hda_nid_t nid = spec->autocfg.input_pins[i]; 10105 if (nid >= 0x0c && nid <= 0x11) { 10106 snd_hda_codec_write(codec, nid, 0, 10107 AC_VERB_SET_PIN_WIDGET_CONTROL, 10108 i <= AUTO_PIN_FRONT_MIC ? 10109 PIN_VREF80 : PIN_IN); 10110 } 10111 } 10112} 10113 10114/* parse the BIOS configuration and set up the alc_spec */ 10115/* return 1 if successful, 0 if the proper config is not found, 10116 * or a negative error code 10117 */ 10118static int alc861_parse_auto_config(struct hda_codec *codec) 10119{ 10120 struct alc_spec *spec = codec->spec; 10121 int err; 10122 static hda_nid_t alc861_ignore[] = { 0x1d, 0 }; 10123 10124 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 10125 alc861_ignore); 10126 if (err < 0) 10127 return err; 10128 if (!spec->autocfg.line_outs) 10129 return 0; /* can't find valid BIOS pin config */ 10130 10131 err = alc861_auto_fill_dac_nids(spec, &spec->autocfg); 10132 if (err < 0) 10133 return err; 10134 err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg); 10135 if (err < 0) 10136 return err; 10137 err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]); 10138 if (err < 0) 10139 return err; 10140 err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg); 10141 if (err < 0) 10142 return err; 10143 10144 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 10145 10146 if (spec->autocfg.dig_out_pin) 10147 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID; 10148 10149 if (spec->kctl_alloc) 10150 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 10151 10152 spec->init_verbs[spec->num_init_verbs++] = alc861_auto_init_verbs; 10153 10154 spec->num_mux_defs = 1; 10155 spec->input_mux = &spec->private_imux; 10156 10157 spec->adc_nids = alc861_adc_nids; 10158 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids); 10159 spec->mixers[spec->num_mixers] = alc861_capture_mixer; 10160 spec->num_mixers++; 10161 10162 return 1; 10163} 10164 10165/* additional initialization for auto-configuration model */ 10166static void alc861_auto_init(struct hda_codec *codec) 10167{ 10168 alc861_auto_init_multi_out(codec); 10169 alc861_auto_init_hp_out(codec); 10170 alc861_auto_init_analog_input(codec); 10171} 10172 10173#ifdef CONFIG_SND_HDA_POWER_SAVE 10174static struct hda_amp_list alc861_loopbacks[] = { 10175 { 0x15, HDA_INPUT, 0 }, 10176 { 0x15, HDA_INPUT, 1 }, 10177 { 0x15, HDA_INPUT, 2 }, 10178 { 0x15, HDA_INPUT, 3 }, 10179 { } /* end */ 10180}; 10181#endif 10182 10183 10184/* 10185 * configuration and preset 10186 */ 10187static const char *alc861_models[ALC861_MODEL_LAST] = { 10188 [ALC861_3ST] = "3stack", 10189 [ALC660_3ST] = "3stack-660", 10190 [ALC861_3ST_DIG] = "3stack-dig", 10191 [ALC861_6ST_DIG] = "6stack-dig", 10192 [ALC861_UNIWILL_M31] = "uniwill-m31", 10193 [ALC861_TOSHIBA] = "toshiba", 10194 [ALC861_ASUS] = "asus", 10195 [ALC861_ASUS_LAPTOP] = "asus-laptop", 10196 [ALC861_AUTO] = "auto", 10197}; 10198 10199static struct snd_pci_quirk alc861_cfg_tbl[] = { 10200 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST), 10201 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP), 10202 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP), 10203 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP), 10204 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP), 10205 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS), 10206 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG), 10207 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA), 10208 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!) 10209 * Any other models that need this preset? 10210 */ 10211 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */ 10212 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31), 10213 SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), 10214 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31), 10215 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST), 10216 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST), 10217 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST), 10218 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST), 10219 {} 10220}; 10221 10222static struct alc_config_preset alc861_presets[] = { 10223 [ALC861_3ST] = { 10224 .mixers = { alc861_3ST_mixer }, 10225 .init_verbs = { alc861_threestack_init_verbs }, 10226 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 10227 .dac_nids = alc861_dac_nids, 10228 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes), 10229 .channel_mode = alc861_threestack_modes, 10230 .need_dac_fix = 1, 10231 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 10232 .adc_nids = alc861_adc_nids, 10233 .input_mux = &alc861_capture_source, 10234 }, 10235 [ALC861_3ST_DIG] = { 10236 .mixers = { alc861_base_mixer }, 10237 .init_verbs = { alc861_threestack_init_verbs }, 10238 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 10239 .dac_nids = alc861_dac_nids, 10240 .dig_out_nid = ALC861_DIGOUT_NID, 10241 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes), 10242 .channel_mode = alc861_threestack_modes, 10243 .need_dac_fix = 1, 10244 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 10245 .adc_nids = alc861_adc_nids, 10246 .input_mux = &alc861_capture_source, 10247 }, 10248 [ALC861_6ST_DIG] = { 10249 .mixers = { alc861_base_mixer }, 10250 .init_verbs = { alc861_base_init_verbs }, 10251 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 10252 .dac_nids = alc861_dac_nids, 10253 .dig_out_nid = ALC861_DIGOUT_NID, 10254 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes), 10255 .channel_mode = alc861_8ch_modes, 10256 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 10257 .adc_nids = alc861_adc_nids, 10258 .input_mux = &alc861_capture_source, 10259 }, 10260 [ALC660_3ST] = { 10261 .mixers = { alc861_3ST_mixer }, 10262 .init_verbs = { alc861_threestack_init_verbs }, 10263 .num_dacs = ARRAY_SIZE(alc660_dac_nids), 10264 .dac_nids = alc660_dac_nids, 10265 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes), 10266 .channel_mode = alc861_threestack_modes, 10267 .need_dac_fix = 1, 10268 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 10269 .adc_nids = alc861_adc_nids, 10270 .input_mux = &alc861_capture_source, 10271 }, 10272 [ALC861_UNIWILL_M31] = { 10273 .mixers = { alc861_uniwill_m31_mixer }, 10274 .init_verbs = { alc861_uniwill_m31_init_verbs }, 10275 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 10276 .dac_nids = alc861_dac_nids, 10277 .dig_out_nid = ALC861_DIGOUT_NID, 10278 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes), 10279 .channel_mode = alc861_uniwill_m31_modes, 10280 .need_dac_fix = 1, 10281 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 10282 .adc_nids = alc861_adc_nids, 10283 .input_mux = &alc861_capture_source, 10284 }, 10285 [ALC861_TOSHIBA] = { 10286 .mixers = { alc861_toshiba_mixer }, 10287 .init_verbs = { alc861_base_init_verbs, 10288 alc861_toshiba_init_verbs }, 10289 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 10290 .dac_nids = alc861_dac_nids, 10291 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10292 .channel_mode = alc883_3ST_2ch_modes, 10293 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 10294 .adc_nids = alc861_adc_nids, 10295 .input_mux = &alc861_capture_source, 10296 .unsol_event = alc861_toshiba_unsol_event, 10297 .init_hook = alc861_toshiba_automute, 10298 }, 10299 [ALC861_ASUS] = { 10300 .mixers = { alc861_asus_mixer }, 10301 .init_verbs = { alc861_asus_init_verbs }, 10302 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 10303 .dac_nids = alc861_dac_nids, 10304 .dig_out_nid = ALC861_DIGOUT_NID, 10305 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes), 10306 .channel_mode = alc861_asus_modes, 10307 .need_dac_fix = 1, 10308 .hp_nid = 0x06, 10309 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 10310 .adc_nids = alc861_adc_nids, 10311 .input_mux = &alc861_capture_source, 10312 }, 10313 [ALC861_ASUS_LAPTOP] = { 10314 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer }, 10315 .init_verbs = { alc861_asus_init_verbs, 10316 alc861_asus_laptop_init_verbs }, 10317 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 10318 .dac_nids = alc861_dac_nids, 10319 .dig_out_nid = ALC861_DIGOUT_NID, 10320 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10321 .channel_mode = alc883_3ST_2ch_modes, 10322 .need_dac_fix = 1, 10323 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 10324 .adc_nids = alc861_adc_nids, 10325 .input_mux = &alc861_capture_source, 10326 }, 10327}; 10328 10329 10330static int patch_alc861(struct hda_codec *codec) 10331{ 10332 struct alc_spec *spec; 10333 int board_config; 10334 int err; 10335 10336 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 10337 if (spec == NULL) 10338 return -ENOMEM; 10339 10340 codec->spec = spec; 10341 10342 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST, 10343 alc861_models, 10344 alc861_cfg_tbl); 10345 10346 if (board_config < 0) { 10347 printk(KERN_INFO "hda_codec: Unknown model for ALC861, " 10348 "trying auto-probe from BIOS...\n"); 10349 board_config = ALC861_AUTO; 10350 } 10351 10352 if (board_config == ALC861_AUTO) { 10353 /* automatic parse from the BIOS config */ 10354 err = alc861_parse_auto_config(codec); 10355 if (err < 0) { 10356 alc_free(codec); 10357 return err; 10358 } else if (!err) { 10359 printk(KERN_INFO 10360 "hda_codec: Cannot set up configuration " 10361 "from BIOS. Using base mode...\n"); 10362 board_config = ALC861_3ST_DIG; 10363 } 10364 } 10365 10366 if (board_config != ALC861_AUTO) 10367 setup_preset(spec, &alc861_presets[board_config]); 10368 10369 spec->stream_name_analog = "ALC861 Analog"; 10370 spec->stream_analog_playback = &alc861_pcm_analog_playback; 10371 spec->stream_analog_capture = &alc861_pcm_analog_capture; 10372 10373 spec->stream_name_digital = "ALC861 Digital"; 10374 spec->stream_digital_playback = &alc861_pcm_digital_playback; 10375 spec->stream_digital_capture = &alc861_pcm_digital_capture; 10376 10377 codec->patch_ops = alc_patch_ops; 10378 if (board_config == ALC861_AUTO) 10379 spec->init_hook = alc861_auto_init; 10380#ifdef CONFIG_SND_HDA_POWER_SAVE 10381 if (!spec->loopback.amplist) 10382 spec->loopback.amplist = alc861_loopbacks; 10383#endif 10384 10385 return 0; 10386} 10387 10388/* 10389 * ALC861-VD support 10390 * 10391 * Based on ALC882 10392 * 10393 * In addition, an independent DAC 10394 */ 10395#define ALC861VD_DIGOUT_NID 0x06 10396 10397static hda_nid_t alc861vd_dac_nids[4] = { 10398 /* front, surr, clfe, side surr */ 10399 0x02, 0x03, 0x04, 0x05 10400}; 10401 10402/* dac_nids for ALC660vd are in a different order - according to 10403 * Realtek's driver. 10404 * This should probably tesult in a different mixer for 6stack models 10405 * of ALC660vd codecs, but for now there is only 3stack mixer 10406 * - and it is the same as in 861vd. 10407 * adc_nids in ALC660vd are (is) the same as in 861vd 10408 */ 10409static hda_nid_t alc660vd_dac_nids[3] = { 10410 /* front, rear, clfe, rear_surr */ 10411 0x02, 0x04, 0x03 10412}; 10413 10414static hda_nid_t alc861vd_adc_nids[1] = { 10415 /* ADC0 */ 10416 0x09, 10417}; 10418 10419/* input MUX */ 10420/* FIXME: should be a matrix-type input source selection */ 10421static struct hda_input_mux alc861vd_capture_source = { 10422 .num_items = 4, 10423 .items = { 10424 { "Mic", 0x0 }, 10425 { "Front Mic", 0x1 }, 10426 { "Line", 0x2 }, 10427 { "CD", 0x4 }, 10428 }, 10429}; 10430 10431static struct hda_input_mux alc861vd_dallas_capture_source = { 10432 .num_items = 3, 10433 .items = { 10434 { "Front Mic", 0x0 }, 10435 { "ATAPI Mic", 0x1 }, 10436 { "Line In", 0x5 }, 10437 }, 10438}; 10439 10440static struct hda_input_mux alc861vd_hp_capture_source = { 10441 .num_items = 2, 10442 .items = { 10443 { "Front Mic", 0x0 }, 10444 { "ATAPI Mic", 0x1 }, 10445 }, 10446}; 10447 10448#define alc861vd_mux_enum_info alc_mux_enum_info 10449#define alc861vd_mux_enum_get alc_mux_enum_get 10450 10451static int alc861vd_mux_enum_put(struct snd_kcontrol *kcontrol, 10452 struct snd_ctl_elem_value *ucontrol) 10453{ 10454 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 10455 struct alc_spec *spec = codec->spec; 10456 const struct hda_input_mux *imux = spec->input_mux; 10457 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 10458 static hda_nid_t capture_mixers[1] = { 0x22 }; 10459 hda_nid_t nid = capture_mixers[adc_idx]; 10460 unsigned int *cur_val = &spec->cur_mux[adc_idx]; 10461 unsigned int i, idx; 10462 10463 idx = ucontrol->value.enumerated.item[0]; 10464 if (idx >= imux->num_items) 10465 idx = imux->num_items - 1; 10466 if (*cur_val == idx) 10467 return 0; 10468 for (i = 0; i < imux->num_items; i++) { 10469 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE; 10470 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 10471 imux->items[i].index, 10472 HDA_AMP_MUTE, v); 10473 } 10474 *cur_val = idx; 10475 return 1; 10476} 10477 10478/* 10479 * 2ch mode 10480 */ 10481static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = { 10482 { 2, NULL } 10483}; 10484 10485/* 10486 * 6ch mode 10487 */ 10488static struct hda_verb alc861vd_6stack_ch6_init[] = { 10489 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 10490 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 10491 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 10492 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 10493 { } /* end */ 10494}; 10495 10496/* 10497 * 8ch mode 10498 */ 10499static struct hda_verb alc861vd_6stack_ch8_init[] = { 10500 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 10501 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 10502 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 10503 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 10504 { } /* end */ 10505}; 10506 10507static struct hda_channel_mode alc861vd_6stack_modes[2] = { 10508 { 6, alc861vd_6stack_ch6_init }, 10509 { 8, alc861vd_6stack_ch8_init }, 10510}; 10511 10512static struct snd_kcontrol_new alc861vd_chmode_mixer[] = { 10513 { 10514 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 10515 .name = "Channel Mode", 10516 .info = alc_ch_mode_info, 10517 .get = alc_ch_mode_get, 10518 .put = alc_ch_mode_put, 10519 }, 10520 { } /* end */ 10521}; 10522 10523static struct snd_kcontrol_new alc861vd_capture_mixer[] = { 10524 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), 10525 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), 10526 10527 { 10528 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 10529 /* The multiple "Capture Source" controls confuse alsamixer 10530 * So call somewhat different.. 10531 *FIXME: the controls appear in the "playback" view! 10532 */ 10533 /* .name = "Capture Source", */ 10534 .name = "Input Source", 10535 .count = 1, 10536 .info = alc861vd_mux_enum_info, 10537 .get = alc861vd_mux_enum_get, 10538 .put = alc861vd_mux_enum_put, 10539 }, 10540 { } /* end */ 10541}; 10542 10543/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 10544 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b 10545 */ 10546static struct snd_kcontrol_new alc861vd_6st_mixer[] = { 10547 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 10548 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 10549 10550 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT), 10551 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 10552 10553 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, 10554 HDA_OUTPUT), 10555 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, 10556 HDA_OUTPUT), 10557 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 10558 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 10559 10560 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT), 10561 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 10562 10563 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 10564 10565 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 10566 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 10567 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 10568 10569 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 10570 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 10571 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 10572 10573 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 10574 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 10575 10576 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 10577 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 10578 10579 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 10580 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 10581 10582 { } /* end */ 10583}; 10584 10585static struct snd_kcontrol_new alc861vd_3st_mixer[] = { 10586 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 10587 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 10588 10589 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 10590 10591 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 10592 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 10593 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 10594 10595 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 10596 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 10597 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 10598 10599 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 10600 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 10601 10602 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 10603 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 10604 10605 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 10606 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 10607 10608 { } /* end */ 10609}; 10610 10611static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = { 10612 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 10613 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/ 10614 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 10615 10616 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 10617 10618 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 10619 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 10620 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 10621 10622 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 10623 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 10624 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 10625 10626 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 10627 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 10628 10629 { } /* end */ 10630}; 10631 10632/* Pin assignment: Front=0x14, HP = 0x15, 10633 * Front Mic=0x18, ATAPI Mic = 0x19, Line In = 0x1d 10634 */ 10635static struct snd_kcontrol_new alc861vd_dallas_mixer[] = { 10636 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 10637 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 10638 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 10639 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT), 10640 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 10641 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 10642 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 10643 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 10644 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x05, HDA_INPUT), 10645 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x05, HDA_INPUT), 10646 { } /* end */ 10647}; 10648 10649/* Pin assignment: Speaker=0x14, Line-out = 0x15, 10650 * Front Mic=0x18, ATAPI Mic = 0x19, 10651 */ 10652static struct snd_kcontrol_new alc861vd_hp_mixer[] = { 10653 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 10654 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 10655 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 10656 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT), 10657 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 10658 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 10659 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 10660 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 10661 10662 { } /* end */ 10663}; 10664 10665/* 10666 * generic initialization of ADC, input mixers and output mixers 10667 */ 10668static struct hda_verb alc861vd_volume_init_verbs[] = { 10669 /* 10670 * Unmute ADC0 and set the default input to mic-in 10671 */ 10672 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 10673 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 10674 10675 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of 10676 * the analog-loopback mixer widget 10677 */ 10678 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 10679 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 10680 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 10681 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 10682 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 10683 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 10684 10685 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */ 10686 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 10687 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 10688 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 10689 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, 10690 10691 /* 10692 * Set up output mixers (0x02 - 0x05) 10693 */ 10694 /* set vol=0 to output mixers */ 10695 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 10696 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 10697 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 10698 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 10699 10700 /* set up input amps for analog loopback */ 10701 /* Amp Indices: DAC = 0, mixer = 1 */ 10702 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 10703 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 10704 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 10705 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 10706 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 10707 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 10708 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 10709 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 10710 10711 { } 10712}; 10713 10714/* 10715 * 3-stack pin configuration: 10716 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b 10717 */ 10718static struct hda_verb alc861vd_3stack_init_verbs[] = { 10719 /* 10720 * Set pin mode and muting 10721 */ 10722 /* set front pin widgets 0x14 for output */ 10723 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 10724 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 10725 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 10726 10727 /* Mic (rear) pin: input vref at 80% */ 10728 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 10729 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 10730 /* Front Mic pin: input vref at 80% */ 10731 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 10732 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 10733 /* Line In pin: input */ 10734 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 10735 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 10736 /* Line-2 In: Headphone output (output 0 - 0x0c) */ 10737 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 10738 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 10739 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 10740 /* CD pin widget for input */ 10741 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 10742 10743 { } 10744}; 10745 10746/* 10747 * 6-stack pin configuration: 10748 */ 10749static struct hda_verb alc861vd_6stack_init_verbs[] = { 10750 /* 10751 * Set pin mode and muting 10752 */ 10753 /* set front pin widgets 0x14 for output */ 10754 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 10755 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 10756 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 10757 10758 /* Rear Pin: output 1 (0x0d) */ 10759 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 10760 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 10761 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 10762 /* CLFE Pin: output 2 (0x0e) */ 10763 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 10764 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 10765 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, 10766 /* Side Pin: output 3 (0x0f) */ 10767 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 10768 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 10769 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, 10770 10771 /* Mic (rear) pin: input vref at 80% */ 10772 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 10773 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 10774 /* Front Mic pin: input vref at 80% */ 10775 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 10776 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 10777 /* Line In pin: input */ 10778 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 10779 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 10780 /* Line-2 In: Headphone output (output 0 - 0x0c) */ 10781 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 10782 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 10783 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 10784 /* CD pin widget for input */ 10785 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 10786 10787 { } 10788}; 10789 10790static struct hda_verb alc861vd_eapd_verbs[] = { 10791 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 10792 { } 10793}; 10794 10795static struct hda_verb alc861vd_lenovo_unsol_verbs[] = { 10796 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 10797 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 10798 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, 10799 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 10800 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 10801 {} 10802}; 10803 10804/* toggle speaker-output according to the hp-jack state */ 10805static void alc861vd_lenovo_hp_automute(struct hda_codec *codec) 10806{ 10807 unsigned int present; 10808 unsigned char bits; 10809 10810 present = snd_hda_codec_read(codec, 0x1b, 0, 10811 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 10812 bits = present ? HDA_AMP_MUTE : 0; 10813 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 10814 HDA_AMP_MUTE, bits); 10815} 10816 10817static void alc861vd_lenovo_mic_automute(struct hda_codec *codec) 10818{ 10819 unsigned int present; 10820 unsigned char bits; 10821 10822 present = snd_hda_codec_read(codec, 0x18, 0, 10823 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 10824 bits = present ? HDA_AMP_MUTE : 0; 10825 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, 10826 HDA_AMP_MUTE, bits); 10827} 10828 10829static void alc861vd_lenovo_automute(struct hda_codec *codec) 10830{ 10831 alc861vd_lenovo_hp_automute(codec); 10832 alc861vd_lenovo_mic_automute(codec); 10833} 10834 10835static void alc861vd_lenovo_unsol_event(struct hda_codec *codec, 10836 unsigned int res) 10837{ 10838 switch (res >> 26) { 10839 case ALC880_HP_EVENT: 10840 alc861vd_lenovo_hp_automute(codec); 10841 break; 10842 case ALC880_MIC_EVENT: 10843 alc861vd_lenovo_mic_automute(codec); 10844 break; 10845 } 10846} 10847 10848static struct hda_verb alc861vd_dallas_verbs[] = { 10849 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 10850 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 10851 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 10852 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 10853 10854 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 10855 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 10856 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 10857 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 10858 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 10859 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 10860 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 10861 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 10862 10863 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 10864 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 10865 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 10866 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 10867 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 10868 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 10869 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 10870 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 10871 10872 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, 10873 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 10874 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, 10875 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 10876 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 10877 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 10878 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 10879 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 10880 10881 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 10882 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 10883 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 10884 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 10885 10886 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 10887 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 10888 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 10889 10890 { } /* end */ 10891}; 10892 10893/* toggle speaker-output according to the hp-jack state */ 10894static void alc861vd_dallas_automute(struct hda_codec *codec) 10895{ 10896 unsigned int present; 10897 10898 present = snd_hda_codec_read(codec, 0x15, 0, 10899 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 10900 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 10901 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 10902} 10903 10904static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int res) 10905{ 10906 if ((res >> 26) == ALC880_HP_EVENT) 10907 alc861vd_dallas_automute(codec); 10908} 10909 10910#ifdef CONFIG_SND_HDA_POWER_SAVE 10911#define alc861vd_loopbacks alc880_loopbacks 10912#endif 10913 10914/* pcm configuration: identiacal with ALC880 */ 10915#define alc861vd_pcm_analog_playback alc880_pcm_analog_playback 10916#define alc861vd_pcm_analog_capture alc880_pcm_analog_capture 10917#define alc861vd_pcm_digital_playback alc880_pcm_digital_playback 10918#define alc861vd_pcm_digital_capture alc880_pcm_digital_capture 10919 10920/* 10921 * configuration and preset 10922 */ 10923static const char *alc861vd_models[ALC861VD_MODEL_LAST] = { 10924 [ALC660VD_3ST] = "3stack-660", 10925 [ALC660VD_3ST_DIG] = "3stack-660-digout", 10926 [ALC861VD_3ST] = "3stack", 10927 [ALC861VD_3ST_DIG] = "3stack-digout", 10928 [ALC861VD_6ST_DIG] = "6stack-digout", 10929 [ALC861VD_LENOVO] = "lenovo", 10930 [ALC861VD_DALLAS] = "dallas", 10931 [ALC861VD_HP] = "hp", 10932 [ALC861VD_AUTO] = "auto", 10933}; 10934 10935static struct snd_pci_quirk alc861vd_cfg_tbl[] = { 10936 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST), 10937 SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST), 10938 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG), 10939 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST), 10940 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST), 10941 10942 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/ 10943 SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS), 10944 SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO), 10945 SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO), 10946 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO), 10947 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO), 10948 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG), 10949 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG), 10950 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP), 10951 {} 10952}; 10953 10954static struct alc_config_preset alc861vd_presets[] = { 10955 [ALC660VD_3ST] = { 10956 .mixers = { alc861vd_3st_mixer }, 10957 .init_verbs = { alc861vd_volume_init_verbs, 10958 alc861vd_3stack_init_verbs }, 10959 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids), 10960 .dac_nids = alc660vd_dac_nids, 10961 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids), 10962 .adc_nids = alc861vd_adc_nids, 10963 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 10964 .channel_mode = alc861vd_3stack_2ch_modes, 10965 .input_mux = &alc861vd_capture_source, 10966 }, 10967 [ALC660VD_3ST_DIG] = { 10968 .mixers = { alc861vd_3st_mixer }, 10969 .init_verbs = { alc861vd_volume_init_verbs, 10970 alc861vd_3stack_init_verbs }, 10971 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids), 10972 .dac_nids = alc660vd_dac_nids, 10973 .dig_out_nid = ALC861VD_DIGOUT_NID, 10974 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids), 10975 .adc_nids = alc861vd_adc_nids, 10976 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 10977 .channel_mode = alc861vd_3stack_2ch_modes, 10978 .input_mux = &alc861vd_capture_source, 10979 }, 10980 [ALC861VD_3ST] = { 10981 .mixers = { alc861vd_3st_mixer }, 10982 .init_verbs = { alc861vd_volume_init_verbs, 10983 alc861vd_3stack_init_verbs }, 10984 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids), 10985 .dac_nids = alc861vd_dac_nids, 10986 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 10987 .channel_mode = alc861vd_3stack_2ch_modes, 10988 .input_mux = &alc861vd_capture_source, 10989 }, 10990 [ALC861VD_3ST_DIG] = { 10991 .mixers = { alc861vd_3st_mixer }, 10992 .init_verbs = { alc861vd_volume_init_verbs, 10993 alc861vd_3stack_init_verbs }, 10994 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids), 10995 .dac_nids = alc861vd_dac_nids, 10996 .dig_out_nid = ALC861VD_DIGOUT_NID, 10997 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 10998 .channel_mode = alc861vd_3stack_2ch_modes, 10999 .input_mux = &alc861vd_capture_source, 11000 }, 11001 [ALC861VD_6ST_DIG] = { 11002 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer }, 11003 .init_verbs = { alc861vd_volume_init_verbs, 11004 alc861vd_6stack_init_verbs }, 11005 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids), 11006 .dac_nids = alc861vd_dac_nids, 11007 .dig_out_nid = ALC861VD_DIGOUT_NID, 11008 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes), 11009 .channel_mode = alc861vd_6stack_modes, 11010 .input_mux = &alc861vd_capture_source, 11011 }, 11012 [ALC861VD_LENOVO] = { 11013 .mixers = { alc861vd_lenovo_mixer }, 11014 .init_verbs = { alc861vd_volume_init_verbs, 11015 alc861vd_3stack_init_verbs, 11016 alc861vd_eapd_verbs, 11017 alc861vd_lenovo_unsol_verbs }, 11018 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids), 11019 .dac_nids = alc660vd_dac_nids, 11020 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids), 11021 .adc_nids = alc861vd_adc_nids, 11022 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 11023 .channel_mode = alc861vd_3stack_2ch_modes, 11024 .input_mux = &alc861vd_capture_source, 11025 .unsol_event = alc861vd_lenovo_unsol_event, 11026 .init_hook = alc861vd_lenovo_automute, 11027 }, 11028 [ALC861VD_DALLAS] = { 11029 .mixers = { alc861vd_dallas_mixer }, 11030 .init_verbs = { alc861vd_dallas_verbs }, 11031 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids), 11032 .dac_nids = alc861vd_dac_nids, 11033 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids), 11034 .adc_nids = alc861vd_adc_nids, 11035 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 11036 .channel_mode = alc861vd_3stack_2ch_modes, 11037 .input_mux = &alc861vd_dallas_capture_source, 11038 .unsol_event = alc861vd_dallas_unsol_event, 11039 .init_hook = alc861vd_dallas_automute, 11040 }, 11041 [ALC861VD_HP] = { 11042 .mixers = { alc861vd_hp_mixer }, 11043 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs }, 11044 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids), 11045 .dac_nids = alc861vd_dac_nids, 11046 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids), 11047 .dig_out_nid = ALC861VD_DIGOUT_NID, 11048 .adc_nids = alc861vd_adc_nids, 11049 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 11050 .channel_mode = alc861vd_3stack_2ch_modes, 11051 .input_mux = &alc861vd_hp_capture_source, 11052 .unsol_event = alc861vd_dallas_unsol_event, 11053 .init_hook = alc861vd_dallas_automute, 11054 }, 11055}; 11056 11057/* 11058 * BIOS auto configuration 11059 */ 11060static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec, 11061 hda_nid_t nid, int pin_type, int dac_idx) 11062{ 11063 /* set as output */ 11064 snd_hda_codec_write(codec, nid, 0, 11065 AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type); 11066 snd_hda_codec_write(codec, nid, 0, 11067 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); 11068} 11069 11070static void alc861vd_auto_init_multi_out(struct hda_codec *codec) 11071{ 11072 struct alc_spec *spec = codec->spec; 11073 int i; 11074 11075 alc_subsystem_id(codec, 0x15, 0x1b, 0x14); 11076 for (i = 0; i <= HDA_SIDE; i++) { 11077 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 11078 int pin_type = get_pin_type(spec->autocfg.line_out_type); 11079 if (nid) 11080 alc861vd_auto_set_output_and_unmute(codec, nid, 11081 pin_type, i); 11082 } 11083} 11084 11085 11086static void alc861vd_auto_init_hp_out(struct hda_codec *codec) 11087{ 11088 struct alc_spec *spec = codec->spec; 11089 hda_nid_t pin; 11090 11091 pin = spec->autocfg.hp_pins[0]; 11092 if (pin) /* connect to front and use dac 0 */ 11093 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); 11094} 11095 11096#define alc861vd_is_input_pin(nid) alc880_is_input_pin(nid) 11097#define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID 11098 11099static void alc861vd_auto_init_analog_input(struct hda_codec *codec) 11100{ 11101 struct alc_spec *spec = codec->spec; 11102 int i; 11103 11104 for (i = 0; i < AUTO_PIN_LAST; i++) { 11105 hda_nid_t nid = spec->autocfg.input_pins[i]; 11106 if (alc861vd_is_input_pin(nid)) { 11107 snd_hda_codec_write(codec, nid, 0, 11108 AC_VERB_SET_PIN_WIDGET_CONTROL, 11109 i <= AUTO_PIN_FRONT_MIC ? 11110 PIN_VREF80 : PIN_IN); 11111 if (nid != ALC861VD_PIN_CD_NID) 11112 snd_hda_codec_write(codec, nid, 0, 11113 AC_VERB_SET_AMP_GAIN_MUTE, 11114 AMP_OUT_MUTE); 11115 } 11116 } 11117} 11118 11119#define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02) 11120#define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c) 11121 11122/* add playback controls from the parsed DAC table */ 11123/* Based on ALC880 version. But ALC861VD has separate, 11124 * different NIDs for mute/unmute switch and volume control */ 11125static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec, 11126 const struct auto_pin_cfg *cfg) 11127{ 11128 char name[32]; 11129 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"}; 11130 hda_nid_t nid_v, nid_s; 11131 int i, err; 11132 11133 for (i = 0; i < cfg->line_outs; i++) { 11134 if (!spec->multiout.dac_nids[i]) 11135 continue; 11136 nid_v = alc861vd_idx_to_mixer_vol( 11137 alc880_dac_to_idx( 11138 spec->multiout.dac_nids[i])); 11139 nid_s = alc861vd_idx_to_mixer_switch( 11140 alc880_dac_to_idx( 11141 spec->multiout.dac_nids[i])); 11142 11143 if (i == 2) { 11144 /* Center/LFE */ 11145 err = add_control(spec, ALC_CTL_WIDGET_VOL, 11146 "Center Playback Volume", 11147 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0, 11148 HDA_OUTPUT)); 11149 if (err < 0) 11150 return err; 11151 err = add_control(spec, ALC_CTL_WIDGET_VOL, 11152 "LFE Playback Volume", 11153 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0, 11154 HDA_OUTPUT)); 11155 if (err < 0) 11156 return err; 11157 err = add_control(spec, ALC_CTL_BIND_MUTE, 11158 "Center Playback Switch", 11159 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2, 11160 HDA_INPUT)); 11161 if (err < 0) 11162 return err; 11163 err = add_control(spec, ALC_CTL_BIND_MUTE, 11164 "LFE Playback Switch", 11165 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2, 11166 HDA_INPUT)); 11167 if (err < 0) 11168 return err; 11169 } else { 11170 sprintf(name, "%s Playback Volume", chname[i]); 11171 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, 11172 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, 11173 HDA_OUTPUT)); 11174 if (err < 0) 11175 return err; 11176 sprintf(name, "%s Playback Switch", chname[i]); 11177 err = add_control(spec, ALC_CTL_BIND_MUTE, name, 11178 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, 11179 HDA_INPUT)); 11180 if (err < 0) 11181 return err; 11182 } 11183 } 11184 return 0; 11185} 11186 11187/* add playback controls for speaker and HP outputs */ 11188/* Based on ALC880 version. But ALC861VD has separate, 11189 * different NIDs for mute/unmute switch and volume control */ 11190static int alc861vd_auto_create_extra_out(struct alc_spec *spec, 11191 hda_nid_t pin, const char *pfx) 11192{ 11193 hda_nid_t nid_v, nid_s; 11194 int err; 11195 char name[32]; 11196 11197 if (!pin) 11198 return 0; 11199 11200 if (alc880_is_fixed_pin(pin)) { 11201 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); 11202 /* specify the DAC as the extra output */ 11203 if (!spec->multiout.hp_nid) 11204 spec->multiout.hp_nid = nid_v; 11205 else 11206 spec->multiout.extra_out_nid[0] = nid_v; 11207 /* control HP volume/switch on the output mixer amp */ 11208 nid_v = alc861vd_idx_to_mixer_vol( 11209 alc880_fixed_pin_idx(pin)); 11210 nid_s = alc861vd_idx_to_mixer_switch( 11211 alc880_fixed_pin_idx(pin)); 11212 11213 sprintf(name, "%s Playback Volume", pfx); 11214 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, 11215 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT)); 11216 if (err < 0) 11217 return err; 11218 sprintf(name, "%s Playback Switch", pfx); 11219 err = add_control(spec, ALC_CTL_BIND_MUTE, name, 11220 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT)); 11221 if (err < 0) 11222 return err; 11223 } else if (alc880_is_multi_pin(pin)) { 11224 /* set manual connection */ 11225 /* we have only a switch on HP-out PIN */ 11226 sprintf(name, "%s Playback Switch", pfx); 11227 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, 11228 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); 11229 if (err < 0) 11230 return err; 11231 } 11232 return 0; 11233} 11234 11235/* parse the BIOS configuration and set up the alc_spec 11236 * return 1 if successful, 0 if the proper config is not found, 11237 * or a negative error code 11238 * Based on ALC880 version - had to change it to override 11239 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */ 11240static int alc861vd_parse_auto_config(struct hda_codec *codec) 11241{ 11242 struct alc_spec *spec = codec->spec; 11243 int err; 11244 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 }; 11245 11246 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 11247 alc861vd_ignore); 11248 if (err < 0) 11249 return err; 11250 if (!spec->autocfg.line_outs) 11251 return 0; /* can't find valid BIOS pin config */ 11252 11253 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); 11254 if (err < 0) 11255 return err; 11256 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg); 11257 if (err < 0) 11258 return err; 11259 err = alc861vd_auto_create_extra_out(spec, 11260 spec->autocfg.speaker_pins[0], 11261 "Speaker"); 11262 if (err < 0) 11263 return err; 11264 err = alc861vd_auto_create_extra_out(spec, 11265 spec->autocfg.hp_pins[0], 11266 "Headphone"); 11267 if (err < 0) 11268 return err; 11269 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg); 11270 if (err < 0) 11271 return err; 11272 11273 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 11274 11275 if (spec->autocfg.dig_out_pin) 11276 spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID; 11277 11278 if (spec->kctl_alloc) 11279 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 11280 11281 spec->init_verbs[spec->num_init_verbs++] 11282 = alc861vd_volume_init_verbs; 11283 11284 spec->num_mux_defs = 1; 11285 spec->input_mux = &spec->private_imux; 11286 11287 err = alc_auto_add_mic_boost(codec); 11288 if (err < 0) 11289 return err; 11290 11291 return 1; 11292} 11293 11294/* additional initialization for auto-configuration model */ 11295static void alc861vd_auto_init(struct hda_codec *codec) 11296{ 11297 alc861vd_auto_init_multi_out(codec); 11298 alc861vd_auto_init_hp_out(codec); 11299 alc861vd_auto_init_analog_input(codec); 11300} 11301 11302static int patch_alc861vd(struct hda_codec *codec) 11303{ 11304 struct alc_spec *spec; 11305 int err, board_config; 11306 11307 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 11308 if (spec == NULL) 11309 return -ENOMEM; 11310 11311 codec->spec = spec; 11312 11313 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST, 11314 alc861vd_models, 11315 alc861vd_cfg_tbl); 11316 11317 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) { 11318 printk(KERN_INFO "hda_codec: Unknown model for ALC660VD/" 11319 "ALC861VD, trying auto-probe from BIOS...\n"); 11320 board_config = ALC861VD_AUTO; 11321 } 11322 11323 if (board_config == ALC861VD_AUTO) { 11324 /* automatic parse from the BIOS config */ 11325 err = alc861vd_parse_auto_config(codec); 11326 if (err < 0) { 11327 alc_free(codec); 11328 return err; 11329 } else if (!err) { 11330 printk(KERN_INFO 11331 "hda_codec: Cannot set up configuration " 11332 "from BIOS. Using base mode...\n"); 11333 board_config = ALC861VD_3ST; 11334 } 11335 } 11336 11337 if (board_config != ALC861VD_AUTO) 11338 setup_preset(spec, &alc861vd_presets[board_config]); 11339 11340 spec->stream_name_analog = "ALC861VD Analog"; 11341 spec->stream_analog_playback = &alc861vd_pcm_analog_playback; 11342 spec->stream_analog_capture = &alc861vd_pcm_analog_capture; 11343 11344 spec->stream_name_digital = "ALC861VD Digital"; 11345 spec->stream_digital_playback = &alc861vd_pcm_digital_playback; 11346 spec->stream_digital_capture = &alc861vd_pcm_digital_capture; 11347 11348 spec->adc_nids = alc861vd_adc_nids; 11349 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids); 11350 11351 spec->mixers[spec->num_mixers] = alc861vd_capture_mixer; 11352 spec->num_mixers++; 11353 11354 codec->patch_ops = alc_patch_ops; 11355 11356 if (board_config == ALC861VD_AUTO) 11357 spec->init_hook = alc861vd_auto_init; 11358#ifdef CONFIG_SND_HDA_POWER_SAVE 11359 if (!spec->loopback.amplist) 11360 spec->loopback.amplist = alc861vd_loopbacks; 11361#endif 11362 11363 return 0; 11364} 11365 11366/* 11367 * ALC662 support 11368 * 11369 * ALC662 is almost identical with ALC880 but has cleaner and more flexible 11370 * configuration. Each pin widget can choose any input DACs and a mixer. 11371 * Each ADC is connected from a mixer of all inputs. This makes possible 11372 * 6-channel independent captures. 11373 * 11374 * In addition, an independent DAC for the multi-playback (not used in this 11375 * driver yet). 11376 */ 11377#define ALC662_DIGOUT_NID 0x06 11378#define ALC662_DIGIN_NID 0x0a 11379 11380static hda_nid_t alc662_dac_nids[4] = { 11381 /* front, rear, clfe, rear_surr */ 11382 0x02, 0x03, 0x04 11383}; 11384 11385static hda_nid_t alc662_adc_nids[1] = { 11386 /* ADC1-2 */ 11387 0x09, 11388}; 11389/* input MUX */ 11390/* FIXME: should be a matrix-type input source selection */ 11391 11392static struct hda_input_mux alc662_capture_source = { 11393 .num_items = 4, 11394 .items = { 11395 { "Mic", 0x0 }, 11396 { "Front Mic", 0x1 }, 11397 { "Line", 0x2 }, 11398 { "CD", 0x4 }, 11399 }, 11400}; 11401 11402static struct hda_input_mux alc662_lenovo_101e_capture_source = { 11403 .num_items = 2, 11404 .items = { 11405 { "Mic", 0x1 }, 11406 { "Line", 0x2 }, 11407 }, 11408}; 11409#define alc662_mux_enum_info alc_mux_enum_info 11410#define alc662_mux_enum_get alc_mux_enum_get 11411 11412static int alc662_mux_enum_put(struct snd_kcontrol *kcontrol, 11413 struct snd_ctl_elem_value *ucontrol) 11414{ 11415 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 11416 struct alc_spec *spec = codec->spec; 11417 const struct hda_input_mux *imux = spec->input_mux; 11418 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 11419 static hda_nid_t capture_mixers[2] = { 0x23, 0x22 }; 11420 hda_nid_t nid = capture_mixers[adc_idx]; 11421 unsigned int *cur_val = &spec->cur_mux[adc_idx]; 11422 unsigned int i, idx; 11423 11424 idx = ucontrol->value.enumerated.item[0]; 11425 if (idx >= imux->num_items) 11426 idx = imux->num_items - 1; 11427 if (*cur_val == idx) 11428 return 0; 11429 for (i = 0; i < imux->num_items; i++) { 11430 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE; 11431 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 11432 imux->items[i].index, 11433 HDA_AMP_MUTE, v); 11434 } 11435 *cur_val = idx; 11436 return 1; 11437} 11438/* 11439 * 2ch mode 11440 */ 11441static struct hda_channel_mode alc662_3ST_2ch_modes[1] = { 11442 { 2, NULL } 11443}; 11444 11445/* 11446 * 2ch mode 11447 */ 11448static struct hda_verb alc662_3ST_ch2_init[] = { 11449 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 11450 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 11451 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 11452 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 11453 { } /* end */ 11454}; 11455 11456/* 11457 * 6ch mode 11458 */ 11459static struct hda_verb alc662_3ST_ch6_init[] = { 11460 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 11461 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 11462 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, 11463 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 11464 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 11465 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 11466 { } /* end */ 11467}; 11468 11469static struct hda_channel_mode alc662_3ST_6ch_modes[2] = { 11470 { 2, alc662_3ST_ch2_init }, 11471 { 6, alc662_3ST_ch6_init }, 11472}; 11473 11474/* 11475 * 2ch mode 11476 */ 11477static struct hda_verb alc662_sixstack_ch6_init[] = { 11478 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 11479 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 11480 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 11481 { } /* end */ 11482}; 11483 11484/* 11485 * 6ch mode 11486 */ 11487static struct hda_verb alc662_sixstack_ch8_init[] = { 11488 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 11489 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 11490 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 11491 { } /* end */ 11492}; 11493 11494static struct hda_channel_mode alc662_5stack_modes[2] = { 11495 { 2, alc662_sixstack_ch6_init }, 11496 { 6, alc662_sixstack_ch8_init }, 11497}; 11498 11499/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 11500 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b 11501 */ 11502 11503static struct snd_kcontrol_new alc662_base_mixer[] = { 11504 /* output mixer control */ 11505 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), 11506 HDA_CODEC_MUTE("Front Playback Switch", 0x02, 0x0, HDA_OUTPUT), 11507 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT), 11508 HDA_CODEC_MUTE("Surround Playback Switch", 0x03, 0x0, HDA_OUTPUT), 11509 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT), 11510 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT), 11511 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT), 11512 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT), 11513 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 11514 11515 /*Input mixer control */ 11516 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT), 11517 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT), 11518 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT), 11519 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT), 11520 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT), 11521 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT), 11522 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT), 11523 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT), 11524 11525 /* Capture mixer control */ 11526 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), 11527 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), 11528 { 11529 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 11530 .name = "Capture Source", 11531 .count = 1, 11532 .info = alc_mux_enum_info, 11533 .get = alc_mux_enum_get, 11534 .put = alc_mux_enum_put, 11535 }, 11536 { } /* end */ 11537}; 11538 11539static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = { 11540 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 11541 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT), 11542 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 11543 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 11544 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 11545 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 11546 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 11547 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11548 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11549 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 11550 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 11551 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 11552 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 11553 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), 11554 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), 11555 { 11556 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 11557 /* .name = "Capture Source", */ 11558 .name = "Input Source", 11559 .count = 1, 11560 .info = alc662_mux_enum_info, 11561 .get = alc662_mux_enum_get, 11562 .put = alc662_mux_enum_put, 11563 }, 11564 { } /* end */ 11565}; 11566 11567static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = { 11568 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 11569 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT), 11570 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT), 11571 HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT), 11572 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT), 11573 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT), 11574 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT), 11575 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT), 11576 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 11577 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 11578 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 11579 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 11580 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 11581 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11582 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11583 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 11584 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 11585 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 11586 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 11587 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), 11588 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), 11589 { 11590 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 11591 /* .name = "Capture Source", */ 11592 .name = "Input Source", 11593 .count = 1, 11594 .info = alc662_mux_enum_info, 11595 .get = alc662_mux_enum_get, 11596 .put = alc662_mux_enum_put, 11597 }, 11598 { } /* end */ 11599}; 11600 11601static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = { 11602 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 11603 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT), 11604 HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x03, 0x0, HDA_OUTPUT), 11605 HDA_BIND_MUTE("iSpeaker Playback Switch", 0x03, 2, HDA_INPUT), 11606 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 11607 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 11608 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 11609 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 11610 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 11611 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), 11612 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), 11613 { 11614 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 11615 /* .name = "Capture Source", */ 11616 .name = "Input Source", 11617 .count = 1, 11618 .info = alc662_mux_enum_info, 11619 .get = alc662_mux_enum_get, 11620 .put = alc662_mux_enum_put, 11621 }, 11622 { } /* end */ 11623}; 11624 11625static struct snd_kcontrol_new alc662_chmode_mixer[] = { 11626 { 11627 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 11628 .name = "Channel Mode", 11629 .info = alc_ch_mode_info, 11630 .get = alc_ch_mode_get, 11631 .put = alc_ch_mode_put, 11632 }, 11633 { } /* end */ 11634}; 11635 11636static struct hda_verb alc662_init_verbs[] = { 11637 /* ADC: mute amp left and right */ 11638 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 11639 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 11640 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 11641 11642 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 11643 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 11644 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 11645 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 11646 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 11647 11648 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11649 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11650 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11651 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11652 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11653 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11654 11655 /* Front Pin: output 0 (0x0c) */ 11656 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 11657 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 11658 11659 /* Rear Pin: output 1 (0x0d) */ 11660 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 11661 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 11662 11663 /* CLFE Pin: output 2 (0x0e) */ 11664 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 11665 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 11666 11667 /* Mic (rear) pin: input vref at 80% */ 11668 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 11669 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 11670 /* Front Mic pin: input vref at 80% */ 11671 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 11672 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 11673 /* Line In pin: input */ 11674 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 11675 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 11676 /* Line-2 In: Headphone output (output 0 - 0x0c) */ 11677 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11678 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 11679 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 11680 /* CD pin widget for input */ 11681 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 11682 11683 /* FIXME: use matrix-type input source selection */ 11684 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 11685 /* Input mixer */ 11686 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11687 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11688 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 11689 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, 11690 { } 11691}; 11692 11693static struct hda_verb alc662_sue_init_verbs[] = { 11694 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT}, 11695 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT}, 11696 {} 11697}; 11698 11699/* 11700 * generic initialization of ADC, input mixers and output mixers 11701 */ 11702static struct hda_verb alc662_auto_init_verbs[] = { 11703 /* 11704 * Unmute ADC and set the default input to mic-in 11705 */ 11706 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 11707 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11708 11709 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 11710 * mixer widget 11711 * Note: PASD motherboards uses the Line In 2 as the input for front 11712 * panel mic (mic 2) 11713 */ 11714 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 11715 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 11716 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 11717 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 11718 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 11719 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 11720 11721 /* 11722 * Set up output mixers (0x0c - 0x0f) 11723 */ 11724 /* set vol=0 to output mixers */ 11725 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 11726 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 11727 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 11728 11729 /* set up input amps for analog loopback */ 11730 /* Amp Indices: DAC = 0, mixer = 1 */ 11731 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11732 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11733 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11734 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11735 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11736 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11737 11738 11739 /* FIXME: use matrix-type input source selection */ 11740 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 11741 /* Input mixer */ 11742 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11743 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11744 { } 11745}; 11746 11747/* capture mixer elements */ 11748static struct snd_kcontrol_new alc662_capture_mixer[] = { 11749 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), 11750 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), 11751 { 11752 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 11753 /* The multiple "Capture Source" controls confuse alsamixer 11754 * So call somewhat different.. 11755 * FIXME: the controls appear in the "playback" view! 11756 */ 11757 /* .name = "Capture Source", */ 11758 .name = "Input Source", 11759 .count = 1, 11760 .info = alc882_mux_enum_info, 11761 .get = alc882_mux_enum_get, 11762 .put = alc882_mux_enum_put, 11763 }, 11764 { } /* end */ 11765}; 11766 11767static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec) 11768{ 11769 unsigned int present; 11770 unsigned char bits; 11771 11772 present = snd_hda_codec_read(codec, 0x14, 0, 11773 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 11774 bits = present ? HDA_AMP_MUTE : 0; 11775 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 11776 HDA_AMP_MUTE, bits); 11777} 11778 11779static void alc662_lenovo_101e_all_automute(struct hda_codec *codec) 11780{ 11781 unsigned int present; 11782 unsigned char bits; 11783 11784 present = snd_hda_codec_read(codec, 0x1b, 0, 11785 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 11786 bits = present ? HDA_AMP_MUTE : 0; 11787 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 11788 HDA_AMP_MUTE, bits); 11789 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 11790 HDA_AMP_MUTE, bits); 11791} 11792 11793static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec, 11794 unsigned int res) 11795{ 11796 if ((res >> 26) == ALC880_HP_EVENT) 11797 alc662_lenovo_101e_all_automute(codec); 11798 if ((res >> 26) == ALC880_FRONT_EVENT) 11799 alc662_lenovo_101e_ispeaker_automute(codec); 11800} 11801 11802#ifdef CONFIG_SND_HDA_POWER_SAVE 11803#define alc662_loopbacks alc880_loopbacks 11804#endif 11805 11806 11807/* pcm configuration: identiacal with ALC880 */ 11808#define alc662_pcm_analog_playback alc880_pcm_analog_playback 11809#define alc662_pcm_analog_capture alc880_pcm_analog_capture 11810#define alc662_pcm_digital_playback alc880_pcm_digital_playback 11811#define alc662_pcm_digital_capture alc880_pcm_digital_capture 11812 11813/* 11814 * configuration and preset 11815 */ 11816static const char *alc662_models[ALC662_MODEL_LAST] = { 11817 [ALC662_3ST_2ch_DIG] = "3stack-dig", 11818 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig", 11819 [ALC662_3ST_6ch] = "3stack-6ch", 11820 [ALC662_5ST_DIG] = "6stack-dig", 11821 [ALC662_LENOVO_101E] = "lenovo-101e", 11822 [ALC662_AUTO] = "auto", 11823}; 11824 11825static struct snd_pci_quirk alc662_cfg_tbl[] = { 11826 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E), 11827 {} 11828}; 11829 11830static struct alc_config_preset alc662_presets[] = { 11831 [ALC662_3ST_2ch_DIG] = { 11832 .mixers = { alc662_3ST_2ch_mixer }, 11833 .init_verbs = { alc662_init_verbs }, 11834 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 11835 .dac_nids = alc662_dac_nids, 11836 .dig_out_nid = ALC662_DIGOUT_NID, 11837 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids), 11838 .adc_nids = alc662_adc_nids, 11839 .dig_in_nid = ALC662_DIGIN_NID, 11840 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 11841 .channel_mode = alc662_3ST_2ch_modes, 11842 .input_mux = &alc662_capture_source, 11843 }, 11844 [ALC662_3ST_6ch_DIG] = { 11845 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer }, 11846 .init_verbs = { alc662_init_verbs }, 11847 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 11848 .dac_nids = alc662_dac_nids, 11849 .dig_out_nid = ALC662_DIGOUT_NID, 11850 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids), 11851 .adc_nids = alc662_adc_nids, 11852 .dig_in_nid = ALC662_DIGIN_NID, 11853 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), 11854 .channel_mode = alc662_3ST_6ch_modes, 11855 .need_dac_fix = 1, 11856 .input_mux = &alc662_capture_source, 11857 }, 11858 [ALC662_3ST_6ch] = { 11859 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer }, 11860 .init_verbs = { alc662_init_verbs }, 11861 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 11862 .dac_nids = alc662_dac_nids, 11863 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids), 11864 .adc_nids = alc662_adc_nids, 11865 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), 11866 .channel_mode = alc662_3ST_6ch_modes, 11867 .need_dac_fix = 1, 11868 .input_mux = &alc662_capture_source, 11869 }, 11870 [ALC662_5ST_DIG] = { 11871 .mixers = { alc662_base_mixer, alc662_chmode_mixer }, 11872 .init_verbs = { alc662_init_verbs }, 11873 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 11874 .dac_nids = alc662_dac_nids, 11875 .dig_out_nid = ALC662_DIGOUT_NID, 11876 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids), 11877 .adc_nids = alc662_adc_nids, 11878 .dig_in_nid = ALC662_DIGIN_NID, 11879 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes), 11880 .channel_mode = alc662_5stack_modes, 11881 .input_mux = &alc662_capture_source, 11882 }, 11883 [ALC662_LENOVO_101E] = { 11884 .mixers = { alc662_lenovo_101e_mixer }, 11885 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs }, 11886 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 11887 .dac_nids = alc662_dac_nids, 11888 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids), 11889 .adc_nids = alc662_adc_nids, 11890 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 11891 .channel_mode = alc662_3ST_2ch_modes, 11892 .input_mux = &alc662_lenovo_101e_capture_source, 11893 .unsol_event = alc662_lenovo_101e_unsol_event, 11894 .init_hook = alc662_lenovo_101e_all_automute, 11895 }, 11896 11897}; 11898 11899 11900/* 11901 * BIOS auto configuration 11902 */ 11903 11904/* add playback controls from the parsed DAC table */ 11905static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec, 11906 const struct auto_pin_cfg *cfg) 11907{ 11908 char name[32]; 11909 static const char *chname[4] = { 11910 "Front", "Surround", NULL /*CLFE*/, "Side" 11911 }; 11912 hda_nid_t nid; 11913 int i, err; 11914 11915 for (i = 0; i < cfg->line_outs; i++) { 11916 if (!spec->multiout.dac_nids[i]) 11917 continue; 11918 nid = alc880_idx_to_mixer(i); 11919 if (i == 2) { 11920 /* Center/LFE */ 11921 err = add_control(spec, ALC_CTL_WIDGET_VOL, 11922 "Center Playback Volume", 11923 HDA_COMPOSE_AMP_VAL(nid, 1, 0, 11924 HDA_OUTPUT)); 11925 if (err < 0) 11926 return err; 11927 err = add_control(spec, ALC_CTL_WIDGET_VOL, 11928 "LFE Playback Volume", 11929 HDA_COMPOSE_AMP_VAL(nid, 2, 0, 11930 HDA_OUTPUT)); 11931 if (err < 0) 11932 return err; 11933 err = add_control(spec, ALC_CTL_BIND_MUTE, 11934 "Center Playback Switch", 11935 HDA_COMPOSE_AMP_VAL(nid, 1, 2, 11936 HDA_INPUT)); 11937 if (err < 0) 11938 return err; 11939 err = add_control(spec, ALC_CTL_BIND_MUTE, 11940 "LFE Playback Switch", 11941 HDA_COMPOSE_AMP_VAL(nid, 2, 2, 11942 HDA_INPUT)); 11943 if (err < 0) 11944 return err; 11945 } else { 11946 sprintf(name, "%s Playback Volume", chname[i]); 11947 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, 11948 HDA_COMPOSE_AMP_VAL(nid, 3, 0, 11949 HDA_OUTPUT)); 11950 if (err < 0) 11951 return err; 11952 sprintf(name, "%s Playback Switch", chname[i]); 11953 err = add_control(spec, ALC_CTL_BIND_MUTE, name, 11954 HDA_COMPOSE_AMP_VAL(nid, 3, 2, 11955 HDA_INPUT)); 11956 if (err < 0) 11957 return err; 11958 } 11959 } 11960 return 0; 11961} 11962 11963/* add playback controls for speaker and HP outputs */ 11964static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin, 11965 const char *pfx) 11966{ 11967 hda_nid_t nid; 11968 int err; 11969 char name[32]; 11970 11971 if (!pin) 11972 return 0; 11973 11974 if (alc880_is_fixed_pin(pin)) { 11975 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); 11976 /* printk("DAC nid=%x\n",nid); */ 11977 /* specify the DAC as the extra output */ 11978 if (!spec->multiout.hp_nid) 11979 spec->multiout.hp_nid = nid; 11980 else 11981 spec->multiout.extra_out_nid[0] = nid; 11982 /* control HP volume/switch on the output mixer amp */ 11983 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); 11984 sprintf(name, "%s Playback Volume", pfx); 11985 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, 11986 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); 11987 if (err < 0) 11988 return err; 11989 sprintf(name, "%s Playback Switch", pfx); 11990 err = add_control(spec, ALC_CTL_BIND_MUTE, name, 11991 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT)); 11992 if (err < 0) 11993 return err; 11994 } else if (alc880_is_multi_pin(pin)) { 11995 /* set manual connection */ 11996 /* we have only a switch on HP-out PIN */ 11997 sprintf(name, "%s Playback Switch", pfx); 11998 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, 11999 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); 12000 if (err < 0) 12001 return err; 12002 } 12003 return 0; 12004} 12005 12006/* create playback/capture controls for input pins */ 12007static int alc662_auto_create_analog_input_ctls(struct alc_spec *spec, 12008 const struct auto_pin_cfg *cfg) 12009{ 12010 struct hda_input_mux *imux = &spec->private_imux; 12011 int i, err, idx; 12012 12013 for (i = 0; i < AUTO_PIN_LAST; i++) { 12014 if (alc880_is_input_pin(cfg->input_pins[i])) { 12015 idx = alc880_input_pin_idx(cfg->input_pins[i]); 12016 err = new_analog_input(spec, cfg->input_pins[i], 12017 auto_pin_cfg_labels[i], 12018 idx, 0x0b); 12019 if (err < 0) 12020 return err; 12021 imux->items[imux->num_items].label = 12022 auto_pin_cfg_labels[i]; 12023 imux->items[imux->num_items].index = 12024 alc880_input_pin_idx(cfg->input_pins[i]); 12025 imux->num_items++; 12026 } 12027 } 12028 return 0; 12029} 12030 12031static void alc662_auto_set_output_and_unmute(struct hda_codec *codec, 12032 hda_nid_t nid, int pin_type, 12033 int dac_idx) 12034{ 12035 /* set as output */ 12036 snd_hda_codec_write(codec, nid, 0, 12037 AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type); 12038 snd_hda_codec_write(codec, nid, 0, 12039 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); 12040 /* need the manual connection? */ 12041 if (alc880_is_multi_pin(nid)) { 12042 struct alc_spec *spec = codec->spec; 12043 int idx = alc880_multi_pin_idx(nid); 12044 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0, 12045 AC_VERB_SET_CONNECT_SEL, 12046 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx])); 12047 } 12048} 12049 12050static void alc662_auto_init_multi_out(struct hda_codec *codec) 12051{ 12052 struct alc_spec *spec = codec->spec; 12053 int i; 12054 12055 for (i = 0; i <= HDA_SIDE; i++) { 12056 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 12057 int pin_type = get_pin_type(spec->autocfg.line_out_type); 12058 if (nid) 12059 alc662_auto_set_output_and_unmute(codec, nid, pin_type, 12060 i); 12061 } 12062} 12063 12064static void alc662_auto_init_hp_out(struct hda_codec *codec) 12065{ 12066 struct alc_spec *spec = codec->spec; 12067 hda_nid_t pin; 12068 12069 pin = spec->autocfg.hp_pins[0]; 12070 if (pin) /* connect to front */ 12071 /* use dac 0 */ 12072 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); 12073} 12074 12075#define alc662_is_input_pin(nid) alc880_is_input_pin(nid) 12076#define ALC662_PIN_CD_NID ALC880_PIN_CD_NID 12077 12078static void alc662_auto_init_analog_input(struct hda_codec *codec) 12079{ 12080 struct alc_spec *spec = codec->spec; 12081 int i; 12082 12083 for (i = 0; i < AUTO_PIN_LAST; i++) { 12084 hda_nid_t nid = spec->autocfg.input_pins[i]; 12085 if (alc662_is_input_pin(nid)) { 12086 snd_hda_codec_write(codec, nid, 0, 12087 AC_VERB_SET_PIN_WIDGET_CONTROL, 12088 (i <= AUTO_PIN_FRONT_MIC ? 12089 PIN_VREF80 : PIN_IN)); 12090 if (nid != ALC662_PIN_CD_NID) 12091 snd_hda_codec_write(codec, nid, 0, 12092 AC_VERB_SET_AMP_GAIN_MUTE, 12093 AMP_OUT_MUTE); 12094 } 12095 } 12096} 12097 12098static int alc662_parse_auto_config(struct hda_codec *codec) 12099{ 12100 struct alc_spec *spec = codec->spec; 12101 int err; 12102 static hda_nid_t alc662_ignore[] = { 0x1d, 0 }; 12103 12104 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 12105 alc662_ignore); 12106 if (err < 0) 12107 return err; 12108 if (!spec->autocfg.line_outs) 12109 return 0; /* can't find valid BIOS pin config */ 12110 12111 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); 12112 if (err < 0) 12113 return err; 12114 err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg); 12115 if (err < 0) 12116 return err; 12117 err = alc662_auto_create_extra_out(spec, 12118 spec->autocfg.speaker_pins[0], 12119 "Speaker"); 12120 if (err < 0) 12121 return err; 12122 err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0], 12123 "Headphone"); 12124 if (err < 0) 12125 return err; 12126 err = alc662_auto_create_analog_input_ctls(spec, &spec->autocfg); 12127 if (err < 0) 12128 return err; 12129 12130 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 12131 12132 if (spec->autocfg.dig_out_pin) 12133 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID; 12134 12135 if (spec->kctl_alloc) 12136 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 12137 12138 spec->num_mux_defs = 1; 12139 spec->input_mux = &spec->private_imux; 12140 12141 spec->init_verbs[spec->num_init_verbs++] = alc662_auto_init_verbs; 12142 spec->mixers[spec->num_mixers] = alc662_capture_mixer; 12143 spec->num_mixers++; 12144 return 1; 12145} 12146 12147/* additional initialization for auto-configuration model */ 12148static void alc662_auto_init(struct hda_codec *codec) 12149{ 12150 alc662_auto_init_multi_out(codec); 12151 alc662_auto_init_hp_out(codec); 12152 alc662_auto_init_analog_input(codec); 12153} 12154 12155static int patch_alc662(struct hda_codec *codec) 12156{ 12157 struct alc_spec *spec; 12158 int err, board_config; 12159 12160 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 12161 if (!spec) 12162 return -ENOMEM; 12163 12164 codec->spec = spec; 12165 12166 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST, 12167 alc662_models, 12168 alc662_cfg_tbl); 12169 if (board_config < 0) { 12170 printk(KERN_INFO "hda_codec: Unknown model for ALC662, " 12171 "trying auto-probe from BIOS...\n"); 12172 board_config = ALC662_AUTO; 12173 } 12174 12175 if (board_config == ALC662_AUTO) { 12176 /* automatic parse from the BIOS config */ 12177 err = alc662_parse_auto_config(codec); 12178 if (err < 0) { 12179 alc_free(codec); 12180 return err; 12181 } else if (!err) { 12182 printk(KERN_INFO 12183 "hda_codec: Cannot set up configuration " 12184 "from BIOS. Using base mode...\n"); 12185 board_config = ALC662_3ST_2ch_DIG; 12186 } 12187 } 12188 12189 if (board_config != ALC662_AUTO) 12190 setup_preset(spec, &alc662_presets[board_config]); 12191 12192 spec->stream_name_analog = "ALC662 Analog"; 12193 spec->stream_analog_playback = &alc662_pcm_analog_playback; 12194 spec->stream_analog_capture = &alc662_pcm_analog_capture; 12195 12196 spec->stream_name_digital = "ALC662 Digital"; 12197 spec->stream_digital_playback = &alc662_pcm_digital_playback; 12198 spec->stream_digital_capture = &alc662_pcm_digital_capture; 12199 12200 if (!spec->adc_nids && spec->input_mux) { 12201 spec->adc_nids = alc662_adc_nids; 12202 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids); 12203 } 12204 12205 codec->patch_ops = alc_patch_ops; 12206 if (board_config == ALC662_AUTO) 12207 spec->init_hook = alc662_auto_init; 12208#ifdef CONFIG_SND_HDA_POWER_SAVE 12209 if (!spec->loopback.amplist) 12210 spec->loopback.amplist = alc662_loopbacks; 12211#endif 12212 12213 return 0; 12214} 12215 12216/* 12217 * patch entries 12218 */ 12219struct hda_codec_preset snd_hda_preset_realtek[] = { 12220 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 }, 12221 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 }, 12222 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 }, 12223 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660", 12224 .patch = patch_alc861 }, 12225 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd }, 12226 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 }, 12227 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd }, 12228 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2", 12229 .patch = patch_alc883 }, 12230 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1", 12231 .patch = patch_alc662 }, 12232 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 }, 12233 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 }, 12234 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 }, 12235 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 }, 12236 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 }, 12237 {} /* terminator */ 12238}; 12239