patch_realtek.c revision 6bc9685796529754acd819d9c979227d823c408d
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 ALC885_MACPRO, 159 ALC885_MBP3, 160 ALC885_IMAC24, 161 ALC882_AUTO, 162 ALC882_MODEL_LAST, 163}; 164 165/* ALC883 models */ 166enum { 167 ALC883_3ST_2ch_DIG, 168 ALC883_3ST_6ch_DIG, 169 ALC883_3ST_6ch, 170 ALC883_6ST_DIG, 171 ALC883_TARGA_DIG, 172 ALC883_TARGA_2ch_DIG, 173 ALC883_ACER, 174 ALC883_ACER_ASPIRE, 175 ALC883_MEDION, 176 ALC883_MEDION_MD2, 177 ALC883_LAPTOP_EAPD, 178 ALC883_LENOVO_101E_2ch, 179 ALC883_LENOVO_NB0763, 180 ALC888_LENOVO_MS7195_DIG, 181 ALC888_6ST_HP, 182 ALC888_3ST_HP, 183 ALC883_AUTO, 184 ALC883_MODEL_LAST, 185}; 186 187/* for GPIO Poll */ 188#define GPIO_MASK 0x03 189 190struct alc_spec { 191 /* codec parameterization */ 192 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */ 193 unsigned int num_mixers; 194 195 const struct hda_verb *init_verbs[5]; /* initialization verbs 196 * don't forget NULL 197 * termination! 198 */ 199 unsigned int num_init_verbs; 200 201 char *stream_name_analog; /* analog PCM stream */ 202 struct hda_pcm_stream *stream_analog_playback; 203 struct hda_pcm_stream *stream_analog_capture; 204 205 char *stream_name_digital; /* digital PCM stream */ 206 struct hda_pcm_stream *stream_digital_playback; 207 struct hda_pcm_stream *stream_digital_capture; 208 209 /* playback */ 210 struct hda_multi_out multiout; /* playback set-up 211 * max_channels, dacs must be set 212 * dig_out_nid and hp_nid are optional 213 */ 214 215 /* capture */ 216 unsigned int num_adc_nids; 217 hda_nid_t *adc_nids; 218 hda_nid_t dig_in_nid; /* digital-in NID; optional */ 219 220 /* capture source */ 221 unsigned int num_mux_defs; 222 const struct hda_input_mux *input_mux; 223 unsigned int cur_mux[3]; 224 225 /* channel model */ 226 const struct hda_channel_mode *channel_mode; 227 int num_channel_mode; 228 int need_dac_fix; 229 230 /* PCM information */ 231 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */ 232 233 /* dynamic controls, init_verbs and input_mux */ 234 struct auto_pin_cfg autocfg; 235 unsigned int num_kctl_alloc, num_kctl_used; 236 struct snd_kcontrol_new *kctl_alloc; 237 struct hda_input_mux private_imux; 238 hda_nid_t private_dac_nids[5]; 239 240 /* hooks */ 241 void (*init_hook)(struct hda_codec *codec); 242 void (*unsol_event)(struct hda_codec *codec, unsigned int res); 243 244 /* for pin sensing */ 245 unsigned int sense_updated: 1; 246 unsigned int jack_present: 1; 247 248#ifdef CONFIG_SND_HDA_POWER_SAVE 249 struct hda_loopback_check loopback; 250#endif 251}; 252 253/* 254 * configuration template - to be copied to the spec instance 255 */ 256struct alc_config_preset { 257 struct snd_kcontrol_new *mixers[5]; /* should be identical size 258 * with spec 259 */ 260 const struct hda_verb *init_verbs[5]; 261 unsigned int num_dacs; 262 hda_nid_t *dac_nids; 263 hda_nid_t dig_out_nid; /* optional */ 264 hda_nid_t hp_nid; /* optional */ 265 unsigned int num_adc_nids; 266 hda_nid_t *adc_nids; 267 hda_nid_t dig_in_nid; 268 unsigned int num_channel_mode; 269 const struct hda_channel_mode *channel_mode; 270 int need_dac_fix; 271 unsigned int num_mux_defs; 272 const struct hda_input_mux *input_mux; 273 void (*unsol_event)(struct hda_codec *, unsigned int); 274 void (*init_hook)(struct hda_codec *); 275#ifdef CONFIG_SND_HDA_POWER_SAVE 276 struct hda_amp_list *loopbacks; 277#endif 278}; 279 280 281/* 282 * input MUX handling 283 */ 284static int alc_mux_enum_info(struct snd_kcontrol *kcontrol, 285 struct snd_ctl_elem_info *uinfo) 286{ 287 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 288 struct alc_spec *spec = codec->spec; 289 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id); 290 if (mux_idx >= spec->num_mux_defs) 291 mux_idx = 0; 292 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo); 293} 294 295static int alc_mux_enum_get(struct snd_kcontrol *kcontrol, 296 struct snd_ctl_elem_value *ucontrol) 297{ 298 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 299 struct alc_spec *spec = codec->spec; 300 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 301 302 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx]; 303 return 0; 304} 305 306static int alc_mux_enum_put(struct snd_kcontrol *kcontrol, 307 struct snd_ctl_elem_value *ucontrol) 308{ 309 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 310 struct alc_spec *spec = codec->spec; 311 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 312 unsigned int mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx; 313 return snd_hda_input_mux_put(codec, &spec->input_mux[mux_idx], ucontrol, 314 spec->adc_nids[adc_idx], 315 &spec->cur_mux[adc_idx]); 316} 317 318 319/* 320 * channel mode setting 321 */ 322static int alc_ch_mode_info(struct snd_kcontrol *kcontrol, 323 struct snd_ctl_elem_info *uinfo) 324{ 325 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 326 struct alc_spec *spec = codec->spec; 327 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode, 328 spec->num_channel_mode); 329} 330 331static int alc_ch_mode_get(struct snd_kcontrol *kcontrol, 332 struct snd_ctl_elem_value *ucontrol) 333{ 334 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 335 struct alc_spec *spec = codec->spec; 336 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode, 337 spec->num_channel_mode, 338 spec->multiout.max_channels); 339} 340 341static int alc_ch_mode_put(struct snd_kcontrol *kcontrol, 342 struct snd_ctl_elem_value *ucontrol) 343{ 344 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 345 struct alc_spec *spec = codec->spec; 346 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode, 347 spec->num_channel_mode, 348 &spec->multiout.max_channels); 349 if (err >= 0 && spec->need_dac_fix) 350 spec->multiout.num_dacs = spec->multiout.max_channels / 2; 351 return err; 352} 353 354/* 355 * Control the mode of pin widget settings via the mixer. "pc" is used 356 * instead of "%" to avoid consequences of accidently treating the % as 357 * being part of a format specifier. Maximum allowed length of a value is 358 * 63 characters plus NULL terminator. 359 * 360 * Note: some retasking pin complexes seem to ignore requests for input 361 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these 362 * are requested. Therefore order this list so that this behaviour will not 363 * cause problems when mixer clients move through the enum sequentially. 364 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of 365 * March 2006. 366 */ 367static char *alc_pin_mode_names[] = { 368 "Mic 50pc bias", "Mic 80pc bias", 369 "Line in", "Line out", "Headphone out", 370}; 371static unsigned char alc_pin_mode_values[] = { 372 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP, 373}; 374/* The control can present all 5 options, or it can limit the options based 375 * in the pin being assumed to be exclusively an input or an output pin. In 376 * addition, "input" pins may or may not process the mic bias option 377 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to 378 * accept requests for bias as of chip versions up to March 2006) and/or 379 * wiring in the computer. 380 */ 381#define ALC_PIN_DIR_IN 0x00 382#define ALC_PIN_DIR_OUT 0x01 383#define ALC_PIN_DIR_INOUT 0x02 384#define ALC_PIN_DIR_IN_NOMICBIAS 0x03 385#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04 386 387/* Info about the pin modes supported by the different pin direction modes. 388 * For each direction the minimum and maximum values are given. 389 */ 390static signed char alc_pin_mode_dir_info[5][2] = { 391 { 0, 2 }, /* ALC_PIN_DIR_IN */ 392 { 3, 4 }, /* ALC_PIN_DIR_OUT */ 393 { 0, 4 }, /* ALC_PIN_DIR_INOUT */ 394 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */ 395 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */ 396}; 397#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0]) 398#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1]) 399#define alc_pin_mode_n_items(_dir) \ 400 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1) 401 402static int alc_pin_mode_info(struct snd_kcontrol *kcontrol, 403 struct snd_ctl_elem_info *uinfo) 404{ 405 unsigned int item_num = uinfo->value.enumerated.item; 406 unsigned char dir = (kcontrol->private_value >> 16) & 0xff; 407 408 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 409 uinfo->count = 1; 410 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir); 411 412 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir)) 413 item_num = alc_pin_mode_min(dir); 414 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]); 415 return 0; 416} 417 418static int alc_pin_mode_get(struct snd_kcontrol *kcontrol, 419 struct snd_ctl_elem_value *ucontrol) 420{ 421 unsigned int i; 422 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 423 hda_nid_t nid = kcontrol->private_value & 0xffff; 424 unsigned char dir = (kcontrol->private_value >> 16) & 0xff; 425 long *valp = ucontrol->value.integer.value; 426 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0, 427 AC_VERB_GET_PIN_WIDGET_CONTROL, 428 0x00); 429 430 /* Find enumerated value for current pinctl setting */ 431 i = alc_pin_mode_min(dir); 432 while (alc_pin_mode_values[i] != pinctl && i <= alc_pin_mode_max(dir)) 433 i++; 434 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir); 435 return 0; 436} 437 438static int alc_pin_mode_put(struct snd_kcontrol *kcontrol, 439 struct snd_ctl_elem_value *ucontrol) 440{ 441 signed int change; 442 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 443 hda_nid_t nid = kcontrol->private_value & 0xffff; 444 unsigned char dir = (kcontrol->private_value >> 16) & 0xff; 445 long val = *ucontrol->value.integer.value; 446 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0, 447 AC_VERB_GET_PIN_WIDGET_CONTROL, 448 0x00); 449 450 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir)) 451 val = alc_pin_mode_min(dir); 452 453 change = pinctl != alc_pin_mode_values[val]; 454 if (change) { 455 /* Set pin mode to that requested */ 456 snd_hda_codec_write_cache(codec, nid, 0, 457 AC_VERB_SET_PIN_WIDGET_CONTROL, 458 alc_pin_mode_values[val]); 459 460 /* Also enable the retasking pin's input/output as required 461 * for the requested pin mode. Enum values of 2 or less are 462 * input modes. 463 * 464 * Dynamically switching the input/output buffers probably 465 * reduces noise slightly (particularly on input) so we'll 466 * do it. However, having both input and output buffers 467 * enabled simultaneously doesn't seem to be problematic if 468 * this turns out to be necessary in the future. 469 */ 470 if (val <= 2) { 471 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, 472 HDA_AMP_MUTE, HDA_AMP_MUTE); 473 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0, 474 HDA_AMP_MUTE, 0); 475 } else { 476 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0, 477 HDA_AMP_MUTE, HDA_AMP_MUTE); 478 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, 479 HDA_AMP_MUTE, 0); 480 } 481 } 482 return change; 483} 484 485#define ALC_PIN_MODE(xname, nid, dir) \ 486 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 487 .info = alc_pin_mode_info, \ 488 .get = alc_pin_mode_get, \ 489 .put = alc_pin_mode_put, \ 490 .private_value = nid | (dir<<16) } 491 492/* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged 493 * together using a mask with more than one bit set. This control is 494 * currently used only by the ALC260 test model. At this stage they are not 495 * needed for any "production" models. 496 */ 497#ifdef CONFIG_SND_DEBUG 498#define alc_gpio_data_info snd_ctl_boolean_mono_info 499 500static int alc_gpio_data_get(struct snd_kcontrol *kcontrol, 501 struct snd_ctl_elem_value *ucontrol) 502{ 503 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 504 hda_nid_t nid = kcontrol->private_value & 0xffff; 505 unsigned char mask = (kcontrol->private_value >> 16) & 0xff; 506 long *valp = ucontrol->value.integer.value; 507 unsigned int val = snd_hda_codec_read(codec, nid, 0, 508 AC_VERB_GET_GPIO_DATA, 0x00); 509 510 *valp = (val & mask) != 0; 511 return 0; 512} 513static int alc_gpio_data_put(struct snd_kcontrol *kcontrol, 514 struct snd_ctl_elem_value *ucontrol) 515{ 516 signed int change; 517 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 518 hda_nid_t nid = kcontrol->private_value & 0xffff; 519 unsigned char mask = (kcontrol->private_value >> 16) & 0xff; 520 long val = *ucontrol->value.integer.value; 521 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0, 522 AC_VERB_GET_GPIO_DATA, 523 0x00); 524 525 /* Set/unset the masked GPIO bit(s) as needed */ 526 change = (val == 0 ? 0 : mask) != (gpio_data & mask); 527 if (val == 0) 528 gpio_data &= ~mask; 529 else 530 gpio_data |= mask; 531 snd_hda_codec_write_cache(codec, nid, 0, 532 AC_VERB_SET_GPIO_DATA, gpio_data); 533 534 return change; 535} 536#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \ 537 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 538 .info = alc_gpio_data_info, \ 539 .get = alc_gpio_data_get, \ 540 .put = alc_gpio_data_put, \ 541 .private_value = nid | (mask<<16) } 542#endif /* CONFIG_SND_DEBUG */ 543 544/* A switch control to allow the enabling of the digital IO pins on the 545 * ALC260. This is incredibly simplistic; the intention of this control is 546 * to provide something in the test model allowing digital outputs to be 547 * identified if present. If models are found which can utilise these 548 * outputs a more complete mixer control can be devised for those models if 549 * necessary. 550 */ 551#ifdef CONFIG_SND_DEBUG 552#define alc_spdif_ctrl_info snd_ctl_boolean_mono_info 553 554static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol, 555 struct snd_ctl_elem_value *ucontrol) 556{ 557 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 558 hda_nid_t nid = kcontrol->private_value & 0xffff; 559 unsigned char mask = (kcontrol->private_value >> 16) & 0xff; 560 long *valp = ucontrol->value.integer.value; 561 unsigned int val = snd_hda_codec_read(codec, nid, 0, 562 AC_VERB_GET_DIGI_CONVERT, 0x00); 563 564 *valp = (val & mask) != 0; 565 return 0; 566} 567static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol, 568 struct snd_ctl_elem_value *ucontrol) 569{ 570 signed int change; 571 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 572 hda_nid_t nid = kcontrol->private_value & 0xffff; 573 unsigned char mask = (kcontrol->private_value >> 16) & 0xff; 574 long val = *ucontrol->value.integer.value; 575 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0, 576 AC_VERB_GET_DIGI_CONVERT, 577 0x00); 578 579 /* Set/unset the masked control bit(s) as needed */ 580 change = (val == 0 ? 0 : mask) != (ctrl_data & mask); 581 if (val==0) 582 ctrl_data &= ~mask; 583 else 584 ctrl_data |= mask; 585 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, 586 ctrl_data); 587 588 return change; 589} 590#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \ 591 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 592 .info = alc_spdif_ctrl_info, \ 593 .get = alc_spdif_ctrl_get, \ 594 .put = alc_spdif_ctrl_put, \ 595 .private_value = nid | (mask<<16) } 596#endif /* CONFIG_SND_DEBUG */ 597 598/* 599 * set up from the preset table 600 */ 601static void setup_preset(struct alc_spec *spec, 602 const struct alc_config_preset *preset) 603{ 604 int i; 605 606 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++) 607 spec->mixers[spec->num_mixers++] = preset->mixers[i]; 608 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i]; 609 i++) 610 spec->init_verbs[spec->num_init_verbs++] = 611 preset->init_verbs[i]; 612 613 spec->channel_mode = preset->channel_mode; 614 spec->num_channel_mode = preset->num_channel_mode; 615 spec->need_dac_fix = preset->need_dac_fix; 616 617 spec->multiout.max_channels = spec->channel_mode[0].channels; 618 619 spec->multiout.num_dacs = preset->num_dacs; 620 spec->multiout.dac_nids = preset->dac_nids; 621 spec->multiout.dig_out_nid = preset->dig_out_nid; 622 spec->multiout.hp_nid = preset->hp_nid; 623 624 spec->num_mux_defs = preset->num_mux_defs; 625 if (!spec->num_mux_defs) 626 spec->num_mux_defs = 1; 627 spec->input_mux = preset->input_mux; 628 629 spec->num_adc_nids = preset->num_adc_nids; 630 spec->adc_nids = preset->adc_nids; 631 spec->dig_in_nid = preset->dig_in_nid; 632 633 spec->unsol_event = preset->unsol_event; 634 spec->init_hook = preset->init_hook; 635#ifdef CONFIG_SND_HDA_POWER_SAVE 636 spec->loopback.amplist = preset->loopbacks; 637#endif 638} 639 640/* Enable GPIO mask and set output */ 641static struct hda_verb alc_gpio1_init_verbs[] = { 642 {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, 643 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, 644 {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, 645 { } 646}; 647 648static struct hda_verb alc_gpio2_init_verbs[] = { 649 {0x01, AC_VERB_SET_GPIO_MASK, 0x02}, 650 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02}, 651 {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, 652 { } 653}; 654 655static struct hda_verb alc_gpio3_init_verbs[] = { 656 {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, 657 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03}, 658 {0x01, AC_VERB_SET_GPIO_DATA, 0x03}, 659 { } 660}; 661 662/* 32-bit subsystem ID for BIOS loading in HD Audio codec. 663 * 31 ~ 16 : Manufacture ID 664 * 15 ~ 8 : SKU ID 665 * 7 ~ 0 : Assembly ID 666 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36 667 */ 668static void alc_subsystem_id(struct hda_codec *codec, 669 unsigned int porta, unsigned int porte, 670 unsigned int portd) 671{ 672 unsigned int ass, tmp; 673 674 ass = codec->subsystem_id; 675 if (!(ass & 1)) 676 return; 677 678 /* Override */ 679 tmp = (ass & 0x38) >> 3; /* external Amp control */ 680 switch (tmp) { 681 case 1: 682 snd_hda_sequence_write(codec, alc_gpio1_init_verbs); 683 break; 684 case 3: 685 snd_hda_sequence_write(codec, alc_gpio2_init_verbs); 686 break; 687 case 7: 688 snd_hda_sequence_write(codec, alc_gpio3_init_verbs); 689 break; 690 case 5: 691 switch (codec->vendor_id) { 692 case 0x10ec0862: 693 case 0x10ec0660: 694 case 0x10ec0662: 695 case 0x10ec0267: 696 case 0x10ec0268: 697 snd_hda_codec_write(codec, 0x14, 0, 698 AC_VERB_SET_EAPD_BTLENABLE, 2); 699 snd_hda_codec_write(codec, 0x15, 0, 700 AC_VERB_SET_EAPD_BTLENABLE, 2); 701 return; 702 } 703 case 6: 704 if (ass & 4) { /* bit 2 : 0 = Desktop, 1 = Laptop */ 705 hda_nid_t port = 0; 706 tmp = (ass & 0x1800) >> 11; 707 switch (tmp) { 708 case 0: port = porta; break; 709 case 1: port = porte; break; 710 case 2: port = portd; break; 711 } 712 if (port) 713 snd_hda_codec_write(codec, port, 0, 714 AC_VERB_SET_EAPD_BTLENABLE, 715 2); 716 } 717 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7); 718 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, 719 (tmp == 5 ? 0x3040 : 0x3050)); 720 break; 721 } 722} 723 724/* 725 * Fix-up pin default configurations 726 */ 727 728struct alc_pincfg { 729 hda_nid_t nid; 730 u32 val; 731}; 732 733static void alc_fix_pincfg(struct hda_codec *codec, 734 const struct snd_pci_quirk *quirk, 735 const struct alc_pincfg **pinfix) 736{ 737 const struct alc_pincfg *cfg; 738 739 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk); 740 if (!quirk) 741 return; 742 743 cfg = pinfix[quirk->value]; 744 for (; cfg->nid; cfg++) { 745 int i; 746 u32 val = cfg->val; 747 for (i = 0; i < 4; i++) { 748 snd_hda_codec_write(codec, cfg->nid, 0, 749 AC_VERB_SET_CONFIG_DEFAULT_BYTES_0 + i, 750 val & 0xff); 751 val >>= 8; 752 } 753 } 754} 755 756/* 757 * ALC880 3-stack model 758 * 759 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e) 760 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18, 761 * F-Mic = 0x1b, HP = 0x19 762 */ 763 764static hda_nid_t alc880_dac_nids[4] = { 765 /* front, rear, clfe, rear_surr */ 766 0x02, 0x05, 0x04, 0x03 767}; 768 769static hda_nid_t alc880_adc_nids[3] = { 770 /* ADC0-2 */ 771 0x07, 0x08, 0x09, 772}; 773 774/* The datasheet says the node 0x07 is connected from inputs, 775 * but it shows zero connection in the real implementation on some devices. 776 * Note: this is a 915GAV bug, fixed on 915GLV 777 */ 778static hda_nid_t alc880_adc_nids_alt[2] = { 779 /* ADC1-2 */ 780 0x08, 0x09, 781}; 782 783#define ALC880_DIGOUT_NID 0x06 784#define ALC880_DIGIN_NID 0x0a 785 786static struct hda_input_mux alc880_capture_source = { 787 .num_items = 4, 788 .items = { 789 { "Mic", 0x0 }, 790 { "Front Mic", 0x3 }, 791 { "Line", 0x2 }, 792 { "CD", 0x4 }, 793 }, 794}; 795 796/* channel source setting (2/6 channel selection for 3-stack) */ 797/* 2ch mode */ 798static struct hda_verb alc880_threestack_ch2_init[] = { 799 /* set line-in to input, mute it */ 800 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 801 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 802 /* set mic-in to input vref 80%, mute it */ 803 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 804 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 805 { } /* end */ 806}; 807 808/* 6ch mode */ 809static struct hda_verb alc880_threestack_ch6_init[] = { 810 /* set line-in to output, unmute it */ 811 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 812 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 813 /* set mic-in to output, unmute it */ 814 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 815 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 816 { } /* end */ 817}; 818 819static struct hda_channel_mode alc880_threestack_modes[2] = { 820 { 2, alc880_threestack_ch2_init }, 821 { 6, alc880_threestack_ch6_init }, 822}; 823 824static struct snd_kcontrol_new alc880_three_stack_mixer[] = { 825 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 826 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 827 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 828 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT), 829 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 830 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 831 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 832 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 833 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 834 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 835 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 836 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 837 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 838 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 839 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT), 840 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT), 841 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 842 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 843 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT), 844 { 845 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 846 .name = "Channel Mode", 847 .info = alc_ch_mode_info, 848 .get = alc_ch_mode_get, 849 .put = alc_ch_mode_put, 850 }, 851 { } /* end */ 852}; 853 854/* capture mixer elements */ 855static struct snd_kcontrol_new alc880_capture_mixer[] = { 856 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT), 857 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT), 858 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT), 859 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT), 860 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT), 861 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT), 862 { 863 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 864 /* The multiple "Capture Source" controls confuse alsamixer 865 * So call somewhat different.. 866 * FIXME: the controls appear in the "playback" view! 867 */ 868 /* .name = "Capture Source", */ 869 .name = "Input Source", 870 .count = 3, 871 .info = alc_mux_enum_info, 872 .get = alc_mux_enum_get, 873 .put = alc_mux_enum_put, 874 }, 875 { } /* end */ 876}; 877 878/* capture mixer elements (in case NID 0x07 not available) */ 879static struct snd_kcontrol_new alc880_capture_alt_mixer[] = { 880 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 881 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 882 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), 883 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), 884 { 885 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 886 /* The multiple "Capture Source" controls confuse alsamixer 887 * So call somewhat different.. 888 * FIXME: the controls appear in the "playback" view! 889 */ 890 /* .name = "Capture Source", */ 891 .name = "Input Source", 892 .count = 2, 893 .info = alc_mux_enum_info, 894 .get = alc_mux_enum_get, 895 .put = alc_mux_enum_put, 896 }, 897 { } /* end */ 898}; 899 900 901 902/* 903 * ALC880 5-stack model 904 * 905 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d), 906 * Side = 0x02 (0xd) 907 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16 908 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19 909 */ 910 911/* additional mixers to alc880_three_stack_mixer */ 912static struct snd_kcontrol_new alc880_five_stack_mixer[] = { 913 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 914 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT), 915 { } /* end */ 916}; 917 918/* channel source setting (6/8 channel selection for 5-stack) */ 919/* 6ch mode */ 920static struct hda_verb alc880_fivestack_ch6_init[] = { 921 /* set line-in to input, mute it */ 922 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 923 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 924 { } /* end */ 925}; 926 927/* 8ch mode */ 928static struct hda_verb alc880_fivestack_ch8_init[] = { 929 /* set line-in to output, unmute it */ 930 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 931 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 932 { } /* end */ 933}; 934 935static struct hda_channel_mode alc880_fivestack_modes[2] = { 936 { 6, alc880_fivestack_ch6_init }, 937 { 8, alc880_fivestack_ch8_init }, 938}; 939 940 941/* 942 * ALC880 6-stack model 943 * 944 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e), 945 * Side = 0x05 (0x0f) 946 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17, 947 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b 948 */ 949 950static hda_nid_t alc880_6st_dac_nids[4] = { 951 /* front, rear, clfe, rear_surr */ 952 0x02, 0x03, 0x04, 0x05 953}; 954 955static struct hda_input_mux alc880_6stack_capture_source = { 956 .num_items = 4, 957 .items = { 958 { "Mic", 0x0 }, 959 { "Front Mic", 0x1 }, 960 { "Line", 0x2 }, 961 { "CD", 0x4 }, 962 }, 963}; 964 965/* fixed 8-channels */ 966static struct hda_channel_mode alc880_sixstack_modes[1] = { 967 { 8, NULL }, 968}; 969 970static struct snd_kcontrol_new alc880_six_stack_mixer[] = { 971 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 972 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 973 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 974 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 975 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 976 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 977 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 978 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 979 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 980 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 981 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 982 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 983 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 984 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 985 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 986 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 987 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 988 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 989 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 990 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 991 { 992 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 993 .name = "Channel Mode", 994 .info = alc_ch_mode_info, 995 .get = alc_ch_mode_get, 996 .put = alc_ch_mode_put, 997 }, 998 { } /* end */ 999}; 1000 1001 1002/* 1003 * ALC880 W810 model 1004 * 1005 * W810 has rear IO for: 1006 * Front (DAC 02) 1007 * Surround (DAC 03) 1008 * Center/LFE (DAC 04) 1009 * Digital out (06) 1010 * 1011 * The system also has a pair of internal speakers, and a headphone jack. 1012 * These are both connected to Line2 on the codec, hence to DAC 02. 1013 * 1014 * There is a variable resistor to control the speaker or headphone 1015 * volume. This is a hardware-only device without a software API. 1016 * 1017 * Plugging headphones in will disable the internal speakers. This is 1018 * implemented in hardware, not via the driver using jack sense. In 1019 * a similar fashion, plugging into the rear socket marked "front" will 1020 * disable both the speakers and headphones. 1021 * 1022 * For input, there's a microphone jack, and an "audio in" jack. 1023 * These may not do anything useful with this driver yet, because I 1024 * haven't setup any initialization verbs for these yet... 1025 */ 1026 1027static hda_nid_t alc880_w810_dac_nids[3] = { 1028 /* front, rear/surround, clfe */ 1029 0x02, 0x03, 0x04 1030}; 1031 1032/* fixed 6 channels */ 1033static struct hda_channel_mode alc880_w810_modes[1] = { 1034 { 6, NULL } 1035}; 1036 1037/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */ 1038static struct snd_kcontrol_new alc880_w810_base_mixer[] = { 1039 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 1040 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 1041 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 1042 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 1043 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 1044 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 1045 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 1046 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 1047 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 1048 { } /* end */ 1049}; 1050 1051 1052/* 1053 * Z710V model 1054 * 1055 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d) 1056 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?), 1057 * Line = 0x1a 1058 */ 1059 1060static hda_nid_t alc880_z71v_dac_nids[1] = { 1061 0x02 1062}; 1063#define ALC880_Z71V_HP_DAC 0x03 1064 1065/* fixed 2 channels */ 1066static struct hda_channel_mode alc880_2_jack_modes[1] = { 1067 { 2, NULL } 1068}; 1069 1070static struct snd_kcontrol_new alc880_z71v_mixer[] = { 1071 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 1072 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 1073 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 1074 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT), 1075 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 1076 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 1077 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 1078 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 1079 { } /* end */ 1080}; 1081 1082 1083/* FIXME! */ 1084/* 1085 * ALC880 F1734 model 1086 * 1087 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d) 1088 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18 1089 */ 1090 1091static hda_nid_t alc880_f1734_dac_nids[1] = { 1092 0x03 1093}; 1094#define ALC880_F1734_HP_DAC 0x02 1095 1096static struct snd_kcontrol_new alc880_f1734_mixer[] = { 1097 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 1098 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), 1099 HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 1100 HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 1101 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 1102 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 1103 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 1104 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 1105 { } /* end */ 1106}; 1107 1108 1109/* FIXME! */ 1110/* 1111 * ALC880 ASUS model 1112 * 1113 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e) 1114 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16, 1115 * Mic = 0x18, Line = 0x1a 1116 */ 1117 1118#define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */ 1119#define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */ 1120 1121static struct snd_kcontrol_new alc880_asus_mixer[] = { 1122 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 1123 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 1124 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 1125 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 1126 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 1127 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 1128 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 1129 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 1130 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 1131 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 1132 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 1133 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 1134 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 1135 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 1136 { 1137 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1138 .name = "Channel Mode", 1139 .info = alc_ch_mode_info, 1140 .get = alc_ch_mode_get, 1141 .put = alc_ch_mode_put, 1142 }, 1143 { } /* end */ 1144}; 1145 1146/* FIXME! */ 1147/* 1148 * ALC880 ASUS W1V model 1149 * 1150 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e) 1151 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16, 1152 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b 1153 */ 1154 1155/* additional mixers to alc880_asus_mixer */ 1156static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = { 1157 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT), 1158 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT), 1159 { } /* end */ 1160}; 1161 1162/* additional mixers to alc880_asus_mixer */ 1163static struct snd_kcontrol_new alc880_pcbeep_mixer[] = { 1164 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 1165 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 1166 { } /* end */ 1167}; 1168 1169/* TCL S700 */ 1170static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = { 1171 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 1172 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 1173 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 1174 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT), 1175 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT), 1176 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT), 1177 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT), 1178 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 1179 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 1180 { 1181 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1182 /* The multiple "Capture Source" controls confuse alsamixer 1183 * So call somewhat different.. 1184 * FIXME: the controls appear in the "playback" view! 1185 */ 1186 /* .name = "Capture Source", */ 1187 .name = "Input Source", 1188 .count = 1, 1189 .info = alc_mux_enum_info, 1190 .get = alc_mux_enum_get, 1191 .put = alc_mux_enum_put, 1192 }, 1193 { } /* end */ 1194}; 1195 1196/* Uniwill */ 1197static struct snd_kcontrol_new alc880_uniwill_mixer[] = { 1198 HDA_CODEC_VOLUME("HPhone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 1199 HDA_BIND_MUTE("HPhone Playback Switch", 0x0c, 2, HDA_INPUT), 1200 HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 1201 HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT), 1202 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 1203 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 1204 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 1205 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 1206 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 1207 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 1208 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 1209 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 1210 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 1211 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 1212 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 1213 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 1214 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 1215 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 1216 { 1217 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1218 .name = "Channel Mode", 1219 .info = alc_ch_mode_info, 1220 .get = alc_ch_mode_get, 1221 .put = alc_ch_mode_put, 1222 }, 1223 { } /* end */ 1224}; 1225 1226static struct snd_kcontrol_new alc880_fujitsu_mixer[] = { 1227 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 1228 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), 1229 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 1230 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 1231 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 1232 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 1233 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 1234 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 1235 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 1236 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 1237 { } /* end */ 1238}; 1239 1240static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = { 1241 HDA_CODEC_VOLUME("HPhone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 1242 HDA_BIND_MUTE("HPhone Playback Switch", 0x0c, 2, HDA_INPUT), 1243 HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 1244 HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT), 1245 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 1246 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 1247 { } /* end */ 1248}; 1249 1250/* 1251 * build control elements 1252 */ 1253static int alc_build_controls(struct hda_codec *codec) 1254{ 1255 struct alc_spec *spec = codec->spec; 1256 int err; 1257 int i; 1258 1259 for (i = 0; i < spec->num_mixers; i++) { 1260 err = snd_hda_add_new_ctls(codec, spec->mixers[i]); 1261 if (err < 0) 1262 return err; 1263 } 1264 1265 if (spec->multiout.dig_out_nid) { 1266 err = snd_hda_create_spdif_out_ctls(codec, 1267 spec->multiout.dig_out_nid); 1268 if (err < 0) 1269 return err; 1270 } 1271 if (spec->dig_in_nid) { 1272 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid); 1273 if (err < 0) 1274 return err; 1275 } 1276 return 0; 1277} 1278 1279 1280/* 1281 * initialize the codec volumes, etc 1282 */ 1283 1284/* 1285 * generic initialization of ADC, input mixers and output mixers 1286 */ 1287static struct hda_verb alc880_volume_init_verbs[] = { 1288 /* 1289 * Unmute ADC0-2 and set the default input to mic-in 1290 */ 1291 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 1292 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1293 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 1294 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1295 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 1296 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1297 1298 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 1299 * mixer widget 1300 * Note: PASD motherboards uses the Line In 2 as the input for front 1301 * panel mic (mic 2) 1302 */ 1303 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 1304 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 1305 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 1306 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 1307 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 1308 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 1309 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, 1310 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, 1311 1312 /* 1313 * Set up output mixers (0x0c - 0x0f) 1314 */ 1315 /* set vol=0 to output mixers */ 1316 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 1317 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 1318 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 1319 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 1320 /* set up input amps for analog loopback */ 1321 /* Amp Indices: DAC = 0, mixer = 1 */ 1322 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 1323 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 1324 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 1325 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 1326 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 1327 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 1328 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 1329 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 1330 1331 { } 1332}; 1333 1334/* 1335 * 3-stack pin configuration: 1336 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b 1337 */ 1338static struct hda_verb alc880_pin_3stack_init_verbs[] = { 1339 /* 1340 * preset connection lists of input pins 1341 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround 1342 */ 1343 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ 1344 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 1345 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */ 1346 1347 /* 1348 * Set pin mode and muting 1349 */ 1350 /* set front pin widgets 0x14 for output */ 1351 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1352 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1353 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 1354 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1355 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1356 /* Mic2 (as headphone out) for HP output */ 1357 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1358 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1359 /* Line In pin widget for input */ 1360 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1361 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1362 /* Line2 (as front mic) pin widget for input and vref at 80% */ 1363 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1364 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1365 /* CD pin widget for input */ 1366 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1367 1368 { } 1369}; 1370 1371/* 1372 * 5-stack pin configuration: 1373 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19, 1374 * line-in/side = 0x1a, f-mic = 0x1b 1375 */ 1376static struct hda_verb alc880_pin_5stack_init_verbs[] = { 1377 /* 1378 * preset connection lists of input pins 1379 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround 1380 */ 1381 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 1382 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */ 1383 1384 /* 1385 * Set pin mode and muting 1386 */ 1387 /* set pin widgets 0x14-0x17 for output */ 1388 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1389 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1390 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1391 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1392 /* unmute pins for output (no gain on this amp) */ 1393 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1394 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1395 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1396 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1397 1398 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 1399 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1400 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1401 /* Mic2 (as headphone out) for HP output */ 1402 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1403 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1404 /* Line In pin widget for input */ 1405 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1406 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1407 /* Line2 (as front mic) pin widget for input and vref at 80% */ 1408 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1409 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1410 /* CD pin widget for input */ 1411 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1412 1413 { } 1414}; 1415 1416/* 1417 * W810 pin configuration: 1418 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b 1419 */ 1420static struct hda_verb alc880_pin_w810_init_verbs[] = { 1421 /* hphone/speaker input selector: front DAC */ 1422 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0}, 1423 1424 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1425 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1426 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1427 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1428 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1429 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1430 1431 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1432 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1433 1434 { } 1435}; 1436 1437/* 1438 * Z71V pin configuration: 1439 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?) 1440 */ 1441static struct hda_verb alc880_pin_z71v_init_verbs[] = { 1442 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1443 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1444 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1445 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1446 1447 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1448 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1449 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1450 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1451 1452 { } 1453}; 1454 1455/* 1456 * 6-stack pin configuration: 1457 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18, 1458 * f-mic = 0x19, line = 0x1a, HP = 0x1b 1459 */ 1460static struct hda_verb alc880_pin_6stack_init_verbs[] = { 1461 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 1462 1463 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1464 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1465 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1466 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1467 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1468 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1469 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1470 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1471 1472 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1473 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1474 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1475 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1476 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1477 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1478 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1479 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1480 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1481 1482 { } 1483}; 1484 1485/* 1486 * Uniwill pin configuration: 1487 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19, 1488 * line = 0x1a 1489 */ 1490static struct hda_verb alc880_uniwill_init_verbs[] = { 1491 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 1492 1493 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1494 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1495 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1496 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1497 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1498 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1499 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1500 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1501 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 1502 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 1503 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 1504 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 1505 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 1506 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 1507 1508 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1509 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1510 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1511 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1512 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1513 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1514 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */ 1515 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */ 1516 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1517 1518 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 1519 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 1520 1521 { } 1522}; 1523 1524/* 1525* Uniwill P53 1526* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19, 1527 */ 1528static struct hda_verb alc880_uniwill_p53_init_verbs[] = { 1529 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 1530 1531 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1532 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1533 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1534 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1535 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1536 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1537 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 1538 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 1539 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 1540 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 1541 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 1542 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 1543 1544 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1545 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1546 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1547 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1548 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1549 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1550 1551 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 1552 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT}, 1553 1554 { } 1555}; 1556 1557static struct hda_verb alc880_beep_init_verbs[] = { 1558 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) }, 1559 { } 1560}; 1561 1562/* toggle speaker-output according to the hp-jack state */ 1563static void alc880_uniwill_hp_automute(struct hda_codec *codec) 1564{ 1565 unsigned int present; 1566 unsigned char bits; 1567 1568 present = snd_hda_codec_read(codec, 0x14, 0, 1569 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 1570 bits = present ? HDA_AMP_MUTE : 0; 1571 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 1572 HDA_AMP_MUTE, bits); 1573 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0, 1574 HDA_AMP_MUTE, bits); 1575} 1576 1577/* auto-toggle front mic */ 1578static void alc880_uniwill_mic_automute(struct hda_codec *codec) 1579{ 1580 unsigned int present; 1581 unsigned char bits; 1582 1583 present = snd_hda_codec_read(codec, 0x18, 0, 1584 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 1585 bits = present ? HDA_AMP_MUTE : 0; 1586 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits); 1587} 1588 1589static void alc880_uniwill_automute(struct hda_codec *codec) 1590{ 1591 alc880_uniwill_hp_automute(codec); 1592 alc880_uniwill_mic_automute(codec); 1593} 1594 1595static void alc880_uniwill_unsol_event(struct hda_codec *codec, 1596 unsigned int res) 1597{ 1598 /* Looks like the unsol event is incompatible with the standard 1599 * definition. 4bit tag is placed at 28 bit! 1600 */ 1601 switch (res >> 28) { 1602 case ALC880_HP_EVENT: 1603 alc880_uniwill_hp_automute(codec); 1604 break; 1605 case ALC880_MIC_EVENT: 1606 alc880_uniwill_mic_automute(codec); 1607 break; 1608 } 1609} 1610 1611static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec) 1612{ 1613 unsigned int present; 1614 unsigned char bits; 1615 1616 present = snd_hda_codec_read(codec, 0x14, 0, 1617 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 1618 bits = present ? HDA_AMP_MUTE : 0; 1619 snd_hda_codec_amp_stereo(codec, 0x15, HDA_INPUT, 0, HDA_AMP_MUTE, bits); 1620} 1621 1622static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec) 1623{ 1624 unsigned int present; 1625 1626 present = snd_hda_codec_read(codec, 0x21, 0, 1627 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0); 1628 present &= HDA_AMP_VOLMASK; 1629 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0, 1630 HDA_AMP_VOLMASK, present); 1631 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0, 1632 HDA_AMP_VOLMASK, present); 1633} 1634 1635static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec, 1636 unsigned int res) 1637{ 1638 /* Looks like the unsol event is incompatible with the standard 1639 * definition. 4bit tag is placed at 28 bit! 1640 */ 1641 if ((res >> 28) == ALC880_HP_EVENT) 1642 alc880_uniwill_p53_hp_automute(codec); 1643 if ((res >> 28) == ALC880_DCVOL_EVENT) 1644 alc880_uniwill_p53_dcvol_automute(codec); 1645} 1646 1647/* FIXME! */ 1648/* 1649 * F1734 pin configuration: 1650 * HP = 0x14, speaker-out = 0x15, mic = 0x18 1651 */ 1652static struct hda_verb alc880_pin_f1734_init_verbs[] = { 1653 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, 1654 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, 1655 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, 1656 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, 1657 1658 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1659 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1660 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1661 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1662 1663 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1664 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1665 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1666 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1667 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1668 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1669 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1670 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1671 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1672 1673 { } 1674}; 1675 1676/* FIXME! */ 1677/* 1678 * ASUS pin configuration: 1679 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a 1680 */ 1681static struct hda_verb alc880_pin_asus_init_verbs[] = { 1682 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, 1683 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, 1684 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, 1685 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, 1686 1687 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1688 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1689 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1690 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1691 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1692 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1693 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1694 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1695 1696 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1697 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1698 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1699 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1700 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1701 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1702 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1703 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1704 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1705 1706 { } 1707}; 1708 1709/* Enable GPIO mask and set output */ 1710#define alc880_gpio1_init_verbs alc_gpio1_init_verbs 1711#define alc880_gpio2_init_verbs alc_gpio2_init_verbs 1712 1713/* Clevo m520g init */ 1714static struct hda_verb alc880_pin_clevo_init_verbs[] = { 1715 /* headphone output */ 1716 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01}, 1717 /* line-out */ 1718 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1719 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1720 /* Line-in */ 1721 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1722 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1723 /* CD */ 1724 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1725 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1726 /* Mic1 (rear panel) */ 1727 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1728 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1729 /* Mic2 (front panel) */ 1730 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1731 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1732 /* headphone */ 1733 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1734 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1735 /* change to EAPD mode */ 1736 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 1737 {0x20, AC_VERB_SET_PROC_COEF, 0x3060}, 1738 1739 { } 1740}; 1741 1742static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = { 1743 /* change to EAPD mode */ 1744 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 1745 {0x20, AC_VERB_SET_PROC_COEF, 0x3060}, 1746 1747 /* Headphone output */ 1748 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1749 /* Front output*/ 1750 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1751 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 1752 1753 /* Line In pin widget for input */ 1754 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1755 /* CD pin widget for input */ 1756 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1757 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 1758 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1759 1760 /* change to EAPD mode */ 1761 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 1762 {0x20, AC_VERB_SET_PROC_COEF, 0x3070}, 1763 1764 { } 1765}; 1766 1767/* 1768 * LG m1 express dual 1769 * 1770 * Pin assignment: 1771 * Rear Line-In/Out (blue): 0x14 1772 * Build-in Mic-In: 0x15 1773 * Speaker-out: 0x17 1774 * HP-Out (green): 0x1b 1775 * Mic-In/Out (red): 0x19 1776 * SPDIF-Out: 0x1e 1777 */ 1778 1779/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */ 1780static hda_nid_t alc880_lg_dac_nids[3] = { 1781 0x05, 0x02, 0x03 1782}; 1783 1784/* seems analog CD is not working */ 1785static struct hda_input_mux alc880_lg_capture_source = { 1786 .num_items = 3, 1787 .items = { 1788 { "Mic", 0x1 }, 1789 { "Line", 0x5 }, 1790 { "Internal Mic", 0x6 }, 1791 }, 1792}; 1793 1794/* 2,4,6 channel modes */ 1795static struct hda_verb alc880_lg_ch2_init[] = { 1796 /* set line-in and mic-in to input */ 1797 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 1798 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 1799 { } 1800}; 1801 1802static struct hda_verb alc880_lg_ch4_init[] = { 1803 /* set line-in to out and mic-in to input */ 1804 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, 1805 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 1806 { } 1807}; 1808 1809static struct hda_verb alc880_lg_ch6_init[] = { 1810 /* set line-in and mic-in to output */ 1811 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, 1812 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, 1813 { } 1814}; 1815 1816static struct hda_channel_mode alc880_lg_ch_modes[3] = { 1817 { 2, alc880_lg_ch2_init }, 1818 { 4, alc880_lg_ch4_init }, 1819 { 6, alc880_lg_ch6_init }, 1820}; 1821 1822static struct snd_kcontrol_new alc880_lg_mixer[] = { 1823 /* FIXME: it's not really "master" but front channels */ 1824 HDA_CODEC_VOLUME("Master Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 1825 HDA_BIND_MUTE("Master Playback Switch", 0x0f, 2, HDA_INPUT), 1826 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 1827 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT), 1828 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT), 1829 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT), 1830 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT), 1831 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT), 1832 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 1833 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 1834 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT), 1835 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT), 1836 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT), 1837 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT), 1838 { 1839 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1840 .name = "Channel Mode", 1841 .info = alc_ch_mode_info, 1842 .get = alc_ch_mode_get, 1843 .put = alc_ch_mode_put, 1844 }, 1845 { } /* end */ 1846}; 1847 1848static struct hda_verb alc880_lg_init_verbs[] = { 1849 /* set capture source to mic-in */ 1850 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 1851 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 1852 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 1853 /* mute all amp mixer inputs */ 1854 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)}, 1855 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, 1856 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, 1857 /* line-in to input */ 1858 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1859 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1860 /* built-in mic */ 1861 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1862 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1863 /* speaker-out */ 1864 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1865 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1866 /* mic-in to input */ 1867 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01}, 1868 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1869 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1870 /* HP-out */ 1871 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03}, 1872 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1873 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1874 /* jack sense */ 1875 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1}, 1876 { } 1877}; 1878 1879/* toggle speaker-output according to the hp-jack state */ 1880static void alc880_lg_automute(struct hda_codec *codec) 1881{ 1882 unsigned int present; 1883 unsigned char bits; 1884 1885 present = snd_hda_codec_read(codec, 0x1b, 0, 1886 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 1887 bits = present ? HDA_AMP_MUTE : 0; 1888 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0, 1889 HDA_AMP_MUTE, bits); 1890} 1891 1892static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res) 1893{ 1894 /* Looks like the unsol event is incompatible with the standard 1895 * definition. 4bit tag is placed at 28 bit! 1896 */ 1897 if ((res >> 28) == 0x01) 1898 alc880_lg_automute(codec); 1899} 1900 1901/* 1902 * LG LW20 1903 * 1904 * Pin assignment: 1905 * Speaker-out: 0x14 1906 * Mic-In: 0x18 1907 * Built-in Mic-In: 0x19 1908 * Line-In: 0x1b 1909 * HP-Out: 0x1a 1910 * SPDIF-Out: 0x1e 1911 */ 1912 1913static struct hda_input_mux alc880_lg_lw_capture_source = { 1914 .num_items = 3, 1915 .items = { 1916 { "Mic", 0x0 }, 1917 { "Internal Mic", 0x1 }, 1918 { "Line In", 0x2 }, 1919 }, 1920}; 1921 1922#define alc880_lg_lw_modes alc880_threestack_modes 1923 1924static struct snd_kcontrol_new alc880_lg_lw_mixer[] = { 1925 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 1926 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 1927 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 1928 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT), 1929 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 1930 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 1931 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 1932 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 1933 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 1934 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 1935 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 1936 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 1937 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 1938 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 1939 { 1940 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1941 .name = "Channel Mode", 1942 .info = alc_ch_mode_info, 1943 .get = alc_ch_mode_get, 1944 .put = alc_ch_mode_put, 1945 }, 1946 { } /* end */ 1947}; 1948 1949static struct hda_verb alc880_lg_lw_init_verbs[] = { 1950 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 1951 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ 1952 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */ 1953 1954 /* set capture source to mic-in */ 1955 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1956 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1957 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1958 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, 1959 /* speaker-out */ 1960 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1961 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1962 /* HP-out */ 1963 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1964 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1965 /* mic-in to input */ 1966 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1967 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1968 /* built-in mic */ 1969 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1970 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1971 /* jack sense */ 1972 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1}, 1973 { } 1974}; 1975 1976/* toggle speaker-output according to the hp-jack state */ 1977static void alc880_lg_lw_automute(struct hda_codec *codec) 1978{ 1979 unsigned int present; 1980 unsigned char bits; 1981 1982 present = snd_hda_codec_read(codec, 0x1b, 0, 1983 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 1984 bits = present ? HDA_AMP_MUTE : 0; 1985 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 1986 HDA_AMP_MUTE, bits); 1987} 1988 1989static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res) 1990{ 1991 /* Looks like the unsol event is incompatible with the standard 1992 * definition. 4bit tag is placed at 28 bit! 1993 */ 1994 if ((res >> 28) == 0x01) 1995 alc880_lg_lw_automute(codec); 1996} 1997 1998#ifdef CONFIG_SND_HDA_POWER_SAVE 1999static struct hda_amp_list alc880_loopbacks[] = { 2000 { 0x0b, HDA_INPUT, 0 }, 2001 { 0x0b, HDA_INPUT, 1 }, 2002 { 0x0b, HDA_INPUT, 2 }, 2003 { 0x0b, HDA_INPUT, 3 }, 2004 { 0x0b, HDA_INPUT, 4 }, 2005 { } /* end */ 2006}; 2007 2008static struct hda_amp_list alc880_lg_loopbacks[] = { 2009 { 0x0b, HDA_INPUT, 1 }, 2010 { 0x0b, HDA_INPUT, 6 }, 2011 { 0x0b, HDA_INPUT, 7 }, 2012 { } /* end */ 2013}; 2014#endif 2015 2016/* 2017 * Common callbacks 2018 */ 2019 2020static int alc_init(struct hda_codec *codec) 2021{ 2022 struct alc_spec *spec = codec->spec; 2023 unsigned int i; 2024 2025 for (i = 0; i < spec->num_init_verbs; i++) 2026 snd_hda_sequence_write(codec, spec->init_verbs[i]); 2027 2028 if (spec->init_hook) 2029 spec->init_hook(codec); 2030 2031 return 0; 2032} 2033 2034static void alc_unsol_event(struct hda_codec *codec, unsigned int res) 2035{ 2036 struct alc_spec *spec = codec->spec; 2037 2038 if (spec->unsol_event) 2039 spec->unsol_event(codec, res); 2040} 2041 2042#ifdef CONFIG_SND_HDA_POWER_SAVE 2043static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid) 2044{ 2045 struct alc_spec *spec = codec->spec; 2046 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid); 2047} 2048#endif 2049 2050/* 2051 * Analog playback callbacks 2052 */ 2053static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo, 2054 struct hda_codec *codec, 2055 struct snd_pcm_substream *substream) 2056{ 2057 struct alc_spec *spec = codec->spec; 2058 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream); 2059} 2060 2061static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo, 2062 struct hda_codec *codec, 2063 unsigned int stream_tag, 2064 unsigned int format, 2065 struct snd_pcm_substream *substream) 2066{ 2067 struct alc_spec *spec = codec->spec; 2068 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, 2069 stream_tag, format, substream); 2070} 2071 2072static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, 2073 struct hda_codec *codec, 2074 struct snd_pcm_substream *substream) 2075{ 2076 struct alc_spec *spec = codec->spec; 2077 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); 2078} 2079 2080/* 2081 * Digital out 2082 */ 2083static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo, 2084 struct hda_codec *codec, 2085 struct snd_pcm_substream *substream) 2086{ 2087 struct alc_spec *spec = codec->spec; 2088 return snd_hda_multi_out_dig_open(codec, &spec->multiout); 2089} 2090 2091static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, 2092 struct hda_codec *codec, 2093 unsigned int stream_tag, 2094 unsigned int format, 2095 struct snd_pcm_substream *substream) 2096{ 2097 struct alc_spec *spec = codec->spec; 2098 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, 2099 stream_tag, format, substream); 2100} 2101 2102static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, 2103 struct hda_codec *codec, 2104 struct snd_pcm_substream *substream) 2105{ 2106 struct alc_spec *spec = codec->spec; 2107 return snd_hda_multi_out_dig_close(codec, &spec->multiout); 2108} 2109 2110/* 2111 * Analog capture 2112 */ 2113static int alc880_capture_pcm_prepare(struct hda_pcm_stream *hinfo, 2114 struct hda_codec *codec, 2115 unsigned int stream_tag, 2116 unsigned int format, 2117 struct snd_pcm_substream *substream) 2118{ 2119 struct alc_spec *spec = codec->spec; 2120 2121 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number], 2122 stream_tag, 0, format); 2123 return 0; 2124} 2125 2126static int alc880_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, 2127 struct hda_codec *codec, 2128 struct snd_pcm_substream *substream) 2129{ 2130 struct alc_spec *spec = codec->spec; 2131 2132 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number], 2133 0, 0, 0); 2134 return 0; 2135} 2136 2137 2138/* 2139 */ 2140static struct hda_pcm_stream alc880_pcm_analog_playback = { 2141 .substreams = 1, 2142 .channels_min = 2, 2143 .channels_max = 8, 2144 /* NID is set in alc_build_pcms */ 2145 .ops = { 2146 .open = alc880_playback_pcm_open, 2147 .prepare = alc880_playback_pcm_prepare, 2148 .cleanup = alc880_playback_pcm_cleanup 2149 }, 2150}; 2151 2152static struct hda_pcm_stream alc880_pcm_analog_capture = { 2153 .substreams = 2, 2154 .channels_min = 2, 2155 .channels_max = 2, 2156 /* NID is set in alc_build_pcms */ 2157 .ops = { 2158 .prepare = alc880_capture_pcm_prepare, 2159 .cleanup = alc880_capture_pcm_cleanup 2160 }, 2161}; 2162 2163static struct hda_pcm_stream alc880_pcm_digital_playback = { 2164 .substreams = 1, 2165 .channels_min = 2, 2166 .channels_max = 2, 2167 /* NID is set in alc_build_pcms */ 2168 .ops = { 2169 .open = alc880_dig_playback_pcm_open, 2170 .close = alc880_dig_playback_pcm_close, 2171 .prepare = alc880_dig_playback_pcm_prepare 2172 }, 2173}; 2174 2175static struct hda_pcm_stream alc880_pcm_digital_capture = { 2176 .substreams = 1, 2177 .channels_min = 2, 2178 .channels_max = 2, 2179 /* NID is set in alc_build_pcms */ 2180}; 2181 2182/* Used by alc_build_pcms to flag that a PCM has no playback stream */ 2183static struct hda_pcm_stream alc_pcm_null_playback = { 2184 .substreams = 0, 2185 .channels_min = 0, 2186 .channels_max = 0, 2187}; 2188 2189static int alc_build_pcms(struct hda_codec *codec) 2190{ 2191 struct alc_spec *spec = codec->spec; 2192 struct hda_pcm *info = spec->pcm_rec; 2193 int i; 2194 2195 codec->num_pcms = 1; 2196 codec->pcm_info = info; 2197 2198 info->name = spec->stream_name_analog; 2199 if (spec->stream_analog_playback) { 2200 snd_assert(spec->multiout.dac_nids, return -EINVAL); 2201 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback); 2202 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0]; 2203 } 2204 if (spec->stream_analog_capture) { 2205 snd_assert(spec->adc_nids, return -EINVAL); 2206 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture); 2207 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0]; 2208 } 2209 2210 if (spec->channel_mode) { 2211 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0; 2212 for (i = 0; i < spec->num_channel_mode; i++) { 2213 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) { 2214 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels; 2215 } 2216 } 2217 } 2218 2219 /* SPDIF for stream index #1 */ 2220 if (spec->multiout.dig_out_nid || spec->dig_in_nid) { 2221 codec->num_pcms = 2; 2222 info = spec->pcm_rec + 1; 2223 info->name = spec->stream_name_digital; 2224 if (spec->multiout.dig_out_nid && 2225 spec->stream_digital_playback) { 2226 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback); 2227 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid; 2228 } 2229 if (spec->dig_in_nid && 2230 spec->stream_digital_capture) { 2231 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture); 2232 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid; 2233 } 2234 } 2235 2236 /* If the use of more than one ADC is requested for the current 2237 * model, configure a second analog capture-only PCM. 2238 */ 2239 /* Additional Analaog capture for index #2 */ 2240 if (spec->num_adc_nids > 1 && spec->stream_analog_capture && 2241 spec->adc_nids) { 2242 codec->num_pcms = 3; 2243 info = spec->pcm_rec + 2; 2244 info->name = spec->stream_name_analog; 2245 /* No playback stream for second PCM */ 2246 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = alc_pcm_null_playback; 2247 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0; 2248 if (spec->stream_analog_capture) { 2249 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture); 2250 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[1]; 2251 } 2252 } 2253 2254 return 0; 2255} 2256 2257static void alc_free(struct hda_codec *codec) 2258{ 2259 struct alc_spec *spec = codec->spec; 2260 unsigned int i; 2261 2262 if (!spec) 2263 return; 2264 2265 if (spec->kctl_alloc) { 2266 for (i = 0; i < spec->num_kctl_used; i++) 2267 kfree(spec->kctl_alloc[i].name); 2268 kfree(spec->kctl_alloc); 2269 } 2270 kfree(spec); 2271} 2272 2273/* 2274 */ 2275static struct hda_codec_ops alc_patch_ops = { 2276 .build_controls = alc_build_controls, 2277 .build_pcms = alc_build_pcms, 2278 .init = alc_init, 2279 .free = alc_free, 2280 .unsol_event = alc_unsol_event, 2281#ifdef CONFIG_SND_HDA_POWER_SAVE 2282 .check_power_status = alc_check_power_status, 2283#endif 2284}; 2285 2286 2287/* 2288 * Test configuration for debugging 2289 * 2290 * Almost all inputs/outputs are enabled. I/O pins can be configured via 2291 * enum controls. 2292 */ 2293#ifdef CONFIG_SND_DEBUG 2294static hda_nid_t alc880_test_dac_nids[4] = { 2295 0x02, 0x03, 0x04, 0x05 2296}; 2297 2298static struct hda_input_mux alc880_test_capture_source = { 2299 .num_items = 7, 2300 .items = { 2301 { "In-1", 0x0 }, 2302 { "In-2", 0x1 }, 2303 { "In-3", 0x2 }, 2304 { "In-4", 0x3 }, 2305 { "CD", 0x4 }, 2306 { "Front", 0x5 }, 2307 { "Surround", 0x6 }, 2308 }, 2309}; 2310 2311static struct hda_channel_mode alc880_test_modes[4] = { 2312 { 2, NULL }, 2313 { 4, NULL }, 2314 { 6, NULL }, 2315 { 8, NULL }, 2316}; 2317 2318static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol, 2319 struct snd_ctl_elem_info *uinfo) 2320{ 2321 static char *texts[] = { 2322 "N/A", "Line Out", "HP Out", 2323 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%" 2324 }; 2325 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 2326 uinfo->count = 1; 2327 uinfo->value.enumerated.items = 8; 2328 if (uinfo->value.enumerated.item >= 8) 2329 uinfo->value.enumerated.item = 7; 2330 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); 2331 return 0; 2332} 2333 2334static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol, 2335 struct snd_ctl_elem_value *ucontrol) 2336{ 2337 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2338 hda_nid_t nid = (hda_nid_t)kcontrol->private_value; 2339 unsigned int pin_ctl, item = 0; 2340 2341 pin_ctl = snd_hda_codec_read(codec, nid, 0, 2342 AC_VERB_GET_PIN_WIDGET_CONTROL, 0); 2343 if (pin_ctl & AC_PINCTL_OUT_EN) { 2344 if (pin_ctl & AC_PINCTL_HP_EN) 2345 item = 2; 2346 else 2347 item = 1; 2348 } else if (pin_ctl & AC_PINCTL_IN_EN) { 2349 switch (pin_ctl & AC_PINCTL_VREFEN) { 2350 case AC_PINCTL_VREF_HIZ: item = 3; break; 2351 case AC_PINCTL_VREF_50: item = 4; break; 2352 case AC_PINCTL_VREF_GRD: item = 5; break; 2353 case AC_PINCTL_VREF_80: item = 6; break; 2354 case AC_PINCTL_VREF_100: item = 7; break; 2355 } 2356 } 2357 ucontrol->value.enumerated.item[0] = item; 2358 return 0; 2359} 2360 2361static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol, 2362 struct snd_ctl_elem_value *ucontrol) 2363{ 2364 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2365 hda_nid_t nid = (hda_nid_t)kcontrol->private_value; 2366 static unsigned int ctls[] = { 2367 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN, 2368 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ, 2369 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50, 2370 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD, 2371 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80, 2372 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100, 2373 }; 2374 unsigned int old_ctl, new_ctl; 2375 2376 old_ctl = snd_hda_codec_read(codec, nid, 0, 2377 AC_VERB_GET_PIN_WIDGET_CONTROL, 0); 2378 new_ctl = ctls[ucontrol->value.enumerated.item[0]]; 2379 if (old_ctl != new_ctl) { 2380 int val; 2381 snd_hda_codec_write_cache(codec, nid, 0, 2382 AC_VERB_SET_PIN_WIDGET_CONTROL, 2383 new_ctl); 2384 val = ucontrol->value.enumerated.item[0] >= 3 ? 2385 HDA_AMP_MUTE : 0; 2386 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, 2387 HDA_AMP_MUTE, val); 2388 return 1; 2389 } 2390 return 0; 2391} 2392 2393static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol, 2394 struct snd_ctl_elem_info *uinfo) 2395{ 2396 static char *texts[] = { 2397 "Front", "Surround", "CLFE", "Side" 2398 }; 2399 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 2400 uinfo->count = 1; 2401 uinfo->value.enumerated.items = 4; 2402 if (uinfo->value.enumerated.item >= 4) 2403 uinfo->value.enumerated.item = 3; 2404 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); 2405 return 0; 2406} 2407 2408static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol, 2409 struct snd_ctl_elem_value *ucontrol) 2410{ 2411 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2412 hda_nid_t nid = (hda_nid_t)kcontrol->private_value; 2413 unsigned int sel; 2414 2415 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0); 2416 ucontrol->value.enumerated.item[0] = sel & 3; 2417 return 0; 2418} 2419 2420static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol, 2421 struct snd_ctl_elem_value *ucontrol) 2422{ 2423 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2424 hda_nid_t nid = (hda_nid_t)kcontrol->private_value; 2425 unsigned int sel; 2426 2427 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3; 2428 if (ucontrol->value.enumerated.item[0] != sel) { 2429 sel = ucontrol->value.enumerated.item[0] & 3; 2430 snd_hda_codec_write_cache(codec, nid, 0, 2431 AC_VERB_SET_CONNECT_SEL, sel); 2432 return 1; 2433 } 2434 return 0; 2435} 2436 2437#define PIN_CTL_TEST(xname,nid) { \ 2438 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 2439 .name = xname, \ 2440 .info = alc_test_pin_ctl_info, \ 2441 .get = alc_test_pin_ctl_get, \ 2442 .put = alc_test_pin_ctl_put, \ 2443 .private_value = nid \ 2444 } 2445 2446#define PIN_SRC_TEST(xname,nid) { \ 2447 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 2448 .name = xname, \ 2449 .info = alc_test_pin_src_info, \ 2450 .get = alc_test_pin_src_get, \ 2451 .put = alc_test_pin_src_put, \ 2452 .private_value = nid \ 2453 } 2454 2455static struct snd_kcontrol_new alc880_test_mixer[] = { 2456 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2457 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2458 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT), 2459 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 2460 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 2461 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 2462 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT), 2463 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 2464 PIN_CTL_TEST("Front Pin Mode", 0x14), 2465 PIN_CTL_TEST("Surround Pin Mode", 0x15), 2466 PIN_CTL_TEST("CLFE Pin Mode", 0x16), 2467 PIN_CTL_TEST("Side Pin Mode", 0x17), 2468 PIN_CTL_TEST("In-1 Pin Mode", 0x18), 2469 PIN_CTL_TEST("In-2 Pin Mode", 0x19), 2470 PIN_CTL_TEST("In-3 Pin Mode", 0x1a), 2471 PIN_CTL_TEST("In-4 Pin Mode", 0x1b), 2472 PIN_SRC_TEST("In-1 Pin Source", 0x18), 2473 PIN_SRC_TEST("In-2 Pin Source", 0x19), 2474 PIN_SRC_TEST("In-3 Pin Source", 0x1a), 2475 PIN_SRC_TEST("In-4 Pin Source", 0x1b), 2476 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT), 2477 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT), 2478 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT), 2479 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT), 2480 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT), 2481 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT), 2482 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT), 2483 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT), 2484 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT), 2485 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT), 2486 { 2487 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2488 .name = "Channel Mode", 2489 .info = alc_ch_mode_info, 2490 .get = alc_ch_mode_get, 2491 .put = alc_ch_mode_put, 2492 }, 2493 { } /* end */ 2494}; 2495 2496static struct hda_verb alc880_test_init_verbs[] = { 2497 /* Unmute inputs of 0x0c - 0x0f */ 2498 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 2499 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 2500 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 2501 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 2502 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 2503 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 2504 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 2505 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 2506 /* Vol output for 0x0c-0x0f */ 2507 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 2508 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 2509 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 2510 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 2511 /* Set output pins 0x14-0x17 */ 2512 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2513 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2514 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2515 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2516 /* Unmute output pins 0x14-0x17 */ 2517 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2518 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2519 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2520 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2521 /* Set input pins 0x18-0x1c */ 2522 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2523 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2524 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2525 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2526 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2527 /* Mute input pins 0x18-0x1b */ 2528 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2529 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2530 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2531 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2532 /* ADC set up */ 2533 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 2534 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 2535 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 2536 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 2537 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 2538 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 2539 /* Analog input/passthru */ 2540 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 2541 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 2542 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 2543 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 2544 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 2545 { } 2546}; 2547#endif 2548 2549/* 2550 */ 2551 2552static const char *alc880_models[ALC880_MODEL_LAST] = { 2553 [ALC880_3ST] = "3stack", 2554 [ALC880_TCL_S700] = "tcl", 2555 [ALC880_3ST_DIG] = "3stack-digout", 2556 [ALC880_CLEVO] = "clevo", 2557 [ALC880_5ST] = "5stack", 2558 [ALC880_5ST_DIG] = "5stack-digout", 2559 [ALC880_W810] = "w810", 2560 [ALC880_Z71V] = "z71v", 2561 [ALC880_6ST] = "6stack", 2562 [ALC880_6ST_DIG] = "6stack-digout", 2563 [ALC880_ASUS] = "asus", 2564 [ALC880_ASUS_W1V] = "asus-w1v", 2565 [ALC880_ASUS_DIG] = "asus-dig", 2566 [ALC880_ASUS_DIG2] = "asus-dig2", 2567 [ALC880_UNIWILL_DIG] = "uniwill", 2568 [ALC880_UNIWILL_P53] = "uniwill-p53", 2569 [ALC880_FUJITSU] = "fujitsu", 2570 [ALC880_F1734] = "F1734", 2571 [ALC880_LG] = "lg", 2572 [ALC880_LG_LW] = "lg-lw", 2573#ifdef CONFIG_SND_DEBUG 2574 [ALC880_TEST] = "test", 2575#endif 2576 [ALC880_AUTO] = "auto", 2577}; 2578 2579static struct snd_pci_quirk alc880_cfg_tbl[] = { 2580 /* Broken BIOS configuration */ 2581 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), 2582 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG), 2583 2584 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG), 2585 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST), 2586 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810), 2587 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG), 2588 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG), 2589 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG), 2590 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG), 2591 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG), 2592 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST), 2593 2594 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG), 2595 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST), 2596 2597 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V), 2598 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG), 2599 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG), 2600 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG), 2601 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG), 2602 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG), 2603 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V), 2604 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */ 2605 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG), 2606 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG), 2607 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS", ALC880_ASUS), 2608 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG), 2609 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST), 2610 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST), 2611 SND_PCI_QUIRK(0x1043, 0, "ASUS", ALC880_ASUS), 2612 2613 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST), 2614 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST), 2615 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST), 2616 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST), 2617 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST), 2618 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO), 2619 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO), 2620 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG), 2621 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810), 2622 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG), 2623 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700), 2624 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG), 2625 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG), 2626 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG), 2627 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG), 2628 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG), 2629 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG), 2630 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2), 2631 2632 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG), 2633 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL), 2634 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53), 2635 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734), 2636 2637 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG), 2638 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL), 2639 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734), 2640 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU), 2641 2642 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG), 2643 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG), 2644 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW), 2645 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW), 2646 2647 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG), 2648 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG), 2649 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG), 2650 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG), 2651 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG), 2652 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG), 2653 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG), 2654 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG), 2655 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG), 2656 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG), 2657 SND_PCI_QUIRK(0x8086, 0, "Intel mobo", ALC880_3ST), 2658 2659 {} 2660}; 2661 2662/* 2663 * ALC880 codec presets 2664 */ 2665static struct alc_config_preset alc880_presets[] = { 2666 [ALC880_3ST] = { 2667 .mixers = { alc880_three_stack_mixer }, 2668 .init_verbs = { alc880_volume_init_verbs, 2669 alc880_pin_3stack_init_verbs }, 2670 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 2671 .dac_nids = alc880_dac_nids, 2672 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), 2673 .channel_mode = alc880_threestack_modes, 2674 .need_dac_fix = 1, 2675 .input_mux = &alc880_capture_source, 2676 }, 2677 [ALC880_3ST_DIG] = { 2678 .mixers = { alc880_three_stack_mixer }, 2679 .init_verbs = { alc880_volume_init_verbs, 2680 alc880_pin_3stack_init_verbs }, 2681 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 2682 .dac_nids = alc880_dac_nids, 2683 .dig_out_nid = ALC880_DIGOUT_NID, 2684 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), 2685 .channel_mode = alc880_threestack_modes, 2686 .need_dac_fix = 1, 2687 .input_mux = &alc880_capture_source, 2688 }, 2689 [ALC880_TCL_S700] = { 2690 .mixers = { alc880_tcl_s700_mixer }, 2691 .init_verbs = { alc880_volume_init_verbs, 2692 alc880_pin_tcl_S700_init_verbs, 2693 alc880_gpio2_init_verbs }, 2694 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 2695 .dac_nids = alc880_dac_nids, 2696 .hp_nid = 0x03, 2697 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), 2698 .channel_mode = alc880_2_jack_modes, 2699 .input_mux = &alc880_capture_source, 2700 }, 2701 [ALC880_5ST] = { 2702 .mixers = { alc880_three_stack_mixer, 2703 alc880_five_stack_mixer}, 2704 .init_verbs = { alc880_volume_init_verbs, 2705 alc880_pin_5stack_init_verbs }, 2706 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 2707 .dac_nids = alc880_dac_nids, 2708 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes), 2709 .channel_mode = alc880_fivestack_modes, 2710 .input_mux = &alc880_capture_source, 2711 }, 2712 [ALC880_5ST_DIG] = { 2713 .mixers = { alc880_three_stack_mixer, 2714 alc880_five_stack_mixer }, 2715 .init_verbs = { alc880_volume_init_verbs, 2716 alc880_pin_5stack_init_verbs }, 2717 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 2718 .dac_nids = alc880_dac_nids, 2719 .dig_out_nid = ALC880_DIGOUT_NID, 2720 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes), 2721 .channel_mode = alc880_fivestack_modes, 2722 .input_mux = &alc880_capture_source, 2723 }, 2724 [ALC880_6ST] = { 2725 .mixers = { alc880_six_stack_mixer }, 2726 .init_verbs = { alc880_volume_init_verbs, 2727 alc880_pin_6stack_init_verbs }, 2728 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids), 2729 .dac_nids = alc880_6st_dac_nids, 2730 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes), 2731 .channel_mode = alc880_sixstack_modes, 2732 .input_mux = &alc880_6stack_capture_source, 2733 }, 2734 [ALC880_6ST_DIG] = { 2735 .mixers = { alc880_six_stack_mixer }, 2736 .init_verbs = { alc880_volume_init_verbs, 2737 alc880_pin_6stack_init_verbs }, 2738 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids), 2739 .dac_nids = alc880_6st_dac_nids, 2740 .dig_out_nid = ALC880_DIGOUT_NID, 2741 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes), 2742 .channel_mode = alc880_sixstack_modes, 2743 .input_mux = &alc880_6stack_capture_source, 2744 }, 2745 [ALC880_W810] = { 2746 .mixers = { alc880_w810_base_mixer }, 2747 .init_verbs = { alc880_volume_init_verbs, 2748 alc880_pin_w810_init_verbs, 2749 alc880_gpio2_init_verbs }, 2750 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids), 2751 .dac_nids = alc880_w810_dac_nids, 2752 .dig_out_nid = ALC880_DIGOUT_NID, 2753 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes), 2754 .channel_mode = alc880_w810_modes, 2755 .input_mux = &alc880_capture_source, 2756 }, 2757 [ALC880_Z71V] = { 2758 .mixers = { alc880_z71v_mixer }, 2759 .init_verbs = { alc880_volume_init_verbs, 2760 alc880_pin_z71v_init_verbs }, 2761 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids), 2762 .dac_nids = alc880_z71v_dac_nids, 2763 .dig_out_nid = ALC880_DIGOUT_NID, 2764 .hp_nid = 0x03, 2765 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), 2766 .channel_mode = alc880_2_jack_modes, 2767 .input_mux = &alc880_capture_source, 2768 }, 2769 [ALC880_F1734] = { 2770 .mixers = { alc880_f1734_mixer }, 2771 .init_verbs = { alc880_volume_init_verbs, 2772 alc880_pin_f1734_init_verbs }, 2773 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids), 2774 .dac_nids = alc880_f1734_dac_nids, 2775 .hp_nid = 0x02, 2776 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), 2777 .channel_mode = alc880_2_jack_modes, 2778 .input_mux = &alc880_capture_source, 2779 }, 2780 [ALC880_ASUS] = { 2781 .mixers = { alc880_asus_mixer }, 2782 .init_verbs = { alc880_volume_init_verbs, 2783 alc880_pin_asus_init_verbs, 2784 alc880_gpio1_init_verbs }, 2785 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 2786 .dac_nids = alc880_asus_dac_nids, 2787 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), 2788 .channel_mode = alc880_asus_modes, 2789 .need_dac_fix = 1, 2790 .input_mux = &alc880_capture_source, 2791 }, 2792 [ALC880_ASUS_DIG] = { 2793 .mixers = { alc880_asus_mixer }, 2794 .init_verbs = { alc880_volume_init_verbs, 2795 alc880_pin_asus_init_verbs, 2796 alc880_gpio1_init_verbs }, 2797 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 2798 .dac_nids = alc880_asus_dac_nids, 2799 .dig_out_nid = ALC880_DIGOUT_NID, 2800 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), 2801 .channel_mode = alc880_asus_modes, 2802 .need_dac_fix = 1, 2803 .input_mux = &alc880_capture_source, 2804 }, 2805 [ALC880_ASUS_DIG2] = { 2806 .mixers = { alc880_asus_mixer }, 2807 .init_verbs = { alc880_volume_init_verbs, 2808 alc880_pin_asus_init_verbs, 2809 alc880_gpio2_init_verbs }, /* use GPIO2 */ 2810 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 2811 .dac_nids = alc880_asus_dac_nids, 2812 .dig_out_nid = ALC880_DIGOUT_NID, 2813 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), 2814 .channel_mode = alc880_asus_modes, 2815 .need_dac_fix = 1, 2816 .input_mux = &alc880_capture_source, 2817 }, 2818 [ALC880_ASUS_W1V] = { 2819 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer }, 2820 .init_verbs = { alc880_volume_init_verbs, 2821 alc880_pin_asus_init_verbs, 2822 alc880_gpio1_init_verbs }, 2823 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 2824 .dac_nids = alc880_asus_dac_nids, 2825 .dig_out_nid = ALC880_DIGOUT_NID, 2826 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), 2827 .channel_mode = alc880_asus_modes, 2828 .need_dac_fix = 1, 2829 .input_mux = &alc880_capture_source, 2830 }, 2831 [ALC880_UNIWILL_DIG] = { 2832 .mixers = { alc880_asus_mixer, alc880_pcbeep_mixer }, 2833 .init_verbs = { alc880_volume_init_verbs, 2834 alc880_pin_asus_init_verbs }, 2835 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 2836 .dac_nids = alc880_asus_dac_nids, 2837 .dig_out_nid = ALC880_DIGOUT_NID, 2838 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), 2839 .channel_mode = alc880_asus_modes, 2840 .need_dac_fix = 1, 2841 .input_mux = &alc880_capture_source, 2842 }, 2843 [ALC880_UNIWILL] = { 2844 .mixers = { alc880_uniwill_mixer }, 2845 .init_verbs = { alc880_volume_init_verbs, 2846 alc880_uniwill_init_verbs }, 2847 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 2848 .dac_nids = alc880_asus_dac_nids, 2849 .dig_out_nid = ALC880_DIGOUT_NID, 2850 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), 2851 .channel_mode = alc880_threestack_modes, 2852 .need_dac_fix = 1, 2853 .input_mux = &alc880_capture_source, 2854 .unsol_event = alc880_uniwill_unsol_event, 2855 .init_hook = alc880_uniwill_automute, 2856 }, 2857 [ALC880_UNIWILL_P53] = { 2858 .mixers = { alc880_uniwill_p53_mixer }, 2859 .init_verbs = { alc880_volume_init_verbs, 2860 alc880_uniwill_p53_init_verbs }, 2861 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 2862 .dac_nids = alc880_asus_dac_nids, 2863 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes), 2864 .channel_mode = alc880_threestack_modes, 2865 .input_mux = &alc880_capture_source, 2866 .unsol_event = alc880_uniwill_p53_unsol_event, 2867 .init_hook = alc880_uniwill_p53_hp_automute, 2868 }, 2869 [ALC880_FUJITSU] = { 2870 .mixers = { alc880_fujitsu_mixer, 2871 alc880_pcbeep_mixer, }, 2872 .init_verbs = { alc880_volume_init_verbs, 2873 alc880_uniwill_p53_init_verbs, 2874 alc880_beep_init_verbs }, 2875 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 2876 .dac_nids = alc880_dac_nids, 2877 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), 2878 .channel_mode = alc880_2_jack_modes, 2879 .input_mux = &alc880_capture_source, 2880 .unsol_event = alc880_uniwill_p53_unsol_event, 2881 .init_hook = alc880_uniwill_p53_hp_automute, 2882 }, 2883 [ALC880_CLEVO] = { 2884 .mixers = { alc880_three_stack_mixer }, 2885 .init_verbs = { alc880_volume_init_verbs, 2886 alc880_pin_clevo_init_verbs }, 2887 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 2888 .dac_nids = alc880_dac_nids, 2889 .hp_nid = 0x03, 2890 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), 2891 .channel_mode = alc880_threestack_modes, 2892 .need_dac_fix = 1, 2893 .input_mux = &alc880_capture_source, 2894 }, 2895 [ALC880_LG] = { 2896 .mixers = { alc880_lg_mixer }, 2897 .init_verbs = { alc880_volume_init_verbs, 2898 alc880_lg_init_verbs }, 2899 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids), 2900 .dac_nids = alc880_lg_dac_nids, 2901 .dig_out_nid = ALC880_DIGOUT_NID, 2902 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes), 2903 .channel_mode = alc880_lg_ch_modes, 2904 .need_dac_fix = 1, 2905 .input_mux = &alc880_lg_capture_source, 2906 .unsol_event = alc880_lg_unsol_event, 2907 .init_hook = alc880_lg_automute, 2908#ifdef CONFIG_SND_HDA_POWER_SAVE 2909 .loopbacks = alc880_lg_loopbacks, 2910#endif 2911 }, 2912 [ALC880_LG_LW] = { 2913 .mixers = { alc880_lg_lw_mixer }, 2914 .init_verbs = { alc880_volume_init_verbs, 2915 alc880_lg_lw_init_verbs }, 2916 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 2917 .dac_nids = alc880_dac_nids, 2918 .dig_out_nid = ALC880_DIGOUT_NID, 2919 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes), 2920 .channel_mode = alc880_lg_lw_modes, 2921 .input_mux = &alc880_lg_lw_capture_source, 2922 .unsol_event = alc880_lg_lw_unsol_event, 2923 .init_hook = alc880_lg_lw_automute, 2924 }, 2925#ifdef CONFIG_SND_DEBUG 2926 [ALC880_TEST] = { 2927 .mixers = { alc880_test_mixer }, 2928 .init_verbs = { alc880_test_init_verbs }, 2929 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids), 2930 .dac_nids = alc880_test_dac_nids, 2931 .dig_out_nid = ALC880_DIGOUT_NID, 2932 .num_channel_mode = ARRAY_SIZE(alc880_test_modes), 2933 .channel_mode = alc880_test_modes, 2934 .input_mux = &alc880_test_capture_source, 2935 }, 2936#endif 2937}; 2938 2939/* 2940 * Automatic parse of I/O pins from the BIOS configuration 2941 */ 2942 2943#define NUM_CONTROL_ALLOC 32 2944#define NUM_VERB_ALLOC 32 2945 2946enum { 2947 ALC_CTL_WIDGET_VOL, 2948 ALC_CTL_WIDGET_MUTE, 2949 ALC_CTL_BIND_MUTE, 2950}; 2951static struct snd_kcontrol_new alc880_control_templates[] = { 2952 HDA_CODEC_VOLUME(NULL, 0, 0, 0), 2953 HDA_CODEC_MUTE(NULL, 0, 0, 0), 2954 HDA_BIND_MUTE(NULL, 0, 0, 0), 2955}; 2956 2957/* add dynamic controls */ 2958static int add_control(struct alc_spec *spec, int type, const char *name, 2959 unsigned long val) 2960{ 2961 struct snd_kcontrol_new *knew; 2962 2963 if (spec->num_kctl_used >= spec->num_kctl_alloc) { 2964 int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC; 2965 2966 /* array + terminator */ 2967 knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL); 2968 if (!knew) 2969 return -ENOMEM; 2970 if (spec->kctl_alloc) { 2971 memcpy(knew, spec->kctl_alloc, 2972 sizeof(*knew) * spec->num_kctl_alloc); 2973 kfree(spec->kctl_alloc); 2974 } 2975 spec->kctl_alloc = knew; 2976 spec->num_kctl_alloc = num; 2977 } 2978 2979 knew = &spec->kctl_alloc[spec->num_kctl_used]; 2980 *knew = alc880_control_templates[type]; 2981 knew->name = kstrdup(name, GFP_KERNEL); 2982 if (!knew->name) 2983 return -ENOMEM; 2984 knew->private_value = val; 2985 spec->num_kctl_used++; 2986 return 0; 2987} 2988 2989#define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17) 2990#define alc880_fixed_pin_idx(nid) ((nid) - 0x14) 2991#define alc880_is_multi_pin(nid) ((nid) >= 0x18) 2992#define alc880_multi_pin_idx(nid) ((nid) - 0x18) 2993#define alc880_is_input_pin(nid) ((nid) >= 0x18) 2994#define alc880_input_pin_idx(nid) ((nid) - 0x18) 2995#define alc880_idx_to_dac(nid) ((nid) + 0x02) 2996#define alc880_dac_to_idx(nid) ((nid) - 0x02) 2997#define alc880_idx_to_mixer(nid) ((nid) + 0x0c) 2998#define alc880_idx_to_selector(nid) ((nid) + 0x10) 2999#define ALC880_PIN_CD_NID 0x1c 3000 3001/* fill in the dac_nids table from the parsed pin configuration */ 3002static int alc880_auto_fill_dac_nids(struct alc_spec *spec, 3003 const struct auto_pin_cfg *cfg) 3004{ 3005 hda_nid_t nid; 3006 int assigned[4]; 3007 int i, j; 3008 3009 memset(assigned, 0, sizeof(assigned)); 3010 spec->multiout.dac_nids = spec->private_dac_nids; 3011 3012 /* check the pins hardwired to audio widget */ 3013 for (i = 0; i < cfg->line_outs; i++) { 3014 nid = cfg->line_out_pins[i]; 3015 if (alc880_is_fixed_pin(nid)) { 3016 int idx = alc880_fixed_pin_idx(nid); 3017 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx); 3018 assigned[idx] = 1; 3019 } 3020 } 3021 /* left pins can be connect to any audio widget */ 3022 for (i = 0; i < cfg->line_outs; i++) { 3023 nid = cfg->line_out_pins[i]; 3024 if (alc880_is_fixed_pin(nid)) 3025 continue; 3026 /* search for an empty channel */ 3027 for (j = 0; j < cfg->line_outs; j++) { 3028 if (!assigned[j]) { 3029 spec->multiout.dac_nids[i] = 3030 alc880_idx_to_dac(j); 3031 assigned[j] = 1; 3032 break; 3033 } 3034 } 3035 } 3036 spec->multiout.num_dacs = cfg->line_outs; 3037 return 0; 3038} 3039 3040/* add playback controls from the parsed DAC table */ 3041static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec, 3042 const struct auto_pin_cfg *cfg) 3043{ 3044 char name[32]; 3045 static const char *chname[4] = { 3046 "Front", "Surround", NULL /*CLFE*/, "Side" 3047 }; 3048 hda_nid_t nid; 3049 int i, err; 3050 3051 for (i = 0; i < cfg->line_outs; i++) { 3052 if (!spec->multiout.dac_nids[i]) 3053 continue; 3054 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i])); 3055 if (i == 2) { 3056 /* Center/LFE */ 3057 err = add_control(spec, ALC_CTL_WIDGET_VOL, 3058 "Center Playback Volume", 3059 HDA_COMPOSE_AMP_VAL(nid, 1, 0, 3060 HDA_OUTPUT)); 3061 if (err < 0) 3062 return err; 3063 err = add_control(spec, ALC_CTL_WIDGET_VOL, 3064 "LFE Playback Volume", 3065 HDA_COMPOSE_AMP_VAL(nid, 2, 0, 3066 HDA_OUTPUT)); 3067 if (err < 0) 3068 return err; 3069 err = add_control(spec, ALC_CTL_BIND_MUTE, 3070 "Center Playback Switch", 3071 HDA_COMPOSE_AMP_VAL(nid, 1, 2, 3072 HDA_INPUT)); 3073 if (err < 0) 3074 return err; 3075 err = add_control(spec, ALC_CTL_BIND_MUTE, 3076 "LFE Playback Switch", 3077 HDA_COMPOSE_AMP_VAL(nid, 2, 2, 3078 HDA_INPUT)); 3079 if (err < 0) 3080 return err; 3081 } else { 3082 sprintf(name, "%s Playback Volume", chname[i]); 3083 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, 3084 HDA_COMPOSE_AMP_VAL(nid, 3, 0, 3085 HDA_OUTPUT)); 3086 if (err < 0) 3087 return err; 3088 sprintf(name, "%s Playback Switch", chname[i]); 3089 err = add_control(spec, ALC_CTL_BIND_MUTE, name, 3090 HDA_COMPOSE_AMP_VAL(nid, 3, 2, 3091 HDA_INPUT)); 3092 if (err < 0) 3093 return err; 3094 } 3095 } 3096 return 0; 3097} 3098 3099/* add playback controls for speaker and HP outputs */ 3100static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin, 3101 const char *pfx) 3102{ 3103 hda_nid_t nid; 3104 int err; 3105 char name[32]; 3106 3107 if (!pin) 3108 return 0; 3109 3110 if (alc880_is_fixed_pin(pin)) { 3111 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); 3112 /* specify the DAC as the extra output */ 3113 if (!spec->multiout.hp_nid) 3114 spec->multiout.hp_nid = nid; 3115 else 3116 spec->multiout.extra_out_nid[0] = nid; 3117 /* control HP volume/switch on the output mixer amp */ 3118 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin)); 3119 sprintf(name, "%s Playback Volume", pfx); 3120 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, 3121 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); 3122 if (err < 0) 3123 return err; 3124 sprintf(name, "%s Playback Switch", pfx); 3125 err = add_control(spec, ALC_CTL_BIND_MUTE, name, 3126 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT)); 3127 if (err < 0) 3128 return err; 3129 } else if (alc880_is_multi_pin(pin)) { 3130 /* set manual connection */ 3131 /* we have only a switch on HP-out PIN */ 3132 sprintf(name, "%s Playback Switch", pfx); 3133 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, 3134 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); 3135 if (err < 0) 3136 return err; 3137 } 3138 return 0; 3139} 3140 3141/* create input playback/capture controls for the given pin */ 3142static int new_analog_input(struct alc_spec *spec, hda_nid_t pin, 3143 const char *ctlname, 3144 int idx, hda_nid_t mix_nid) 3145{ 3146 char name[32]; 3147 int err; 3148 3149 sprintf(name, "%s Playback Volume", ctlname); 3150 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, 3151 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT)); 3152 if (err < 0) 3153 return err; 3154 sprintf(name, "%s Playback Switch", ctlname); 3155 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, 3156 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT)); 3157 if (err < 0) 3158 return err; 3159 return 0; 3160} 3161 3162/* create playback/capture controls for input pins */ 3163static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec, 3164 const struct auto_pin_cfg *cfg) 3165{ 3166 struct hda_input_mux *imux = &spec->private_imux; 3167 int i, err, idx; 3168 3169 for (i = 0; i < AUTO_PIN_LAST; i++) { 3170 if (alc880_is_input_pin(cfg->input_pins[i])) { 3171 idx = alc880_input_pin_idx(cfg->input_pins[i]); 3172 err = new_analog_input(spec, cfg->input_pins[i], 3173 auto_pin_cfg_labels[i], 3174 idx, 0x0b); 3175 if (err < 0) 3176 return err; 3177 imux->items[imux->num_items].label = 3178 auto_pin_cfg_labels[i]; 3179 imux->items[imux->num_items].index = 3180 alc880_input_pin_idx(cfg->input_pins[i]); 3181 imux->num_items++; 3182 } 3183 } 3184 return 0; 3185} 3186 3187static void alc880_auto_set_output_and_unmute(struct hda_codec *codec, 3188 hda_nid_t nid, int pin_type, 3189 int dac_idx) 3190{ 3191 /* set as output */ 3192 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 3193 pin_type); 3194 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, 3195 AMP_OUT_UNMUTE); 3196 /* need the manual connection? */ 3197 if (alc880_is_multi_pin(nid)) { 3198 struct alc_spec *spec = codec->spec; 3199 int idx = alc880_multi_pin_idx(nid); 3200 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0, 3201 AC_VERB_SET_CONNECT_SEL, 3202 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx])); 3203 } 3204} 3205 3206static int get_pin_type(int line_out_type) 3207{ 3208 if (line_out_type == AUTO_PIN_HP_OUT) 3209 return PIN_HP; 3210 else 3211 return PIN_OUT; 3212} 3213 3214static void alc880_auto_init_multi_out(struct hda_codec *codec) 3215{ 3216 struct alc_spec *spec = codec->spec; 3217 int i; 3218 3219 alc_subsystem_id(codec, 0x15, 0x1b, 0x14); 3220 for (i = 0; i < spec->autocfg.line_outs; i++) { 3221 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 3222 int pin_type = get_pin_type(spec->autocfg.line_out_type); 3223 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i); 3224 } 3225} 3226 3227static void alc880_auto_init_extra_out(struct hda_codec *codec) 3228{ 3229 struct alc_spec *spec = codec->spec; 3230 hda_nid_t pin; 3231 3232 pin = spec->autocfg.speaker_pins[0]; 3233 if (pin) /* connect to front */ 3234 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0); 3235 pin = spec->autocfg.hp_pins[0]; 3236 if (pin) /* connect to front */ 3237 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); 3238} 3239 3240static void alc880_auto_init_analog_input(struct hda_codec *codec) 3241{ 3242 struct alc_spec *spec = codec->spec; 3243 int i; 3244 3245 for (i = 0; i < AUTO_PIN_LAST; i++) { 3246 hda_nid_t nid = spec->autocfg.input_pins[i]; 3247 if (alc880_is_input_pin(nid)) { 3248 snd_hda_codec_write(codec, nid, 0, 3249 AC_VERB_SET_PIN_WIDGET_CONTROL, 3250 i <= AUTO_PIN_FRONT_MIC ? 3251 PIN_VREF80 : PIN_IN); 3252 if (nid != ALC880_PIN_CD_NID) 3253 snd_hda_codec_write(codec, nid, 0, 3254 AC_VERB_SET_AMP_GAIN_MUTE, 3255 AMP_OUT_MUTE); 3256 } 3257 } 3258} 3259 3260/* parse the BIOS configuration and set up the alc_spec */ 3261/* return 1 if successful, 0 if the proper config is not found, 3262 * or a negative error code 3263 */ 3264static int alc880_parse_auto_config(struct hda_codec *codec) 3265{ 3266 struct alc_spec *spec = codec->spec; 3267 int err; 3268 static hda_nid_t alc880_ignore[] = { 0x1d, 0 }; 3269 3270 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 3271 alc880_ignore); 3272 if (err < 0) 3273 return err; 3274 if (!spec->autocfg.line_outs) 3275 return 0; /* can't find valid BIOS pin config */ 3276 3277 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); 3278 if (err < 0) 3279 return err; 3280 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg); 3281 if (err < 0) 3282 return err; 3283 err = alc880_auto_create_extra_out(spec, 3284 spec->autocfg.speaker_pins[0], 3285 "Speaker"); 3286 if (err < 0) 3287 return err; 3288 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0], 3289 "Headphone"); 3290 if (err < 0) 3291 return err; 3292 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg); 3293 if (err < 0) 3294 return err; 3295 3296 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 3297 3298 if (spec->autocfg.dig_out_pin) 3299 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID; 3300 if (spec->autocfg.dig_in_pin) 3301 spec->dig_in_nid = ALC880_DIGIN_NID; 3302 3303 if (spec->kctl_alloc) 3304 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 3305 3306 spec->init_verbs[spec->num_init_verbs++] = alc880_volume_init_verbs; 3307 3308 spec->num_mux_defs = 1; 3309 spec->input_mux = &spec->private_imux; 3310 3311 return 1; 3312} 3313 3314/* additional initialization for auto-configuration model */ 3315static void alc880_auto_init(struct hda_codec *codec) 3316{ 3317 alc880_auto_init_multi_out(codec); 3318 alc880_auto_init_extra_out(codec); 3319 alc880_auto_init_analog_input(codec); 3320} 3321 3322/* 3323 * OK, here we have finally the patch for ALC880 3324 */ 3325 3326static int patch_alc880(struct hda_codec *codec) 3327{ 3328 struct alc_spec *spec; 3329 int board_config; 3330 int err; 3331 3332 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 3333 if (spec == NULL) 3334 return -ENOMEM; 3335 3336 codec->spec = spec; 3337 3338 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST, 3339 alc880_models, 3340 alc880_cfg_tbl); 3341 if (board_config < 0) { 3342 printk(KERN_INFO "hda_codec: Unknown model for ALC880, " 3343 "trying auto-probe from BIOS...\n"); 3344 board_config = ALC880_AUTO; 3345 } 3346 3347 if (board_config == ALC880_AUTO) { 3348 /* automatic parse from the BIOS config */ 3349 err = alc880_parse_auto_config(codec); 3350 if (err < 0) { 3351 alc_free(codec); 3352 return err; 3353 } else if (!err) { 3354 printk(KERN_INFO 3355 "hda_codec: Cannot set up configuration " 3356 "from BIOS. Using 3-stack mode...\n"); 3357 board_config = ALC880_3ST; 3358 } 3359 } 3360 3361 if (board_config != ALC880_AUTO) 3362 setup_preset(spec, &alc880_presets[board_config]); 3363 3364 spec->stream_name_analog = "ALC880 Analog"; 3365 spec->stream_analog_playback = &alc880_pcm_analog_playback; 3366 spec->stream_analog_capture = &alc880_pcm_analog_capture; 3367 3368 spec->stream_name_digital = "ALC880 Digital"; 3369 spec->stream_digital_playback = &alc880_pcm_digital_playback; 3370 spec->stream_digital_capture = &alc880_pcm_digital_capture; 3371 3372 if (!spec->adc_nids && spec->input_mux) { 3373 /* check whether NID 0x07 is valid */ 3374 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]); 3375 /* get type */ 3376 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; 3377 if (wcap != AC_WID_AUD_IN) { 3378 spec->adc_nids = alc880_adc_nids_alt; 3379 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt); 3380 spec->mixers[spec->num_mixers] = 3381 alc880_capture_alt_mixer; 3382 spec->num_mixers++; 3383 } else { 3384 spec->adc_nids = alc880_adc_nids; 3385 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids); 3386 spec->mixers[spec->num_mixers] = alc880_capture_mixer; 3387 spec->num_mixers++; 3388 } 3389 } 3390 3391 codec->patch_ops = alc_patch_ops; 3392 if (board_config == ALC880_AUTO) 3393 spec->init_hook = alc880_auto_init; 3394#ifdef CONFIG_SND_HDA_POWER_SAVE 3395 if (!spec->loopback.amplist) 3396 spec->loopback.amplist = alc880_loopbacks; 3397#endif 3398 3399 return 0; 3400} 3401 3402 3403/* 3404 * ALC260 support 3405 */ 3406 3407static hda_nid_t alc260_dac_nids[1] = { 3408 /* front */ 3409 0x02, 3410}; 3411 3412static hda_nid_t alc260_adc_nids[1] = { 3413 /* ADC0 */ 3414 0x04, 3415}; 3416 3417static hda_nid_t alc260_adc_nids_alt[1] = { 3418 /* ADC1 */ 3419 0x05, 3420}; 3421 3422static hda_nid_t alc260_hp_adc_nids[2] = { 3423 /* ADC1, 0 */ 3424 0x05, 0x04 3425}; 3426 3427/* NIDs used when simultaneous access to both ADCs makes sense. Note that 3428 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC. 3429 */ 3430static hda_nid_t alc260_dual_adc_nids[2] = { 3431 /* ADC0, ADC1 */ 3432 0x04, 0x05 3433}; 3434 3435#define ALC260_DIGOUT_NID 0x03 3436#define ALC260_DIGIN_NID 0x06 3437 3438static struct hda_input_mux alc260_capture_source = { 3439 .num_items = 4, 3440 .items = { 3441 { "Mic", 0x0 }, 3442 { "Front Mic", 0x1 }, 3443 { "Line", 0x2 }, 3444 { "CD", 0x4 }, 3445 }, 3446}; 3447 3448/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack, 3449 * headphone jack and the internal CD lines since these are the only pins at 3450 * which audio can appear. For flexibility, also allow the option of 3451 * recording the mixer output on the second ADC (ADC0 doesn't have a 3452 * connection to the mixer output). 3453 */ 3454static struct hda_input_mux alc260_fujitsu_capture_sources[2] = { 3455 { 3456 .num_items = 3, 3457 .items = { 3458 { "Mic/Line", 0x0 }, 3459 { "CD", 0x4 }, 3460 { "Headphone", 0x2 }, 3461 }, 3462 }, 3463 { 3464 .num_items = 4, 3465 .items = { 3466 { "Mic/Line", 0x0 }, 3467 { "CD", 0x4 }, 3468 { "Headphone", 0x2 }, 3469 { "Mixer", 0x5 }, 3470 }, 3471 }, 3472 3473}; 3474 3475/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to 3476 * the Fujitsu S702x, but jacks are marked differently. 3477 */ 3478static struct hda_input_mux alc260_acer_capture_sources[2] = { 3479 { 3480 .num_items = 4, 3481 .items = { 3482 { "Mic", 0x0 }, 3483 { "Line", 0x2 }, 3484 { "CD", 0x4 }, 3485 { "Headphone", 0x5 }, 3486 }, 3487 }, 3488 { 3489 .num_items = 5, 3490 .items = { 3491 { "Mic", 0x0 }, 3492 { "Line", 0x2 }, 3493 { "CD", 0x4 }, 3494 { "Headphone", 0x6 }, 3495 { "Mixer", 0x5 }, 3496 }, 3497 }, 3498}; 3499/* 3500 * This is just place-holder, so there's something for alc_build_pcms to look 3501 * at when it calculates the maximum number of channels. ALC260 has no mixer 3502 * element which allows changing the channel mode, so the verb list is 3503 * never used. 3504 */ 3505static struct hda_channel_mode alc260_modes[1] = { 3506 { 2, NULL }, 3507}; 3508 3509 3510/* Mixer combinations 3511 * 3512 * basic: base_output + input + pc_beep + capture 3513 * HP: base_output + input + capture_alt 3514 * HP_3013: hp_3013 + input + capture 3515 * fujitsu: fujitsu + capture 3516 * acer: acer + capture 3517 */ 3518 3519static struct snd_kcontrol_new alc260_base_output_mixer[] = { 3520 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT), 3521 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT), 3522 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT), 3523 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT), 3524 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), 3525 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT), 3526 { } /* end */ 3527}; 3528 3529static struct snd_kcontrol_new alc260_input_mixer[] = { 3530 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), 3531 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), 3532 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), 3533 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT), 3534 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), 3535 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT), 3536 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT), 3537 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT), 3538 { } /* end */ 3539}; 3540 3541static struct snd_kcontrol_new alc260_pc_beep_mixer[] = { 3542 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT), 3543 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT), 3544 { } /* end */ 3545}; 3546 3547static struct snd_kcontrol_new alc260_hp_3013_mixer[] = { 3548 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT), 3549 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT), 3550 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT), 3551 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT), 3552 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT), 3553 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 3554 HDA_CODEC_VOLUME_MONO("iSpeaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), 3555 HDA_CODEC_MUTE_MONO("iSpeaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT), 3556 { } /* end */ 3557}; 3558 3559/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12, 3560 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10. 3561 */ 3562static struct snd_kcontrol_new alc260_fujitsu_mixer[] = { 3563 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT), 3564 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT), 3565 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT), 3566 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), 3567 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), 3568 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT), 3569 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT), 3570 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN), 3571 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT), 3572 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT), 3573 HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT), 3574 HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x09, 2, HDA_INPUT), 3575 { } /* end */ 3576}; 3577 3578/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current 3579 * versions of the ALC260 don't act on requests to enable mic bias from NID 3580 * 0x0f (used to drive the headphone jack in these laptops). The ALC260 3581 * datasheet doesn't mention this restriction. At this stage it's not clear 3582 * whether this behaviour is intentional or is a hardware bug in chip 3583 * revisions available in early 2006. Therefore for now allow the 3584 * "Headphone Jack Mode" control to span all choices, but if it turns out 3585 * that the lack of mic bias for this NID is intentional we could change the 3586 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS. 3587 * 3588 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006 3589 * don't appear to make the mic bias available from the "line" jack, even 3590 * though the NID used for this jack (0x14) can supply it. The theory is 3591 * that perhaps Acer have included blocking capacitors between the ALC260 3592 * and the output jack. If this turns out to be the case for all such 3593 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT 3594 * to ALC_PIN_DIR_INOUT_NOMICBIAS. 3595 * 3596 * The C20x Tablet series have a mono internal speaker which is controlled 3597 * via the chip's Mono sum widget and pin complex, so include the necessary 3598 * controls for such models. On models without a "mono speaker" the control 3599 * won't do anything. 3600 */ 3601static struct snd_kcontrol_new alc260_acer_mixer[] = { 3602 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), 3603 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT), 3604 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT), 3605 HDA_CODEC_VOLUME_MONO("Mono Speaker Playback Volume", 0x0a, 1, 0x0, 3606 HDA_OUTPUT), 3607 HDA_BIND_MUTE_MONO("Mono Speaker Playback Switch", 0x0a, 1, 2, 3608 HDA_INPUT), 3609 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), 3610 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), 3611 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), 3612 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT), 3613 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN), 3614 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), 3615 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT), 3616 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT), 3617 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT), 3618 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT), 3619 { } /* end */ 3620}; 3621 3622/* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12, 3623 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17. 3624 */ 3625static struct snd_kcontrol_new alc260_will_mixer[] = { 3626 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), 3627 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT), 3628 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), 3629 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT), 3630 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN), 3631 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), 3632 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT), 3633 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT), 3634 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), 3635 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), 3636 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT), 3637 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT), 3638 { } /* end */ 3639}; 3640 3641/* Replacer 672V ALC260 pin usage: Mic jack = 0x12, 3642 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f. 3643 */ 3644static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = { 3645 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), 3646 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT), 3647 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), 3648 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT), 3649 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN), 3650 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT), 3651 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT), 3652 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), 3653 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT), 3654 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT), 3655 { } /* end */ 3656}; 3657 3658/* capture mixer elements */ 3659static struct snd_kcontrol_new alc260_capture_mixer[] = { 3660 HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT), 3661 HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT), 3662 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x05, 0x0, HDA_INPUT), 3663 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x05, 0x0, HDA_INPUT), 3664 { 3665 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 3666 /* The multiple "Capture Source" controls confuse alsamixer 3667 * So call somewhat different.. 3668 * FIXME: the controls appear in the "playback" view! 3669 */ 3670 /* .name = "Capture Source", */ 3671 .name = "Input Source", 3672 .count = 2, 3673 .info = alc_mux_enum_info, 3674 .get = alc_mux_enum_get, 3675 .put = alc_mux_enum_put, 3676 }, 3677 { } /* end */ 3678}; 3679 3680static struct snd_kcontrol_new alc260_capture_alt_mixer[] = { 3681 HDA_CODEC_VOLUME("Capture Volume", 0x05, 0x0, HDA_INPUT), 3682 HDA_CODEC_MUTE("Capture Switch", 0x05, 0x0, HDA_INPUT), 3683 { 3684 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 3685 /* The multiple "Capture Source" controls confuse alsamixer 3686 * So call somewhat different.. 3687 * FIXME: the controls appear in the "playback" view! 3688 */ 3689 /* .name = "Capture Source", */ 3690 .name = "Input Source", 3691 .count = 1, 3692 .info = alc_mux_enum_info, 3693 .get = alc_mux_enum_get, 3694 .put = alc_mux_enum_put, 3695 }, 3696 { } /* end */ 3697}; 3698 3699/* 3700 * initialization verbs 3701 */ 3702static struct hda_verb alc260_init_verbs[] = { 3703 /* Line In pin widget for input */ 3704 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3705 /* CD pin widget for input */ 3706 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3707 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 3708 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3709 /* Mic2 (front panel) pin widget for input and vref at 80% */ 3710 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3711 /* LINE-2 is used for line-out in rear */ 3712 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3713 /* select line-out */ 3714 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00}, 3715 /* LINE-OUT pin */ 3716 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3717 /* enable HP */ 3718 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3719 /* enable Mono */ 3720 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3721 /* mute capture amp left and right */ 3722 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3723 /* set connection select to line in (default select for this ADC) */ 3724 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02}, 3725 /* mute capture amp left and right */ 3726 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3727 /* set connection select to line in (default select for this ADC) */ 3728 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02}, 3729 /* set vol=0 Line-Out mixer amp left and right */ 3730 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3731 /* unmute pin widget amp left and right (no gain on this amp) */ 3732 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3733 /* set vol=0 HP mixer amp left and right */ 3734 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3735 /* unmute pin widget amp left and right (no gain on this amp) */ 3736 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3737 /* set vol=0 Mono mixer amp left and right */ 3738 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3739 /* unmute pin widget amp left and right (no gain on this amp) */ 3740 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3741 /* unmute LINE-2 out pin */ 3742 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3743 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & 3744 * Line In 2 = 0x03 3745 */ 3746 /* mute analog inputs */ 3747 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3748 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 3749 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 3750 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 3751 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 3752 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */ 3753 /* mute Front out path */ 3754 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3755 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 3756 /* mute Headphone out path */ 3757 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3758 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 3759 /* mute Mono out path */ 3760 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3761 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 3762 { } 3763}; 3764 3765#if 0 /* should be identical with alc260_init_verbs? */ 3766static struct hda_verb alc260_hp_init_verbs[] = { 3767 /* Headphone and output */ 3768 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 3769 /* mono output */ 3770 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 3771 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 3772 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 3773 /* Mic2 (front panel) pin widget for input and vref at 80% */ 3774 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 3775 /* Line In pin widget for input */ 3776 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 3777 /* Line-2 pin widget for output */ 3778 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 3779 /* CD pin widget for input */ 3780 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 3781 /* unmute amp left and right */ 3782 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000}, 3783 /* set connection select to line in (default select for this ADC) */ 3784 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02}, 3785 /* unmute Line-Out mixer amp left and right (volume = 0) */ 3786 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 3787 /* mute pin widget amp left and right (no gain on this amp) */ 3788 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 3789 /* unmute HP mixer amp left and right (volume = 0) */ 3790 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 3791 /* mute pin widget amp left and right (no gain on this amp) */ 3792 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 3793 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & 3794 * Line In 2 = 0x03 3795 */ 3796 /* mute analog inputs */ 3797 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3798 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 3799 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 3800 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 3801 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 3802 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */ 3803 /* Unmute Front out path */ 3804 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 3805 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 3806 /* Unmute Headphone out path */ 3807 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 3808 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 3809 /* Unmute Mono out path */ 3810 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 3811 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 3812 { } 3813}; 3814#endif 3815 3816static struct hda_verb alc260_hp_3013_init_verbs[] = { 3817 /* Line out and output */ 3818 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 3819 /* mono output */ 3820 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 3821 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 3822 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 3823 /* Mic2 (front panel) pin widget for input and vref at 80% */ 3824 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 3825 /* Line In pin widget for input */ 3826 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 3827 /* Headphone pin widget for output */ 3828 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 3829 /* CD pin widget for input */ 3830 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 3831 /* unmute amp left and right */ 3832 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000}, 3833 /* set connection select to line in (default select for this ADC) */ 3834 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02}, 3835 /* unmute Line-Out mixer amp left and right (volume = 0) */ 3836 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 3837 /* mute pin widget amp left and right (no gain on this amp) */ 3838 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 3839 /* unmute HP mixer amp left and right (volume = 0) */ 3840 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 3841 /* mute pin widget amp left and right (no gain on this amp) */ 3842 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 3843 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & 3844 * Line In 2 = 0x03 3845 */ 3846 /* mute analog inputs */ 3847 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3848 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 3849 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 3850 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 3851 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 3852 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */ 3853 /* Unmute Front out path */ 3854 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 3855 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 3856 /* Unmute Headphone out path */ 3857 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 3858 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 3859 /* Unmute Mono out path */ 3860 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 3861 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 3862 { } 3863}; 3864 3865/* Initialisation sequence for ALC260 as configured in Fujitsu S702x 3866 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD 3867 * audio = 0x16, internal speaker = 0x10. 3868 */ 3869static struct hda_verb alc260_fujitsu_init_verbs[] = { 3870 /* Disable all GPIOs */ 3871 {0x01, AC_VERB_SET_GPIO_MASK, 0}, 3872 /* Internal speaker is connected to headphone pin */ 3873 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3874 /* Headphone/Line-out jack connects to Line1 pin; make it an output */ 3875 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3876 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */ 3877 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3878 /* Ensure all other unused pins are disabled and muted. */ 3879 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 3880 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3881 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 3882 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3883 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 3884 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3885 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 3886 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3887 3888 /* Disable digital (SPDIF) pins */ 3889 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0}, 3890 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0}, 3891 3892 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus 3893 * when acting as an output. 3894 */ 3895 {0x0d, AC_VERB_SET_CONNECT_SEL, 0}, 3896 3897 /* Start with output sum widgets muted and their output gains at min */ 3898 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3899 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 3900 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3901 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3902 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 3903 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3904 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3905 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 3906 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3907 3908 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */ 3909 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3910 /* Unmute Line1 pin widget output buffer since it starts as an output. 3911 * If the pin mode is changed by the user the pin mode control will 3912 * take care of enabling the pin's input/output buffers as needed. 3913 * Therefore there's no need to enable the input buffer at this 3914 * stage. 3915 */ 3916 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3917 /* Unmute input buffer of pin widget used for Line-in (no equiv 3918 * mixer ctrl) 3919 */ 3920 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3921 3922 /* Mute capture amp left and right */ 3923 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3924 /* Set ADC connection select to match default mixer setting - line 3925 * in (on mic1 pin) 3926 */ 3927 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, 3928 3929 /* Do the same for the second ADC: mute capture input amp and 3930 * set ADC connection to line in (on mic1 pin) 3931 */ 3932 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3933 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, 3934 3935 /* Mute all inputs to mixer widget (even unconnected ones) */ 3936 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */ 3937 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */ 3938 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */ 3939 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */ 3940 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */ 3941 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */ 3942 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */ 3943 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */ 3944 3945 { } 3946}; 3947 3948/* Initialisation sequence for ALC260 as configured in Acer TravelMate and 3949 * similar laptops (adapted from Fujitsu init verbs). 3950 */ 3951static struct hda_verb alc260_acer_init_verbs[] = { 3952 /* On TravelMate laptops, GPIO 0 enables the internal speaker and 3953 * the headphone jack. Turn this on and rely on the standard mute 3954 * methods whenever the user wants to turn these outputs off. 3955 */ 3956 {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, 3957 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, 3958 {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, 3959 /* Internal speaker/Headphone jack is connected to Line-out pin */ 3960 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3961 /* Internal microphone/Mic jack is connected to Mic1 pin */ 3962 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, 3963 /* Line In jack is connected to Line1 pin */ 3964 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3965 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */ 3966 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3967 /* Ensure all other unused pins are disabled and muted. */ 3968 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 3969 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3970 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 3971 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3972 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 3973 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3974 /* Disable digital (SPDIF) pins */ 3975 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0}, 3976 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0}, 3977 3978 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum 3979 * bus when acting as outputs. 3980 */ 3981 {0x0b, AC_VERB_SET_CONNECT_SEL, 0}, 3982 {0x0d, AC_VERB_SET_CONNECT_SEL, 0}, 3983 3984 /* Start with output sum widgets muted and their output gains at min */ 3985 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3986 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 3987 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3988 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3989 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 3990 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3991 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3992 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 3993 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3994 3995 /* Unmute Line-out pin widget amp left and right 3996 * (no equiv mixer ctrl) 3997 */ 3998 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3999 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */ 4000 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4001 /* Unmute Mic1 and Line1 pin widget input buffers since they start as 4002 * inputs. If the pin mode is changed by the user the pin mode control 4003 * will take care of enabling the pin's input/output buffers as needed. 4004 * Therefore there's no need to enable the input buffer at this 4005 * stage. 4006 */ 4007 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4008 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4009 4010 /* Mute capture amp left and right */ 4011 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4012 /* Set ADC connection select to match default mixer setting - mic 4013 * (on mic1 pin) 4014 */ 4015 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, 4016 4017 /* Do similar with the second ADC: mute capture input amp and 4018 * set ADC connection to mic to match ALSA's default state. 4019 */ 4020 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4021 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, 4022 4023 /* Mute all inputs to mixer widget (even unconnected ones) */ 4024 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */ 4025 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */ 4026 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */ 4027 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */ 4028 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */ 4029 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */ 4030 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */ 4031 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */ 4032 4033 { } 4034}; 4035 4036static struct hda_verb alc260_will_verbs[] = { 4037 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 4038 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00}, 4039 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00}, 4040 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02}, 4041 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07}, 4042 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040}, 4043 {} 4044}; 4045 4046static struct hda_verb alc260_replacer_672v_verbs[] = { 4047 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02}, 4048 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07}, 4049 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050}, 4050 4051 {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, 4052 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, 4053 {0x01, AC_VERB_SET_GPIO_DATA, 0x00}, 4054 4055 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 4056 {} 4057}; 4058 4059/* toggle speaker-output according to the hp-jack state */ 4060static void alc260_replacer_672v_automute(struct hda_codec *codec) 4061{ 4062 unsigned int present; 4063 4064 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */ 4065 present = snd_hda_codec_read(codec, 0x0f, 0, 4066 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 4067 if (present) { 4068 snd_hda_codec_write_cache(codec, 0x01, 0, 4069 AC_VERB_SET_GPIO_DATA, 1); 4070 snd_hda_codec_write_cache(codec, 0x0f, 0, 4071 AC_VERB_SET_PIN_WIDGET_CONTROL, 4072 PIN_HP); 4073 } else { 4074 snd_hda_codec_write_cache(codec, 0x01, 0, 4075 AC_VERB_SET_GPIO_DATA, 0); 4076 snd_hda_codec_write_cache(codec, 0x0f, 0, 4077 AC_VERB_SET_PIN_WIDGET_CONTROL, 4078 PIN_OUT); 4079 } 4080} 4081 4082static void alc260_replacer_672v_unsol_event(struct hda_codec *codec, 4083 unsigned int res) 4084{ 4085 if ((res >> 26) == ALC880_HP_EVENT) 4086 alc260_replacer_672v_automute(codec); 4087} 4088 4089/* Test configuration for debugging, modelled after the ALC880 test 4090 * configuration. 4091 */ 4092#ifdef CONFIG_SND_DEBUG 4093static hda_nid_t alc260_test_dac_nids[1] = { 4094 0x02, 4095}; 4096static hda_nid_t alc260_test_adc_nids[2] = { 4097 0x04, 0x05, 4098}; 4099/* For testing the ALC260, each input MUX needs its own definition since 4100 * the signal assignments are different. This assumes that the first ADC 4101 * is NID 0x04. 4102 */ 4103static struct hda_input_mux alc260_test_capture_sources[2] = { 4104 { 4105 .num_items = 7, 4106 .items = { 4107 { "MIC1 pin", 0x0 }, 4108 { "MIC2 pin", 0x1 }, 4109 { "LINE1 pin", 0x2 }, 4110 { "LINE2 pin", 0x3 }, 4111 { "CD pin", 0x4 }, 4112 { "LINE-OUT pin", 0x5 }, 4113 { "HP-OUT pin", 0x6 }, 4114 }, 4115 }, 4116 { 4117 .num_items = 8, 4118 .items = { 4119 { "MIC1 pin", 0x0 }, 4120 { "MIC2 pin", 0x1 }, 4121 { "LINE1 pin", 0x2 }, 4122 { "LINE2 pin", 0x3 }, 4123 { "CD pin", 0x4 }, 4124 { "Mixer", 0x5 }, 4125 { "LINE-OUT pin", 0x6 }, 4126 { "HP-OUT pin", 0x7 }, 4127 }, 4128 }, 4129}; 4130static struct snd_kcontrol_new alc260_test_mixer[] = { 4131 /* Output driver widgets */ 4132 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), 4133 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT), 4134 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT), 4135 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT), 4136 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT), 4137 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT), 4138 4139 /* Modes for retasking pin widgets 4140 * Note: the ALC260 doesn't seem to act on requests to enable mic 4141 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't 4142 * mention this restriction. At this stage it's not clear whether 4143 * this behaviour is intentional or is a hardware bug in chip 4144 * revisions available at least up until early 2006. Therefore for 4145 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all 4146 * choices, but if it turns out that the lack of mic bias for these 4147 * NIDs is intentional we could change their modes from 4148 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS. 4149 */ 4150 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT), 4151 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT), 4152 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT), 4153 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT), 4154 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT), 4155 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT), 4156 4157 /* Loopback mixer controls */ 4158 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT), 4159 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT), 4160 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT), 4161 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT), 4162 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT), 4163 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT), 4164 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT), 4165 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT), 4166 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), 4167 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), 4168 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT), 4169 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT), 4170 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT), 4171 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT), 4172 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT), 4173 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT), 4174 4175 /* Controls for GPIO pins, assuming they are configured as outputs */ 4176 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01), 4177 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02), 4178 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04), 4179 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08), 4180 4181 /* Switches to allow the digital IO pins to be enabled. The datasheet 4182 * is ambigious as to which NID is which; testing on laptops which 4183 * make this output available should provide clarification. 4184 */ 4185 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01), 4186 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01), 4187 4188 { } /* end */ 4189}; 4190static struct hda_verb alc260_test_init_verbs[] = { 4191 /* Enable all GPIOs as outputs with an initial value of 0 */ 4192 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f}, 4193 {0x01, AC_VERB_SET_GPIO_DATA, 0x00}, 4194 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f}, 4195 4196 /* Enable retasking pins as output, initially without power amp */ 4197 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4198 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4199 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4200 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4201 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4202 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4203 4204 /* Disable digital (SPDIF) pins initially, but users can enable 4205 * them via a mixer switch. In the case of SPDIF-out, this initverb 4206 * payload also sets the generation to 0, output to be in "consumer" 4207 * PCM format, copyright asserted, no pre-emphasis and no validity 4208 * control. 4209 */ 4210 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0}, 4211 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0}, 4212 4213 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the 4214 * OUT1 sum bus when acting as an output. 4215 */ 4216 {0x0b, AC_VERB_SET_CONNECT_SEL, 0}, 4217 {0x0c, AC_VERB_SET_CONNECT_SEL, 0}, 4218 {0x0d, AC_VERB_SET_CONNECT_SEL, 0}, 4219 {0x0e, AC_VERB_SET_CONNECT_SEL, 0}, 4220 4221 /* Start with output sum widgets muted and their output gains at min */ 4222 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4223 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4224 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4225 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4226 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4227 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4228 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4229 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4230 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4231 4232 /* Unmute retasking pin widget output buffers since the default 4233 * state appears to be output. As the pin mode is changed by the 4234 * user the pin mode control will take care of enabling the pin's 4235 * input/output buffers as needed. 4236 */ 4237 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4238 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4239 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4240 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4241 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4242 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4243 /* Also unmute the mono-out pin widget */ 4244 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4245 4246 /* Mute capture amp left and right */ 4247 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4248 /* Set ADC connection select to match default mixer setting (mic1 4249 * pin) 4250 */ 4251 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, 4252 4253 /* Do the same for the second ADC: mute capture input amp and 4254 * set ADC connection to mic1 pin 4255 */ 4256 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4257 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, 4258 4259 /* Mute all inputs to mixer widget (even unconnected ones) */ 4260 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */ 4261 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */ 4262 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */ 4263 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */ 4264 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */ 4265 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */ 4266 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */ 4267 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */ 4268 4269 { } 4270}; 4271#endif 4272 4273static struct hda_pcm_stream alc260_pcm_analog_playback = { 4274 .substreams = 1, 4275 .channels_min = 2, 4276 .channels_max = 2, 4277}; 4278 4279static struct hda_pcm_stream alc260_pcm_analog_capture = { 4280 .substreams = 1, 4281 .channels_min = 2, 4282 .channels_max = 2, 4283}; 4284 4285#define alc260_pcm_digital_playback alc880_pcm_digital_playback 4286#define alc260_pcm_digital_capture alc880_pcm_digital_capture 4287 4288/* 4289 * for BIOS auto-configuration 4290 */ 4291 4292static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid, 4293 const char *pfx) 4294{ 4295 hda_nid_t nid_vol; 4296 unsigned long vol_val, sw_val; 4297 char name[32]; 4298 int err; 4299 4300 if (nid >= 0x0f && nid < 0x11) { 4301 nid_vol = nid - 0x7; 4302 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT); 4303 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT); 4304 } else if (nid == 0x11) { 4305 nid_vol = nid - 0x7; 4306 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT); 4307 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT); 4308 } else if (nid >= 0x12 && nid <= 0x15) { 4309 nid_vol = 0x08; 4310 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT); 4311 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT); 4312 } else 4313 return 0; /* N/A */ 4314 4315 snprintf(name, sizeof(name), "%s Playback Volume", pfx); 4316 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val); 4317 if (err < 0) 4318 return err; 4319 snprintf(name, sizeof(name), "%s Playback Switch", pfx); 4320 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val); 4321 if (err < 0) 4322 return err; 4323 return 1; 4324} 4325 4326/* add playback controls from the parsed DAC table */ 4327static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec, 4328 const struct auto_pin_cfg *cfg) 4329{ 4330 hda_nid_t nid; 4331 int err; 4332 4333 spec->multiout.num_dacs = 1; 4334 spec->multiout.dac_nids = spec->private_dac_nids; 4335 spec->multiout.dac_nids[0] = 0x02; 4336 4337 nid = cfg->line_out_pins[0]; 4338 if (nid) { 4339 err = alc260_add_playback_controls(spec, nid, "Front"); 4340 if (err < 0) 4341 return err; 4342 } 4343 4344 nid = cfg->speaker_pins[0]; 4345 if (nid) { 4346 err = alc260_add_playback_controls(spec, nid, "Speaker"); 4347 if (err < 0) 4348 return err; 4349 } 4350 4351 nid = cfg->hp_pins[0]; 4352 if (nid) { 4353 err = alc260_add_playback_controls(spec, nid, "Headphone"); 4354 if (err < 0) 4355 return err; 4356 } 4357 return 0; 4358} 4359 4360/* create playback/capture controls for input pins */ 4361static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec, 4362 const struct auto_pin_cfg *cfg) 4363{ 4364 struct hda_input_mux *imux = &spec->private_imux; 4365 int i, err, idx; 4366 4367 for (i = 0; i < AUTO_PIN_LAST; i++) { 4368 if (cfg->input_pins[i] >= 0x12) { 4369 idx = cfg->input_pins[i] - 0x12; 4370 err = new_analog_input(spec, cfg->input_pins[i], 4371 auto_pin_cfg_labels[i], idx, 4372 0x07); 4373 if (err < 0) 4374 return err; 4375 imux->items[imux->num_items].label = 4376 auto_pin_cfg_labels[i]; 4377 imux->items[imux->num_items].index = idx; 4378 imux->num_items++; 4379 } 4380 if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){ 4381 idx = cfg->input_pins[i] - 0x09; 4382 err = new_analog_input(spec, cfg->input_pins[i], 4383 auto_pin_cfg_labels[i], idx, 4384 0x07); 4385 if (err < 0) 4386 return err; 4387 imux->items[imux->num_items].label = 4388 auto_pin_cfg_labels[i]; 4389 imux->items[imux->num_items].index = idx; 4390 imux->num_items++; 4391 } 4392 } 4393 return 0; 4394} 4395 4396static void alc260_auto_set_output_and_unmute(struct hda_codec *codec, 4397 hda_nid_t nid, int pin_type, 4398 int sel_idx) 4399{ 4400 /* set as output */ 4401 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 4402 pin_type); 4403 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, 4404 AMP_OUT_UNMUTE); 4405 /* need the manual connection? */ 4406 if (nid >= 0x12) { 4407 int idx = nid - 0x12; 4408 snd_hda_codec_write(codec, idx + 0x0b, 0, 4409 AC_VERB_SET_CONNECT_SEL, sel_idx); 4410 } 4411} 4412 4413static void alc260_auto_init_multi_out(struct hda_codec *codec) 4414{ 4415 struct alc_spec *spec = codec->spec; 4416 hda_nid_t nid; 4417 4418 alc_subsystem_id(codec, 0x10, 0x15, 0x0f); 4419 nid = spec->autocfg.line_out_pins[0]; 4420 if (nid) { 4421 int pin_type = get_pin_type(spec->autocfg.line_out_type); 4422 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0); 4423 } 4424 4425 nid = spec->autocfg.speaker_pins[0]; 4426 if (nid) 4427 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0); 4428 4429 nid = spec->autocfg.hp_pins[0]; 4430 if (nid) 4431 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0); 4432} 4433 4434#define ALC260_PIN_CD_NID 0x16 4435static void alc260_auto_init_analog_input(struct hda_codec *codec) 4436{ 4437 struct alc_spec *spec = codec->spec; 4438 int i; 4439 4440 for (i = 0; i < AUTO_PIN_LAST; i++) { 4441 hda_nid_t nid = spec->autocfg.input_pins[i]; 4442 if (nid >= 0x12) { 4443 snd_hda_codec_write(codec, nid, 0, 4444 AC_VERB_SET_PIN_WIDGET_CONTROL, 4445 i <= AUTO_PIN_FRONT_MIC ? 4446 PIN_VREF80 : PIN_IN); 4447 if (nid != ALC260_PIN_CD_NID) 4448 snd_hda_codec_write(codec, nid, 0, 4449 AC_VERB_SET_AMP_GAIN_MUTE, 4450 AMP_OUT_MUTE); 4451 } 4452 } 4453} 4454 4455/* 4456 * generic initialization of ADC, input mixers and output mixers 4457 */ 4458static struct hda_verb alc260_volume_init_verbs[] = { 4459 /* 4460 * Unmute ADC0-1 and set the default input to mic-in 4461 */ 4462 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, 4463 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4464 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, 4465 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4466 4467 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 4468 * mixer widget 4469 * Note: PASD motherboards uses the Line In 2 as the input for 4470 * front panel mic (mic 2) 4471 */ 4472 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 4473 /* mute analog inputs */ 4474 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4475 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4476 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 4477 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 4478 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 4479 4480 /* 4481 * Set up output mixers (0x08 - 0x0a) 4482 */ 4483 /* set vol=0 to output mixers */ 4484 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4485 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4486 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4487 /* set up input amps for analog loopback */ 4488 /* Amp Indices: DAC = 0, mixer = 1 */ 4489 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4490 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4491 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4492 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4493 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4494 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4495 4496 { } 4497}; 4498 4499static int alc260_parse_auto_config(struct hda_codec *codec) 4500{ 4501 struct alc_spec *spec = codec->spec; 4502 unsigned int wcap; 4503 int err; 4504 static hda_nid_t alc260_ignore[] = { 0x17, 0 }; 4505 4506 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 4507 alc260_ignore); 4508 if (err < 0) 4509 return err; 4510 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg); 4511 if (err < 0) 4512 return err; 4513 if (!spec->kctl_alloc) 4514 return 0; /* can't find valid BIOS pin config */ 4515 err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg); 4516 if (err < 0) 4517 return err; 4518 4519 spec->multiout.max_channels = 2; 4520 4521 if (spec->autocfg.dig_out_pin) 4522 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID; 4523 if (spec->kctl_alloc) 4524 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 4525 4526 spec->init_verbs[spec->num_init_verbs++] = alc260_volume_init_verbs; 4527 4528 spec->num_mux_defs = 1; 4529 spec->input_mux = &spec->private_imux; 4530 4531 /* check whether NID 0x04 is valid */ 4532 wcap = get_wcaps(codec, 0x04); 4533 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */ 4534 if (wcap != AC_WID_AUD_IN) { 4535 spec->adc_nids = alc260_adc_nids_alt; 4536 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt); 4537 spec->mixers[spec->num_mixers] = alc260_capture_alt_mixer; 4538 } else { 4539 spec->adc_nids = alc260_adc_nids; 4540 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids); 4541 spec->mixers[spec->num_mixers] = alc260_capture_mixer; 4542 } 4543 spec->num_mixers++; 4544 4545 return 1; 4546} 4547 4548/* additional initialization for auto-configuration model */ 4549static void alc260_auto_init(struct hda_codec *codec) 4550{ 4551 alc260_auto_init_multi_out(codec); 4552 alc260_auto_init_analog_input(codec); 4553} 4554 4555#ifdef CONFIG_SND_HDA_POWER_SAVE 4556static struct hda_amp_list alc260_loopbacks[] = { 4557 { 0x07, HDA_INPUT, 0 }, 4558 { 0x07, HDA_INPUT, 1 }, 4559 { 0x07, HDA_INPUT, 2 }, 4560 { 0x07, HDA_INPUT, 3 }, 4561 { 0x07, HDA_INPUT, 4 }, 4562 { } /* end */ 4563}; 4564#endif 4565 4566/* 4567 * ALC260 configurations 4568 */ 4569static const char *alc260_models[ALC260_MODEL_LAST] = { 4570 [ALC260_BASIC] = "basic", 4571 [ALC260_HP] = "hp", 4572 [ALC260_HP_3013] = "hp-3013", 4573 [ALC260_FUJITSU_S702X] = "fujitsu", 4574 [ALC260_ACER] = "acer", 4575 [ALC260_WILL] = "will", 4576 [ALC260_REPLACER_672V] = "replacer", 4577#ifdef CONFIG_SND_DEBUG 4578 [ALC260_TEST] = "test", 4579#endif 4580 [ALC260_AUTO] = "auto", 4581}; 4582 4583static struct snd_pci_quirk alc260_cfg_tbl[] = { 4584 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER), 4585 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER), 4586 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013), 4587 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013), 4588 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013), 4589 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP), 4590 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_3013), 4591 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013), 4592 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP), 4593 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP), 4594 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP), 4595 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC), 4596 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC), 4597 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC), 4598 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X), 4599 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC), 4600 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL), 4601 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V), 4602 {} 4603}; 4604 4605static struct alc_config_preset alc260_presets[] = { 4606 [ALC260_BASIC] = { 4607 .mixers = { alc260_base_output_mixer, 4608 alc260_input_mixer, 4609 alc260_pc_beep_mixer, 4610 alc260_capture_mixer }, 4611 .init_verbs = { alc260_init_verbs }, 4612 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 4613 .dac_nids = alc260_dac_nids, 4614 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids), 4615 .adc_nids = alc260_adc_nids, 4616 .num_channel_mode = ARRAY_SIZE(alc260_modes), 4617 .channel_mode = alc260_modes, 4618 .input_mux = &alc260_capture_source, 4619 }, 4620 [ALC260_HP] = { 4621 .mixers = { alc260_base_output_mixer, 4622 alc260_input_mixer, 4623 alc260_capture_alt_mixer }, 4624 .init_verbs = { alc260_init_verbs }, 4625 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 4626 .dac_nids = alc260_dac_nids, 4627 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids), 4628 .adc_nids = alc260_hp_adc_nids, 4629 .num_channel_mode = ARRAY_SIZE(alc260_modes), 4630 .channel_mode = alc260_modes, 4631 .input_mux = &alc260_capture_source, 4632 }, 4633 [ALC260_HP_3013] = { 4634 .mixers = { alc260_hp_3013_mixer, 4635 alc260_input_mixer, 4636 alc260_capture_alt_mixer }, 4637 .init_verbs = { alc260_hp_3013_init_verbs }, 4638 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 4639 .dac_nids = alc260_dac_nids, 4640 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids), 4641 .adc_nids = alc260_hp_adc_nids, 4642 .num_channel_mode = ARRAY_SIZE(alc260_modes), 4643 .channel_mode = alc260_modes, 4644 .input_mux = &alc260_capture_source, 4645 }, 4646 [ALC260_FUJITSU_S702X] = { 4647 .mixers = { alc260_fujitsu_mixer, 4648 alc260_capture_mixer }, 4649 .init_verbs = { alc260_fujitsu_init_verbs }, 4650 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 4651 .dac_nids = alc260_dac_nids, 4652 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids), 4653 .adc_nids = alc260_dual_adc_nids, 4654 .num_channel_mode = ARRAY_SIZE(alc260_modes), 4655 .channel_mode = alc260_modes, 4656 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources), 4657 .input_mux = alc260_fujitsu_capture_sources, 4658 }, 4659 [ALC260_ACER] = { 4660 .mixers = { alc260_acer_mixer, 4661 alc260_capture_mixer }, 4662 .init_verbs = { alc260_acer_init_verbs }, 4663 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 4664 .dac_nids = alc260_dac_nids, 4665 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids), 4666 .adc_nids = alc260_dual_adc_nids, 4667 .num_channel_mode = ARRAY_SIZE(alc260_modes), 4668 .channel_mode = alc260_modes, 4669 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources), 4670 .input_mux = alc260_acer_capture_sources, 4671 }, 4672 [ALC260_WILL] = { 4673 .mixers = { alc260_will_mixer, 4674 alc260_capture_mixer }, 4675 .init_verbs = { alc260_init_verbs, alc260_will_verbs }, 4676 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 4677 .dac_nids = alc260_dac_nids, 4678 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids), 4679 .adc_nids = alc260_adc_nids, 4680 .dig_out_nid = ALC260_DIGOUT_NID, 4681 .num_channel_mode = ARRAY_SIZE(alc260_modes), 4682 .channel_mode = alc260_modes, 4683 .input_mux = &alc260_capture_source, 4684 }, 4685 [ALC260_REPLACER_672V] = { 4686 .mixers = { alc260_replacer_672v_mixer, 4687 alc260_capture_mixer }, 4688 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs }, 4689 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 4690 .dac_nids = alc260_dac_nids, 4691 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids), 4692 .adc_nids = alc260_adc_nids, 4693 .dig_out_nid = ALC260_DIGOUT_NID, 4694 .num_channel_mode = ARRAY_SIZE(alc260_modes), 4695 .channel_mode = alc260_modes, 4696 .input_mux = &alc260_capture_source, 4697 .unsol_event = alc260_replacer_672v_unsol_event, 4698 .init_hook = alc260_replacer_672v_automute, 4699 }, 4700#ifdef CONFIG_SND_DEBUG 4701 [ALC260_TEST] = { 4702 .mixers = { alc260_test_mixer, 4703 alc260_capture_mixer }, 4704 .init_verbs = { alc260_test_init_verbs }, 4705 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids), 4706 .dac_nids = alc260_test_dac_nids, 4707 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids), 4708 .adc_nids = alc260_test_adc_nids, 4709 .num_channel_mode = ARRAY_SIZE(alc260_modes), 4710 .channel_mode = alc260_modes, 4711 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources), 4712 .input_mux = alc260_test_capture_sources, 4713 }, 4714#endif 4715}; 4716 4717static int patch_alc260(struct hda_codec *codec) 4718{ 4719 struct alc_spec *spec; 4720 int err, board_config; 4721 4722 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 4723 if (spec == NULL) 4724 return -ENOMEM; 4725 4726 codec->spec = spec; 4727 4728 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST, 4729 alc260_models, 4730 alc260_cfg_tbl); 4731 if (board_config < 0) { 4732 snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, " 4733 "trying auto-probe from BIOS...\n"); 4734 board_config = ALC260_AUTO; 4735 } 4736 4737 if (board_config == ALC260_AUTO) { 4738 /* automatic parse from the BIOS config */ 4739 err = alc260_parse_auto_config(codec); 4740 if (err < 0) { 4741 alc_free(codec); 4742 return err; 4743 } else if (!err) { 4744 printk(KERN_INFO 4745 "hda_codec: Cannot set up configuration " 4746 "from BIOS. Using base mode...\n"); 4747 board_config = ALC260_BASIC; 4748 } 4749 } 4750 4751 if (board_config != ALC260_AUTO) 4752 setup_preset(spec, &alc260_presets[board_config]); 4753 4754 spec->stream_name_analog = "ALC260 Analog"; 4755 spec->stream_analog_playback = &alc260_pcm_analog_playback; 4756 spec->stream_analog_capture = &alc260_pcm_analog_capture; 4757 4758 spec->stream_name_digital = "ALC260 Digital"; 4759 spec->stream_digital_playback = &alc260_pcm_digital_playback; 4760 spec->stream_digital_capture = &alc260_pcm_digital_capture; 4761 4762 codec->patch_ops = alc_patch_ops; 4763 if (board_config == ALC260_AUTO) 4764 spec->init_hook = alc260_auto_init; 4765#ifdef CONFIG_SND_HDA_POWER_SAVE 4766 if (!spec->loopback.amplist) 4767 spec->loopback.amplist = alc260_loopbacks; 4768#endif 4769 4770 return 0; 4771} 4772 4773 4774/* 4775 * ALC882 support 4776 * 4777 * ALC882 is almost identical with ALC880 but has cleaner and more flexible 4778 * configuration. Each pin widget can choose any input DACs and a mixer. 4779 * Each ADC is connected from a mixer of all inputs. This makes possible 4780 * 6-channel independent captures. 4781 * 4782 * In addition, an independent DAC for the multi-playback (not used in this 4783 * driver yet). 4784 */ 4785#define ALC882_DIGOUT_NID 0x06 4786#define ALC882_DIGIN_NID 0x0a 4787 4788static struct hda_channel_mode alc882_ch_modes[1] = { 4789 { 8, NULL } 4790}; 4791 4792static hda_nid_t alc882_dac_nids[4] = { 4793 /* front, rear, clfe, rear_surr */ 4794 0x02, 0x03, 0x04, 0x05 4795}; 4796 4797/* identical with ALC880 */ 4798#define alc882_adc_nids alc880_adc_nids 4799#define alc882_adc_nids_alt alc880_adc_nids_alt 4800 4801/* input MUX */ 4802/* FIXME: should be a matrix-type input source selection */ 4803 4804static struct hda_input_mux alc882_capture_source = { 4805 .num_items = 4, 4806 .items = { 4807 { "Mic", 0x0 }, 4808 { "Front Mic", 0x1 }, 4809 { "Line", 0x2 }, 4810 { "CD", 0x4 }, 4811 }, 4812}; 4813#define alc882_mux_enum_info alc_mux_enum_info 4814#define alc882_mux_enum_get alc_mux_enum_get 4815 4816static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol, 4817 struct snd_ctl_elem_value *ucontrol) 4818{ 4819 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 4820 struct alc_spec *spec = codec->spec; 4821 const struct hda_input_mux *imux = spec->input_mux; 4822 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 4823 static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 }; 4824 hda_nid_t nid = capture_mixers[adc_idx]; 4825 unsigned int *cur_val = &spec->cur_mux[adc_idx]; 4826 unsigned int i, idx; 4827 4828 idx = ucontrol->value.enumerated.item[0]; 4829 if (idx >= imux->num_items) 4830 idx = imux->num_items - 1; 4831 if (*cur_val == idx) 4832 return 0; 4833 for (i = 0; i < imux->num_items; i++) { 4834 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE; 4835 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 4836 imux->items[i].index, 4837 HDA_AMP_MUTE, v); 4838 } 4839 *cur_val = idx; 4840 return 1; 4841} 4842 4843/* 4844 * 2ch mode 4845 */ 4846static struct hda_verb alc882_3ST_ch2_init[] = { 4847 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 4848 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 4849 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 4850 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 4851 { } /* end */ 4852}; 4853 4854/* 4855 * 6ch mode 4856 */ 4857static struct hda_verb alc882_3ST_ch6_init[] = { 4858 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 4859 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 4860 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, 4861 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 4862 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 4863 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 4864 { } /* end */ 4865}; 4866 4867static struct hda_channel_mode alc882_3ST_6ch_modes[2] = { 4868 { 2, alc882_3ST_ch2_init }, 4869 { 6, alc882_3ST_ch6_init }, 4870}; 4871 4872/* 4873 * 6ch mode 4874 */ 4875static struct hda_verb alc882_sixstack_ch6_init[] = { 4876 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 4877 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 4878 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 4879 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 4880 { } /* end */ 4881}; 4882 4883/* 4884 * 8ch mode 4885 */ 4886static struct hda_verb alc882_sixstack_ch8_init[] = { 4887 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 4888 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 4889 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 4890 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 4891 { } /* end */ 4892}; 4893 4894static struct hda_channel_mode alc882_sixstack_modes[2] = { 4895 { 6, alc882_sixstack_ch6_init }, 4896 { 8, alc882_sixstack_ch8_init }, 4897}; 4898 4899/* 4900 * macbook pro ALC885 can switch LineIn to LineOut without loosing Mic 4901 */ 4902 4903/* 4904 * 2ch mode 4905 */ 4906static struct hda_verb alc885_mbp_ch2_init[] = { 4907 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 4908 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4909 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4910 { } /* end */ 4911}; 4912 4913/* 4914 * 6ch mode 4915 */ 4916static struct hda_verb alc885_mbp_ch6_init[] = { 4917 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 4918 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4919 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 4920 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4921 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4922 { } /* end */ 4923}; 4924 4925static struct hda_channel_mode alc885_mbp_6ch_modes[2] = { 4926 { 2, alc885_mbp_ch2_init }, 4927 { 6, alc885_mbp_ch6_init }, 4928}; 4929 4930 4931/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 4932 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b 4933 */ 4934static struct snd_kcontrol_new alc882_base_mixer[] = { 4935 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 4936 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 4937 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 4938 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 4939 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 4940 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 4941 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 4942 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 4943 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 4944 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 4945 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 4946 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 4947 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 4948 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 4949 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 4950 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 4951 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 4952 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 4953 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 4954 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 4955 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 4956 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 4957 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 4958 { } /* end */ 4959}; 4960 4961static struct snd_kcontrol_new alc885_mbp3_mixer[] = { 4962 HDA_CODEC_VOLUME("Master Volume", 0x0c, 0x00, HDA_OUTPUT), 4963 HDA_BIND_MUTE ("Master Switch", 0x0c, 0x02, HDA_INPUT), 4964 HDA_CODEC_MUTE ("Speaker Switch", 0x14, 0x00, HDA_OUTPUT), 4965 HDA_CODEC_VOLUME("Line Out Volume", 0x0d,0x00, HDA_OUTPUT), 4966 HDA_CODEC_VOLUME("Line In Playback Volume", 0x0b, 0x02, HDA_INPUT), 4967 HDA_CODEC_MUTE ("Line In Playback Switch", 0x0b, 0x02, HDA_INPUT), 4968 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT), 4969 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT), 4970 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0x00, HDA_INPUT), 4971 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT), 4972 { } /* end */ 4973}; 4974static struct snd_kcontrol_new alc882_w2jc_mixer[] = { 4975 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 4976 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 4977 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 4978 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 4979 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 4980 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 4981 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 4982 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 4983 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 4984 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 4985 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 4986 { } /* end */ 4987}; 4988 4989static struct snd_kcontrol_new alc882_targa_mixer[] = { 4990 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 4991 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 4992 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 4993 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 4994 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 4995 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 4996 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 4997 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 4998 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 4999 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 5000 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 5001 { } /* end */ 5002}; 5003 5004/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ??? 5005 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c 5006 */ 5007static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = { 5008 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 5009 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 5010 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 5011 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT), 5012 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 5013 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 5014 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 5015 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 5016 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT), 5017 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT), 5018 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 5019 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 5020 { } /* end */ 5021}; 5022 5023static struct snd_kcontrol_new alc882_chmode_mixer[] = { 5024 { 5025 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 5026 .name = "Channel Mode", 5027 .info = alc_ch_mode_info, 5028 .get = alc_ch_mode_get, 5029 .put = alc_ch_mode_put, 5030 }, 5031 { } /* end */ 5032}; 5033 5034static struct hda_verb alc882_init_verbs[] = { 5035 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 5036 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5037 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5038 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 5039 /* Rear mixer */ 5040 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5041 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5042 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 5043 /* CLFE mixer */ 5044 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5045 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5046 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 5047 /* Side mixer */ 5048 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5049 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5050 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 5051 5052 /* Front Pin: output 0 (0x0c) */ 5053 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5054 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5055 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 5056 /* Rear Pin: output 1 (0x0d) */ 5057 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5058 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5059 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 5060 /* CLFE Pin: output 2 (0x0e) */ 5061 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5062 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5063 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, 5064 /* Side Pin: output 3 (0x0f) */ 5065 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5066 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5067 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, 5068 /* Mic (rear) pin: input vref at 80% */ 5069 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 5070 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 5071 /* Front Mic pin: input vref at 80% */ 5072 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 5073 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 5074 /* Line In pin: input */ 5075 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 5076 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 5077 /* Line-2 In: Headphone output (output 0 - 0x0c) */ 5078 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 5079 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5080 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 5081 /* CD pin widget for input */ 5082 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 5083 5084 /* FIXME: use matrix-type input source selection */ 5085 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 5086 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 5087 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5088 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 5089 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 5090 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 5091 /* Input mixer2 */ 5092 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5093 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 5094 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 5095 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 5096 /* Input mixer3 */ 5097 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5098 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 5099 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 5100 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 5101 /* ADC1: mute amp left and right */ 5102 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5103 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 5104 /* ADC2: mute amp left and right */ 5105 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5106 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 5107 /* ADC3: mute amp left and right */ 5108 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5109 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 5110 5111 { } 5112}; 5113 5114static struct hda_verb alc882_eapd_verbs[] = { 5115 /* change to EAPD mode */ 5116 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 5117 {0x20, AC_VERB_SET_PROC_COEF, 0x3060}, 5118 { } 5119}; 5120 5121/* Mac Pro test */ 5122static struct snd_kcontrol_new alc882_macpro_mixer[] = { 5123 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 5124 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 5125 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT), 5126 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT), 5127 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT), 5128 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT), 5129 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT), 5130 { } /* end */ 5131}; 5132 5133static struct hda_verb alc882_macpro_init_verbs[] = { 5134 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 5135 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5136 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5137 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 5138 /* Front Pin: output 0 (0x0c) */ 5139 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5140 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5141 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 5142 /* Front Mic pin: input vref at 80% */ 5143 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 5144 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 5145 /* Speaker: output */ 5146 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5147 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5148 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04}, 5149 /* Headphone output (output 0 - 0x0c) */ 5150 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 5151 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5152 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00}, 5153 5154 /* FIXME: use matrix-type input source selection */ 5155 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 5156 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 5157 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5158 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 5159 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 5160 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 5161 /* Input mixer2 */ 5162 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5163 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 5164 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 5165 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 5166 /* Input mixer3 */ 5167 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5168 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 5169 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 5170 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 5171 /* ADC1: mute amp left and right */ 5172 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5173 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 5174 /* ADC2: mute amp left and right */ 5175 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5176 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 5177 /* ADC3: mute amp left and right */ 5178 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5179 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 5180 5181 { } 5182}; 5183 5184/* Macbook Pro rev3 */ 5185static struct hda_verb alc885_mbp3_init_verbs[] = { 5186 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 5187 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5188 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5189 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 5190 /* Rear mixer */ 5191 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5192 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5193 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 5194 /* Front Pin: output 0 (0x0c) */ 5195 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5196 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5197 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 5198 /* HP Pin: output 0 (0x0d) */ 5199 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, 5200 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 5201 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 5202 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 5203 /* Mic (rear) pin: input vref at 80% */ 5204 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 5205 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 5206 /* Front Mic pin: input vref at 80% */ 5207 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 5208 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 5209 /* Line In pin: use output 1 when in LineOut mode */ 5210 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 5211 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 5212 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, 5213 5214 /* FIXME: use matrix-type input source selection */ 5215 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 5216 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 5217 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5218 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 5219 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 5220 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 5221 /* Input mixer2 */ 5222 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5223 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 5224 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 5225 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 5226 /* Input mixer3 */ 5227 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5228 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 5229 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 5230 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 5231 /* ADC1: mute amp left and right */ 5232 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5233 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 5234 /* ADC2: mute amp left and right */ 5235 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5236 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 5237 /* ADC3: mute amp left and right */ 5238 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5239 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 5240 5241 { } 5242}; 5243 5244/* iMac 24 mixer. */ 5245static struct snd_kcontrol_new alc885_imac24_mixer[] = { 5246 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 5247 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT), 5248 { } /* end */ 5249}; 5250 5251/* iMac 24 init verbs. */ 5252static struct hda_verb alc885_imac24_init_verbs[] = { 5253 /* Internal speakers: output 0 (0x0c) */ 5254 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5255 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5256 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00}, 5257 /* Internal speakers: output 0 (0x0c) */ 5258 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5259 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5260 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00}, 5261 /* Headphone: output 0 (0x0c) */ 5262 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 5263 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5264 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 5265 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 5266 /* Front Mic: input vref at 80% */ 5267 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 5268 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 5269 { } 5270}; 5271 5272/* Toggle speaker-output according to the hp-jack state */ 5273static void alc885_imac24_automute(struct hda_codec *codec) 5274{ 5275 unsigned int present; 5276 5277 present = snd_hda_codec_read(codec, 0x14, 0, 5278 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 5279 snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0, 5280 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 5281 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0, 5282 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 5283} 5284 5285/* Processes unsolicited events. */ 5286static void alc885_imac24_unsol_event(struct hda_codec *codec, 5287 unsigned int res) 5288{ 5289 /* Headphone insertion or removal. */ 5290 if ((res >> 26) == ALC880_HP_EVENT) 5291 alc885_imac24_automute(codec); 5292} 5293 5294static void alc885_mbp3_automute(struct hda_codec *codec) 5295{ 5296 unsigned int present; 5297 5298 present = snd_hda_codec_read(codec, 0x15, 0, 5299 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 5300 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 5301 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 5302 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 5303 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE); 5304 5305} 5306static void alc885_mbp3_unsol_event(struct hda_codec *codec, 5307 unsigned int res) 5308{ 5309 /* Headphone insertion or removal. */ 5310 if ((res >> 26) == ALC880_HP_EVENT) 5311 alc885_mbp3_automute(codec); 5312} 5313 5314 5315static struct hda_verb alc882_targa_verbs[] = { 5316 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5317 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 5318 5319 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 5320 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5321 5322 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ 5323 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */ 5324 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 5325 5326 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 5327 {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, 5328 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03}, 5329 {0x01, AC_VERB_SET_GPIO_DATA, 0x03}, 5330 { } /* end */ 5331}; 5332 5333/* toggle speaker-output according to the hp-jack state */ 5334static void alc882_targa_automute(struct hda_codec *codec) 5335{ 5336 unsigned int present; 5337 5338 present = snd_hda_codec_read(codec, 0x14, 0, 5339 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 5340 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0, 5341 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 5342 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA, 5343 present ? 1 : 3); 5344} 5345 5346static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res) 5347{ 5348 /* Looks like the unsol event is incompatible with the standard 5349 * definition. 4bit tag is placed at 26 bit! 5350 */ 5351 if (((res >> 26) == ALC880_HP_EVENT)) { 5352 alc882_targa_automute(codec); 5353 } 5354} 5355 5356static struct hda_verb alc882_asus_a7j_verbs[] = { 5357 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5358 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 5359 5360 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 5361 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5362 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5363 5364 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */ 5365 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 5366 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */ 5367 5368 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ 5369 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */ 5370 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 5371 { } /* end */ 5372}; 5373 5374static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted) 5375{ 5376 unsigned int gpiostate, gpiomask, gpiodir; 5377 5378 gpiostate = snd_hda_codec_read(codec, codec->afg, 0, 5379 AC_VERB_GET_GPIO_DATA, 0); 5380 5381 if (!muted) 5382 gpiostate |= (1 << pin); 5383 else 5384 gpiostate &= ~(1 << pin); 5385 5386 gpiomask = snd_hda_codec_read(codec, codec->afg, 0, 5387 AC_VERB_GET_GPIO_MASK, 0); 5388 gpiomask |= (1 << pin); 5389 5390 gpiodir = snd_hda_codec_read(codec, codec->afg, 0, 5391 AC_VERB_GET_GPIO_DIRECTION, 0); 5392 gpiodir |= (1 << pin); 5393 5394 5395 snd_hda_codec_write(codec, codec->afg, 0, 5396 AC_VERB_SET_GPIO_MASK, gpiomask); 5397 snd_hda_codec_write(codec, codec->afg, 0, 5398 AC_VERB_SET_GPIO_DIRECTION, gpiodir); 5399 5400 msleep(1); 5401 5402 snd_hda_codec_write(codec, codec->afg, 0, 5403 AC_VERB_SET_GPIO_DATA, gpiostate); 5404} 5405 5406/* set up GPIO at initialization */ 5407static void alc885_macpro_init_hook(struct hda_codec *codec) 5408{ 5409 alc882_gpio_mute(codec, 0, 0); 5410 alc882_gpio_mute(codec, 1, 0); 5411} 5412 5413/* set up GPIO and update auto-muting at initialization */ 5414static void alc885_imac24_init_hook(struct hda_codec *codec) 5415{ 5416 alc885_macpro_init_hook(codec); 5417 alc885_imac24_automute(codec); 5418} 5419 5420/* 5421 * generic initialization of ADC, input mixers and output mixers 5422 */ 5423static struct hda_verb alc882_auto_init_verbs[] = { 5424 /* 5425 * Unmute ADC0-2 and set the default input to mic-in 5426 */ 5427 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 5428 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5429 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 5430 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5431 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 5432 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5433 5434 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 5435 * mixer widget 5436 * Note: PASD motherboards uses the Line In 2 as the input for 5437 * front panel mic (mic 2) 5438 */ 5439 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 5440 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5441 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 5442 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 5443 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 5444 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 5445 5446 /* 5447 * Set up output mixers (0x0c - 0x0f) 5448 */ 5449 /* set vol=0 to output mixers */ 5450 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5451 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5452 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5453 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5454 /* set up input amps for analog loopback */ 5455 /* Amp Indices: DAC = 0, mixer = 1 */ 5456 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5457 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 5458 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5459 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 5460 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5461 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 5462 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5463 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 5464 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5465 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 5466 5467 /* FIXME: use matrix-type input source selection */ 5468 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 5469 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 5470 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 5471 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 5472 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 5473 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 5474 /* Input mixer2 */ 5475 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 5476 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 5477 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 5478 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 5479 /* Input mixer3 */ 5480 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 5481 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 5482 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 5483 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 5484 5485 { } 5486}; 5487 5488/* capture mixer elements */ 5489static struct snd_kcontrol_new alc882_capture_alt_mixer[] = { 5490 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 5491 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 5492 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), 5493 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), 5494 { 5495 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 5496 /* The multiple "Capture Source" controls confuse alsamixer 5497 * So call somewhat different.. 5498 * FIXME: the controls appear in the "playback" view! 5499 */ 5500 /* .name = "Capture Source", */ 5501 .name = "Input Source", 5502 .count = 2, 5503 .info = alc882_mux_enum_info, 5504 .get = alc882_mux_enum_get, 5505 .put = alc882_mux_enum_put, 5506 }, 5507 { } /* end */ 5508}; 5509 5510static struct snd_kcontrol_new alc882_capture_mixer[] = { 5511 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT), 5512 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT), 5513 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT), 5514 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT), 5515 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT), 5516 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT), 5517 { 5518 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 5519 /* The multiple "Capture Source" controls confuse alsamixer 5520 * So call somewhat different.. 5521 * FIXME: the controls appear in the "playback" view! 5522 */ 5523 /* .name = "Capture Source", */ 5524 .name = "Input Source", 5525 .count = 3, 5526 .info = alc882_mux_enum_info, 5527 .get = alc882_mux_enum_get, 5528 .put = alc882_mux_enum_put, 5529 }, 5530 { } /* end */ 5531}; 5532 5533#ifdef CONFIG_SND_HDA_POWER_SAVE 5534#define alc882_loopbacks alc880_loopbacks 5535#endif 5536 5537/* pcm configuration: identiacal with ALC880 */ 5538#define alc882_pcm_analog_playback alc880_pcm_analog_playback 5539#define alc882_pcm_analog_capture alc880_pcm_analog_capture 5540#define alc882_pcm_digital_playback alc880_pcm_digital_playback 5541#define alc882_pcm_digital_capture alc880_pcm_digital_capture 5542 5543/* 5544 * configuration and preset 5545 */ 5546static const char *alc882_models[ALC882_MODEL_LAST] = { 5547 [ALC882_3ST_DIG] = "3stack-dig", 5548 [ALC882_6ST_DIG] = "6stack-dig", 5549 [ALC882_ARIMA] = "arima", 5550 [ALC882_W2JC] = "w2jc", 5551 [ALC885_MACPRO] = "macpro", 5552 [ALC885_MBP3] = "mbp3", 5553 [ALC885_IMAC24] = "imac24", 5554 [ALC882_AUTO] = "auto", 5555}; 5556 5557static struct snd_pci_quirk alc882_cfg_tbl[] = { 5558 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG), 5559 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG), 5560 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG), 5561 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */ 5562 SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), 5563 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J), 5564 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG), 5565 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG), 5566 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC), 5567 {} 5568}; 5569 5570static struct alc_config_preset alc882_presets[] = { 5571 [ALC882_3ST_DIG] = { 5572 .mixers = { alc882_base_mixer }, 5573 .init_verbs = { alc882_init_verbs }, 5574 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 5575 .dac_nids = alc882_dac_nids, 5576 .dig_out_nid = ALC882_DIGOUT_NID, 5577 .dig_in_nid = ALC882_DIGIN_NID, 5578 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes), 5579 .channel_mode = alc882_ch_modes, 5580 .need_dac_fix = 1, 5581 .input_mux = &alc882_capture_source, 5582 }, 5583 [ALC882_6ST_DIG] = { 5584 .mixers = { alc882_base_mixer, alc882_chmode_mixer }, 5585 .init_verbs = { alc882_init_verbs }, 5586 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 5587 .dac_nids = alc882_dac_nids, 5588 .dig_out_nid = ALC882_DIGOUT_NID, 5589 .dig_in_nid = ALC882_DIGIN_NID, 5590 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes), 5591 .channel_mode = alc882_sixstack_modes, 5592 .input_mux = &alc882_capture_source, 5593 }, 5594 [ALC882_ARIMA] = { 5595 .mixers = { alc882_base_mixer, alc882_chmode_mixer }, 5596 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs }, 5597 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 5598 .dac_nids = alc882_dac_nids, 5599 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes), 5600 .channel_mode = alc882_sixstack_modes, 5601 .input_mux = &alc882_capture_source, 5602 }, 5603 [ALC882_W2JC] = { 5604 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer }, 5605 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs, 5606 alc880_gpio1_init_verbs }, 5607 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 5608 .dac_nids = alc882_dac_nids, 5609 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), 5610 .channel_mode = alc880_threestack_modes, 5611 .need_dac_fix = 1, 5612 .input_mux = &alc882_capture_source, 5613 .dig_out_nid = ALC882_DIGOUT_NID, 5614 }, 5615 [ALC885_MBP3] = { 5616 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer }, 5617 .init_verbs = { alc885_mbp3_init_verbs, 5618 alc880_gpio1_init_verbs }, 5619 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 5620 .dac_nids = alc882_dac_nids, 5621 .channel_mode = alc885_mbp_6ch_modes, 5622 .num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes), 5623 .input_mux = &alc882_capture_source, 5624 .dig_out_nid = ALC882_DIGOUT_NID, 5625 .dig_in_nid = ALC882_DIGIN_NID, 5626 .unsol_event = alc885_mbp3_unsol_event, 5627 .init_hook = alc885_mbp3_automute, 5628 }, 5629 [ALC885_MACPRO] = { 5630 .mixers = { alc882_macpro_mixer }, 5631 .init_verbs = { alc882_macpro_init_verbs }, 5632 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 5633 .dac_nids = alc882_dac_nids, 5634 .dig_out_nid = ALC882_DIGOUT_NID, 5635 .dig_in_nid = ALC882_DIGIN_NID, 5636 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes), 5637 .channel_mode = alc882_ch_modes, 5638 .input_mux = &alc882_capture_source, 5639 .init_hook = alc885_macpro_init_hook, 5640 }, 5641 [ALC885_IMAC24] = { 5642 .mixers = { alc885_imac24_mixer }, 5643 .init_verbs = { alc885_imac24_init_verbs }, 5644 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 5645 .dac_nids = alc882_dac_nids, 5646 .dig_out_nid = ALC882_DIGOUT_NID, 5647 .dig_in_nid = ALC882_DIGIN_NID, 5648 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes), 5649 .channel_mode = alc882_ch_modes, 5650 .input_mux = &alc882_capture_source, 5651 .unsol_event = alc885_imac24_unsol_event, 5652 .init_hook = alc885_imac24_init_hook, 5653 }, 5654 [ALC882_TARGA] = { 5655 .mixers = { alc882_targa_mixer, alc882_chmode_mixer, 5656 alc882_capture_mixer }, 5657 .init_verbs = { alc882_init_verbs, alc882_targa_verbs}, 5658 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 5659 .dac_nids = alc882_dac_nids, 5660 .dig_out_nid = ALC882_DIGOUT_NID, 5661 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids), 5662 .adc_nids = alc882_adc_nids, 5663 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes), 5664 .channel_mode = alc882_3ST_6ch_modes, 5665 .need_dac_fix = 1, 5666 .input_mux = &alc882_capture_source, 5667 .unsol_event = alc882_targa_unsol_event, 5668 .init_hook = alc882_targa_automute, 5669 }, 5670 [ALC882_ASUS_A7J] = { 5671 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer, 5672 alc882_capture_mixer }, 5673 .init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs}, 5674 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 5675 .dac_nids = alc882_dac_nids, 5676 .dig_out_nid = ALC882_DIGOUT_NID, 5677 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids), 5678 .adc_nids = alc882_adc_nids, 5679 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes), 5680 .channel_mode = alc882_3ST_6ch_modes, 5681 .need_dac_fix = 1, 5682 .input_mux = &alc882_capture_source, 5683 }, 5684}; 5685 5686 5687/* 5688 * Pin config fixes 5689 */ 5690enum { 5691 PINFIX_ABIT_AW9D_MAX 5692}; 5693 5694static struct alc_pincfg alc882_abit_aw9d_pinfix[] = { 5695 { 0x15, 0x01080104 }, /* side */ 5696 { 0x16, 0x01011012 }, /* rear */ 5697 { 0x17, 0x01016011 }, /* clfe */ 5698 { } 5699}; 5700 5701static const struct alc_pincfg *alc882_pin_fixes[] = { 5702 [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix, 5703}; 5704 5705static struct snd_pci_quirk alc882_pinfix_tbl[] = { 5706 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX), 5707 {} 5708}; 5709 5710/* 5711 * BIOS auto configuration 5712 */ 5713static void alc882_auto_set_output_and_unmute(struct hda_codec *codec, 5714 hda_nid_t nid, int pin_type, 5715 int dac_idx) 5716{ 5717 /* set as output */ 5718 struct alc_spec *spec = codec->spec; 5719 int idx; 5720 5721 if (spec->multiout.dac_nids[dac_idx] == 0x25) 5722 idx = 4; 5723 else 5724 idx = spec->multiout.dac_nids[dac_idx] - 2; 5725 5726 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 5727 pin_type); 5728 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, 5729 AMP_OUT_UNMUTE); 5730 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx); 5731 5732} 5733 5734static void alc882_auto_init_multi_out(struct hda_codec *codec) 5735{ 5736 struct alc_spec *spec = codec->spec; 5737 int i; 5738 5739 alc_subsystem_id(codec, 0x15, 0x1b, 0x14); 5740 for (i = 0; i <= HDA_SIDE; i++) { 5741 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 5742 int pin_type = get_pin_type(spec->autocfg.line_out_type); 5743 if (nid) 5744 alc882_auto_set_output_and_unmute(codec, nid, pin_type, 5745 i); 5746 } 5747} 5748 5749static void alc882_auto_init_hp_out(struct hda_codec *codec) 5750{ 5751 struct alc_spec *spec = codec->spec; 5752 hda_nid_t pin; 5753 5754 pin = spec->autocfg.hp_pins[0]; 5755 if (pin) /* connect to front */ 5756 /* use dac 0 */ 5757 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); 5758} 5759 5760#define alc882_is_input_pin(nid) alc880_is_input_pin(nid) 5761#define ALC882_PIN_CD_NID ALC880_PIN_CD_NID 5762 5763static void alc882_auto_init_analog_input(struct hda_codec *codec) 5764{ 5765 struct alc_spec *spec = codec->spec; 5766 int i; 5767 5768 for (i = 0; i < AUTO_PIN_LAST; i++) { 5769 hda_nid_t nid = spec->autocfg.input_pins[i]; 5770 if (alc882_is_input_pin(nid)) { 5771 snd_hda_codec_write(codec, nid, 0, 5772 AC_VERB_SET_PIN_WIDGET_CONTROL, 5773 i <= AUTO_PIN_FRONT_MIC ? 5774 PIN_VREF80 : PIN_IN); 5775 if (nid != ALC882_PIN_CD_NID) 5776 snd_hda_codec_write(codec, nid, 0, 5777 AC_VERB_SET_AMP_GAIN_MUTE, 5778 AMP_OUT_MUTE); 5779 } 5780 } 5781} 5782 5783/* almost identical with ALC880 parser... */ 5784static int alc882_parse_auto_config(struct hda_codec *codec) 5785{ 5786 struct alc_spec *spec = codec->spec; 5787 int err = alc880_parse_auto_config(codec); 5788 5789 if (err < 0) 5790 return err; 5791 else if (err > 0) 5792 /* hack - override the init verbs */ 5793 spec->init_verbs[0] = alc882_auto_init_verbs; 5794 return err; 5795} 5796 5797/* additional initialization for auto-configuration model */ 5798static void alc882_auto_init(struct hda_codec *codec) 5799{ 5800 alc882_auto_init_multi_out(codec); 5801 alc882_auto_init_hp_out(codec); 5802 alc882_auto_init_analog_input(codec); 5803} 5804 5805static int patch_alc882(struct hda_codec *codec) 5806{ 5807 struct alc_spec *spec; 5808 int err, board_config; 5809 5810 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 5811 if (spec == NULL) 5812 return -ENOMEM; 5813 5814 codec->spec = spec; 5815 5816 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST, 5817 alc882_models, 5818 alc882_cfg_tbl); 5819 5820 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) { 5821 /* Pick up systems that don't supply PCI SSID */ 5822 switch (codec->subsystem_id) { 5823 case 0x106b0c00: /* Mac Pro */ 5824 board_config = ALC885_MACPRO; 5825 break; 5826 case 0x106b1000: /* iMac 24 */ 5827 board_config = ALC885_IMAC24; 5828 break; 5829 case 0x106b2c00: /* Macbook Pro rev3 */ 5830 board_config = ALC885_MBP3; 5831 break; 5832 default: 5833 printk(KERN_INFO "hda_codec: Unknown model for ALC882, " 5834 "trying auto-probe from BIOS...\n"); 5835 board_config = ALC882_AUTO; 5836 } 5837 } 5838 5839 alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes); 5840 5841 if (board_config == ALC882_AUTO) { 5842 /* automatic parse from the BIOS config */ 5843 err = alc882_parse_auto_config(codec); 5844 if (err < 0) { 5845 alc_free(codec); 5846 return err; 5847 } else if (!err) { 5848 printk(KERN_INFO 5849 "hda_codec: Cannot set up configuration " 5850 "from BIOS. Using base mode...\n"); 5851 board_config = ALC882_3ST_DIG; 5852 } 5853 } 5854 5855 if (board_config != ALC882_AUTO) 5856 setup_preset(spec, &alc882_presets[board_config]); 5857 5858 spec->stream_name_analog = "ALC882 Analog"; 5859 spec->stream_analog_playback = &alc882_pcm_analog_playback; 5860 spec->stream_analog_capture = &alc882_pcm_analog_capture; 5861 5862 spec->stream_name_digital = "ALC882 Digital"; 5863 spec->stream_digital_playback = &alc882_pcm_digital_playback; 5864 spec->stream_digital_capture = &alc882_pcm_digital_capture; 5865 5866 if (!spec->adc_nids && spec->input_mux) { 5867 /* check whether NID 0x07 is valid */ 5868 unsigned int wcap = get_wcaps(codec, 0x07); 5869 /* get type */ 5870 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; 5871 if (wcap != AC_WID_AUD_IN) { 5872 spec->adc_nids = alc882_adc_nids_alt; 5873 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt); 5874 spec->mixers[spec->num_mixers] = 5875 alc882_capture_alt_mixer; 5876 spec->num_mixers++; 5877 } else { 5878 spec->adc_nids = alc882_adc_nids; 5879 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids); 5880 spec->mixers[spec->num_mixers] = alc882_capture_mixer; 5881 spec->num_mixers++; 5882 } 5883 } 5884 5885 codec->patch_ops = alc_patch_ops; 5886 if (board_config == ALC882_AUTO) 5887 spec->init_hook = alc882_auto_init; 5888#ifdef CONFIG_SND_HDA_POWER_SAVE 5889 if (!spec->loopback.amplist) 5890 spec->loopback.amplist = alc882_loopbacks; 5891#endif 5892 5893 return 0; 5894} 5895 5896/* 5897 * ALC883 support 5898 * 5899 * ALC883 is almost identical with ALC880 but has cleaner and more flexible 5900 * configuration. Each pin widget can choose any input DACs and a mixer. 5901 * Each ADC is connected from a mixer of all inputs. This makes possible 5902 * 6-channel independent captures. 5903 * 5904 * In addition, an independent DAC for the multi-playback (not used in this 5905 * driver yet). 5906 */ 5907#define ALC883_DIGOUT_NID 0x06 5908#define ALC883_DIGIN_NID 0x0a 5909 5910static hda_nid_t alc883_dac_nids[4] = { 5911 /* front, rear, clfe, rear_surr */ 5912 0x02, 0x04, 0x03, 0x05 5913}; 5914 5915static hda_nid_t alc883_adc_nids[2] = { 5916 /* ADC1-2 */ 5917 0x08, 0x09, 5918}; 5919 5920/* input MUX */ 5921/* FIXME: should be a matrix-type input source selection */ 5922 5923static struct hda_input_mux alc883_capture_source = { 5924 .num_items = 4, 5925 .items = { 5926 { "Mic", 0x0 }, 5927 { "Front Mic", 0x1 }, 5928 { "Line", 0x2 }, 5929 { "CD", 0x4 }, 5930 }, 5931}; 5932 5933static struct hda_input_mux alc883_lenovo_101e_capture_source = { 5934 .num_items = 2, 5935 .items = { 5936 { "Mic", 0x1 }, 5937 { "Line", 0x2 }, 5938 }, 5939}; 5940 5941static struct hda_input_mux alc883_lenovo_nb0763_capture_source = { 5942 .num_items = 4, 5943 .items = { 5944 { "Mic", 0x0 }, 5945 { "iMic", 0x1 }, 5946 { "Line", 0x2 }, 5947 { "CD", 0x4 }, 5948 }, 5949}; 5950 5951#define alc883_mux_enum_info alc_mux_enum_info 5952#define alc883_mux_enum_get alc_mux_enum_get 5953 5954static int alc883_mux_enum_put(struct snd_kcontrol *kcontrol, 5955 struct snd_ctl_elem_value *ucontrol) 5956{ 5957 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 5958 struct alc_spec *spec = codec->spec; 5959 const struct hda_input_mux *imux = spec->input_mux; 5960 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 5961 static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 }; 5962 hda_nid_t nid = capture_mixers[adc_idx]; 5963 unsigned int *cur_val = &spec->cur_mux[adc_idx]; 5964 unsigned int i, idx; 5965 5966 idx = ucontrol->value.enumerated.item[0]; 5967 if (idx >= imux->num_items) 5968 idx = imux->num_items - 1; 5969 if (*cur_val == idx) 5970 return 0; 5971 for (i = 0; i < imux->num_items; i++) { 5972 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE; 5973 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 5974 imux->items[i].index, 5975 HDA_AMP_MUTE, v); 5976 } 5977 *cur_val = idx; 5978 return 1; 5979} 5980 5981/* 5982 * 2ch mode 5983 */ 5984static struct hda_channel_mode alc883_3ST_2ch_modes[1] = { 5985 { 2, NULL } 5986}; 5987 5988/* 5989 * 2ch mode 5990 */ 5991static struct hda_verb alc883_3ST_ch2_init[] = { 5992 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 5993 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 5994 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 5995 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 5996 { } /* end */ 5997}; 5998 5999/* 6000 * 6ch mode 6001 */ 6002static struct hda_verb alc883_3ST_ch6_init[] = { 6003 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 6004 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 6005 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, 6006 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 6007 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 6008 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 6009 { } /* end */ 6010}; 6011 6012static struct hda_channel_mode alc883_3ST_6ch_modes[2] = { 6013 { 2, alc883_3ST_ch2_init }, 6014 { 6, alc883_3ST_ch6_init }, 6015}; 6016 6017/* 6018 * 6ch mode 6019 */ 6020static struct hda_verb alc883_sixstack_ch6_init[] = { 6021 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 6022 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 6023 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 6024 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 6025 { } /* end */ 6026}; 6027 6028/* 6029 * 8ch mode 6030 */ 6031static struct hda_verb alc883_sixstack_ch8_init[] = { 6032 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 6033 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 6034 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 6035 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 6036 { } /* end */ 6037}; 6038 6039static struct hda_channel_mode alc883_sixstack_modes[2] = { 6040 { 6, alc883_sixstack_ch6_init }, 6041 { 8, alc883_sixstack_ch8_init }, 6042}; 6043 6044static struct hda_verb alc883_medion_eapd_verbs[] = { 6045 /* eanable EAPD on medion laptop */ 6046 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 6047 {0x20, AC_VERB_SET_PROC_COEF, 0x3070}, 6048 { } 6049}; 6050 6051/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 6052 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b 6053 */ 6054 6055static struct snd_kcontrol_new alc883_base_mixer[] = { 6056 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 6057 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 6058 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 6059 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 6060 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 6061 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 6062 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 6063 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 6064 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 6065 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 6066 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 6067 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 6068 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 6069 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 6070 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 6071 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 6072 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 6073 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 6074 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 6075 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 6076 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 6077 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 6078 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 6079 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 6080 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 6081 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), 6082 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), 6083 { 6084 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 6085 /* .name = "Capture Source", */ 6086 .name = "Input Source", 6087 .count = 2, 6088 .info = alc883_mux_enum_info, 6089 .get = alc883_mux_enum_get, 6090 .put = alc883_mux_enum_put, 6091 }, 6092 { } /* end */ 6093}; 6094 6095static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = { 6096 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 6097 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 6098 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 6099 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 6100 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 6101 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 6102 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 6103 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 6104 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 6105 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 6106 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 6107 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 6108 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 6109 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 6110 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 6111 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 6112 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 6113 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), 6114 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), 6115 { 6116 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 6117 /* .name = "Capture Source", */ 6118 .name = "Input Source", 6119 .count = 2, 6120 .info = alc883_mux_enum_info, 6121 .get = alc883_mux_enum_get, 6122 .put = alc883_mux_enum_put, 6123 }, 6124 { } /* end */ 6125}; 6126 6127static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = { 6128 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 6129 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 6130 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 6131 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 6132 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 6133 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 6134 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 6135 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 6136 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 6137 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 6138 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 6139 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 6140 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 6141 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 6142 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 6143 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 6144 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 6145 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 6146 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 6147 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 6148 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 6149 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 6150 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 6151 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), 6152 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), 6153 { 6154 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 6155 /* .name = "Capture Source", */ 6156 .name = "Input Source", 6157 .count = 2, 6158 .info = alc883_mux_enum_info, 6159 .get = alc883_mux_enum_get, 6160 .put = alc883_mux_enum_put, 6161 }, 6162 { } /* end */ 6163}; 6164 6165static struct snd_kcontrol_new alc883_fivestack_mixer[] = { 6166 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 6167 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 6168 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 6169 HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT), 6170 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 6171 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 6172 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x16, 1, 0x0, HDA_OUTPUT), 6173 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT), 6174 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 6175 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 6176 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 6177 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 6178 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 6179 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 6180 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 6181 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 6182 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 6183 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 6184 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 6185 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 6186 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 6187 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 6188 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 6189 6190 { 6191 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 6192 /* .name = "Capture Source", */ 6193 .name = "Input Source", 6194 .count = 1, 6195 .info = alc883_mux_enum_info, 6196 .get = alc883_mux_enum_get, 6197 .put = alc883_mux_enum_put, 6198 }, 6199 { } /* end */ 6200}; 6201 6202static struct snd_kcontrol_new alc883_tagra_mixer[] = { 6203 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 6204 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 6205 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 6206 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 6207 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 6208 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 6209 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 6210 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 6211 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 6212 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 6213 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 6214 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 6215 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 6216 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 6217 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 6218 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 6219 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 6220 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 6221 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), 6222 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), 6223 { 6224 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 6225 /* .name = "Capture Source", */ 6226 .name = "Input Source", 6227 .count = 2, 6228 .info = alc883_mux_enum_info, 6229 .get = alc883_mux_enum_get, 6230 .put = alc883_mux_enum_put, 6231 }, 6232 { } /* end */ 6233}; 6234 6235static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = { 6236 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 6237 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 6238 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 6239 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 6240 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 6241 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 6242 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 6243 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 6244 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 6245 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 6246 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), 6247 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), 6248 { 6249 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 6250 /* .name = "Capture Source", */ 6251 .name = "Input Source", 6252 .count = 2, 6253 .info = alc883_mux_enum_info, 6254 .get = alc883_mux_enum_get, 6255 .put = alc883_mux_enum_put, 6256 }, 6257 { } /* end */ 6258}; 6259 6260static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = { 6261 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 6262 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 6263 HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 6264 HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT), 6265 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 6266 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 6267 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 6268 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 6269 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 6270 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 6271 { 6272 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 6273 /* .name = "Capture Source", */ 6274 .name = "Input Source", 6275 .count = 1, 6276 .info = alc883_mux_enum_info, 6277 .get = alc883_mux_enum_get, 6278 .put = alc883_mux_enum_put, 6279 }, 6280 { } /* end */ 6281}; 6282 6283static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = { 6284 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 6285 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT), 6286 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 6287 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 6288 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 6289 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 6290 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 6291 HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT), 6292 HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT), 6293 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 6294 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 6295 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), 6296 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), 6297 { 6298 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 6299 /* .name = "Capture Source", */ 6300 .name = "Input Source", 6301 .count = 2, 6302 .info = alc883_mux_enum_info, 6303 .get = alc883_mux_enum_get, 6304 .put = alc883_mux_enum_put, 6305 }, 6306 { } /* end */ 6307}; 6308 6309static struct snd_kcontrol_new alc883_medion_md2_mixer[] = { 6310 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 6311 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 6312 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT), 6313 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 6314 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 6315 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 6316 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 6317 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 6318 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 6319 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 6320 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 6321 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), 6322 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), 6323 { 6324 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 6325 /* .name = "Capture Source", */ 6326 .name = "Input Source", 6327 .count = 2, 6328 .info = alc883_mux_enum_info, 6329 .get = alc883_mux_enum_get, 6330 .put = alc883_mux_enum_put, 6331 }, 6332 { } /* end */ 6333}; 6334 6335static struct snd_kcontrol_new alc888_6st_hp_mixer[] = { 6336 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 6337 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 6338 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT), 6339 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT), 6340 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT), 6341 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT), 6342 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT), 6343 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT), 6344 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 6345 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 6346 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 6347 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 6348 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 6349 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 6350 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 6351 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 6352 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 6353 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 6354 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 6355 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 6356 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 6357 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 6358 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 6359 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 6360 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 6361 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), 6362 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), 6363 { 6364 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 6365 /* .name = "Capture Source", */ 6366 .name = "Input Source", 6367 .count = 2, 6368 .info = alc883_mux_enum_info, 6369 .get = alc883_mux_enum_get, 6370 .put = alc883_mux_enum_put, 6371 }, 6372 { } /* end */ 6373}; 6374 6375static struct snd_kcontrol_new alc888_3st_hp_mixer[] = { 6376 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 6377 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 6378 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT), 6379 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT), 6380 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT), 6381 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT), 6382 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT), 6383 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT), 6384 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 6385 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 6386 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 6387 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 6388 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 6389 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 6390 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 6391 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 6392 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 6393 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 6394 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 6395 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 6396 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 6397 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 6398 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 6399 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), 6400 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), 6401 { 6402 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 6403 /* .name = "Capture Source", */ 6404 .name = "Input Source", 6405 .count = 2, 6406 .info = alc883_mux_enum_info, 6407 .get = alc883_mux_enum_get, 6408 .put = alc883_mux_enum_put, 6409 }, 6410 { } /* end */ 6411}; 6412 6413static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = { 6414 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 6415 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 6416 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 6417 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 6418 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 6419 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 6420 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 6421 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 6422 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 6423 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 6424 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), 6425 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), 6426 { 6427 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 6428 /* .name = "Capture Source", */ 6429 .name = "Input Source", 6430 .count = 2, 6431 .info = alc883_mux_enum_info, 6432 .get = alc883_mux_enum_get, 6433 .put = alc883_mux_enum_put, 6434 }, 6435 { } /* end */ 6436}; 6437 6438static struct snd_kcontrol_new alc883_chmode_mixer[] = { 6439 { 6440 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 6441 .name = "Channel Mode", 6442 .info = alc_ch_mode_info, 6443 .get = alc_ch_mode_get, 6444 .put = alc_ch_mode_put, 6445 }, 6446 { } /* end */ 6447}; 6448 6449static struct hda_verb alc883_init_verbs[] = { 6450 /* ADC1: mute amp left and right */ 6451 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6452 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 6453 /* ADC2: mute amp left and right */ 6454 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6455 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 6456 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 6457 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6458 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6459 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6460 /* Rear mixer */ 6461 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6462 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6463 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6464 /* CLFE mixer */ 6465 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6466 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6467 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6468 /* Side mixer */ 6469 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6470 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6471 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6472 6473 /* mute analog input loopbacks */ 6474 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6475 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6476 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 6477 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 6478 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 6479 6480 /* Front Pin: output 0 (0x0c) */ 6481 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6482 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6483 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 6484 /* Rear Pin: output 1 (0x0d) */ 6485 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6486 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6487 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 6488 /* CLFE Pin: output 2 (0x0e) */ 6489 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6490 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6491 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, 6492 /* Side Pin: output 3 (0x0f) */ 6493 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6494 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6495 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, 6496 /* Mic (rear) pin: input vref at 80% */ 6497 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 6498 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 6499 /* Front Mic pin: input vref at 80% */ 6500 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 6501 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 6502 /* Line In pin: input */ 6503 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 6504 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 6505 /* Line-2 In: Headphone output (output 0 - 0x0c) */ 6506 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6507 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6508 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 6509 /* CD pin widget for input */ 6510 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 6511 6512 /* FIXME: use matrix-type input source selection */ 6513 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 6514 /* Input mixer2 */ 6515 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6516 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 6517 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 6518 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, 6519 /* Input mixer3 */ 6520 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6521 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 6522 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 6523 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, 6524 { } 6525}; 6526 6527static struct hda_verb alc883_tagra_verbs[] = { 6528 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6529 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 6530 6531 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6532 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6533 6534 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ 6535 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */ 6536 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 6537 6538 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 6539 {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, 6540 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03}, 6541 {0x01, AC_VERB_SET_GPIO_DATA, 0x03}, 6542 6543 { } /* end */ 6544}; 6545 6546static struct hda_verb alc883_lenovo_101e_verbs[] = { 6547 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 6548 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN}, 6549 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN}, 6550 { } /* end */ 6551}; 6552 6553static struct hda_verb alc883_lenovo_nb0763_verbs[] = { 6554 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 6555 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6556 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 6557 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6558 { } /* end */ 6559}; 6560 6561static struct hda_verb alc888_lenovo_ms7195_verbs[] = { 6562 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6563 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 6564 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 6565 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN}, 6566 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 6567 { } /* end */ 6568}; 6569 6570static struct hda_verb alc888_6st_hp_verbs[] = { 6571 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */ 6572 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Rear : output 2 (0x0e) */ 6573 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* CLFE : output 1 (0x0d) */ 6574 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, /* Side : output 3 (0x0f) */ 6575 { } 6576}; 6577 6578static struct hda_verb alc888_3st_hp_verbs[] = { 6579 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */ 6580 {0x18, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */ 6581 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */ 6582 { } 6583}; 6584 6585static struct hda_verb alc888_3st_hp_2ch_init[] = { 6586 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 6587 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 6588 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 6589 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 6590 { } 6591}; 6592 6593static struct hda_verb alc888_3st_hp_6ch_init[] = { 6594 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 6595 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 6596 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 6597 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 6598 { } 6599}; 6600 6601static struct hda_channel_mode alc888_3st_hp_modes[2] = { 6602 { 2, alc888_3st_hp_2ch_init }, 6603 { 6, alc888_3st_hp_6ch_init }, 6604}; 6605 6606/* toggle front-jack and RCA according to the hp-jack state */ 6607static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec) 6608{ 6609 unsigned int present; 6610 6611 present = snd_hda_codec_read(codec, 0x1b, 0, 6612 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 6613 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 6614 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 6615 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 6616 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 6617} 6618 6619/* toggle RCA according to the front-jack state */ 6620static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec) 6621{ 6622 unsigned int present; 6623 6624 present = snd_hda_codec_read(codec, 0x14, 0, 6625 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 6626 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 6627 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 6628} 6629 6630static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec, 6631 unsigned int res) 6632{ 6633 if ((res >> 26) == ALC880_HP_EVENT) 6634 alc888_lenovo_ms7195_front_automute(codec); 6635 if ((res >> 26) == ALC880_FRONT_EVENT) 6636 alc888_lenovo_ms7195_rca_automute(codec); 6637} 6638 6639static struct hda_verb alc883_medion_md2_verbs[] = { 6640 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6641 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 6642 6643 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6644 6645 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 6646 { } /* end */ 6647}; 6648 6649/* toggle speaker-output according to the hp-jack state */ 6650static void alc883_medion_md2_automute(struct hda_codec *codec) 6651{ 6652 unsigned int present; 6653 6654 present = snd_hda_codec_read(codec, 0x14, 0, 6655 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 6656 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 6657 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 6658} 6659 6660static void alc883_medion_md2_unsol_event(struct hda_codec *codec, 6661 unsigned int res) 6662{ 6663 if ((res >> 26) == ALC880_HP_EVENT) 6664 alc883_medion_md2_automute(codec); 6665} 6666 6667/* toggle speaker-output according to the hp-jack state */ 6668static void alc883_tagra_automute(struct hda_codec *codec) 6669{ 6670 unsigned int present; 6671 unsigned char bits; 6672 6673 present = snd_hda_codec_read(codec, 0x14, 0, 6674 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 6675 bits = present ? HDA_AMP_MUTE : 0; 6676 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0, 6677 HDA_AMP_MUTE, bits); 6678 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA, 6679 present ? 1 : 3); 6680} 6681 6682static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res) 6683{ 6684 if ((res >> 26) == ALC880_HP_EVENT) 6685 alc883_tagra_automute(codec); 6686} 6687 6688static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec) 6689{ 6690 unsigned int present; 6691 unsigned char bits; 6692 6693 present = snd_hda_codec_read(codec, 0x14, 0, 6694 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 6695 bits = present ? HDA_AMP_MUTE : 0; 6696 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 6697 HDA_AMP_MUTE, bits); 6698} 6699 6700static void alc883_lenovo_101e_all_automute(struct hda_codec *codec) 6701{ 6702 unsigned int present; 6703 unsigned char bits; 6704 6705 present = snd_hda_codec_read(codec, 0x1b, 0, 6706 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 6707 bits = present ? HDA_AMP_MUTE : 0; 6708 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 6709 HDA_AMP_MUTE, bits); 6710 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 6711 HDA_AMP_MUTE, bits); 6712} 6713 6714static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec, 6715 unsigned int res) 6716{ 6717 if ((res >> 26) == ALC880_HP_EVENT) 6718 alc883_lenovo_101e_all_automute(codec); 6719 if ((res >> 26) == ALC880_FRONT_EVENT) 6720 alc883_lenovo_101e_ispeaker_automute(codec); 6721} 6722 6723/* toggle speaker-output according to the hp-jack state */ 6724static void alc883_acer_aspire_automute(struct hda_codec *codec) 6725{ 6726 unsigned int present; 6727 6728 present = snd_hda_codec_read(codec, 0x14, 0, 6729 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 6730 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 6731 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 6732 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0, 6733 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 6734} 6735 6736static void alc883_acer_aspire_unsol_event(struct hda_codec *codec, 6737 unsigned int res) 6738{ 6739 if ((res >> 26) == ALC880_HP_EVENT) 6740 alc883_acer_aspire_automute(codec); 6741} 6742 6743static struct hda_verb alc883_acer_eapd_verbs[] = { 6744 /* HP Pin: output 0 (0x0c) */ 6745 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6746 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6747 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 6748 /* Front Pin: output 0 (0x0c) */ 6749 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6750 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 6751 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6752 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, 6753 /* eanable EAPD on medion laptop */ 6754 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 6755 {0x20, AC_VERB_SET_PROC_COEF, 0x3050}, 6756 /* enable unsolicited event */ 6757 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 6758 { } 6759}; 6760 6761/* 6762 * generic initialization of ADC, input mixers and output mixers 6763 */ 6764static struct hda_verb alc883_auto_init_verbs[] = { 6765 /* 6766 * Unmute ADC0-2 and set the default input to mic-in 6767 */ 6768 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 6769 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6770 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 6771 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6772 6773 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 6774 * mixer widget 6775 * Note: PASD motherboards uses the Line In 2 as the input for 6776 * front panel mic (mic 2) 6777 */ 6778 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 6779 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6780 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6781 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 6782 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 6783 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 6784 6785 /* 6786 * Set up output mixers (0x0c - 0x0f) 6787 */ 6788 /* set vol=0 to output mixers */ 6789 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6790 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6791 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6792 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6793 /* set up input amps for analog loopback */ 6794 /* Amp Indices: DAC = 0, mixer = 1 */ 6795 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6796 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 6797 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6798 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 6799 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6800 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 6801 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6802 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 6803 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6804 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 6805 6806 /* FIXME: use matrix-type input source selection */ 6807 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 6808 /* Input mixer1 */ 6809 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6810 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 6811 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 6812 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */ 6813 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, 6814 /* Input mixer2 */ 6815 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6816 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 6817 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 6818 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */ 6819 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, 6820 6821 { } 6822}; 6823 6824/* capture mixer elements */ 6825static struct snd_kcontrol_new alc883_capture_mixer[] = { 6826 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 6827 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 6828 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), 6829 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), 6830 { 6831 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 6832 /* The multiple "Capture Source" controls confuse alsamixer 6833 * So call somewhat different.. 6834 * FIXME: the controls appear in the "playback" view! 6835 */ 6836 /* .name = "Capture Source", */ 6837 .name = "Input Source", 6838 .count = 2, 6839 .info = alc882_mux_enum_info, 6840 .get = alc882_mux_enum_get, 6841 .put = alc882_mux_enum_put, 6842 }, 6843 { } /* end */ 6844}; 6845 6846#ifdef CONFIG_SND_HDA_POWER_SAVE 6847#define alc883_loopbacks alc880_loopbacks 6848#endif 6849 6850/* pcm configuration: identiacal with ALC880 */ 6851#define alc883_pcm_analog_playback alc880_pcm_analog_playback 6852#define alc883_pcm_analog_capture alc880_pcm_analog_capture 6853#define alc883_pcm_digital_playback alc880_pcm_digital_playback 6854#define alc883_pcm_digital_capture alc880_pcm_digital_capture 6855 6856/* 6857 * configuration and preset 6858 */ 6859static const char *alc883_models[ALC883_MODEL_LAST] = { 6860 [ALC883_3ST_2ch_DIG] = "3stack-dig", 6861 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig", 6862 [ALC883_3ST_6ch] = "3stack-6ch", 6863 [ALC883_6ST_DIG] = "6stack-dig", 6864 [ALC883_TARGA_DIG] = "targa-dig", 6865 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig", 6866 [ALC883_ACER] = "acer", 6867 [ALC883_ACER_ASPIRE] = "acer-aspire", 6868 [ALC883_MEDION] = "medion", 6869 [ALC883_MEDION_MD2] = "medion-md2", 6870 [ALC883_LAPTOP_EAPD] = "laptop-eapd", 6871 [ALC883_LENOVO_101E_2ch] = "lenovo-101e", 6872 [ALC883_LENOVO_NB0763] = "lenovo-nb0763", 6873 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig", 6874 [ALC888_6ST_HP] = "6stack-hp", 6875 [ALC888_3ST_HP] = "3stack-hp", 6876 [ALC883_AUTO] = "auto", 6877}; 6878 6879static struct snd_pci_quirk alc883_cfg_tbl[] = { 6880 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG), 6881 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG), 6882 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch), 6883 SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD), 6884 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG), 6885 SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG), 6886 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG), 6887 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG), 6888 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG), 6889 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG), 6890 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG), 6891 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG), 6892 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG), 6893 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG), 6894 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG), 6895 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG), 6896 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG), 6897 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG), 6898 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG), 6899 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG), 6900 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG), 6901 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG), 6902 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG), 6903 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG), 6904 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE), 6905 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE), 6906 SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER), 6907 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch), 6908 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION), 6909 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD), 6910 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch), 6911 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch), 6912 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763), 6913 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763), 6914 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC888_6ST_HP), 6915 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP), 6916 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP), 6917 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2), 6918 {} 6919}; 6920 6921static struct alc_config_preset alc883_presets[] = { 6922 [ALC883_3ST_2ch_DIG] = { 6923 .mixers = { alc883_3ST_2ch_mixer }, 6924 .init_verbs = { alc883_init_verbs }, 6925 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 6926 .dac_nids = alc883_dac_nids, 6927 .dig_out_nid = ALC883_DIGOUT_NID, 6928 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 6929 .adc_nids = alc883_adc_nids, 6930 .dig_in_nid = ALC883_DIGIN_NID, 6931 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 6932 .channel_mode = alc883_3ST_2ch_modes, 6933 .input_mux = &alc883_capture_source, 6934 }, 6935 [ALC883_3ST_6ch_DIG] = { 6936 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, 6937 .init_verbs = { alc883_init_verbs }, 6938 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 6939 .dac_nids = alc883_dac_nids, 6940 .dig_out_nid = ALC883_DIGOUT_NID, 6941 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 6942 .adc_nids = alc883_adc_nids, 6943 .dig_in_nid = ALC883_DIGIN_NID, 6944 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 6945 .channel_mode = alc883_3ST_6ch_modes, 6946 .need_dac_fix = 1, 6947 .input_mux = &alc883_capture_source, 6948 }, 6949 [ALC883_3ST_6ch] = { 6950 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, 6951 .init_verbs = { alc883_init_verbs }, 6952 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 6953 .dac_nids = alc883_dac_nids, 6954 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 6955 .adc_nids = alc883_adc_nids, 6956 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 6957 .channel_mode = alc883_3ST_6ch_modes, 6958 .need_dac_fix = 1, 6959 .input_mux = &alc883_capture_source, 6960 }, 6961 [ALC883_6ST_DIG] = { 6962 .mixers = { alc883_base_mixer, alc883_chmode_mixer }, 6963 .init_verbs = { alc883_init_verbs }, 6964 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 6965 .dac_nids = alc883_dac_nids, 6966 .dig_out_nid = ALC883_DIGOUT_NID, 6967 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 6968 .adc_nids = alc883_adc_nids, 6969 .dig_in_nid = ALC883_DIGIN_NID, 6970 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), 6971 .channel_mode = alc883_sixstack_modes, 6972 .input_mux = &alc883_capture_source, 6973 }, 6974 [ALC883_TARGA_DIG] = { 6975 .mixers = { alc883_tagra_mixer, alc883_chmode_mixer }, 6976 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs}, 6977 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 6978 .dac_nids = alc883_dac_nids, 6979 .dig_out_nid = ALC883_DIGOUT_NID, 6980 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 6981 .adc_nids = alc883_adc_nids, 6982 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 6983 .channel_mode = alc883_3ST_6ch_modes, 6984 .need_dac_fix = 1, 6985 .input_mux = &alc883_capture_source, 6986 .unsol_event = alc883_tagra_unsol_event, 6987 .init_hook = alc883_tagra_automute, 6988 }, 6989 [ALC883_TARGA_2ch_DIG] = { 6990 .mixers = { alc883_tagra_2ch_mixer}, 6991 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs}, 6992 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 6993 .dac_nids = alc883_dac_nids, 6994 .dig_out_nid = ALC883_DIGOUT_NID, 6995 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 6996 .adc_nids = alc883_adc_nids, 6997 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 6998 .channel_mode = alc883_3ST_2ch_modes, 6999 .input_mux = &alc883_capture_source, 7000 .unsol_event = alc883_tagra_unsol_event, 7001 .init_hook = alc883_tagra_automute, 7002 }, 7003 [ALC883_ACER] = { 7004 .mixers = { alc883_base_mixer }, 7005 /* On TravelMate laptops, GPIO 0 enables the internal speaker 7006 * and the headphone jack. Turn this on and rely on the 7007 * standard mute methods whenever the user wants to turn 7008 * these outputs off. 7009 */ 7010 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs }, 7011 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 7012 .dac_nids = alc883_dac_nids, 7013 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 7014 .adc_nids = alc883_adc_nids, 7015 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 7016 .channel_mode = alc883_3ST_2ch_modes, 7017 .input_mux = &alc883_capture_source, 7018 }, 7019 [ALC883_ACER_ASPIRE] = { 7020 .mixers = { alc883_acer_aspire_mixer }, 7021 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs }, 7022 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 7023 .dac_nids = alc883_dac_nids, 7024 .dig_out_nid = ALC883_DIGOUT_NID, 7025 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 7026 .adc_nids = alc883_adc_nids, 7027 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 7028 .channel_mode = alc883_3ST_2ch_modes, 7029 .input_mux = &alc883_capture_source, 7030 .unsol_event = alc883_acer_aspire_unsol_event, 7031 .init_hook = alc883_acer_aspire_automute, 7032 }, 7033 [ALC883_MEDION] = { 7034 .mixers = { alc883_fivestack_mixer, 7035 alc883_chmode_mixer }, 7036 .init_verbs = { alc883_init_verbs, 7037 alc883_medion_eapd_verbs }, 7038 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 7039 .dac_nids = alc883_dac_nids, 7040 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 7041 .adc_nids = alc883_adc_nids, 7042 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), 7043 .channel_mode = alc883_sixstack_modes, 7044 .input_mux = &alc883_capture_source, 7045 }, 7046 [ALC883_MEDION_MD2] = { 7047 .mixers = { alc883_medion_md2_mixer}, 7048 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs}, 7049 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 7050 .dac_nids = alc883_dac_nids, 7051 .dig_out_nid = ALC883_DIGOUT_NID, 7052 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 7053 .adc_nids = alc883_adc_nids, 7054 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 7055 .channel_mode = alc883_3ST_2ch_modes, 7056 .input_mux = &alc883_capture_source, 7057 .unsol_event = alc883_medion_md2_unsol_event, 7058 .init_hook = alc883_medion_md2_automute, 7059 }, 7060 [ALC883_LAPTOP_EAPD] = { 7061 .mixers = { alc883_base_mixer }, 7062 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs }, 7063 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 7064 .dac_nids = alc883_dac_nids, 7065 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 7066 .adc_nids = alc883_adc_nids, 7067 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 7068 .channel_mode = alc883_3ST_2ch_modes, 7069 .input_mux = &alc883_capture_source, 7070 }, 7071 [ALC883_LENOVO_101E_2ch] = { 7072 .mixers = { alc883_lenovo_101e_2ch_mixer}, 7073 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs}, 7074 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 7075 .dac_nids = alc883_dac_nids, 7076 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 7077 .adc_nids = alc883_adc_nids, 7078 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 7079 .channel_mode = alc883_3ST_2ch_modes, 7080 .input_mux = &alc883_lenovo_101e_capture_source, 7081 .unsol_event = alc883_lenovo_101e_unsol_event, 7082 .init_hook = alc883_lenovo_101e_all_automute, 7083 }, 7084 [ALC883_LENOVO_NB0763] = { 7085 .mixers = { alc883_lenovo_nb0763_mixer }, 7086 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs}, 7087 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 7088 .dac_nids = alc883_dac_nids, 7089 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 7090 .adc_nids = alc883_adc_nids, 7091 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 7092 .channel_mode = alc883_3ST_2ch_modes, 7093 .need_dac_fix = 1, 7094 .input_mux = &alc883_lenovo_nb0763_capture_source, 7095 .unsol_event = alc883_medion_md2_unsol_event, 7096 .init_hook = alc883_medion_md2_automute, 7097 }, 7098 [ALC888_LENOVO_MS7195_DIG] = { 7099 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, 7100 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs}, 7101 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 7102 .dac_nids = alc883_dac_nids, 7103 .dig_out_nid = ALC883_DIGOUT_NID, 7104 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 7105 .adc_nids = alc883_adc_nids, 7106 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 7107 .channel_mode = alc883_3ST_6ch_modes, 7108 .need_dac_fix = 1, 7109 .input_mux = &alc883_capture_source, 7110 .unsol_event = alc883_lenovo_ms7195_unsol_event, 7111 .init_hook = alc888_lenovo_ms7195_front_automute, 7112 }, 7113 [ALC888_6ST_HP] = { 7114 .mixers = { alc888_6st_hp_mixer, alc883_chmode_mixer }, 7115 .init_verbs = { alc883_init_verbs, alc888_6st_hp_verbs }, 7116 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 7117 .dac_nids = alc883_dac_nids, 7118 .dig_out_nid = ALC883_DIGOUT_NID, 7119 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 7120 .adc_nids = alc883_adc_nids, 7121 .dig_in_nid = ALC883_DIGIN_NID, 7122 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), 7123 .channel_mode = alc883_sixstack_modes, 7124 .input_mux = &alc883_capture_source, 7125 }, 7126 [ALC888_3ST_HP] = { 7127 .mixers = { alc888_3st_hp_mixer, alc883_chmode_mixer }, 7128 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs }, 7129 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 7130 .dac_nids = alc883_dac_nids, 7131 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 7132 .adc_nids = alc883_adc_nids, 7133 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes), 7134 .channel_mode = alc888_3st_hp_modes, 7135 .need_dac_fix = 1, 7136 .input_mux = &alc883_capture_source, 7137 }, 7138}; 7139 7140 7141/* 7142 * BIOS auto configuration 7143 */ 7144static void alc883_auto_set_output_and_unmute(struct hda_codec *codec, 7145 hda_nid_t nid, int pin_type, 7146 int dac_idx) 7147{ 7148 /* set as output */ 7149 struct alc_spec *spec = codec->spec; 7150 int idx; 7151 7152 if (spec->multiout.dac_nids[dac_idx] == 0x25) 7153 idx = 4; 7154 else 7155 idx = spec->multiout.dac_nids[dac_idx] - 2; 7156 7157 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 7158 pin_type); 7159 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, 7160 AMP_OUT_UNMUTE); 7161 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx); 7162 7163} 7164 7165static void alc883_auto_init_multi_out(struct hda_codec *codec) 7166{ 7167 struct alc_spec *spec = codec->spec; 7168 int i; 7169 7170 alc_subsystem_id(codec, 0x15, 0x1b, 0x14); 7171 for (i = 0; i <= HDA_SIDE; i++) { 7172 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 7173 int pin_type = get_pin_type(spec->autocfg.line_out_type); 7174 if (nid) 7175 alc883_auto_set_output_and_unmute(codec, nid, pin_type, 7176 i); 7177 } 7178} 7179 7180static void alc883_auto_init_hp_out(struct hda_codec *codec) 7181{ 7182 struct alc_spec *spec = codec->spec; 7183 hda_nid_t pin; 7184 7185 pin = spec->autocfg.hp_pins[0]; 7186 if (pin) /* connect to front */ 7187 /* use dac 0 */ 7188 alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); 7189} 7190 7191#define alc883_is_input_pin(nid) alc880_is_input_pin(nid) 7192#define ALC883_PIN_CD_NID ALC880_PIN_CD_NID 7193 7194static void alc883_auto_init_analog_input(struct hda_codec *codec) 7195{ 7196 struct alc_spec *spec = codec->spec; 7197 int i; 7198 7199 for (i = 0; i < AUTO_PIN_LAST; i++) { 7200 hda_nid_t nid = spec->autocfg.input_pins[i]; 7201 if (alc883_is_input_pin(nid)) { 7202 snd_hda_codec_write(codec, nid, 0, 7203 AC_VERB_SET_PIN_WIDGET_CONTROL, 7204 (i <= AUTO_PIN_FRONT_MIC ? 7205 PIN_VREF80 : PIN_IN)); 7206 if (nid != ALC883_PIN_CD_NID) 7207 snd_hda_codec_write(codec, nid, 0, 7208 AC_VERB_SET_AMP_GAIN_MUTE, 7209 AMP_OUT_MUTE); 7210 } 7211 } 7212} 7213 7214/* almost identical with ALC880 parser... */ 7215static int alc883_parse_auto_config(struct hda_codec *codec) 7216{ 7217 struct alc_spec *spec = codec->spec; 7218 int err = alc880_parse_auto_config(codec); 7219 7220 if (err < 0) 7221 return err; 7222 else if (err > 0) 7223 /* hack - override the init verbs */ 7224 spec->init_verbs[0] = alc883_auto_init_verbs; 7225 spec->mixers[spec->num_mixers] = alc883_capture_mixer; 7226 spec->num_mixers++; 7227 return err; 7228} 7229 7230/* additional initialization for auto-configuration model */ 7231static void alc883_auto_init(struct hda_codec *codec) 7232{ 7233 alc883_auto_init_multi_out(codec); 7234 alc883_auto_init_hp_out(codec); 7235 alc883_auto_init_analog_input(codec); 7236} 7237 7238static int patch_alc883(struct hda_codec *codec) 7239{ 7240 struct alc_spec *spec; 7241 int err, board_config; 7242 7243 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 7244 if (spec == NULL) 7245 return -ENOMEM; 7246 7247 codec->spec = spec; 7248 7249 board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST, 7250 alc883_models, 7251 alc883_cfg_tbl); 7252 if (board_config < 0) { 7253 printk(KERN_INFO "hda_codec: Unknown model for ALC883, " 7254 "trying auto-probe from BIOS...\n"); 7255 board_config = ALC883_AUTO; 7256 } 7257 7258 if (board_config == ALC883_AUTO) { 7259 /* automatic parse from the BIOS config */ 7260 err = alc883_parse_auto_config(codec); 7261 if (err < 0) { 7262 alc_free(codec); 7263 return err; 7264 } else if (!err) { 7265 printk(KERN_INFO 7266 "hda_codec: Cannot set up configuration " 7267 "from BIOS. Using base mode...\n"); 7268 board_config = ALC883_3ST_2ch_DIG; 7269 } 7270 } 7271 7272 if (board_config != ALC883_AUTO) 7273 setup_preset(spec, &alc883_presets[board_config]); 7274 7275 spec->stream_name_analog = "ALC883 Analog"; 7276 spec->stream_analog_playback = &alc883_pcm_analog_playback; 7277 spec->stream_analog_capture = &alc883_pcm_analog_capture; 7278 7279 spec->stream_name_digital = "ALC883 Digital"; 7280 spec->stream_digital_playback = &alc883_pcm_digital_playback; 7281 spec->stream_digital_capture = &alc883_pcm_digital_capture; 7282 7283 if (!spec->adc_nids && spec->input_mux) { 7284 spec->adc_nids = alc883_adc_nids; 7285 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids); 7286 } 7287 7288 codec->patch_ops = alc_patch_ops; 7289 if (board_config == ALC883_AUTO) 7290 spec->init_hook = alc883_auto_init; 7291#ifdef CONFIG_SND_HDA_POWER_SAVE 7292 if (!spec->loopback.amplist) 7293 spec->loopback.amplist = alc883_loopbacks; 7294#endif 7295 7296 return 0; 7297} 7298 7299/* 7300 * ALC262 support 7301 */ 7302 7303#define ALC262_DIGOUT_NID ALC880_DIGOUT_NID 7304#define ALC262_DIGIN_NID ALC880_DIGIN_NID 7305 7306#define alc262_dac_nids alc260_dac_nids 7307#define alc262_adc_nids alc882_adc_nids 7308#define alc262_adc_nids_alt alc882_adc_nids_alt 7309 7310#define alc262_modes alc260_modes 7311#define alc262_capture_source alc882_capture_source 7312 7313static struct snd_kcontrol_new alc262_base_mixer[] = { 7314 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7315 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 7316 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 7317 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 7318 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 7319 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 7320 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7321 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7322 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 7323 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 7324 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 7325 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 7326 /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT), 7327 HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */ 7328 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT), 7329 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 7330 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 7331 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT), 7332 { } /* end */ 7333}; 7334 7335static struct snd_kcontrol_new alc262_hippo1_mixer[] = { 7336 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7337 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 7338 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 7339 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 7340 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 7341 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 7342 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7343 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7344 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 7345 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 7346 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 7347 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 7348 /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT), 7349 HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */ 7350 /*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/ 7351 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 7352 { } /* end */ 7353}; 7354 7355static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = { 7356 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7357 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT), 7358 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 7359 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 7360 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT), 7361 7362 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7363 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7364 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 7365 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 7366 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 7367 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 7368 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 7369 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 7370 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 7371 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 7372 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT), 7373 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), 7374 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT), 7375 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT), 7376 { } /* end */ 7377}; 7378 7379static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = { 7380 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7381 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 7382 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 7383 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 7384 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 7385 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT), 7386 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT), 7387 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT), 7388 HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT), 7389 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT), 7390 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT), 7391 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 7392 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 7393 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT), 7394 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), 7395 { } /* end */ 7396}; 7397 7398static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = { 7399 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7400 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7401 HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT), 7402 { } /* end */ 7403}; 7404 7405static struct hda_bind_ctls alc262_sony_bind_sw = { 7406 .ops = &snd_hda_bind_sw, 7407 .values = { 7408 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT), 7409 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 7410 0, 7411 }, 7412}; 7413 7414static struct snd_kcontrol_new alc262_sony_mixer[] = { 7415 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7416 HDA_BIND_SW("Front Playback Switch", &alc262_sony_bind_sw), 7417 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7418 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7419 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 7420 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 7421 { } /* end */ 7422}; 7423 7424static struct snd_kcontrol_new alc262_benq_t31_mixer[] = { 7425 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7426 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 7427 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 7428 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7429 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7430 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 7431 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 7432 { } /* end */ 7433}; 7434 7435#define alc262_capture_mixer alc882_capture_mixer 7436#define alc262_capture_alt_mixer alc882_capture_alt_mixer 7437 7438/* 7439 * generic initialization of ADC, input mixers and output mixers 7440 */ 7441static struct hda_verb alc262_init_verbs[] = { 7442 /* 7443 * Unmute ADC0-2 and set the default input to mic-in 7444 */ 7445 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 7446 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7447 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 7448 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7449 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 7450 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7451 7452 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 7453 * mixer widget 7454 * Note: PASD motherboards uses the Line In 2 as the input for 7455 * front panel mic (mic 2) 7456 */ 7457 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 7458 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7459 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7460 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 7461 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 7462 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 7463 7464 /* 7465 * Set up output mixers (0x0c - 0x0e) 7466 */ 7467 /* set vol=0 to output mixers */ 7468 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 7469 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 7470 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 7471 /* set up input amps for analog loopback */ 7472 /* Amp Indices: DAC = 0, mixer = 1 */ 7473 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7474 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 7475 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7476 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 7477 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7478 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 7479 7480 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 7481 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 7482 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 7483 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 7484 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 7485 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 7486 7487 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 7488 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 7489 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 7490 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 7491 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 7492 7493 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 7494 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 7495 7496 /* FIXME: use matrix-type input source selection */ 7497 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 7498 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 7499 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 7500 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 7501 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 7502 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 7503 /* Input mixer2 */ 7504 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 7505 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 7506 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 7507 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 7508 /* Input mixer3 */ 7509 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 7510 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 7511 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 7512 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 7513 7514 { } 7515}; 7516 7517static struct hda_verb alc262_hippo_unsol_verbs[] = { 7518 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 7519 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 7520 {} 7521}; 7522 7523static struct hda_verb alc262_hippo1_unsol_verbs[] = { 7524 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 7525 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 7526 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 7527 7528 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 7529 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 7530 {} 7531}; 7532 7533static struct hda_verb alc262_sony_unsol_verbs[] = { 7534 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 7535 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 7536 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic 7537 7538 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 7539 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 7540}; 7541 7542/* mute/unmute internal speaker according to the hp jack and mute state */ 7543static void alc262_hippo_automute(struct hda_codec *codec) 7544{ 7545 struct alc_spec *spec = codec->spec; 7546 unsigned int mute; 7547 unsigned int present; 7548 7549 /* need to execute and sync at first */ 7550 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0); 7551 present = snd_hda_codec_read(codec, 0x15, 0, 7552 AC_VERB_GET_PIN_SENSE, 0); 7553 spec->jack_present = (present & 0x80000000) != 0; 7554 if (spec->jack_present) { 7555 /* mute internal speaker */ 7556 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 7557 HDA_AMP_MUTE, HDA_AMP_MUTE); 7558 } else { 7559 /* unmute internal speaker if necessary */ 7560 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0); 7561 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 7562 HDA_AMP_MUTE, mute); 7563 } 7564} 7565 7566/* unsolicited event for HP jack sensing */ 7567static void alc262_hippo_unsol_event(struct hda_codec *codec, 7568 unsigned int res) 7569{ 7570 if ((res >> 26) != ALC880_HP_EVENT) 7571 return; 7572 alc262_hippo_automute(codec); 7573} 7574 7575static void alc262_hippo1_automute(struct hda_codec *codec) 7576{ 7577 unsigned int mute; 7578 unsigned int present; 7579 7580 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0); 7581 present = snd_hda_codec_read(codec, 0x1b, 0, 7582 AC_VERB_GET_PIN_SENSE, 0); 7583 present = (present & 0x80000000) != 0; 7584 if (present) { 7585 /* mute internal speaker */ 7586 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 7587 HDA_AMP_MUTE, HDA_AMP_MUTE); 7588 } else { 7589 /* unmute internal speaker if necessary */ 7590 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0); 7591 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 7592 HDA_AMP_MUTE, mute); 7593 } 7594} 7595 7596/* unsolicited event for HP jack sensing */ 7597static void alc262_hippo1_unsol_event(struct hda_codec *codec, 7598 unsigned int res) 7599{ 7600 if ((res >> 26) != ALC880_HP_EVENT) 7601 return; 7602 alc262_hippo1_automute(codec); 7603} 7604 7605/* 7606 * fujitsu model 7607 * 0x14 = headphone/spdif-out, 0x15 = internal speaker 7608 */ 7609 7610#define ALC_HP_EVENT 0x37 7611 7612static struct hda_verb alc262_fujitsu_unsol_verbs[] = { 7613 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, 7614 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 7615 {} 7616}; 7617 7618static struct hda_input_mux alc262_fujitsu_capture_source = { 7619 .num_items = 2, 7620 .items = { 7621 { "Mic", 0x0 }, 7622 { "CD", 0x4 }, 7623 }, 7624}; 7625 7626static struct hda_input_mux alc262_HP_capture_source = { 7627 .num_items = 5, 7628 .items = { 7629 { "Mic", 0x0 }, 7630 { "Front Mic", 0x3 }, 7631 { "Line", 0x2 }, 7632 { "CD", 0x4 }, 7633 { "AUX IN", 0x6 }, 7634 }, 7635}; 7636 7637/* mute/unmute internal speaker according to the hp jack and mute state */ 7638static void alc262_fujitsu_automute(struct hda_codec *codec, int force) 7639{ 7640 struct alc_spec *spec = codec->spec; 7641 unsigned int mute; 7642 7643 if (force || !spec->sense_updated) { 7644 unsigned int present; 7645 /* need to execute and sync at first */ 7646 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0); 7647 present = snd_hda_codec_read(codec, 0x14, 0, 7648 AC_VERB_GET_PIN_SENSE, 0); 7649 spec->jack_present = (present & 0x80000000) != 0; 7650 spec->sense_updated = 1; 7651 } 7652 if (spec->jack_present) { 7653 /* mute internal speaker */ 7654 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 7655 HDA_AMP_MUTE, HDA_AMP_MUTE); 7656 } else { 7657 /* unmute internal speaker if necessary */ 7658 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0); 7659 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 7660 HDA_AMP_MUTE, mute); 7661 } 7662} 7663 7664/* unsolicited event for HP jack sensing */ 7665static void alc262_fujitsu_unsol_event(struct hda_codec *codec, 7666 unsigned int res) 7667{ 7668 if ((res >> 26) != ALC_HP_EVENT) 7669 return; 7670 alc262_fujitsu_automute(codec, 1); 7671} 7672 7673/* bind volumes of both NID 0x0c and 0x0d */ 7674static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = { 7675 .ops = &snd_hda_bind_vol, 7676 .values = { 7677 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT), 7678 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT), 7679 0 7680 }, 7681}; 7682 7683/* bind hp and internal speaker mute (with plug check) */ 7684static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol, 7685 struct snd_ctl_elem_value *ucontrol) 7686{ 7687 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 7688 long *valp = ucontrol->value.integer.value; 7689 int change; 7690 7691 change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0, 7692 HDA_AMP_MUTE, 7693 valp[0] ? 0 : HDA_AMP_MUTE); 7694 change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0, 7695 HDA_AMP_MUTE, 7696 valp[1] ? 0 : HDA_AMP_MUTE); 7697 if (change) 7698 alc262_fujitsu_automute(codec, 0); 7699 return change; 7700} 7701 7702static struct snd_kcontrol_new alc262_fujitsu_mixer[] = { 7703 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol), 7704 { 7705 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 7706 .name = "Master Playback Switch", 7707 .info = snd_hda_mixer_amp_switch_info, 7708 .get = snd_hda_mixer_amp_switch_get, 7709 .put = alc262_fujitsu_master_sw_put, 7710 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 7711 }, 7712 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 7713 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 7714 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 7715 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7716 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7717 { } /* end */ 7718}; 7719 7720/* additional init verbs for Benq laptops */ 7721static struct hda_verb alc262_EAPD_verbs[] = { 7722 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 7723 {0x20, AC_VERB_SET_PROC_COEF, 0x3070}, 7724 {} 7725}; 7726 7727static struct hda_verb alc262_benq_t31_EAPD_verbs[] = { 7728 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 7729 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 7730 7731 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 7732 {0x20, AC_VERB_SET_PROC_COEF, 0x3050}, 7733 {} 7734}; 7735 7736/* add playback controls from the parsed DAC table */ 7737static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, 7738 const struct auto_pin_cfg *cfg) 7739{ 7740 hda_nid_t nid; 7741 int err; 7742 7743 spec->multiout.num_dacs = 1; /* only use one dac */ 7744 spec->multiout.dac_nids = spec->private_dac_nids; 7745 spec->multiout.dac_nids[0] = 2; 7746 7747 nid = cfg->line_out_pins[0]; 7748 if (nid) { 7749 err = add_control(spec, ALC_CTL_WIDGET_VOL, 7750 "Front Playback Volume", 7751 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT)); 7752 if (err < 0) 7753 return err; 7754 err = add_control(spec, ALC_CTL_WIDGET_MUTE, 7755 "Front Playback Switch", 7756 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); 7757 if (err < 0) 7758 return err; 7759 } 7760 7761 nid = cfg->speaker_pins[0]; 7762 if (nid) { 7763 if (nid == 0x16) { 7764 err = add_control(spec, ALC_CTL_WIDGET_VOL, 7765 "Speaker Playback Volume", 7766 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, 7767 HDA_OUTPUT)); 7768 if (err < 0) 7769 return err; 7770 err = add_control(spec, ALC_CTL_WIDGET_MUTE, 7771 "Speaker Playback Switch", 7772 HDA_COMPOSE_AMP_VAL(nid, 2, 0, 7773 HDA_OUTPUT)); 7774 if (err < 0) 7775 return err; 7776 } else { 7777 err = add_control(spec, ALC_CTL_WIDGET_MUTE, 7778 "Speaker Playback Switch", 7779 HDA_COMPOSE_AMP_VAL(nid, 3, 0, 7780 HDA_OUTPUT)); 7781 if (err < 0) 7782 return err; 7783 } 7784 } 7785 nid = cfg->hp_pins[0]; 7786 if (nid) { 7787 /* spec->multiout.hp_nid = 2; */ 7788 if (nid == 0x16) { 7789 err = add_control(spec, ALC_CTL_WIDGET_VOL, 7790 "Headphone Playback Volume", 7791 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, 7792 HDA_OUTPUT)); 7793 if (err < 0) 7794 return err; 7795 err = add_control(spec, ALC_CTL_WIDGET_MUTE, 7796 "Headphone Playback Switch", 7797 HDA_COMPOSE_AMP_VAL(nid, 2, 0, 7798 HDA_OUTPUT)); 7799 if (err < 0) 7800 return err; 7801 } else { 7802 err = add_control(spec, ALC_CTL_WIDGET_MUTE, 7803 "Headphone Playback Switch", 7804 HDA_COMPOSE_AMP_VAL(nid, 3, 0, 7805 HDA_OUTPUT)); 7806 if (err < 0) 7807 return err; 7808 } 7809 } 7810 return 0; 7811} 7812 7813/* identical with ALC880 */ 7814#define alc262_auto_create_analog_input_ctls \ 7815 alc880_auto_create_analog_input_ctls 7816 7817/* 7818 * generic initialization of ADC, input mixers and output mixers 7819 */ 7820static struct hda_verb alc262_volume_init_verbs[] = { 7821 /* 7822 * Unmute ADC0-2 and set the default input to mic-in 7823 */ 7824 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 7825 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7826 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 7827 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7828 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 7829 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7830 7831 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 7832 * mixer widget 7833 * Note: PASD motherboards uses the Line In 2 as the input for 7834 * front panel mic (mic 2) 7835 */ 7836 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 7837 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7838 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7839 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 7840 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 7841 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 7842 7843 /* 7844 * Set up output mixers (0x0c - 0x0f) 7845 */ 7846 /* set vol=0 to output mixers */ 7847 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 7848 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 7849 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 7850 7851 /* set up input amps for analog loopback */ 7852 /* Amp Indices: DAC = 0, mixer = 1 */ 7853 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7854 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 7855 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7856 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 7857 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7858 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 7859 7860 /* FIXME: use matrix-type input source selection */ 7861 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 7862 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 7863 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 7864 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 7865 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 7866 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 7867 /* Input mixer2 */ 7868 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 7869 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 7870 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 7871 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 7872 /* Input mixer3 */ 7873 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 7874 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 7875 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 7876 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 7877 7878 { } 7879}; 7880 7881static struct hda_verb alc262_HP_BPC_init_verbs[] = { 7882 /* 7883 * Unmute ADC0-2 and set the default input to mic-in 7884 */ 7885 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 7886 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7887 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 7888 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7889 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 7890 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7891 7892 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 7893 * mixer widget 7894 * Note: PASD motherboards uses the Line In 2 as the input for 7895 * front panel mic (mic 2) 7896 */ 7897 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 7898 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7899 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7900 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 7901 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 7902 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 7903 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, 7904 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, 7905 7906 /* 7907 * Set up output mixers (0x0c - 0x0e) 7908 */ 7909 /* set vol=0 to output mixers */ 7910 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 7911 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 7912 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 7913 7914 /* set up input amps for analog loopback */ 7915 /* Amp Indices: DAC = 0, mixer = 1 */ 7916 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7917 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 7918 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7919 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 7920 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7921 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 7922 7923 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 7924 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7925 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7926 7927 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7928 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7929 7930 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 7931 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 7932 7933 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 7934 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 7935 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 7936 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 7937 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 7938 7939 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, 7940 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 7941 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 7942 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, 7943 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 7944 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 7945 7946 7947 /* FIXME: use matrix-type input source selection */ 7948 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 7949 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 7950 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 7951 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, 7952 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, 7953 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, 7954 /* Input mixer2 */ 7955 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 7956 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, 7957 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, 7958 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, 7959 /* Input mixer3 */ 7960 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 7961 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, 7962 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, 7963 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, 7964 7965 { } 7966}; 7967 7968static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = { 7969 /* 7970 * Unmute ADC0-2 and set the default input to mic-in 7971 */ 7972 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 7973 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7974 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 7975 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7976 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 7977 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7978 7979 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 7980 * mixer widget 7981 * Note: PASD motherboards uses the Line In 2 as the input for front 7982 * panel mic (mic 2) 7983 */ 7984 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 7985 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7986 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7987 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 7988 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 7989 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 7990 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, 7991 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, 7992 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, 7993 /* 7994 * Set up output mixers (0x0c - 0x0e) 7995 */ 7996 /* set vol=0 to output mixers */ 7997 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 7998 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 7999 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8000 8001 /* set up input amps for analog loopback */ 8002 /* Amp Indices: DAC = 0, mixer = 1 */ 8003 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8004 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8005 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8006 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8007 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8008 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8009 8010 8011 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */ 8012 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */ 8013 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */ 8014 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */ 8015 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */ 8016 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */ 8017 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */ 8018 8019 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 8020 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 8021 8022 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 8023 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 8024 8025 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */ 8026 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 8027 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 8028 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, 8029 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 8030 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 8031 8032 /* FIXME: use matrix-type input source selection */ 8033 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 8034 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 8035 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/ 8036 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/ 8037 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/ 8038 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/ 8039 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/ 8040 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */ 8041 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/ 8042 /* Input mixer2 */ 8043 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 8044 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 8045 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, 8046 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, 8047 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, 8048 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */ 8049 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, 8050 /* Input mixer3 */ 8051 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 8052 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 8053 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, 8054 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, 8055 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, 8056 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */ 8057 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, 8058 8059 { } 8060}; 8061 8062#ifdef CONFIG_SND_HDA_POWER_SAVE 8063#define alc262_loopbacks alc880_loopbacks 8064#endif 8065 8066/* pcm configuration: identiacal with ALC880 */ 8067#define alc262_pcm_analog_playback alc880_pcm_analog_playback 8068#define alc262_pcm_analog_capture alc880_pcm_analog_capture 8069#define alc262_pcm_digital_playback alc880_pcm_digital_playback 8070#define alc262_pcm_digital_capture alc880_pcm_digital_capture 8071 8072/* 8073 * BIOS auto configuration 8074 */ 8075static int alc262_parse_auto_config(struct hda_codec *codec) 8076{ 8077 struct alc_spec *spec = codec->spec; 8078 int err; 8079 static hda_nid_t alc262_ignore[] = { 0x1d, 0 }; 8080 8081 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 8082 alc262_ignore); 8083 if (err < 0) 8084 return err; 8085 if (!spec->autocfg.line_outs) 8086 return 0; /* can't find valid BIOS pin config */ 8087 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg); 8088 if (err < 0) 8089 return err; 8090 err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg); 8091 if (err < 0) 8092 return err; 8093 8094 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 8095 8096 if (spec->autocfg.dig_out_pin) 8097 spec->multiout.dig_out_nid = ALC262_DIGOUT_NID; 8098 if (spec->autocfg.dig_in_pin) 8099 spec->dig_in_nid = ALC262_DIGIN_NID; 8100 8101 if (spec->kctl_alloc) 8102 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 8103 8104 spec->init_verbs[spec->num_init_verbs++] = alc262_volume_init_verbs; 8105 spec->num_mux_defs = 1; 8106 spec->input_mux = &spec->private_imux; 8107 8108 return 1; 8109} 8110 8111#define alc262_auto_init_multi_out alc882_auto_init_multi_out 8112#define alc262_auto_init_hp_out alc882_auto_init_hp_out 8113#define alc262_auto_init_analog_input alc882_auto_init_analog_input 8114 8115 8116/* init callback for auto-configuration model -- overriding the default init */ 8117static void alc262_auto_init(struct hda_codec *codec) 8118{ 8119 alc262_auto_init_multi_out(codec); 8120 alc262_auto_init_hp_out(codec); 8121 alc262_auto_init_analog_input(codec); 8122} 8123 8124/* 8125 * configuration and preset 8126 */ 8127static const char *alc262_models[ALC262_MODEL_LAST] = { 8128 [ALC262_BASIC] = "basic", 8129 [ALC262_HIPPO] = "hippo", 8130 [ALC262_HIPPO_1] = "hippo_1", 8131 [ALC262_FUJITSU] = "fujitsu", 8132 [ALC262_HP_BPC] = "hp-bpc", 8133 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000", 8134 [ALC262_BENQ_ED8] = "benq", 8135 [ALC262_BENQ_T31] = "benq-t31", 8136 [ALC262_SONY_ASSAMD] = "sony-assamd", 8137 [ALC262_AUTO] = "auto", 8138}; 8139 8140static struct snd_pci_quirk alc262_cfg_tbl[] = { 8141 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO), 8142 SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC), 8143 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC), 8144 SND_PCI_QUIRK(0x103c, 0x12ff, "HP xw4550", ALC262_HP_BPC), 8145 SND_PCI_QUIRK(0x103c, 0x1308, "HP xw4600", ALC262_HP_BPC), 8146 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC), 8147 SND_PCI_QUIRK(0x103c, 0x1307, "HP xw6600", ALC262_HP_BPC), 8148 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC), 8149 SND_PCI_QUIRK(0x103c, 0x1306, "HP xw8600", ALC262_HP_BPC), 8150 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL), 8151 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL), 8152 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL), 8153 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL), 8154 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF), 8155 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF), 8156 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF), 8157 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF), 8158 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO), 8159 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU), 8160 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1), 8161 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8), 8162 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31), 8163 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD), 8164 SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD), 8165 SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD), 8166 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD), 8167 {} 8168}; 8169 8170static struct alc_config_preset alc262_presets[] = { 8171 [ALC262_BASIC] = { 8172 .mixers = { alc262_base_mixer }, 8173 .init_verbs = { alc262_init_verbs }, 8174 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 8175 .dac_nids = alc262_dac_nids, 8176 .hp_nid = 0x03, 8177 .num_channel_mode = ARRAY_SIZE(alc262_modes), 8178 .channel_mode = alc262_modes, 8179 .input_mux = &alc262_capture_source, 8180 }, 8181 [ALC262_HIPPO] = { 8182 .mixers = { alc262_base_mixer }, 8183 .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs}, 8184 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 8185 .dac_nids = alc262_dac_nids, 8186 .hp_nid = 0x03, 8187 .dig_out_nid = ALC262_DIGOUT_NID, 8188 .num_channel_mode = ARRAY_SIZE(alc262_modes), 8189 .channel_mode = alc262_modes, 8190 .input_mux = &alc262_capture_source, 8191 .unsol_event = alc262_hippo_unsol_event, 8192 .init_hook = alc262_hippo_automute, 8193 }, 8194 [ALC262_HIPPO_1] = { 8195 .mixers = { alc262_hippo1_mixer }, 8196 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs}, 8197 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 8198 .dac_nids = alc262_dac_nids, 8199 .hp_nid = 0x02, 8200 .dig_out_nid = ALC262_DIGOUT_NID, 8201 .num_channel_mode = ARRAY_SIZE(alc262_modes), 8202 .channel_mode = alc262_modes, 8203 .input_mux = &alc262_capture_source, 8204 .unsol_event = alc262_hippo1_unsol_event, 8205 .init_hook = alc262_hippo1_automute, 8206 }, 8207 [ALC262_FUJITSU] = { 8208 .mixers = { alc262_fujitsu_mixer }, 8209 .init_verbs = { alc262_init_verbs, alc262_fujitsu_unsol_verbs }, 8210 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 8211 .dac_nids = alc262_dac_nids, 8212 .hp_nid = 0x03, 8213 .dig_out_nid = ALC262_DIGOUT_NID, 8214 .num_channel_mode = ARRAY_SIZE(alc262_modes), 8215 .channel_mode = alc262_modes, 8216 .input_mux = &alc262_fujitsu_capture_source, 8217 .unsol_event = alc262_fujitsu_unsol_event, 8218 }, 8219 [ALC262_HP_BPC] = { 8220 .mixers = { alc262_HP_BPC_mixer }, 8221 .init_verbs = { alc262_HP_BPC_init_verbs }, 8222 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 8223 .dac_nids = alc262_dac_nids, 8224 .hp_nid = 0x03, 8225 .num_channel_mode = ARRAY_SIZE(alc262_modes), 8226 .channel_mode = alc262_modes, 8227 .input_mux = &alc262_HP_capture_source, 8228 }, 8229 [ALC262_HP_BPC_D7000_WF] = { 8230 .mixers = { alc262_HP_BPC_WildWest_mixer }, 8231 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs }, 8232 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 8233 .dac_nids = alc262_dac_nids, 8234 .hp_nid = 0x03, 8235 .num_channel_mode = ARRAY_SIZE(alc262_modes), 8236 .channel_mode = alc262_modes, 8237 .input_mux = &alc262_HP_capture_source, 8238 }, 8239 [ALC262_HP_BPC_D7000_WL] = { 8240 .mixers = { alc262_HP_BPC_WildWest_mixer, 8241 alc262_HP_BPC_WildWest_option_mixer }, 8242 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs }, 8243 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 8244 .dac_nids = alc262_dac_nids, 8245 .hp_nid = 0x03, 8246 .num_channel_mode = ARRAY_SIZE(alc262_modes), 8247 .channel_mode = alc262_modes, 8248 .input_mux = &alc262_HP_capture_source, 8249 }, 8250 [ALC262_BENQ_ED8] = { 8251 .mixers = { alc262_base_mixer }, 8252 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs }, 8253 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 8254 .dac_nids = alc262_dac_nids, 8255 .hp_nid = 0x03, 8256 .num_channel_mode = ARRAY_SIZE(alc262_modes), 8257 .channel_mode = alc262_modes, 8258 .input_mux = &alc262_capture_source, 8259 }, 8260 [ALC262_SONY_ASSAMD] = { 8261 .mixers = { alc262_sony_mixer }, 8262 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs}, 8263 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 8264 .dac_nids = alc262_dac_nids, 8265 .hp_nid = 0x02, 8266 .num_channel_mode = ARRAY_SIZE(alc262_modes), 8267 .channel_mode = alc262_modes, 8268 .input_mux = &alc262_capture_source, 8269 .unsol_event = alc262_hippo_unsol_event, 8270 .init_hook = alc262_hippo_automute, 8271 }, 8272 [ALC262_BENQ_T31] = { 8273 .mixers = { alc262_benq_t31_mixer }, 8274 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs }, 8275 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 8276 .dac_nids = alc262_dac_nids, 8277 .hp_nid = 0x03, 8278 .num_channel_mode = ARRAY_SIZE(alc262_modes), 8279 .channel_mode = alc262_modes, 8280 .input_mux = &alc262_capture_source, 8281 .unsol_event = alc262_hippo_unsol_event, 8282 .init_hook = alc262_hippo_automute, 8283 }, 8284}; 8285 8286static int patch_alc262(struct hda_codec *codec) 8287{ 8288 struct alc_spec *spec; 8289 int board_config; 8290 int err; 8291 8292 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 8293 if (spec == NULL) 8294 return -ENOMEM; 8295 8296 codec->spec = spec; 8297#if 0 8298 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is 8299 * under-run 8300 */ 8301 { 8302 int tmp; 8303 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7); 8304 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0); 8305 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7); 8306 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80); 8307 } 8308#endif 8309 8310 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST, 8311 alc262_models, 8312 alc262_cfg_tbl); 8313 8314 if (board_config < 0) { 8315 printk(KERN_INFO "hda_codec: Unknown model for ALC262, " 8316 "trying auto-probe from BIOS...\n"); 8317 board_config = ALC262_AUTO; 8318 } 8319 8320 if (board_config == ALC262_AUTO) { 8321 /* automatic parse from the BIOS config */ 8322 err = alc262_parse_auto_config(codec); 8323 if (err < 0) { 8324 alc_free(codec); 8325 return err; 8326 } else if (!err) { 8327 printk(KERN_INFO 8328 "hda_codec: Cannot set up configuration " 8329 "from BIOS. Using base mode...\n"); 8330 board_config = ALC262_BASIC; 8331 } 8332 } 8333 8334 if (board_config != ALC262_AUTO) 8335 setup_preset(spec, &alc262_presets[board_config]); 8336 8337 spec->stream_name_analog = "ALC262 Analog"; 8338 spec->stream_analog_playback = &alc262_pcm_analog_playback; 8339 spec->stream_analog_capture = &alc262_pcm_analog_capture; 8340 8341 spec->stream_name_digital = "ALC262 Digital"; 8342 spec->stream_digital_playback = &alc262_pcm_digital_playback; 8343 spec->stream_digital_capture = &alc262_pcm_digital_capture; 8344 8345 if (!spec->adc_nids && spec->input_mux) { 8346 /* check whether NID 0x07 is valid */ 8347 unsigned int wcap = get_wcaps(codec, 0x07); 8348 8349 /* get type */ 8350 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; 8351 if (wcap != AC_WID_AUD_IN) { 8352 spec->adc_nids = alc262_adc_nids_alt; 8353 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt); 8354 spec->mixers[spec->num_mixers] = 8355 alc262_capture_alt_mixer; 8356 spec->num_mixers++; 8357 } else { 8358 spec->adc_nids = alc262_adc_nids; 8359 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids); 8360 spec->mixers[spec->num_mixers] = alc262_capture_mixer; 8361 spec->num_mixers++; 8362 } 8363 } 8364 8365 codec->patch_ops = alc_patch_ops; 8366 if (board_config == ALC262_AUTO) 8367 spec->init_hook = alc262_auto_init; 8368#ifdef CONFIG_SND_HDA_POWER_SAVE 8369 if (!spec->loopback.amplist) 8370 spec->loopback.amplist = alc262_loopbacks; 8371#endif 8372 8373 return 0; 8374} 8375 8376/* 8377 * ALC268 channel source setting (2 channel) 8378 */ 8379#define ALC268_DIGOUT_NID ALC880_DIGOUT_NID 8380#define alc268_modes alc260_modes 8381 8382static hda_nid_t alc268_dac_nids[2] = { 8383 /* front, hp */ 8384 0x02, 0x03 8385}; 8386 8387static hda_nid_t alc268_adc_nids[2] = { 8388 /* ADC0-1 */ 8389 0x08, 0x07 8390}; 8391 8392static hda_nid_t alc268_adc_nids_alt[1] = { 8393 /* ADC0 */ 8394 0x08 8395}; 8396 8397static struct snd_kcontrol_new alc268_base_mixer[] = { 8398 /* output mixer control */ 8399 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), 8400 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 8401 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT), 8402 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 8403 { } 8404}; 8405 8406static struct hda_verb alc268_eapd_verbs[] = { 8407 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 8408 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, 8409 { } 8410}; 8411 8412/* Toshiba specific */ 8413#define alc268_toshiba_automute alc262_hippo_automute 8414 8415static struct hda_verb alc268_toshiba_verbs[] = { 8416 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 8417 { } /* end */ 8418}; 8419 8420/* Acer specific */ 8421/* bind volumes of both NID 0x0c and 0x0d */ 8422static struct hda_bind_ctls alc268_acer_bind_master_vol = { 8423 .ops = &snd_hda_bind_vol, 8424 .values = { 8425 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), 8426 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT), 8427 0 8428 }, 8429}; 8430 8431#define alc268_acer_master_sw_put alc262_fujitsu_master_sw_put 8432#define alc268_acer_automute alc262_fujitsu_automute 8433 8434static struct snd_kcontrol_new alc268_acer_mixer[] = { 8435 /* output mixer control */ 8436 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), 8437 { 8438 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 8439 .name = "Master Playback Switch", 8440 .info = snd_hda_mixer_amp_switch_info, 8441 .get = snd_hda_mixer_amp_switch_get, 8442 .put = alc268_acer_master_sw_put, 8443 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 8444 }, 8445 { } 8446}; 8447 8448static struct hda_verb alc268_acer_verbs[] = { 8449 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8450 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8451 8452 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 8453 { } 8454}; 8455 8456/* unsolicited event for HP jack sensing */ 8457static void alc268_toshiba_unsol_event(struct hda_codec *codec, 8458 unsigned int res) 8459{ 8460 if ((res >> 28) != ALC880_HP_EVENT) 8461 return; 8462 alc268_toshiba_automute(codec); 8463} 8464 8465static void alc268_acer_unsol_event(struct hda_codec *codec, 8466 unsigned int res) 8467{ 8468 if ((res >> 28) != ALC880_HP_EVENT) 8469 return; 8470 alc268_acer_automute(codec, 1); 8471} 8472 8473/* 8474 * generic initialization of ADC, input mixers and output mixers 8475 */ 8476static struct hda_verb alc268_base_init_verbs[] = { 8477 /* Unmute DAC0-1 and set vol = 0 */ 8478 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8479 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8480 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8481 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8482 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8483 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8484 8485 /* 8486 * Set up output mixers (0x0c - 0x0e) 8487 */ 8488 /* set vol=0 to output mixers */ 8489 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8490 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8491 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8492 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00}, 8493 8494 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8495 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8496 8497 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 8498 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 8499 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 8500 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 8501 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 8502 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 8503 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 8504 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 8505 8506 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8507 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8508 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8509 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8510 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8511 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8512 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8513 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 8514 8515 /* FIXME: use matrix-type input source selection */ 8516 /* Mixer elements: 0x18, 19, 1a, 1c, 14, 15, 0b */ 8517 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 8518 /* Input mixer2 */ 8519 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 8520 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 8521 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, 8522 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, 8523 8524 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 8525 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 8526 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, 8527 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, 8528 { } 8529}; 8530 8531/* 8532 * generic initialization of ADC, input mixers and output mixers 8533 */ 8534static struct hda_verb alc268_volume_init_verbs[] = { 8535 /* set output DAC */ 8536 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8537 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8538 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8539 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8540 8541 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 8542 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 8543 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 8544 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 8545 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 8546 8547 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8548 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8549 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8550 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8551 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8552 8553 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8554 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8555 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8556 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8557 8558 /* set PCBEEP vol = 0 */ 8559 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, (0xb000 | (0x00 << 8))}, 8560 8561 { } 8562}; 8563 8564#define alc268_mux_enum_info alc_mux_enum_info 8565#define alc268_mux_enum_get alc_mux_enum_get 8566 8567static int alc268_mux_enum_put(struct snd_kcontrol *kcontrol, 8568 struct snd_ctl_elem_value *ucontrol) 8569{ 8570 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 8571 struct alc_spec *spec = codec->spec; 8572 const struct hda_input_mux *imux = spec->input_mux; 8573 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 8574 static hda_nid_t capture_mixers[3] = { 0x23, 0x24 }; 8575 hda_nid_t nid = capture_mixers[adc_idx]; 8576 unsigned int *cur_val = &spec->cur_mux[adc_idx]; 8577 unsigned int i, idx; 8578 8579 idx = ucontrol->value.enumerated.item[0]; 8580 if (idx >= imux->num_items) 8581 idx = imux->num_items - 1; 8582 if (*cur_val == idx) 8583 return 0; 8584 for (i = 0; i < imux->num_items; i++) { 8585 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE; 8586 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 8587 imux->items[i].index, 8588 HDA_AMP_MUTE, v); 8589 snd_hda_codec_write_cache(codec, nid, 0, 8590 AC_VERB_SET_CONNECT_SEL, 8591 idx ); 8592 } 8593 *cur_val = idx; 8594 return 1; 8595} 8596 8597static struct snd_kcontrol_new alc268_capture_alt_mixer[] = { 8598 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT), 8599 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT), 8600 { 8601 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 8602 /* The multiple "Capture Source" controls confuse alsamixer 8603 * So call somewhat different.. 8604 * FIXME: the controls appear in the "playback" view! 8605 */ 8606 /* .name = "Capture Source", */ 8607 .name = "Input Source", 8608 .count = 1, 8609 .info = alc268_mux_enum_info, 8610 .get = alc268_mux_enum_get, 8611 .put = alc268_mux_enum_put, 8612 }, 8613 { } /* end */ 8614}; 8615 8616static struct snd_kcontrol_new alc268_capture_mixer[] = { 8617 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT), 8618 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT), 8619 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT), 8620 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT), 8621 { 8622 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 8623 /* The multiple "Capture Source" controls confuse alsamixer 8624 * So call somewhat different.. 8625 * FIXME: the controls appear in the "playback" view! 8626 */ 8627 /* .name = "Capture Source", */ 8628 .name = "Input Source", 8629 .count = 2, 8630 .info = alc268_mux_enum_info, 8631 .get = alc268_mux_enum_get, 8632 .put = alc268_mux_enum_put, 8633 }, 8634 { } /* end */ 8635}; 8636 8637static struct hda_input_mux alc268_capture_source = { 8638 .num_items = 4, 8639 .items = { 8640 { "Mic", 0x0 }, 8641 { "Front Mic", 0x1 }, 8642 { "Line", 0x2 }, 8643 { "CD", 0x3 }, 8644 }, 8645}; 8646 8647/* create input playback/capture controls for the given pin */ 8648static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid, 8649 const char *ctlname, int idx) 8650{ 8651 char name[32]; 8652 int err; 8653 8654 sprintf(name, "%s Playback Volume", ctlname); 8655 if (nid == 0x14) { 8656 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, 8657 HDA_COMPOSE_AMP_VAL(0x02, 3, idx, 8658 HDA_OUTPUT)); 8659 if (err < 0) 8660 return err; 8661 } else if (nid == 0x15) { 8662 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, 8663 HDA_COMPOSE_AMP_VAL(0x03, 3, idx, 8664 HDA_OUTPUT)); 8665 if (err < 0) 8666 return err; 8667 } else 8668 return -1; 8669 sprintf(name, "%s Playback Switch", ctlname); 8670 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, 8671 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT)); 8672 if (err < 0) 8673 return err; 8674 return 0; 8675} 8676 8677/* add playback controls from the parsed DAC table */ 8678static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec, 8679 const struct auto_pin_cfg *cfg) 8680{ 8681 hda_nid_t nid; 8682 int err; 8683 8684 spec->multiout.num_dacs = 2; /* only use one dac */ 8685 spec->multiout.dac_nids = spec->private_dac_nids; 8686 spec->multiout.dac_nids[0] = 2; 8687 spec->multiout.dac_nids[1] = 3; 8688 8689 nid = cfg->line_out_pins[0]; 8690 if (nid) 8691 alc268_new_analog_output(spec, nid, "Front", 0); 8692 8693 nid = cfg->speaker_pins[0]; 8694 if (nid == 0x1d) { 8695 err = add_control(spec, ALC_CTL_WIDGET_VOL, 8696 "Speaker Playback Volume", 8697 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT)); 8698 if (err < 0) 8699 return err; 8700 } 8701 nid = cfg->hp_pins[0]; 8702 if (nid) 8703 alc268_new_analog_output(spec, nid, "Headphone", 0); 8704 8705 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2]; 8706 if (nid == 0x16) { 8707 err = add_control(spec, ALC_CTL_WIDGET_MUTE, 8708 "Mono Playback Switch", 8709 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT)); 8710 if (err < 0) 8711 return err; 8712 } 8713 return 0; 8714} 8715 8716/* create playback/capture controls for input pins */ 8717static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec, 8718 const struct auto_pin_cfg *cfg) 8719{ 8720 struct hda_input_mux *imux = &spec->private_imux; 8721 int i, idx1; 8722 8723 for (i = 0; i < AUTO_PIN_LAST; i++) { 8724 switch(cfg->input_pins[i]) { 8725 case 0x18: 8726 idx1 = 0; /* Mic 1 */ 8727 break; 8728 case 0x19: 8729 idx1 = 1; /* Mic 2 */ 8730 break; 8731 case 0x1a: 8732 idx1 = 2; /* Line In */ 8733 break; 8734 case 0x1c: 8735 idx1 = 3; /* CD */ 8736 break; 8737 default: 8738 continue; 8739 } 8740 imux->items[imux->num_items].label = auto_pin_cfg_labels[i]; 8741 imux->items[imux->num_items].index = idx1; 8742 imux->num_items++; 8743 } 8744 return 0; 8745} 8746 8747static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec) 8748{ 8749 struct alc_spec *spec = codec->spec; 8750 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0]; 8751 hda_nid_t hp_nid = spec->autocfg.hp_pins[0]; 8752 hda_nid_t line_nid = spec->autocfg.line_out_pins[0]; 8753 unsigned int dac_vol1, dac_vol2; 8754 8755 if (speaker_nid) { 8756 snd_hda_codec_write(codec, speaker_nid, 0, 8757 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); 8758 snd_hda_codec_write(codec, 0x0f, 0, 8759 AC_VERB_SET_AMP_GAIN_MUTE, 8760 AMP_IN_UNMUTE(1)); 8761 snd_hda_codec_write(codec, 0x10, 0, 8762 AC_VERB_SET_AMP_GAIN_MUTE, 8763 AMP_IN_UNMUTE(1)); 8764 } else { 8765 snd_hda_codec_write(codec, 0x0f, 0, 8766 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)); 8767 snd_hda_codec_write(codec, 0x10, 0, 8768 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)); 8769 } 8770 8771 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */ 8772 if (line_nid == 0x14) 8773 dac_vol2 = AMP_OUT_ZERO; 8774 else if (line_nid == 0x15) 8775 dac_vol1 = AMP_OUT_ZERO; 8776 if (hp_nid == 0x14) 8777 dac_vol2 = AMP_OUT_ZERO; 8778 else if (hp_nid == 0x15) 8779 dac_vol1 = AMP_OUT_ZERO; 8780 if (line_nid != 0x16 || hp_nid != 0x16 || 8781 spec->autocfg.line_out_pins[1] != 0x16 || 8782 spec->autocfg.line_out_pins[2] != 0x16) 8783 dac_vol1 = dac_vol2 = AMP_OUT_ZERO; 8784 8785 snd_hda_codec_write(codec, 0x02, 0, 8786 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1); 8787 snd_hda_codec_write(codec, 0x03, 0, 8788 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2); 8789} 8790 8791/* pcm configuration: identiacal with ALC880 */ 8792#define alc268_pcm_analog_playback alc880_pcm_analog_playback 8793#define alc268_pcm_analog_capture alc880_pcm_analog_capture 8794#define alc268_pcm_digital_playback alc880_pcm_digital_playback 8795 8796/* 8797 * BIOS auto configuration 8798 */ 8799static int alc268_parse_auto_config(struct hda_codec *codec) 8800{ 8801 struct alc_spec *spec = codec->spec; 8802 int err; 8803 static hda_nid_t alc268_ignore[] = { 0 }; 8804 8805 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 8806 alc268_ignore); 8807 if (err < 0) 8808 return err; 8809 if (!spec->autocfg.line_outs) 8810 return 0; /* can't find valid BIOS pin config */ 8811 8812 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg); 8813 if (err < 0) 8814 return err; 8815 err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg); 8816 if (err < 0) 8817 return err; 8818 8819 spec->multiout.max_channels = 2; 8820 8821 /* digital only support output */ 8822 if (spec->autocfg.dig_out_pin) 8823 spec->multiout.dig_out_nid = ALC268_DIGOUT_NID; 8824 8825 if (spec->kctl_alloc) 8826 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 8827 8828 spec->init_verbs[spec->num_init_verbs++] = alc268_volume_init_verbs; 8829 spec->num_mux_defs = 1; 8830 spec->input_mux = &spec->private_imux; 8831 8832 return 1; 8833} 8834 8835#define alc268_auto_init_multi_out alc882_auto_init_multi_out 8836#define alc268_auto_init_hp_out alc882_auto_init_hp_out 8837#define alc268_auto_init_analog_input alc882_auto_init_analog_input 8838 8839/* init callback for auto-configuration model -- overriding the default init */ 8840static void alc268_auto_init(struct hda_codec *codec) 8841{ 8842 alc268_auto_init_multi_out(codec); 8843 alc268_auto_init_hp_out(codec); 8844 alc268_auto_init_mono_speaker_out(codec); 8845 alc268_auto_init_analog_input(codec); 8846} 8847 8848/* 8849 * configuration and preset 8850 */ 8851static const char *alc268_models[ALC268_MODEL_LAST] = { 8852 [ALC268_3ST] = "3stack", 8853 [ALC268_TOSHIBA] = "toshiba", 8854 [ALC268_ACER] = "acer", 8855 [ALC268_AUTO] = "auto", 8856}; 8857 8858static struct snd_pci_quirk alc268_cfg_tbl[] = { 8859 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST), 8860 SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA), 8861 SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA), 8862 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER), 8863 {} 8864}; 8865 8866static struct alc_config_preset alc268_presets[] = { 8867 [ALC268_3ST] = { 8868 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer }, 8869 .init_verbs = { alc268_base_init_verbs }, 8870 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 8871 .dac_nids = alc268_dac_nids, 8872 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 8873 .adc_nids = alc268_adc_nids_alt, 8874 .hp_nid = 0x03, 8875 .dig_out_nid = ALC268_DIGOUT_NID, 8876 .num_channel_mode = ARRAY_SIZE(alc268_modes), 8877 .channel_mode = alc268_modes, 8878 .input_mux = &alc268_capture_source, 8879 }, 8880 [ALC268_TOSHIBA] = { 8881 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer }, 8882 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 8883 alc268_toshiba_verbs }, 8884 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 8885 .dac_nids = alc268_dac_nids, 8886 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 8887 .adc_nids = alc268_adc_nids_alt, 8888 .hp_nid = 0x03, 8889 .num_channel_mode = ARRAY_SIZE(alc268_modes), 8890 .channel_mode = alc268_modes, 8891 .input_mux = &alc268_capture_source, 8892 .input_mux = &alc268_capture_source, 8893 .unsol_event = alc268_toshiba_unsol_event, 8894 .init_hook = alc268_toshiba_automute, 8895 }, 8896 [ALC268_ACER] = { 8897 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer }, 8898 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 8899 alc268_acer_verbs }, 8900 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 8901 .dac_nids = alc268_dac_nids, 8902 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 8903 .adc_nids = alc268_adc_nids_alt, 8904 .hp_nid = 0x02, 8905 .num_channel_mode = ARRAY_SIZE(alc268_modes), 8906 .channel_mode = alc268_modes, 8907 .input_mux = &alc268_capture_source, 8908 .unsol_event = alc268_acer_unsol_event, 8909 }, 8910}; 8911 8912static int patch_alc268(struct hda_codec *codec) 8913{ 8914 struct alc_spec *spec; 8915 int board_config; 8916 int err; 8917 8918 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); 8919 if (spec == NULL) 8920 return -ENOMEM; 8921 8922 codec->spec = spec; 8923 8924 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST, 8925 alc268_models, 8926 alc268_cfg_tbl); 8927 8928 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) { 8929 printk(KERN_INFO "hda_codec: Unknown model for ALC268, " 8930 "trying auto-probe from BIOS...\n"); 8931 board_config = ALC268_AUTO; 8932 } 8933 8934 if (board_config == ALC268_AUTO) { 8935 /* automatic parse from the BIOS config */ 8936 err = alc268_parse_auto_config(codec); 8937 if (err < 0) { 8938 alc_free(codec); 8939 return err; 8940 } else if (!err) { 8941 printk(KERN_INFO 8942 "hda_codec: Cannot set up configuration " 8943 "from BIOS. Using base mode...\n"); 8944 board_config = ALC268_3ST; 8945 } 8946 } 8947 8948 if (board_config != ALC268_AUTO) 8949 setup_preset(spec, &alc268_presets[board_config]); 8950 8951 spec->stream_name_analog = "ALC268 Analog"; 8952 spec->stream_analog_playback = &alc268_pcm_analog_playback; 8953 spec->stream_analog_capture = &alc268_pcm_analog_capture; 8954 8955 spec->stream_name_digital = "ALC268 Digital"; 8956 spec->stream_digital_playback = &alc268_pcm_digital_playback; 8957 8958 if (board_config == ALC268_AUTO) { 8959 if (!spec->adc_nids && spec->input_mux) { 8960 /* check whether NID 0x07 is valid */ 8961 unsigned int wcap = get_wcaps(codec, 0x07); 8962 8963 /* get type */ 8964 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; 8965 if (wcap != AC_WID_AUD_IN) { 8966 spec->adc_nids = alc268_adc_nids_alt; 8967 spec->num_adc_nids = 8968 ARRAY_SIZE(alc268_adc_nids_alt); 8969 spec->mixers[spec->num_mixers] = 8970 alc268_capture_alt_mixer; 8971 spec->num_mixers++; 8972 } else { 8973 spec->adc_nids = alc268_adc_nids; 8974 spec->num_adc_nids = 8975 ARRAY_SIZE(alc268_adc_nids); 8976 spec->mixers[spec->num_mixers] = 8977 alc268_capture_mixer; 8978 spec->num_mixers++; 8979 } 8980 } 8981 } 8982 codec->patch_ops = alc_patch_ops; 8983 if (board_config == ALC268_AUTO) 8984 spec->init_hook = alc268_auto_init; 8985 8986 return 0; 8987} 8988 8989/* 8990 * ALC861 channel source setting (2/6 channel selection for 3-stack) 8991 */ 8992 8993/* 8994 * set the path ways for 2 channel output 8995 * need to set the codec line out and mic 1 pin widgets to inputs 8996 */ 8997static struct hda_verb alc861_threestack_ch2_init[] = { 8998 /* set pin widget 1Ah (line in) for input */ 8999 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 9000 /* set pin widget 18h (mic1/2) for input, for mic also enable 9001 * the vref 9002 */ 9003 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 9004 9005 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, 9006#if 0 9007 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/ 9008 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/ 9009#endif 9010 { } /* end */ 9011}; 9012/* 9013 * 6ch mode 9014 * need to set the codec line out and mic 1 pin widgets to outputs 9015 */ 9016static struct hda_verb alc861_threestack_ch6_init[] = { 9017 /* set pin widget 1Ah (line in) for output (Back Surround)*/ 9018 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 9019 /* set pin widget 18h (mic1) for output (CLFE)*/ 9020 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 9021 9022 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 }, 9023 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 }, 9024 9025 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 }, 9026#if 0 9027 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/ 9028 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/ 9029#endif 9030 { } /* end */ 9031}; 9032 9033static struct hda_channel_mode alc861_threestack_modes[2] = { 9034 { 2, alc861_threestack_ch2_init }, 9035 { 6, alc861_threestack_ch6_init }, 9036}; 9037/* Set mic1 as input and unmute the mixer */ 9038static struct hda_verb alc861_uniwill_m31_ch2_init[] = { 9039 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 9040 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/ 9041 { } /* end */ 9042}; 9043/* Set mic1 as output and mute mixer */ 9044static struct hda_verb alc861_uniwill_m31_ch4_init[] = { 9045 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 9046 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/ 9047 { } /* end */ 9048}; 9049 9050static struct hda_channel_mode alc861_uniwill_m31_modes[2] = { 9051 { 2, alc861_uniwill_m31_ch2_init }, 9052 { 4, alc861_uniwill_m31_ch4_init }, 9053}; 9054 9055/* Set mic1 and line-in as input and unmute the mixer */ 9056static struct hda_verb alc861_asus_ch2_init[] = { 9057 /* set pin widget 1Ah (line in) for input */ 9058 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 9059 /* set pin widget 18h (mic1/2) for input, for mic also enable 9060 * the vref 9061 */ 9062 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 9063 9064 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, 9065#if 0 9066 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/ 9067 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/ 9068#endif 9069 { } /* end */ 9070}; 9071/* Set mic1 nad line-in as output and mute mixer */ 9072static struct hda_verb alc861_asus_ch6_init[] = { 9073 /* set pin widget 1Ah (line in) for output (Back Surround)*/ 9074 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 9075 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */ 9076 /* set pin widget 18h (mic1) for output (CLFE)*/ 9077 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 9078 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */ 9079 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 }, 9080 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 }, 9081 9082 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 }, 9083#if 0 9084 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/ 9085 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/ 9086#endif 9087 { } /* end */ 9088}; 9089 9090static struct hda_channel_mode alc861_asus_modes[2] = { 9091 { 2, alc861_asus_ch2_init }, 9092 { 6, alc861_asus_ch6_init }, 9093}; 9094 9095/* patch-ALC861 */ 9096 9097static struct snd_kcontrol_new alc861_base_mixer[] = { 9098 /* output mixer control */ 9099 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), 9100 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), 9101 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT), 9102 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT), 9103 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), 9104 9105 /*Input mixer control */ 9106 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT), 9107 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */ 9108 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), 9109 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), 9110 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT), 9111 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT), 9112 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), 9113 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), 9114 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), 9115 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT), 9116 9117 /* Capture mixer control */ 9118 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 9119 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 9120 { 9121 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 9122 .name = "Capture Source", 9123 .count = 1, 9124 .info = alc_mux_enum_info, 9125 .get = alc_mux_enum_get, 9126 .put = alc_mux_enum_put, 9127 }, 9128 { } /* end */ 9129}; 9130 9131static struct snd_kcontrol_new alc861_3ST_mixer[] = { 9132 /* output mixer control */ 9133 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), 9134 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), 9135 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT), 9136 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT), 9137 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */ 9138 9139 /* Input mixer control */ 9140 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT), 9141 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */ 9142 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), 9143 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), 9144 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT), 9145 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT), 9146 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), 9147 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), 9148 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), 9149 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT), 9150 9151 /* Capture mixer control */ 9152 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 9153 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 9154 { 9155 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 9156 .name = "Capture Source", 9157 .count = 1, 9158 .info = alc_mux_enum_info, 9159 .get = alc_mux_enum_get, 9160 .put = alc_mux_enum_put, 9161 }, 9162 { 9163 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 9164 .name = "Channel Mode", 9165 .info = alc_ch_mode_info, 9166 .get = alc_ch_mode_get, 9167 .put = alc_ch_mode_put, 9168 .private_value = ARRAY_SIZE(alc861_threestack_modes), 9169 }, 9170 { } /* end */ 9171}; 9172 9173static struct snd_kcontrol_new alc861_toshiba_mixer[] = { 9174 /* output mixer control */ 9175 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT), 9176 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), 9177 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), 9178 9179 /*Capture mixer control */ 9180 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 9181 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 9182 { 9183 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 9184 .name = "Capture Source", 9185 .count = 1, 9186 .info = alc_mux_enum_info, 9187 .get = alc_mux_enum_get, 9188 .put = alc_mux_enum_put, 9189 }, 9190 9191 { } /* end */ 9192}; 9193 9194static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = { 9195 /* output mixer control */ 9196 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), 9197 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), 9198 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT), 9199 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT), 9200 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */ 9201 9202 /* Input mixer control */ 9203 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT), 9204 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */ 9205 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), 9206 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), 9207 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT), 9208 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT), 9209 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), 9210 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), 9211 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), 9212 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT), 9213 9214 /* Capture mixer control */ 9215 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 9216 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 9217 { 9218 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 9219 .name = "Capture Source", 9220 .count = 1, 9221 .info = alc_mux_enum_info, 9222 .get = alc_mux_enum_get, 9223 .put = alc_mux_enum_put, 9224 }, 9225 { 9226 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 9227 .name = "Channel Mode", 9228 .info = alc_ch_mode_info, 9229 .get = alc_ch_mode_get, 9230 .put = alc_ch_mode_put, 9231 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes), 9232 }, 9233 { } /* end */ 9234}; 9235 9236static struct snd_kcontrol_new alc861_asus_mixer[] = { 9237 /* output mixer control */ 9238 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), 9239 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), 9240 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT), 9241 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT), 9242 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), 9243 9244 /* Input mixer control */ 9245 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT), 9246 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), 9247 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), 9248 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), 9249 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT), 9250 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT), 9251 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), 9252 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), 9253 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), 9254 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT), 9255 9256 /* Capture mixer control */ 9257 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 9258 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 9259 { 9260 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 9261 .name = "Capture Source", 9262 .count = 1, 9263 .info = alc_mux_enum_info, 9264 .get = alc_mux_enum_get, 9265 .put = alc_mux_enum_put, 9266 }, 9267 { 9268 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 9269 .name = "Channel Mode", 9270 .info = alc_ch_mode_info, 9271 .get = alc_ch_mode_get, 9272 .put = alc_ch_mode_put, 9273 .private_value = ARRAY_SIZE(alc861_asus_modes), 9274 }, 9275 { } 9276}; 9277 9278/* additional mixer */ 9279static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = { 9280 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), 9281 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), 9282 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x23, 0x0, HDA_OUTPUT), 9283 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x23, 0x0, HDA_OUTPUT), 9284 { } 9285}; 9286 9287/* 9288 * generic initialization of ADC, input mixers and output mixers 9289 */ 9290static struct hda_verb alc861_base_init_verbs[] = { 9291 /* 9292 * Unmute ADC0 and set the default input to mic-in 9293 */ 9294 /* port-A for surround (rear panel) */ 9295 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 9296 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 }, 9297 /* port-B for mic-in (rear panel) with vref */ 9298 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 9299 /* port-C for line-in (rear panel) */ 9300 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 9301 /* port-D for Front */ 9302 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 9303 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 }, 9304 /* port-E for HP out (front panel) */ 9305 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, 9306 /* route front PCM to HP */ 9307 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, 9308 /* port-F for mic-in (front panel) with vref */ 9309 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 9310 /* port-G for CLFE (rear panel) */ 9311 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 9312 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 }, 9313 /* port-H for side (rear panel) */ 9314 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 9315 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 }, 9316 /* CD-in */ 9317 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 9318 /* route front mic to ADC1*/ 9319 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 9320 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9321 9322 /* Unmute DAC0~3 & spdif out*/ 9323 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9324 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9325 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9326 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9327 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9328 9329 /* Unmute Mixer 14 (mic) 1c (Line in)*/ 9330 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9331 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9332 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9333 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9334 9335 /* Unmute Stereo Mixer 15 */ 9336 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9337 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9338 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 9339 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */ 9340 9341 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9342 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9343 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9344 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9345 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9346 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9347 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9348 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9349 /* hp used DAC 3 (Front) */ 9350 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 9351 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 9352 9353 { } 9354}; 9355 9356static struct hda_verb alc861_threestack_init_verbs[] = { 9357 /* 9358 * Unmute ADC0 and set the default input to mic-in 9359 */ 9360 /* port-A for surround (rear panel) */ 9361 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 9362 /* port-B for mic-in (rear panel) with vref */ 9363 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 9364 /* port-C for line-in (rear panel) */ 9365 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 9366 /* port-D for Front */ 9367 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 9368 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 }, 9369 /* port-E for HP out (front panel) */ 9370 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, 9371 /* route front PCM to HP */ 9372 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, 9373 /* port-F for mic-in (front panel) with vref */ 9374 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 9375 /* port-G for CLFE (rear panel) */ 9376 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 9377 /* port-H for side (rear panel) */ 9378 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 9379 /* CD-in */ 9380 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 9381 /* route front mic to ADC1*/ 9382 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 9383 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9384 /* Unmute DAC0~3 & spdif out*/ 9385 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9386 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9387 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9388 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9389 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9390 9391 /* Unmute Mixer 14 (mic) 1c (Line in)*/ 9392 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9393 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9394 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9395 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9396 9397 /* Unmute Stereo Mixer 15 */ 9398 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9399 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9400 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 9401 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */ 9402 9403 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9404 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9405 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9406 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9407 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9408 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9409 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9410 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9411 /* hp used DAC 3 (Front) */ 9412 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 9413 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 9414 { } 9415}; 9416 9417static struct hda_verb alc861_uniwill_m31_init_verbs[] = { 9418 /* 9419 * Unmute ADC0 and set the default input to mic-in 9420 */ 9421 /* port-A for surround (rear panel) */ 9422 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 9423 /* port-B for mic-in (rear panel) with vref */ 9424 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 9425 /* port-C for line-in (rear panel) */ 9426 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 9427 /* port-D for Front */ 9428 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 9429 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 }, 9430 /* port-E for HP out (front panel) */ 9431 /* this has to be set to VREF80 */ 9432 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 9433 /* route front PCM to HP */ 9434 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, 9435 /* port-F for mic-in (front panel) with vref */ 9436 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 9437 /* port-G for CLFE (rear panel) */ 9438 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 9439 /* port-H for side (rear panel) */ 9440 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 9441 /* CD-in */ 9442 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 9443 /* route front mic to ADC1*/ 9444 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 9445 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9446 /* Unmute DAC0~3 & spdif out*/ 9447 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9448 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9449 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9450 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9451 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9452 9453 /* Unmute Mixer 14 (mic) 1c (Line in)*/ 9454 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9455 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9456 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9457 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9458 9459 /* Unmute Stereo Mixer 15 */ 9460 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9461 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9462 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 9463 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */ 9464 9465 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9466 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9467 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9468 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9469 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9470 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9471 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9472 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9473 /* hp used DAC 3 (Front) */ 9474 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 9475 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 9476 { } 9477}; 9478 9479static struct hda_verb alc861_asus_init_verbs[] = { 9480 /* 9481 * Unmute ADC0 and set the default input to mic-in 9482 */ 9483 /* port-A for surround (rear panel) 9484 * according to codec#0 this is the HP jack 9485 */ 9486 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */ 9487 /* route front PCM to HP */ 9488 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 }, 9489 /* port-B for mic-in (rear panel) with vref */ 9490 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 9491 /* port-C for line-in (rear panel) */ 9492 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 9493 /* port-D for Front */ 9494 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 9495 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 }, 9496 /* port-E for HP out (front panel) */ 9497 /* this has to be set to VREF80 */ 9498 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 9499 /* route front PCM to HP */ 9500 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, 9501 /* port-F for mic-in (front panel) with vref */ 9502 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 9503 /* port-G for CLFE (rear panel) */ 9504 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 9505 /* port-H for side (rear panel) */ 9506 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 9507 /* CD-in */ 9508 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 9509 /* route front mic to ADC1*/ 9510 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 9511 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9512 /* Unmute DAC0~3 & spdif out*/ 9513 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9514 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9515 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9516 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9517 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9518 /* Unmute Mixer 14 (mic) 1c (Line in)*/ 9519 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9520 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9521 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9522 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9523 9524 /* Unmute Stereo Mixer 15 */ 9525 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9526 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9527 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 9528 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */ 9529 9530 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9531 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9532 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9533 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9534 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9535 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9536 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9537 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9538 /* hp used DAC 3 (Front) */ 9539 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 9540 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 9541 { } 9542}; 9543 9544/* additional init verbs for ASUS laptops */ 9545static struct hda_verb alc861_asus_laptop_init_verbs[] = { 9546 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */ 9547 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */ 9548 { } 9549}; 9550 9551/* 9552 * generic initialization of ADC, input mixers and output mixers 9553 */ 9554static struct hda_verb alc861_auto_init_verbs[] = { 9555 /* 9556 * Unmute ADC0 and set the default input to mic-in 9557 */ 9558 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */ 9559 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9560 9561 /* Unmute DAC0~3 & spdif out*/ 9562 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 9563 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 9564 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 9565 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 9566 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9567 9568 /* Unmute Mixer 14 (mic) 1c (Line in)*/ 9569 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9570 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9571 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9572 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9573 9574 /* Unmute Stereo Mixer 15 */ 9575 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9576 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9577 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 9578 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, 9579 9580 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9581 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9582 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9583 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9584 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9585 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9586 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9587 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9588 9589 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 9590 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 9591 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 9592 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 9593 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 9594 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 9595 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 9596 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 9597 9598 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */ 9599 9600 { } 9601}; 9602 9603static struct hda_verb alc861_toshiba_init_verbs[] = { 9604 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 9605 9606 { } 9607}; 9608 9609/* toggle speaker-output according to the hp-jack state */ 9610static void alc861_toshiba_automute(struct hda_codec *codec) 9611{ 9612 unsigned int present; 9613 9614 present = snd_hda_codec_read(codec, 0x0f, 0, 9615 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 9616 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0, 9617 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 9618 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3, 9619 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE); 9620} 9621 9622static void alc861_toshiba_unsol_event(struct hda_codec *codec, 9623 unsigned int res) 9624{ 9625 if ((res >> 26) == ALC880_HP_EVENT) 9626 alc861_toshiba_automute(codec); 9627} 9628 9629/* pcm configuration: identiacal with ALC880 */ 9630#define alc861_pcm_analog_playback alc880_pcm_analog_playback 9631#define alc861_pcm_analog_capture alc880_pcm_analog_capture 9632#define alc861_pcm_digital_playback alc880_pcm_digital_playback 9633#define alc861_pcm_digital_capture alc880_pcm_digital_capture 9634 9635 9636#define ALC861_DIGOUT_NID 0x07 9637 9638static struct hda_channel_mode alc861_8ch_modes[1] = { 9639 { 8, NULL } 9640}; 9641 9642static hda_nid_t alc861_dac_nids[4] = { 9643 /* front, surround, clfe, side */ 9644 0x03, 0x06, 0x05, 0x04 9645}; 9646 9647static hda_nid_t alc660_dac_nids[3] = { 9648 /* front, clfe, surround */ 9649 0x03, 0x05, 0x06 9650}; 9651 9652static hda_nid_t alc861_adc_nids[1] = { 9653 /* ADC0-2 */ 9654 0x08, 9655}; 9656 9657static struct hda_input_mux alc861_capture_source = { 9658 .num_items = 5, 9659 .items = { 9660 { "Mic", 0x0 }, 9661 { "Front Mic", 0x3 }, 9662 { "Line", 0x1 }, 9663 { "CD", 0x4 }, 9664 { "Mixer", 0x5 }, 9665 }, 9666}; 9667 9668/* fill in the dac_nids table from the parsed pin configuration */ 9669static int alc861_auto_fill_dac_nids(struct alc_spec *spec, 9670 const struct auto_pin_cfg *cfg) 9671{ 9672 int i; 9673 hda_nid_t nid; 9674 9675 spec->multiout.dac_nids = spec->private_dac_nids; 9676 for (i = 0; i < cfg->line_outs; i++) { 9677 nid = cfg->line_out_pins[i]; 9678 if (nid) { 9679 if (i >= ARRAY_SIZE(alc861_dac_nids)) 9680 continue; 9681 spec->multiout.dac_nids[i] = alc861_dac_nids[i]; 9682 } 9683 } 9684 spec->multiout.num_dacs = cfg->line_outs; 9685 return 0; 9686} 9687 9688/* add playback controls from the parsed DAC table */ 9689static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec, 9690 const struct auto_pin_cfg *cfg) 9691{ 9692 char name[32]; 9693 static const char *chname[4] = { 9694 "Front", "Surround", NULL /*CLFE*/, "Side" 9695 }; 9696 hda_nid_t nid; 9697 int i, idx, err; 9698 9699 for (i = 0; i < cfg->line_outs; i++) { 9700 nid = spec->multiout.dac_nids[i]; 9701 if (!nid) 9702 continue; 9703 if (nid == 0x05) { 9704 /* Center/LFE */ 9705 err = add_control(spec, ALC_CTL_BIND_MUTE, 9706 "Center Playback Switch", 9707 HDA_COMPOSE_AMP_VAL(nid, 1, 0, 9708 HDA_OUTPUT)); 9709 if (err < 0) 9710 return err; 9711 err = add_control(spec, ALC_CTL_BIND_MUTE, 9712 "LFE Playback Switch", 9713 HDA_COMPOSE_AMP_VAL(nid, 2, 0, 9714 HDA_OUTPUT)); 9715 if (err < 0) 9716 return err; 9717 } else { 9718 for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1; 9719 idx++) 9720 if (nid == alc861_dac_nids[idx]) 9721 break; 9722 sprintf(name, "%s Playback Switch", chname[idx]); 9723 err = add_control(spec, ALC_CTL_BIND_MUTE, name, 9724 HDA_COMPOSE_AMP_VAL(nid, 3, 0, 9725 HDA_OUTPUT)); 9726 if (err < 0) 9727 return err; 9728 } 9729 } 9730 return 0; 9731} 9732 9733static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin) 9734{ 9735 int err; 9736 hda_nid_t nid; 9737 9738 if (!pin) 9739 return 0; 9740 9741 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) { 9742 nid = 0x03; 9743 err = add_control(spec, ALC_CTL_WIDGET_MUTE, 9744 "Headphone Playback Switch", 9745 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); 9746 if (err < 0) 9747 return err; 9748 spec->multiout.hp_nid = nid; 9749 } 9750 return 0; 9751} 9752 9753/* create playback/capture controls for input pins */ 9754static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec, 9755 const struct auto_pin_cfg *cfg) 9756{ 9757 struct hda_input_mux *imux = &spec->private_imux; 9758 int i, err, idx, idx1; 9759 9760 for (i = 0; i < AUTO_PIN_LAST; i++) { 9761 switch (cfg->input_pins[i]) { 9762 case 0x0c: 9763 idx1 = 1; 9764 idx = 2; /* Line In */ 9765 break; 9766 case 0x0f: 9767 idx1 = 2; 9768 idx = 2; /* Line In */ 9769 break; 9770 case 0x0d: 9771 idx1 = 0; 9772 idx = 1; /* Mic In */ 9773 break; 9774 case 0x10: 9775 idx1 = 3; 9776 idx = 1; /* Mic In */ 9777 break; 9778 case 0x11: 9779 idx1 = 4; 9780 idx = 0; /* CD */ 9781 break; 9782 default: 9783 continue; 9784 } 9785 9786 err = new_analog_input(spec, cfg->input_pins[i], 9787 auto_pin_cfg_labels[i], idx, 0x15); 9788 if (err < 0) 9789 return err; 9790 9791 imux->items[imux->num_items].label = auto_pin_cfg_labels[i]; 9792 imux->items[imux->num_items].index = idx1; 9793 imux->num_items++; 9794 } 9795 return 0; 9796} 9797 9798static struct snd_kcontrol_new alc861_capture_mixer[] = { 9799 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 9800 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 9801 9802 { 9803 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 9804 /* The multiple "Capture Source" controls confuse alsamixer 9805 * So call somewhat different.. 9806 *FIXME: the controls appear in the "playback" view! 9807 */ 9808 /* .name = "Capture Source", */ 9809 .name = "Input Source", 9810 .count = 1, 9811 .info = alc_mux_enum_info, 9812 .get = alc_mux_enum_get, 9813 .put = alc_mux_enum_put, 9814 }, 9815 { } /* end */ 9816}; 9817 9818static void alc861_auto_set_output_and_unmute(struct hda_codec *codec, 9819 hda_nid_t nid, 9820 int pin_type, int dac_idx) 9821{ 9822 /* set as output */ 9823 9824 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 9825 pin_type); 9826 snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE, 9827 AMP_OUT_UNMUTE); 9828 9829} 9830 9831static void alc861_auto_init_multi_out(struct hda_codec *codec) 9832{ 9833 struct alc_spec *spec = codec->spec; 9834 int i; 9835 9836 alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b); 9837 for (i = 0; i < spec->autocfg.line_outs; i++) { 9838 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 9839 int pin_type = get_pin_type(spec->autocfg.line_out_type); 9840 if (nid) 9841 alc861_auto_set_output_and_unmute(codec, nid, pin_type, 9842 spec->multiout.dac_nids[i]); 9843 } 9844} 9845 9846static void alc861_auto_init_hp_out(struct hda_codec *codec) 9847{ 9848 struct alc_spec *spec = codec->spec; 9849 hda_nid_t pin; 9850 9851 pin = spec->autocfg.hp_pins[0]; 9852 if (pin) /* connect to front */ 9853 alc861_auto_set_output_and_unmute(codec, pin, PIN_HP, 9854 spec->multiout.dac_nids[0]); 9855} 9856 9857static void alc861_auto_init_analog_input(struct hda_codec *codec) 9858{ 9859 struct alc_spec *spec = codec->spec; 9860 int i; 9861 9862 for (i = 0; i < AUTO_PIN_LAST; i++) { 9863 hda_nid_t nid = spec->autocfg.input_pins[i]; 9864 if (nid >= 0x0c && nid <= 0x11) { 9865 snd_hda_codec_write(codec, nid, 0, 9866 AC_VERB_SET_PIN_WIDGET_CONTROL, 9867 i <= AUTO_PIN_FRONT_MIC ? 9868 PIN_VREF80 : PIN_IN); 9869 } 9870 } 9871} 9872 9873/* parse the BIOS configuration and set up the alc_spec */ 9874/* return 1 if successful, 0 if the proper config is not found, 9875 * or a negative error code 9876 */ 9877static int alc861_parse_auto_config(struct hda_codec *codec) 9878{ 9879 struct alc_spec *spec = codec->spec; 9880 int err; 9881 static hda_nid_t alc861_ignore[] = { 0x1d, 0 }; 9882 9883 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 9884 alc861_ignore); 9885 if (err < 0) 9886 return err; 9887 if (!spec->autocfg.line_outs) 9888 return 0; /* can't find valid BIOS pin config */ 9889 9890 err = alc861_auto_fill_dac_nids(spec, &spec->autocfg); 9891 if (err < 0) 9892 return err; 9893 err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg); 9894 if (err < 0) 9895 return err; 9896 err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]); 9897 if (err < 0) 9898 return err; 9899 err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg); 9900 if (err < 0) 9901 return err; 9902 9903 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 9904 9905 if (spec->autocfg.dig_out_pin) 9906 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID; 9907 9908 if (spec->kctl_alloc) 9909 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 9910 9911 spec->init_verbs[spec->num_init_verbs++] = alc861_auto_init_verbs; 9912 9913 spec->num_mux_defs = 1; 9914 spec->input_mux = &spec->private_imux; 9915 9916 spec->adc_nids = alc861_adc_nids; 9917 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids); 9918 spec->mixers[spec->num_mixers] = alc861_capture_mixer; 9919 spec->num_mixers++; 9920 9921 return 1; 9922} 9923 9924/* additional initialization for auto-configuration model */ 9925static void alc861_auto_init(struct hda_codec *codec) 9926{ 9927 alc861_auto_init_multi_out(codec); 9928 alc861_auto_init_hp_out(codec); 9929 alc861_auto_init_analog_input(codec); 9930} 9931 9932#ifdef CONFIG_SND_HDA_POWER_SAVE 9933static struct hda_amp_list alc861_loopbacks[] = { 9934 { 0x15, HDA_INPUT, 0 }, 9935 { 0x15, HDA_INPUT, 1 }, 9936 { 0x15, HDA_INPUT, 2 }, 9937 { 0x15, HDA_INPUT, 3 }, 9938 { } /* end */ 9939}; 9940#endif 9941 9942 9943/* 9944 * configuration and preset 9945 */ 9946static const char *alc861_models[ALC861_MODEL_LAST] = { 9947 [ALC861_3ST] = "3stack", 9948 [ALC660_3ST] = "3stack-660", 9949 [ALC861_3ST_DIG] = "3stack-dig", 9950 [ALC861_6ST_DIG] = "6stack-dig", 9951 [ALC861_UNIWILL_M31] = "uniwill-m31", 9952 [ALC861_TOSHIBA] = "toshiba", 9953 [ALC861_ASUS] = "asus", 9954 [ALC861_ASUS_LAPTOP] = "asus-laptop", 9955 [ALC861_AUTO] = "auto", 9956}; 9957 9958static struct snd_pci_quirk alc861_cfg_tbl[] = { 9959 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST), 9960 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP), 9961 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP), 9962 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP), 9963 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP), 9964 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS), 9965 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG), 9966 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA), 9967 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!) 9968 * Any other models that need this preset? 9969 */ 9970 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */ 9971 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31), 9972 SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), 9973 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31), 9974 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST), 9975 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST), 9976 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST), 9977 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST), 9978 {} 9979}; 9980 9981static struct alc_config_preset alc861_presets[] = { 9982 [ALC861_3ST] = { 9983 .mixers = { alc861_3ST_mixer }, 9984 .init_verbs = { alc861_threestack_init_verbs }, 9985 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 9986 .dac_nids = alc861_dac_nids, 9987 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes), 9988 .channel_mode = alc861_threestack_modes, 9989 .need_dac_fix = 1, 9990 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 9991 .adc_nids = alc861_adc_nids, 9992 .input_mux = &alc861_capture_source, 9993 }, 9994 [ALC861_3ST_DIG] = { 9995 .mixers = { alc861_base_mixer }, 9996 .init_verbs = { alc861_threestack_init_verbs }, 9997 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 9998 .dac_nids = alc861_dac_nids, 9999 .dig_out_nid = ALC861_DIGOUT_NID, 10000 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes), 10001 .channel_mode = alc861_threestack_modes, 10002 .need_dac_fix = 1, 10003 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 10004 .adc_nids = alc861_adc_nids, 10005 .input_mux = &alc861_capture_source, 10006 }, 10007 [ALC861_6ST_DIG] = { 10008 .mixers = { alc861_base_mixer }, 10009 .init_verbs = { alc861_base_init_verbs }, 10010 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 10011 .dac_nids = alc861_dac_nids, 10012 .dig_out_nid = ALC861_DIGOUT_NID, 10013 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes), 10014 .channel_mode = alc861_8ch_modes, 10015 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 10016 .adc_nids = alc861_adc_nids, 10017 .input_mux = &alc861_capture_source, 10018 }, 10019 [ALC660_3ST] = { 10020 .mixers = { alc861_3ST_mixer }, 10021 .init_verbs = { alc861_threestack_init_verbs }, 10022 .num_dacs = ARRAY_SIZE(alc660_dac_nids), 10023 .dac_nids = alc660_dac_nids, 10024 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes), 10025 .channel_mode = alc861_threestack_modes, 10026 .need_dac_fix = 1, 10027 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 10028 .adc_nids = alc861_adc_nids, 10029 .input_mux = &alc861_capture_source, 10030 }, 10031 [ALC861_UNIWILL_M31] = { 10032 .mixers = { alc861_uniwill_m31_mixer }, 10033 .init_verbs = { alc861_uniwill_m31_init_verbs }, 10034 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 10035 .dac_nids = alc861_dac_nids, 10036 .dig_out_nid = ALC861_DIGOUT_NID, 10037 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes), 10038 .channel_mode = alc861_uniwill_m31_modes, 10039 .need_dac_fix = 1, 10040 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 10041 .adc_nids = alc861_adc_nids, 10042 .input_mux = &alc861_capture_source, 10043 }, 10044 [ALC861_TOSHIBA] = { 10045 .mixers = { alc861_toshiba_mixer }, 10046 .init_verbs = { alc861_base_init_verbs, 10047 alc861_toshiba_init_verbs }, 10048 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 10049 .dac_nids = alc861_dac_nids, 10050 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10051 .channel_mode = alc883_3ST_2ch_modes, 10052 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 10053 .adc_nids = alc861_adc_nids, 10054 .input_mux = &alc861_capture_source, 10055 .unsol_event = alc861_toshiba_unsol_event, 10056 .init_hook = alc861_toshiba_automute, 10057 }, 10058 [ALC861_ASUS] = { 10059 .mixers = { alc861_asus_mixer }, 10060 .init_verbs = { alc861_asus_init_verbs }, 10061 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 10062 .dac_nids = alc861_dac_nids, 10063 .dig_out_nid = ALC861_DIGOUT_NID, 10064 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes), 10065 .channel_mode = alc861_asus_modes, 10066 .need_dac_fix = 1, 10067 .hp_nid = 0x06, 10068 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 10069 .adc_nids = alc861_adc_nids, 10070 .input_mux = &alc861_capture_source, 10071 }, 10072 [ALC861_ASUS_LAPTOP] = { 10073 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer }, 10074 .init_verbs = { alc861_asus_init_verbs, 10075 alc861_asus_laptop_init_verbs }, 10076 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 10077 .dac_nids = alc861_dac_nids, 10078 .dig_out_nid = ALC861_DIGOUT_NID, 10079 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10080 .channel_mode = alc883_3ST_2ch_modes, 10081 .need_dac_fix = 1, 10082 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 10083 .adc_nids = alc861_adc_nids, 10084 .input_mux = &alc861_capture_source, 10085 }, 10086}; 10087 10088 10089static int patch_alc861(struct hda_codec *codec) 10090{ 10091 struct alc_spec *spec; 10092 int board_config; 10093 int err; 10094 10095 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 10096 if (spec == NULL) 10097 return -ENOMEM; 10098 10099 codec->spec = spec; 10100 10101 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST, 10102 alc861_models, 10103 alc861_cfg_tbl); 10104 10105 if (board_config < 0) { 10106 printk(KERN_INFO "hda_codec: Unknown model for ALC861, " 10107 "trying auto-probe from BIOS...\n"); 10108 board_config = ALC861_AUTO; 10109 } 10110 10111 if (board_config == ALC861_AUTO) { 10112 /* automatic parse from the BIOS config */ 10113 err = alc861_parse_auto_config(codec); 10114 if (err < 0) { 10115 alc_free(codec); 10116 return err; 10117 } else if (!err) { 10118 printk(KERN_INFO 10119 "hda_codec: Cannot set up configuration " 10120 "from BIOS. Using base mode...\n"); 10121 board_config = ALC861_3ST_DIG; 10122 } 10123 } 10124 10125 if (board_config != ALC861_AUTO) 10126 setup_preset(spec, &alc861_presets[board_config]); 10127 10128 spec->stream_name_analog = "ALC861 Analog"; 10129 spec->stream_analog_playback = &alc861_pcm_analog_playback; 10130 spec->stream_analog_capture = &alc861_pcm_analog_capture; 10131 10132 spec->stream_name_digital = "ALC861 Digital"; 10133 spec->stream_digital_playback = &alc861_pcm_digital_playback; 10134 spec->stream_digital_capture = &alc861_pcm_digital_capture; 10135 10136 codec->patch_ops = alc_patch_ops; 10137 if (board_config == ALC861_AUTO) 10138 spec->init_hook = alc861_auto_init; 10139#ifdef CONFIG_SND_HDA_POWER_SAVE 10140 if (!spec->loopback.amplist) 10141 spec->loopback.amplist = alc861_loopbacks; 10142#endif 10143 10144 return 0; 10145} 10146 10147/* 10148 * ALC861-VD support 10149 * 10150 * Based on ALC882 10151 * 10152 * In addition, an independent DAC 10153 */ 10154#define ALC861VD_DIGOUT_NID 0x06 10155 10156static hda_nid_t alc861vd_dac_nids[4] = { 10157 /* front, surr, clfe, side surr */ 10158 0x02, 0x03, 0x04, 0x05 10159}; 10160 10161/* dac_nids for ALC660vd are in a different order - according to 10162 * Realtek's driver. 10163 * This should probably tesult in a different mixer for 6stack models 10164 * of ALC660vd codecs, but for now there is only 3stack mixer 10165 * - and it is the same as in 861vd. 10166 * adc_nids in ALC660vd are (is) the same as in 861vd 10167 */ 10168static hda_nid_t alc660vd_dac_nids[3] = { 10169 /* front, rear, clfe, rear_surr */ 10170 0x02, 0x04, 0x03 10171}; 10172 10173static hda_nid_t alc861vd_adc_nids[1] = { 10174 /* ADC0 */ 10175 0x09, 10176}; 10177 10178/* input MUX */ 10179/* FIXME: should be a matrix-type input source selection */ 10180static struct hda_input_mux alc861vd_capture_source = { 10181 .num_items = 4, 10182 .items = { 10183 { "Mic", 0x0 }, 10184 { "Front Mic", 0x1 }, 10185 { "Line", 0x2 }, 10186 { "CD", 0x4 }, 10187 }, 10188}; 10189 10190static struct hda_input_mux alc861vd_dallas_capture_source = { 10191 .num_items = 3, 10192 .items = { 10193 { "Front Mic", 0x0 }, 10194 { "ATAPI Mic", 0x1 }, 10195 { "Line In", 0x5 }, 10196 }, 10197}; 10198 10199static struct hda_input_mux alc861vd_hp_capture_source = { 10200 .num_items = 2, 10201 .items = { 10202 { "Front Mic", 0x0 }, 10203 { "ATAPI Mic", 0x1 }, 10204 }, 10205}; 10206 10207#define alc861vd_mux_enum_info alc_mux_enum_info 10208#define alc861vd_mux_enum_get alc_mux_enum_get 10209 10210static int alc861vd_mux_enum_put(struct snd_kcontrol *kcontrol, 10211 struct snd_ctl_elem_value *ucontrol) 10212{ 10213 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 10214 struct alc_spec *spec = codec->spec; 10215 const struct hda_input_mux *imux = spec->input_mux; 10216 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 10217 static hda_nid_t capture_mixers[1] = { 0x22 }; 10218 hda_nid_t nid = capture_mixers[adc_idx]; 10219 unsigned int *cur_val = &spec->cur_mux[adc_idx]; 10220 unsigned int i, idx; 10221 10222 idx = ucontrol->value.enumerated.item[0]; 10223 if (idx >= imux->num_items) 10224 idx = imux->num_items - 1; 10225 if (*cur_val == idx) 10226 return 0; 10227 for (i = 0; i < imux->num_items; i++) { 10228 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE; 10229 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 10230 imux->items[i].index, 10231 HDA_AMP_MUTE, v); 10232 } 10233 *cur_val = idx; 10234 return 1; 10235} 10236 10237/* 10238 * 2ch mode 10239 */ 10240static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = { 10241 { 2, NULL } 10242}; 10243 10244/* 10245 * 6ch mode 10246 */ 10247static struct hda_verb alc861vd_6stack_ch6_init[] = { 10248 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 10249 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 10250 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 10251 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 10252 { } /* end */ 10253}; 10254 10255/* 10256 * 8ch mode 10257 */ 10258static struct hda_verb alc861vd_6stack_ch8_init[] = { 10259 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 10260 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 10261 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 10262 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 10263 { } /* end */ 10264}; 10265 10266static struct hda_channel_mode alc861vd_6stack_modes[2] = { 10267 { 6, alc861vd_6stack_ch6_init }, 10268 { 8, alc861vd_6stack_ch8_init }, 10269}; 10270 10271static struct snd_kcontrol_new alc861vd_chmode_mixer[] = { 10272 { 10273 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 10274 .name = "Channel Mode", 10275 .info = alc_ch_mode_info, 10276 .get = alc_ch_mode_get, 10277 .put = alc_ch_mode_put, 10278 }, 10279 { } /* end */ 10280}; 10281 10282static struct snd_kcontrol_new alc861vd_capture_mixer[] = { 10283 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), 10284 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), 10285 10286 { 10287 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 10288 /* The multiple "Capture Source" controls confuse alsamixer 10289 * So call somewhat different.. 10290 *FIXME: the controls appear in the "playback" view! 10291 */ 10292 /* .name = "Capture Source", */ 10293 .name = "Input Source", 10294 .count = 1, 10295 .info = alc861vd_mux_enum_info, 10296 .get = alc861vd_mux_enum_get, 10297 .put = alc861vd_mux_enum_put, 10298 }, 10299 { } /* end */ 10300}; 10301 10302/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 10303 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b 10304 */ 10305static struct snd_kcontrol_new alc861vd_6st_mixer[] = { 10306 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 10307 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 10308 10309 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT), 10310 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 10311 10312 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, 10313 HDA_OUTPUT), 10314 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, 10315 HDA_OUTPUT), 10316 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 10317 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 10318 10319 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT), 10320 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 10321 10322 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 10323 10324 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 10325 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 10326 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 10327 10328 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 10329 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 10330 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 10331 10332 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 10333 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 10334 10335 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 10336 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 10337 10338 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 10339 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 10340 10341 { } /* end */ 10342}; 10343 10344static struct snd_kcontrol_new alc861vd_3st_mixer[] = { 10345 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 10346 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 10347 10348 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 10349 10350 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 10351 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 10352 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 10353 10354 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 10355 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 10356 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 10357 10358 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 10359 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 10360 10361 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 10362 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 10363 10364 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 10365 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 10366 10367 { } /* end */ 10368}; 10369 10370static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = { 10371 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 10372 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/ 10373 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 10374 10375 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 10376 10377 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 10378 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 10379 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 10380 10381 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 10382 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 10383 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 10384 10385 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 10386 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 10387 10388 { } /* end */ 10389}; 10390 10391/* Pin assignment: Front=0x14, HP = 0x15, 10392 * Front Mic=0x18, ATAPI Mic = 0x19, Line In = 0x1d 10393 */ 10394static struct snd_kcontrol_new alc861vd_dallas_mixer[] = { 10395 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 10396 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 10397 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 10398 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT), 10399 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 10400 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 10401 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 10402 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 10403 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x05, HDA_INPUT), 10404 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x05, HDA_INPUT), 10405 { } /* end */ 10406}; 10407 10408/* Pin assignment: Speaker=0x14, Line-out = 0x15, 10409 * Front Mic=0x18, ATAPI Mic = 0x19, 10410 */ 10411static struct snd_kcontrol_new alc861vd_hp_mixer[] = { 10412 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 10413 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 10414 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 10415 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT), 10416 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 10417 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 10418 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 10419 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 10420 10421 { } /* end */ 10422}; 10423 10424/* 10425 * generic initialization of ADC, input mixers and output mixers 10426 */ 10427static struct hda_verb alc861vd_volume_init_verbs[] = { 10428 /* 10429 * Unmute ADC0 and set the default input to mic-in 10430 */ 10431 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 10432 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 10433 10434 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of 10435 * the analog-loopback mixer widget 10436 */ 10437 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 10438 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 10439 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 10440 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 10441 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 10442 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 10443 10444 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */ 10445 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 10446 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 10447 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 10448 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, 10449 10450 /* 10451 * Set up output mixers (0x02 - 0x05) 10452 */ 10453 /* set vol=0 to output mixers */ 10454 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 10455 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 10456 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 10457 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 10458 10459 /* set up input amps for analog loopback */ 10460 /* Amp Indices: DAC = 0, mixer = 1 */ 10461 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 10462 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 10463 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 10464 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 10465 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 10466 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 10467 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 10468 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 10469 10470 { } 10471}; 10472 10473/* 10474 * 3-stack pin configuration: 10475 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b 10476 */ 10477static struct hda_verb alc861vd_3stack_init_verbs[] = { 10478 /* 10479 * Set pin mode and muting 10480 */ 10481 /* set front pin widgets 0x14 for output */ 10482 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 10483 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 10484 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 10485 10486 /* Mic (rear) pin: input vref at 80% */ 10487 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 10488 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 10489 /* Front Mic pin: input vref at 80% */ 10490 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 10491 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 10492 /* Line In pin: input */ 10493 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 10494 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 10495 /* Line-2 In: Headphone output (output 0 - 0x0c) */ 10496 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 10497 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 10498 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 10499 /* CD pin widget for input */ 10500 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 10501 10502 { } 10503}; 10504 10505/* 10506 * 6-stack pin configuration: 10507 */ 10508static struct hda_verb alc861vd_6stack_init_verbs[] = { 10509 /* 10510 * Set pin mode and muting 10511 */ 10512 /* set front pin widgets 0x14 for output */ 10513 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 10514 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 10515 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 10516 10517 /* Rear Pin: output 1 (0x0d) */ 10518 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 10519 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 10520 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 10521 /* CLFE Pin: output 2 (0x0e) */ 10522 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 10523 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 10524 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, 10525 /* Side Pin: output 3 (0x0f) */ 10526 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 10527 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 10528 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, 10529 10530 /* Mic (rear) pin: input vref at 80% */ 10531 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 10532 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 10533 /* Front Mic pin: input vref at 80% */ 10534 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 10535 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 10536 /* Line In pin: input */ 10537 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 10538 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 10539 /* Line-2 In: Headphone output (output 0 - 0x0c) */ 10540 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 10541 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 10542 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 10543 /* CD pin widget for input */ 10544 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 10545 10546 { } 10547}; 10548 10549static struct hda_verb alc861vd_eapd_verbs[] = { 10550 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 10551 { } 10552}; 10553 10554static struct hda_verb alc861vd_lenovo_unsol_verbs[] = { 10555 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 10556 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 10557 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, 10558 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 10559 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 10560 {} 10561}; 10562 10563/* toggle speaker-output according to the hp-jack state */ 10564static void alc861vd_lenovo_hp_automute(struct hda_codec *codec) 10565{ 10566 unsigned int present; 10567 unsigned char bits; 10568 10569 present = snd_hda_codec_read(codec, 0x1b, 0, 10570 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 10571 bits = present ? HDA_AMP_MUTE : 0; 10572 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 10573 HDA_AMP_MUTE, bits); 10574} 10575 10576static void alc861vd_lenovo_mic_automute(struct hda_codec *codec) 10577{ 10578 unsigned int present; 10579 unsigned char bits; 10580 10581 present = snd_hda_codec_read(codec, 0x18, 0, 10582 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 10583 bits = present ? HDA_AMP_MUTE : 0; 10584 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, 10585 HDA_AMP_MUTE, bits); 10586} 10587 10588static void alc861vd_lenovo_automute(struct hda_codec *codec) 10589{ 10590 alc861vd_lenovo_hp_automute(codec); 10591 alc861vd_lenovo_mic_automute(codec); 10592} 10593 10594static void alc861vd_lenovo_unsol_event(struct hda_codec *codec, 10595 unsigned int res) 10596{ 10597 switch (res >> 26) { 10598 case ALC880_HP_EVENT: 10599 alc861vd_lenovo_hp_automute(codec); 10600 break; 10601 case ALC880_MIC_EVENT: 10602 alc861vd_lenovo_mic_automute(codec); 10603 break; 10604 } 10605} 10606 10607static struct hda_verb alc861vd_dallas_verbs[] = { 10608 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 10609 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 10610 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 10611 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 10612 10613 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 10614 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 10615 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 10616 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 10617 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 10618 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 10619 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 10620 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 10621 10622 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 10623 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 10624 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 10625 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 10626 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 10627 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 10628 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 10629 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 10630 10631 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, 10632 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 10633 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, 10634 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 10635 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 10636 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 10637 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 10638 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 10639 10640 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 10641 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 10642 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 10643 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 10644 10645 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 10646 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 10647 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 10648 10649 { } /* end */ 10650}; 10651 10652/* toggle speaker-output according to the hp-jack state */ 10653static void alc861vd_dallas_automute(struct hda_codec *codec) 10654{ 10655 unsigned int present; 10656 10657 present = snd_hda_codec_read(codec, 0x15, 0, 10658 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 10659 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 10660 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 10661} 10662 10663static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int res) 10664{ 10665 if ((res >> 26) == ALC880_HP_EVENT) 10666 alc861vd_dallas_automute(codec); 10667} 10668 10669#ifdef CONFIG_SND_HDA_POWER_SAVE 10670#define alc861vd_loopbacks alc880_loopbacks 10671#endif 10672 10673/* pcm configuration: identiacal with ALC880 */ 10674#define alc861vd_pcm_analog_playback alc880_pcm_analog_playback 10675#define alc861vd_pcm_analog_capture alc880_pcm_analog_capture 10676#define alc861vd_pcm_digital_playback alc880_pcm_digital_playback 10677#define alc861vd_pcm_digital_capture alc880_pcm_digital_capture 10678 10679/* 10680 * configuration and preset 10681 */ 10682static const char *alc861vd_models[ALC861VD_MODEL_LAST] = { 10683 [ALC660VD_3ST] = "3stack-660", 10684 [ALC660VD_3ST_DIG] = "3stack-660-digout", 10685 [ALC861VD_3ST] = "3stack", 10686 [ALC861VD_3ST_DIG] = "3stack-digout", 10687 [ALC861VD_6ST_DIG] = "6stack-digout", 10688 [ALC861VD_LENOVO] = "lenovo", 10689 [ALC861VD_DALLAS] = "dallas", 10690 [ALC861VD_HP] = "hp", 10691 [ALC861VD_AUTO] = "auto", 10692}; 10693 10694static struct snd_pci_quirk alc861vd_cfg_tbl[] = { 10695 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST), 10696 SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST), 10697 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG), 10698 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST), 10699 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST), 10700 10701 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/ 10702 SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS), 10703 SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO), 10704 SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO), 10705 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO), 10706 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO), 10707 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG), 10708 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG), 10709 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP), 10710 {} 10711}; 10712 10713static struct alc_config_preset alc861vd_presets[] = { 10714 [ALC660VD_3ST] = { 10715 .mixers = { alc861vd_3st_mixer }, 10716 .init_verbs = { alc861vd_volume_init_verbs, 10717 alc861vd_3stack_init_verbs }, 10718 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids), 10719 .dac_nids = alc660vd_dac_nids, 10720 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids), 10721 .adc_nids = alc861vd_adc_nids, 10722 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 10723 .channel_mode = alc861vd_3stack_2ch_modes, 10724 .input_mux = &alc861vd_capture_source, 10725 }, 10726 [ALC660VD_3ST_DIG] = { 10727 .mixers = { alc861vd_3st_mixer }, 10728 .init_verbs = { alc861vd_volume_init_verbs, 10729 alc861vd_3stack_init_verbs }, 10730 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids), 10731 .dac_nids = alc660vd_dac_nids, 10732 .dig_out_nid = ALC861VD_DIGOUT_NID, 10733 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids), 10734 .adc_nids = alc861vd_adc_nids, 10735 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 10736 .channel_mode = alc861vd_3stack_2ch_modes, 10737 .input_mux = &alc861vd_capture_source, 10738 }, 10739 [ALC861VD_3ST] = { 10740 .mixers = { alc861vd_3st_mixer }, 10741 .init_verbs = { alc861vd_volume_init_verbs, 10742 alc861vd_3stack_init_verbs }, 10743 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids), 10744 .dac_nids = alc861vd_dac_nids, 10745 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 10746 .channel_mode = alc861vd_3stack_2ch_modes, 10747 .input_mux = &alc861vd_capture_source, 10748 }, 10749 [ALC861VD_3ST_DIG] = { 10750 .mixers = { alc861vd_3st_mixer }, 10751 .init_verbs = { alc861vd_volume_init_verbs, 10752 alc861vd_3stack_init_verbs }, 10753 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids), 10754 .dac_nids = alc861vd_dac_nids, 10755 .dig_out_nid = ALC861VD_DIGOUT_NID, 10756 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 10757 .channel_mode = alc861vd_3stack_2ch_modes, 10758 .input_mux = &alc861vd_capture_source, 10759 }, 10760 [ALC861VD_6ST_DIG] = { 10761 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer }, 10762 .init_verbs = { alc861vd_volume_init_verbs, 10763 alc861vd_6stack_init_verbs }, 10764 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids), 10765 .dac_nids = alc861vd_dac_nids, 10766 .dig_out_nid = ALC861VD_DIGOUT_NID, 10767 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes), 10768 .channel_mode = alc861vd_6stack_modes, 10769 .input_mux = &alc861vd_capture_source, 10770 }, 10771 [ALC861VD_LENOVO] = { 10772 .mixers = { alc861vd_lenovo_mixer }, 10773 .init_verbs = { alc861vd_volume_init_verbs, 10774 alc861vd_3stack_init_verbs, 10775 alc861vd_eapd_verbs, 10776 alc861vd_lenovo_unsol_verbs }, 10777 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids), 10778 .dac_nids = alc660vd_dac_nids, 10779 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids), 10780 .adc_nids = alc861vd_adc_nids, 10781 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 10782 .channel_mode = alc861vd_3stack_2ch_modes, 10783 .input_mux = &alc861vd_capture_source, 10784 .unsol_event = alc861vd_lenovo_unsol_event, 10785 .init_hook = alc861vd_lenovo_automute, 10786 }, 10787 [ALC861VD_DALLAS] = { 10788 .mixers = { alc861vd_dallas_mixer }, 10789 .init_verbs = { alc861vd_dallas_verbs }, 10790 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids), 10791 .dac_nids = alc861vd_dac_nids, 10792 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids), 10793 .adc_nids = alc861vd_adc_nids, 10794 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 10795 .channel_mode = alc861vd_3stack_2ch_modes, 10796 .input_mux = &alc861vd_dallas_capture_source, 10797 .unsol_event = alc861vd_dallas_unsol_event, 10798 .init_hook = alc861vd_dallas_automute, 10799 }, 10800 [ALC861VD_HP] = { 10801 .mixers = { alc861vd_hp_mixer }, 10802 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs }, 10803 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids), 10804 .dac_nids = alc861vd_dac_nids, 10805 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids), 10806 .dig_out_nid = ALC861VD_DIGOUT_NID, 10807 .adc_nids = alc861vd_adc_nids, 10808 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 10809 .channel_mode = alc861vd_3stack_2ch_modes, 10810 .input_mux = &alc861vd_hp_capture_source, 10811 .unsol_event = alc861vd_dallas_unsol_event, 10812 .init_hook = alc861vd_dallas_automute, 10813 }, 10814}; 10815 10816/* 10817 * BIOS auto configuration 10818 */ 10819static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec, 10820 hda_nid_t nid, int pin_type, int dac_idx) 10821{ 10822 /* set as output */ 10823 snd_hda_codec_write(codec, nid, 0, 10824 AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type); 10825 snd_hda_codec_write(codec, nid, 0, 10826 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); 10827} 10828 10829static void alc861vd_auto_init_multi_out(struct hda_codec *codec) 10830{ 10831 struct alc_spec *spec = codec->spec; 10832 int i; 10833 10834 alc_subsystem_id(codec, 0x15, 0x1b, 0x14); 10835 for (i = 0; i <= HDA_SIDE; i++) { 10836 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 10837 int pin_type = get_pin_type(spec->autocfg.line_out_type); 10838 if (nid) 10839 alc861vd_auto_set_output_and_unmute(codec, nid, 10840 pin_type, i); 10841 } 10842} 10843 10844 10845static void alc861vd_auto_init_hp_out(struct hda_codec *codec) 10846{ 10847 struct alc_spec *spec = codec->spec; 10848 hda_nid_t pin; 10849 10850 pin = spec->autocfg.hp_pins[0]; 10851 if (pin) /* connect to front and use dac 0 */ 10852 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); 10853} 10854 10855#define alc861vd_is_input_pin(nid) alc880_is_input_pin(nid) 10856#define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID 10857 10858static void alc861vd_auto_init_analog_input(struct hda_codec *codec) 10859{ 10860 struct alc_spec *spec = codec->spec; 10861 int i; 10862 10863 for (i = 0; i < AUTO_PIN_LAST; i++) { 10864 hda_nid_t nid = spec->autocfg.input_pins[i]; 10865 if (alc861vd_is_input_pin(nid)) { 10866 snd_hda_codec_write(codec, nid, 0, 10867 AC_VERB_SET_PIN_WIDGET_CONTROL, 10868 i <= AUTO_PIN_FRONT_MIC ? 10869 PIN_VREF80 : PIN_IN); 10870 if (nid != ALC861VD_PIN_CD_NID) 10871 snd_hda_codec_write(codec, nid, 0, 10872 AC_VERB_SET_AMP_GAIN_MUTE, 10873 AMP_OUT_MUTE); 10874 } 10875 } 10876} 10877 10878#define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02) 10879#define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c) 10880 10881/* add playback controls from the parsed DAC table */ 10882/* Based on ALC880 version. But ALC861VD has separate, 10883 * different NIDs for mute/unmute switch and volume control */ 10884static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec, 10885 const struct auto_pin_cfg *cfg) 10886{ 10887 char name[32]; 10888 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"}; 10889 hda_nid_t nid_v, nid_s; 10890 int i, err; 10891 10892 for (i = 0; i < cfg->line_outs; i++) { 10893 if (!spec->multiout.dac_nids[i]) 10894 continue; 10895 nid_v = alc861vd_idx_to_mixer_vol( 10896 alc880_dac_to_idx( 10897 spec->multiout.dac_nids[i])); 10898 nid_s = alc861vd_idx_to_mixer_switch( 10899 alc880_dac_to_idx( 10900 spec->multiout.dac_nids[i])); 10901 10902 if (i == 2) { 10903 /* Center/LFE */ 10904 err = add_control(spec, ALC_CTL_WIDGET_VOL, 10905 "Center Playback Volume", 10906 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0, 10907 HDA_OUTPUT)); 10908 if (err < 0) 10909 return err; 10910 err = add_control(spec, ALC_CTL_WIDGET_VOL, 10911 "LFE Playback Volume", 10912 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0, 10913 HDA_OUTPUT)); 10914 if (err < 0) 10915 return err; 10916 err = add_control(spec, ALC_CTL_BIND_MUTE, 10917 "Center Playback Switch", 10918 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2, 10919 HDA_INPUT)); 10920 if (err < 0) 10921 return err; 10922 err = add_control(spec, ALC_CTL_BIND_MUTE, 10923 "LFE Playback Switch", 10924 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2, 10925 HDA_INPUT)); 10926 if (err < 0) 10927 return err; 10928 } else { 10929 sprintf(name, "%s Playback Volume", chname[i]); 10930 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, 10931 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, 10932 HDA_OUTPUT)); 10933 if (err < 0) 10934 return err; 10935 sprintf(name, "%s Playback Switch", chname[i]); 10936 err = add_control(spec, ALC_CTL_BIND_MUTE, name, 10937 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, 10938 HDA_INPUT)); 10939 if (err < 0) 10940 return err; 10941 } 10942 } 10943 return 0; 10944} 10945 10946/* add playback controls for speaker and HP outputs */ 10947/* Based on ALC880 version. But ALC861VD has separate, 10948 * different NIDs for mute/unmute switch and volume control */ 10949static int alc861vd_auto_create_extra_out(struct alc_spec *spec, 10950 hda_nid_t pin, const char *pfx) 10951{ 10952 hda_nid_t nid_v, nid_s; 10953 int err; 10954 char name[32]; 10955 10956 if (!pin) 10957 return 0; 10958 10959 if (alc880_is_fixed_pin(pin)) { 10960 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); 10961 /* specify the DAC as the extra output */ 10962 if (!spec->multiout.hp_nid) 10963 spec->multiout.hp_nid = nid_v; 10964 else 10965 spec->multiout.extra_out_nid[0] = nid_v; 10966 /* control HP volume/switch on the output mixer amp */ 10967 nid_v = alc861vd_idx_to_mixer_vol( 10968 alc880_fixed_pin_idx(pin)); 10969 nid_s = alc861vd_idx_to_mixer_switch( 10970 alc880_fixed_pin_idx(pin)); 10971 10972 sprintf(name, "%s Playback Volume", pfx); 10973 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, 10974 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT)); 10975 if (err < 0) 10976 return err; 10977 sprintf(name, "%s Playback Switch", pfx); 10978 err = add_control(spec, ALC_CTL_BIND_MUTE, name, 10979 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT)); 10980 if (err < 0) 10981 return err; 10982 } else if (alc880_is_multi_pin(pin)) { 10983 /* set manual connection */ 10984 /* we have only a switch on HP-out PIN */ 10985 sprintf(name, "%s Playback Switch", pfx); 10986 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, 10987 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); 10988 if (err < 0) 10989 return err; 10990 } 10991 return 0; 10992} 10993 10994/* parse the BIOS configuration and set up the alc_spec 10995 * return 1 if successful, 0 if the proper config is not found, 10996 * or a negative error code 10997 * Based on ALC880 version - had to change it to override 10998 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */ 10999static int alc861vd_parse_auto_config(struct hda_codec *codec) 11000{ 11001 struct alc_spec *spec = codec->spec; 11002 int err; 11003 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 }; 11004 11005 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 11006 alc861vd_ignore); 11007 if (err < 0) 11008 return err; 11009 if (!spec->autocfg.line_outs) 11010 return 0; /* can't find valid BIOS pin config */ 11011 11012 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); 11013 if (err < 0) 11014 return err; 11015 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg); 11016 if (err < 0) 11017 return err; 11018 err = alc861vd_auto_create_extra_out(spec, 11019 spec->autocfg.speaker_pins[0], 11020 "Speaker"); 11021 if (err < 0) 11022 return err; 11023 err = alc861vd_auto_create_extra_out(spec, 11024 spec->autocfg.hp_pins[0], 11025 "Headphone"); 11026 if (err < 0) 11027 return err; 11028 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg); 11029 if (err < 0) 11030 return err; 11031 11032 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 11033 11034 if (spec->autocfg.dig_out_pin) 11035 spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID; 11036 11037 if (spec->kctl_alloc) 11038 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 11039 11040 spec->init_verbs[spec->num_init_verbs++] 11041 = alc861vd_volume_init_verbs; 11042 11043 spec->num_mux_defs = 1; 11044 spec->input_mux = &spec->private_imux; 11045 11046 return 1; 11047} 11048 11049/* additional initialization for auto-configuration model */ 11050static void alc861vd_auto_init(struct hda_codec *codec) 11051{ 11052 alc861vd_auto_init_multi_out(codec); 11053 alc861vd_auto_init_hp_out(codec); 11054 alc861vd_auto_init_analog_input(codec); 11055} 11056 11057static int patch_alc861vd(struct hda_codec *codec) 11058{ 11059 struct alc_spec *spec; 11060 int err, board_config; 11061 11062 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 11063 if (spec == NULL) 11064 return -ENOMEM; 11065 11066 codec->spec = spec; 11067 11068 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST, 11069 alc861vd_models, 11070 alc861vd_cfg_tbl); 11071 11072 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) { 11073 printk(KERN_INFO "hda_codec: Unknown model for ALC660VD/" 11074 "ALC861VD, trying auto-probe from BIOS...\n"); 11075 board_config = ALC861VD_AUTO; 11076 } 11077 11078 if (board_config == ALC861VD_AUTO) { 11079 /* automatic parse from the BIOS config */ 11080 err = alc861vd_parse_auto_config(codec); 11081 if (err < 0) { 11082 alc_free(codec); 11083 return err; 11084 } else if (!err) { 11085 printk(KERN_INFO 11086 "hda_codec: Cannot set up configuration " 11087 "from BIOS. Using base mode...\n"); 11088 board_config = ALC861VD_3ST; 11089 } 11090 } 11091 11092 if (board_config != ALC861VD_AUTO) 11093 setup_preset(spec, &alc861vd_presets[board_config]); 11094 11095 spec->stream_name_analog = "ALC861VD Analog"; 11096 spec->stream_analog_playback = &alc861vd_pcm_analog_playback; 11097 spec->stream_analog_capture = &alc861vd_pcm_analog_capture; 11098 11099 spec->stream_name_digital = "ALC861VD Digital"; 11100 spec->stream_digital_playback = &alc861vd_pcm_digital_playback; 11101 spec->stream_digital_capture = &alc861vd_pcm_digital_capture; 11102 11103 spec->adc_nids = alc861vd_adc_nids; 11104 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids); 11105 11106 spec->mixers[spec->num_mixers] = alc861vd_capture_mixer; 11107 spec->num_mixers++; 11108 11109 codec->patch_ops = alc_patch_ops; 11110 11111 if (board_config == ALC861VD_AUTO) 11112 spec->init_hook = alc861vd_auto_init; 11113#ifdef CONFIG_SND_HDA_POWER_SAVE 11114 if (!spec->loopback.amplist) 11115 spec->loopback.amplist = alc861vd_loopbacks; 11116#endif 11117 11118 return 0; 11119} 11120 11121/* 11122 * ALC662 support 11123 * 11124 * ALC662 is almost identical with ALC880 but has cleaner and more flexible 11125 * configuration. Each pin widget can choose any input DACs and a mixer. 11126 * Each ADC is connected from a mixer of all inputs. This makes possible 11127 * 6-channel independent captures. 11128 * 11129 * In addition, an independent DAC for the multi-playback (not used in this 11130 * driver yet). 11131 */ 11132#define ALC662_DIGOUT_NID 0x06 11133#define ALC662_DIGIN_NID 0x0a 11134 11135static hda_nid_t alc662_dac_nids[4] = { 11136 /* front, rear, clfe, rear_surr */ 11137 0x02, 0x03, 0x04 11138}; 11139 11140static hda_nid_t alc662_adc_nids[1] = { 11141 /* ADC1-2 */ 11142 0x09, 11143}; 11144/* input MUX */ 11145/* FIXME: should be a matrix-type input source selection */ 11146 11147static struct hda_input_mux alc662_capture_source = { 11148 .num_items = 4, 11149 .items = { 11150 { "Mic", 0x0 }, 11151 { "Front Mic", 0x1 }, 11152 { "Line", 0x2 }, 11153 { "CD", 0x4 }, 11154 }, 11155}; 11156 11157static struct hda_input_mux alc662_lenovo_101e_capture_source = { 11158 .num_items = 2, 11159 .items = { 11160 { "Mic", 0x1 }, 11161 { "Line", 0x2 }, 11162 }, 11163}; 11164#define alc662_mux_enum_info alc_mux_enum_info 11165#define alc662_mux_enum_get alc_mux_enum_get 11166 11167static int alc662_mux_enum_put(struct snd_kcontrol *kcontrol, 11168 struct snd_ctl_elem_value *ucontrol) 11169{ 11170 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 11171 struct alc_spec *spec = codec->spec; 11172 const struct hda_input_mux *imux = spec->input_mux; 11173 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 11174 static hda_nid_t capture_mixers[2] = { 0x23, 0x22 }; 11175 hda_nid_t nid = capture_mixers[adc_idx]; 11176 unsigned int *cur_val = &spec->cur_mux[adc_idx]; 11177 unsigned int i, idx; 11178 11179 idx = ucontrol->value.enumerated.item[0]; 11180 if (idx >= imux->num_items) 11181 idx = imux->num_items - 1; 11182 if (*cur_val == idx) 11183 return 0; 11184 for (i = 0; i < imux->num_items; i++) { 11185 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE; 11186 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 11187 imux->items[i].index, 11188 HDA_AMP_MUTE, v); 11189 } 11190 *cur_val = idx; 11191 return 1; 11192} 11193/* 11194 * 2ch mode 11195 */ 11196static struct hda_channel_mode alc662_3ST_2ch_modes[1] = { 11197 { 2, NULL } 11198}; 11199 11200/* 11201 * 2ch mode 11202 */ 11203static struct hda_verb alc662_3ST_ch2_init[] = { 11204 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 11205 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 11206 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 11207 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 11208 { } /* end */ 11209}; 11210 11211/* 11212 * 6ch mode 11213 */ 11214static struct hda_verb alc662_3ST_ch6_init[] = { 11215 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 11216 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 11217 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, 11218 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 11219 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 11220 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 11221 { } /* end */ 11222}; 11223 11224static struct hda_channel_mode alc662_3ST_6ch_modes[2] = { 11225 { 2, alc662_3ST_ch2_init }, 11226 { 6, alc662_3ST_ch6_init }, 11227}; 11228 11229/* 11230 * 2ch mode 11231 */ 11232static struct hda_verb alc662_sixstack_ch6_init[] = { 11233 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 11234 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 11235 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 11236 { } /* end */ 11237}; 11238 11239/* 11240 * 6ch mode 11241 */ 11242static struct hda_verb alc662_sixstack_ch8_init[] = { 11243 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 11244 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 11245 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 11246 { } /* end */ 11247}; 11248 11249static struct hda_channel_mode alc662_5stack_modes[2] = { 11250 { 2, alc662_sixstack_ch6_init }, 11251 { 6, alc662_sixstack_ch8_init }, 11252}; 11253 11254/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 11255 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b 11256 */ 11257 11258static struct snd_kcontrol_new alc662_base_mixer[] = { 11259 /* output mixer control */ 11260 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), 11261 HDA_CODEC_MUTE("Front Playback Switch", 0x02, 0x0, HDA_OUTPUT), 11262 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT), 11263 HDA_CODEC_MUTE("Surround Playback Switch", 0x03, 0x0, HDA_OUTPUT), 11264 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT), 11265 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT), 11266 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT), 11267 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT), 11268 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 11269 11270 /*Input mixer control */ 11271 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT), 11272 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT), 11273 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT), 11274 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT), 11275 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT), 11276 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT), 11277 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT), 11278 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT), 11279 11280 /* Capture mixer control */ 11281 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), 11282 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), 11283 { 11284 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 11285 .name = "Capture Source", 11286 .count = 1, 11287 .info = alc_mux_enum_info, 11288 .get = alc_mux_enum_get, 11289 .put = alc_mux_enum_put, 11290 }, 11291 { } /* end */ 11292}; 11293 11294static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = { 11295 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 11296 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT), 11297 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 11298 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 11299 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 11300 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 11301 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 11302 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11303 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11304 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 11305 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 11306 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 11307 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 11308 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), 11309 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), 11310 { 11311 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 11312 /* .name = "Capture Source", */ 11313 .name = "Input Source", 11314 .count = 1, 11315 .info = alc662_mux_enum_info, 11316 .get = alc662_mux_enum_get, 11317 .put = alc662_mux_enum_put, 11318 }, 11319 { } /* end */ 11320}; 11321 11322static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = { 11323 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 11324 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT), 11325 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT), 11326 HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT), 11327 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT), 11328 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT), 11329 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT), 11330 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT), 11331 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 11332 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 11333 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 11334 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 11335 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 11336 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11337 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11338 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 11339 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 11340 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 11341 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 11342 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), 11343 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), 11344 { 11345 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 11346 /* .name = "Capture Source", */ 11347 .name = "Input Source", 11348 .count = 1, 11349 .info = alc662_mux_enum_info, 11350 .get = alc662_mux_enum_get, 11351 .put = alc662_mux_enum_put, 11352 }, 11353 { } /* end */ 11354}; 11355 11356static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = { 11357 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 11358 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT), 11359 HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x03, 0x0, HDA_OUTPUT), 11360 HDA_BIND_MUTE("iSpeaker Playback Switch", 0x03, 2, HDA_INPUT), 11361 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 11362 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 11363 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 11364 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 11365 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 11366 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), 11367 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), 11368 { 11369 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 11370 /* .name = "Capture Source", */ 11371 .name = "Input Source", 11372 .count = 1, 11373 .info = alc662_mux_enum_info, 11374 .get = alc662_mux_enum_get, 11375 .put = alc662_mux_enum_put, 11376 }, 11377 { } /* end */ 11378}; 11379 11380static struct snd_kcontrol_new alc662_chmode_mixer[] = { 11381 { 11382 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 11383 .name = "Channel Mode", 11384 .info = alc_ch_mode_info, 11385 .get = alc_ch_mode_get, 11386 .put = alc_ch_mode_put, 11387 }, 11388 { } /* end */ 11389}; 11390 11391static struct hda_verb alc662_init_verbs[] = { 11392 /* ADC: mute amp left and right */ 11393 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 11394 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 11395 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 11396 11397 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 11398 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 11399 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 11400 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 11401 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 11402 11403 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11404 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11405 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11406 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11407 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11408 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11409 11410 /* Front Pin: output 0 (0x0c) */ 11411 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 11412 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 11413 11414 /* Rear Pin: output 1 (0x0d) */ 11415 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 11416 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 11417 11418 /* CLFE Pin: output 2 (0x0e) */ 11419 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 11420 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 11421 11422 /* Mic (rear) pin: input vref at 80% */ 11423 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 11424 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 11425 /* Front Mic pin: input vref at 80% */ 11426 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 11427 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 11428 /* Line In pin: input */ 11429 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 11430 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 11431 /* Line-2 In: Headphone output (output 0 - 0x0c) */ 11432 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11433 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 11434 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 11435 /* CD pin widget for input */ 11436 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 11437 11438 /* FIXME: use matrix-type input source selection */ 11439 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 11440 /* Input mixer */ 11441 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11442 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11443 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 11444 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, 11445 { } 11446}; 11447 11448static struct hda_verb alc662_sue_init_verbs[] = { 11449 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT}, 11450 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT}, 11451 {} 11452}; 11453 11454/* 11455 * generic initialization of ADC, input mixers and output mixers 11456 */ 11457static struct hda_verb alc662_auto_init_verbs[] = { 11458 /* 11459 * Unmute ADC and set the default input to mic-in 11460 */ 11461 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 11462 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11463 11464 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 11465 * mixer widget 11466 * Note: PASD motherboards uses the Line In 2 as the input for front 11467 * panel mic (mic 2) 11468 */ 11469 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 11470 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 11471 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 11472 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 11473 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 11474 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 11475 11476 /* 11477 * Set up output mixers (0x0c - 0x0f) 11478 */ 11479 /* set vol=0 to output mixers */ 11480 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 11481 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 11482 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 11483 11484 /* set up input amps for analog loopback */ 11485 /* Amp Indices: DAC = 0, mixer = 1 */ 11486 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11487 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11488 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11489 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11490 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11491 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11492 11493 11494 /* FIXME: use matrix-type input source selection */ 11495 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 11496 /* Input mixer */ 11497 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11498 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11499 { } 11500}; 11501 11502/* capture mixer elements */ 11503static struct snd_kcontrol_new alc662_capture_mixer[] = { 11504 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), 11505 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), 11506 { 11507 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 11508 /* The multiple "Capture Source" controls confuse alsamixer 11509 * So call somewhat different.. 11510 * FIXME: the controls appear in the "playback" view! 11511 */ 11512 /* .name = "Capture Source", */ 11513 .name = "Input Source", 11514 .count = 1, 11515 .info = alc882_mux_enum_info, 11516 .get = alc882_mux_enum_get, 11517 .put = alc882_mux_enum_put, 11518 }, 11519 { } /* end */ 11520}; 11521 11522static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec) 11523{ 11524 unsigned int present; 11525 unsigned char bits; 11526 11527 present = snd_hda_codec_read(codec, 0x14, 0, 11528 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 11529 bits = present ? HDA_AMP_MUTE : 0; 11530 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 11531 HDA_AMP_MUTE, bits); 11532} 11533 11534static void alc662_lenovo_101e_all_automute(struct hda_codec *codec) 11535{ 11536 unsigned int present; 11537 unsigned char bits; 11538 11539 present = snd_hda_codec_read(codec, 0x1b, 0, 11540 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 11541 bits = present ? HDA_AMP_MUTE : 0; 11542 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 11543 HDA_AMP_MUTE, bits); 11544 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 11545 HDA_AMP_MUTE, bits); 11546} 11547 11548static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec, 11549 unsigned int res) 11550{ 11551 if ((res >> 26) == ALC880_HP_EVENT) 11552 alc662_lenovo_101e_all_automute(codec); 11553 if ((res >> 26) == ALC880_FRONT_EVENT) 11554 alc662_lenovo_101e_ispeaker_automute(codec); 11555} 11556 11557#ifdef CONFIG_SND_HDA_POWER_SAVE 11558#define alc662_loopbacks alc880_loopbacks 11559#endif 11560 11561 11562/* pcm configuration: identiacal with ALC880 */ 11563#define alc662_pcm_analog_playback alc880_pcm_analog_playback 11564#define alc662_pcm_analog_capture alc880_pcm_analog_capture 11565#define alc662_pcm_digital_playback alc880_pcm_digital_playback 11566#define alc662_pcm_digital_capture alc880_pcm_digital_capture 11567 11568/* 11569 * configuration and preset 11570 */ 11571static const char *alc662_models[ALC662_MODEL_LAST] = { 11572 [ALC662_3ST_2ch_DIG] = "3stack-dig", 11573 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig", 11574 [ALC662_3ST_6ch] = "3stack-6ch", 11575 [ALC662_5ST_DIG] = "6stack-dig", 11576 [ALC662_LENOVO_101E] = "lenovo-101e", 11577 [ALC662_AUTO] = "auto", 11578}; 11579 11580static struct snd_pci_quirk alc662_cfg_tbl[] = { 11581 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E), 11582 {} 11583}; 11584 11585static struct alc_config_preset alc662_presets[] = { 11586 [ALC662_3ST_2ch_DIG] = { 11587 .mixers = { alc662_3ST_2ch_mixer }, 11588 .init_verbs = { alc662_init_verbs }, 11589 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 11590 .dac_nids = alc662_dac_nids, 11591 .dig_out_nid = ALC662_DIGOUT_NID, 11592 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids), 11593 .adc_nids = alc662_adc_nids, 11594 .dig_in_nid = ALC662_DIGIN_NID, 11595 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 11596 .channel_mode = alc662_3ST_2ch_modes, 11597 .input_mux = &alc662_capture_source, 11598 }, 11599 [ALC662_3ST_6ch_DIG] = { 11600 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer }, 11601 .init_verbs = { alc662_init_verbs }, 11602 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 11603 .dac_nids = alc662_dac_nids, 11604 .dig_out_nid = ALC662_DIGOUT_NID, 11605 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids), 11606 .adc_nids = alc662_adc_nids, 11607 .dig_in_nid = ALC662_DIGIN_NID, 11608 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), 11609 .channel_mode = alc662_3ST_6ch_modes, 11610 .need_dac_fix = 1, 11611 .input_mux = &alc662_capture_source, 11612 }, 11613 [ALC662_3ST_6ch] = { 11614 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer }, 11615 .init_verbs = { alc662_init_verbs }, 11616 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 11617 .dac_nids = alc662_dac_nids, 11618 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids), 11619 .adc_nids = alc662_adc_nids, 11620 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), 11621 .channel_mode = alc662_3ST_6ch_modes, 11622 .need_dac_fix = 1, 11623 .input_mux = &alc662_capture_source, 11624 }, 11625 [ALC662_5ST_DIG] = { 11626 .mixers = { alc662_base_mixer, alc662_chmode_mixer }, 11627 .init_verbs = { alc662_init_verbs }, 11628 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 11629 .dac_nids = alc662_dac_nids, 11630 .dig_out_nid = ALC662_DIGOUT_NID, 11631 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids), 11632 .adc_nids = alc662_adc_nids, 11633 .dig_in_nid = ALC662_DIGIN_NID, 11634 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes), 11635 .channel_mode = alc662_5stack_modes, 11636 .input_mux = &alc662_capture_source, 11637 }, 11638 [ALC662_LENOVO_101E] = { 11639 .mixers = { alc662_lenovo_101e_mixer }, 11640 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs }, 11641 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 11642 .dac_nids = alc662_dac_nids, 11643 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids), 11644 .adc_nids = alc662_adc_nids, 11645 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 11646 .channel_mode = alc662_3ST_2ch_modes, 11647 .input_mux = &alc662_lenovo_101e_capture_source, 11648 .unsol_event = alc662_lenovo_101e_unsol_event, 11649 .init_hook = alc662_lenovo_101e_all_automute, 11650 }, 11651 11652}; 11653 11654 11655/* 11656 * BIOS auto configuration 11657 */ 11658 11659/* add playback controls from the parsed DAC table */ 11660static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec, 11661 const struct auto_pin_cfg *cfg) 11662{ 11663 char name[32]; 11664 static const char *chname[4] = { 11665 "Front", "Surround", NULL /*CLFE*/, "Side" 11666 }; 11667 hda_nid_t nid; 11668 int i, err; 11669 11670 for (i = 0; i < cfg->line_outs; i++) { 11671 if (!spec->multiout.dac_nids[i]) 11672 continue; 11673 nid = alc880_idx_to_mixer(i); 11674 if (i == 2) { 11675 /* Center/LFE */ 11676 err = add_control(spec, ALC_CTL_WIDGET_VOL, 11677 "Center Playback Volume", 11678 HDA_COMPOSE_AMP_VAL(nid, 1, 0, 11679 HDA_OUTPUT)); 11680 if (err < 0) 11681 return err; 11682 err = add_control(spec, ALC_CTL_WIDGET_VOL, 11683 "LFE Playback Volume", 11684 HDA_COMPOSE_AMP_VAL(nid, 2, 0, 11685 HDA_OUTPUT)); 11686 if (err < 0) 11687 return err; 11688 err = add_control(spec, ALC_CTL_BIND_MUTE, 11689 "Center Playback Switch", 11690 HDA_COMPOSE_AMP_VAL(nid, 1, 2, 11691 HDA_INPUT)); 11692 if (err < 0) 11693 return err; 11694 err = add_control(spec, ALC_CTL_BIND_MUTE, 11695 "LFE Playback Switch", 11696 HDA_COMPOSE_AMP_VAL(nid, 2, 2, 11697 HDA_INPUT)); 11698 if (err < 0) 11699 return err; 11700 } else { 11701 sprintf(name, "%s Playback Volume", chname[i]); 11702 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, 11703 HDA_COMPOSE_AMP_VAL(nid, 3, 0, 11704 HDA_OUTPUT)); 11705 if (err < 0) 11706 return err; 11707 sprintf(name, "%s Playback Switch", chname[i]); 11708 err = add_control(spec, ALC_CTL_BIND_MUTE, name, 11709 HDA_COMPOSE_AMP_VAL(nid, 3, 2, 11710 HDA_INPUT)); 11711 if (err < 0) 11712 return err; 11713 } 11714 } 11715 return 0; 11716} 11717 11718/* add playback controls for speaker and HP outputs */ 11719static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin, 11720 const char *pfx) 11721{ 11722 hda_nid_t nid; 11723 int err; 11724 char name[32]; 11725 11726 if (!pin) 11727 return 0; 11728 11729 if (alc880_is_fixed_pin(pin)) { 11730 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); 11731 /* printk("DAC nid=%x\n",nid); */ 11732 /* specify the DAC as the extra output */ 11733 if (!spec->multiout.hp_nid) 11734 spec->multiout.hp_nid = nid; 11735 else 11736 spec->multiout.extra_out_nid[0] = nid; 11737 /* control HP volume/switch on the output mixer amp */ 11738 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); 11739 sprintf(name, "%s Playback Volume", pfx); 11740 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, 11741 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); 11742 if (err < 0) 11743 return err; 11744 sprintf(name, "%s Playback Switch", pfx); 11745 err = add_control(spec, ALC_CTL_BIND_MUTE, name, 11746 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT)); 11747 if (err < 0) 11748 return err; 11749 } else if (alc880_is_multi_pin(pin)) { 11750 /* set manual connection */ 11751 /* we have only a switch on HP-out PIN */ 11752 sprintf(name, "%s Playback Switch", pfx); 11753 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, 11754 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); 11755 if (err < 0) 11756 return err; 11757 } 11758 return 0; 11759} 11760 11761/* create playback/capture controls for input pins */ 11762static int alc662_auto_create_analog_input_ctls(struct alc_spec *spec, 11763 const struct auto_pin_cfg *cfg) 11764{ 11765 struct hda_input_mux *imux = &spec->private_imux; 11766 int i, err, idx; 11767 11768 for (i = 0; i < AUTO_PIN_LAST; i++) { 11769 if (alc880_is_input_pin(cfg->input_pins[i])) { 11770 idx = alc880_input_pin_idx(cfg->input_pins[i]); 11771 err = new_analog_input(spec, cfg->input_pins[i], 11772 auto_pin_cfg_labels[i], 11773 idx, 0x0b); 11774 if (err < 0) 11775 return err; 11776 imux->items[imux->num_items].label = 11777 auto_pin_cfg_labels[i]; 11778 imux->items[imux->num_items].index = 11779 alc880_input_pin_idx(cfg->input_pins[i]); 11780 imux->num_items++; 11781 } 11782 } 11783 return 0; 11784} 11785 11786static void alc662_auto_set_output_and_unmute(struct hda_codec *codec, 11787 hda_nid_t nid, int pin_type, 11788 int dac_idx) 11789{ 11790 /* set as output */ 11791 snd_hda_codec_write(codec, nid, 0, 11792 AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type); 11793 snd_hda_codec_write(codec, nid, 0, 11794 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); 11795 /* need the manual connection? */ 11796 if (alc880_is_multi_pin(nid)) { 11797 struct alc_spec *spec = codec->spec; 11798 int idx = alc880_multi_pin_idx(nid); 11799 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0, 11800 AC_VERB_SET_CONNECT_SEL, 11801 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx])); 11802 } 11803} 11804 11805static void alc662_auto_init_multi_out(struct hda_codec *codec) 11806{ 11807 struct alc_spec *spec = codec->spec; 11808 int i; 11809 11810 for (i = 0; i <= HDA_SIDE; i++) { 11811 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 11812 int pin_type = get_pin_type(spec->autocfg.line_out_type); 11813 if (nid) 11814 alc662_auto_set_output_and_unmute(codec, nid, pin_type, 11815 i); 11816 } 11817} 11818 11819static void alc662_auto_init_hp_out(struct hda_codec *codec) 11820{ 11821 struct alc_spec *spec = codec->spec; 11822 hda_nid_t pin; 11823 11824 pin = spec->autocfg.hp_pins[0]; 11825 if (pin) /* connect to front */ 11826 /* use dac 0 */ 11827 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); 11828} 11829 11830#define alc662_is_input_pin(nid) alc880_is_input_pin(nid) 11831#define ALC662_PIN_CD_NID ALC880_PIN_CD_NID 11832 11833static void alc662_auto_init_analog_input(struct hda_codec *codec) 11834{ 11835 struct alc_spec *spec = codec->spec; 11836 int i; 11837 11838 for (i = 0; i < AUTO_PIN_LAST; i++) { 11839 hda_nid_t nid = spec->autocfg.input_pins[i]; 11840 if (alc662_is_input_pin(nid)) { 11841 snd_hda_codec_write(codec, nid, 0, 11842 AC_VERB_SET_PIN_WIDGET_CONTROL, 11843 (i <= AUTO_PIN_FRONT_MIC ? 11844 PIN_VREF80 : PIN_IN)); 11845 if (nid != ALC662_PIN_CD_NID) 11846 snd_hda_codec_write(codec, nid, 0, 11847 AC_VERB_SET_AMP_GAIN_MUTE, 11848 AMP_OUT_MUTE); 11849 } 11850 } 11851} 11852 11853static int alc662_parse_auto_config(struct hda_codec *codec) 11854{ 11855 struct alc_spec *spec = codec->spec; 11856 int err; 11857 static hda_nid_t alc662_ignore[] = { 0x1d, 0 }; 11858 11859 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 11860 alc662_ignore); 11861 if (err < 0) 11862 return err; 11863 if (!spec->autocfg.line_outs) 11864 return 0; /* can't find valid BIOS pin config */ 11865 11866 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); 11867 if (err < 0) 11868 return err; 11869 err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg); 11870 if (err < 0) 11871 return err; 11872 err = alc662_auto_create_extra_out(spec, 11873 spec->autocfg.speaker_pins[0], 11874 "Speaker"); 11875 if (err < 0) 11876 return err; 11877 err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0], 11878 "Headphone"); 11879 if (err < 0) 11880 return err; 11881 err = alc662_auto_create_analog_input_ctls(spec, &spec->autocfg); 11882 if (err < 0) 11883 return err; 11884 11885 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 11886 11887 if (spec->autocfg.dig_out_pin) 11888 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID; 11889 11890 if (spec->kctl_alloc) 11891 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 11892 11893 spec->num_mux_defs = 1; 11894 spec->input_mux = &spec->private_imux; 11895 11896 spec->init_verbs[spec->num_init_verbs++] = alc662_auto_init_verbs; 11897 spec->mixers[spec->num_mixers] = alc662_capture_mixer; 11898 spec->num_mixers++; 11899 return 1; 11900} 11901 11902/* additional initialization for auto-configuration model */ 11903static void alc662_auto_init(struct hda_codec *codec) 11904{ 11905 alc662_auto_init_multi_out(codec); 11906 alc662_auto_init_hp_out(codec); 11907 alc662_auto_init_analog_input(codec); 11908} 11909 11910static int patch_alc662(struct hda_codec *codec) 11911{ 11912 struct alc_spec *spec; 11913 int err, board_config; 11914 11915 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 11916 if (!spec) 11917 return -ENOMEM; 11918 11919 codec->spec = spec; 11920 11921 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST, 11922 alc662_models, 11923 alc662_cfg_tbl); 11924 if (board_config < 0) { 11925 printk(KERN_INFO "hda_codec: Unknown model for ALC662, " 11926 "trying auto-probe from BIOS...\n"); 11927 board_config = ALC662_AUTO; 11928 } 11929 11930 if (board_config == ALC662_AUTO) { 11931 /* automatic parse from the BIOS config */ 11932 err = alc662_parse_auto_config(codec); 11933 if (err < 0) { 11934 alc_free(codec); 11935 return err; 11936 } else if (!err) { 11937 printk(KERN_INFO 11938 "hda_codec: Cannot set up configuration " 11939 "from BIOS. Using base mode...\n"); 11940 board_config = ALC662_3ST_2ch_DIG; 11941 } 11942 } 11943 11944 if (board_config != ALC662_AUTO) 11945 setup_preset(spec, &alc662_presets[board_config]); 11946 11947 spec->stream_name_analog = "ALC662 Analog"; 11948 spec->stream_analog_playback = &alc662_pcm_analog_playback; 11949 spec->stream_analog_capture = &alc662_pcm_analog_capture; 11950 11951 spec->stream_name_digital = "ALC662 Digital"; 11952 spec->stream_digital_playback = &alc662_pcm_digital_playback; 11953 spec->stream_digital_capture = &alc662_pcm_digital_capture; 11954 11955 if (!spec->adc_nids && spec->input_mux) { 11956 spec->adc_nids = alc662_adc_nids; 11957 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids); 11958 } 11959 11960 codec->patch_ops = alc_patch_ops; 11961 if (board_config == ALC662_AUTO) 11962 spec->init_hook = alc662_auto_init; 11963#ifdef CONFIG_SND_HDA_POWER_SAVE 11964 if (!spec->loopback.amplist) 11965 spec->loopback.amplist = alc662_loopbacks; 11966#endif 11967 11968 return 0; 11969} 11970 11971/* 11972 * patch entries 11973 */ 11974struct hda_codec_preset snd_hda_preset_realtek[] = { 11975 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 }, 11976 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 }, 11977 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 }, 11978 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660", 11979 .patch = patch_alc861 }, 11980 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd }, 11981 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 }, 11982 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd }, 11983 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2", 11984 .patch = patch_alc883 }, 11985 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1", 11986 .patch = patch_alc662 }, 11987 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 }, 11988 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 }, 11989 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 }, 11990 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 }, 11991 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 }, 11992 {} /* terminator */ 11993}; 11994