1 /* 2 * HD audio interface patch for AD1882, AD1884, AD1981HD, AD1983, AD1984, 3 * AD1986A, AD1988 4 * 5 * Copyright (c) 2005-2007 Takashi Iwai <tiwai@suse.de> 6 * 7 * This driver is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This driver is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 */ 21 22 #include <linux/init.h> 23 #include <linux/delay.h> 24 #include <linux/slab.h> 25 #include <linux/pci.h> 26 #include <linux/module.h> 27 28 #include <sound/core.h> 29 #include "hda_codec.h" 30 #include "hda_local.h" 31 #include "hda_beep.h" 32 #include "hda_jack.h" 33 34 struct ad198x_spec { 35 const struct snd_kcontrol_new *mixers[6]; 36 int num_mixers; 37 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */ 38 const struct hda_verb *init_verbs[6]; /* initialization verbs 39 * don't forget NULL termination! 40 */ 41 unsigned int num_init_verbs; 42 43 /* playback */ 44 struct hda_multi_out multiout; /* playback set-up 45 * max_channels, dacs must be set 46 * dig_out_nid and hp_nid are optional 47 */ 48 unsigned int cur_eapd; 49 unsigned int need_dac_fix; 50 51 const hda_nid_t *alt_dac_nid; 52 const struct hda_pcm_stream *stream_analog_alt_playback; 53 int independent_hp; 54 int num_active_streams; 55 56 /* capture */ 57 unsigned int num_adc_nids; 58 const hda_nid_t *adc_nids; 59 hda_nid_t dig_in_nid; /* digital-in NID; optional */ 60 61 /* capture source */ 62 const struct hda_input_mux *input_mux; 63 const hda_nid_t *capsrc_nids; 64 unsigned int cur_mux[3]; 65 66 /* channel model */ 67 const struct hda_channel_mode *channel_mode; 68 int num_channel_mode; 69 70 /* PCM information */ 71 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */ 72 73 unsigned int spdif_route; 74 75 /* dynamic controls, init_verbs and input_mux */ 76 struct auto_pin_cfg autocfg; 77 struct snd_array kctls; 78 struct hda_input_mux private_imux; 79 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; 80 81 unsigned int jack_present: 1; 82 unsigned int inv_jack_detect: 1;/* inverted jack-detection */ 83 unsigned int inv_eapd: 1; /* inverted EAPD implementation */ 84 unsigned int analog_beep: 1; /* analog beep input present */ 85 unsigned int avoid_init_slave_vol:1; 86 87 #ifdef CONFIG_SND_HDA_POWER_SAVE 88 struct hda_loopback_check loopback; 89 #endif 90 /* for virtual master */ 91 hda_nid_t vmaster_nid; 92 const char * const *slave_vols; 93 const char * const *slave_sws; 94 }; 95 96 /* 97 * input MUX handling (common part) 98 */ 99 static int ad198x_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 100 { 101 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 102 struct ad198x_spec *spec = codec->spec; 103 104 return snd_hda_input_mux_info(spec->input_mux, uinfo); 105 } 106 107 static int ad198x_mux_enum_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 108 { 109 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 110 struct ad198x_spec *spec = codec->spec; 111 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 112 113 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx]; 114 return 0; 115 } 116 117 static int ad198x_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 118 { 119 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 120 struct ad198x_spec *spec = codec->spec; 121 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 122 123 return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol, 124 spec->capsrc_nids[adc_idx], 125 &spec->cur_mux[adc_idx]); 126 } 127 128 /* 129 * initialization (common callbacks) 130 */ 131 static int ad198x_init(struct hda_codec *codec) 132 { 133 struct ad198x_spec *spec = codec->spec; 134 int i; 135 136 for (i = 0; i < spec->num_init_verbs; i++) 137 snd_hda_sequence_write(codec, spec->init_verbs[i]); 138 return 0; 139 } 140 141 static const char * const ad_slave_pfxs[] = { 142 "Front", "Surround", "Center", "LFE", "Side", 143 "Headphone", "Mono", "Speaker", "IEC958", 144 NULL 145 }; 146 147 static const char * const ad1988_6stack_fp_slave_pfxs[] = { 148 "Front", "Surround", "Center", "LFE", "Side", "IEC958", 149 NULL 150 }; 151 152 static void ad198x_free_kctls(struct hda_codec *codec); 153 154 #ifdef CONFIG_SND_HDA_INPUT_BEEP 155 /* additional beep mixers; the actual parameters are overwritten at build */ 156 static const struct snd_kcontrol_new ad_beep_mixer[] = { 157 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_OUTPUT), 158 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_OUTPUT), 159 { } /* end */ 160 }; 161 162 static const struct snd_kcontrol_new ad_beep2_mixer[] = { 163 HDA_CODEC_VOLUME("Digital Beep Playback Volume", 0, 0, HDA_OUTPUT), 164 HDA_CODEC_MUTE_BEEP("Digital Beep Playback Switch", 0, 0, HDA_OUTPUT), 165 { } /* end */ 166 }; 167 168 #define set_beep_amp(spec, nid, idx, dir) \ 169 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 1, idx, dir)) /* mono */ 170 #else 171 #define set_beep_amp(spec, nid, idx, dir) /* NOP */ 172 #endif 173 174 static int ad198x_build_controls(struct hda_codec *codec) 175 { 176 struct ad198x_spec *spec = codec->spec; 177 struct snd_kcontrol *kctl; 178 unsigned int i; 179 int err; 180 181 for (i = 0; i < spec->num_mixers; i++) { 182 err = snd_hda_add_new_ctls(codec, spec->mixers[i]); 183 if (err < 0) 184 return err; 185 } 186 if (spec->multiout.dig_out_nid) { 187 err = snd_hda_create_spdif_out_ctls(codec, 188 spec->multiout.dig_out_nid, 189 spec->multiout.dig_out_nid); 190 if (err < 0) 191 return err; 192 err = snd_hda_create_spdif_share_sw(codec, 193 &spec->multiout); 194 if (err < 0) 195 return err; 196 spec->multiout.share_spdif = 1; 197 } 198 if (spec->dig_in_nid) { 199 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid); 200 if (err < 0) 201 return err; 202 } 203 204 /* create beep controls if needed */ 205 #ifdef CONFIG_SND_HDA_INPUT_BEEP 206 if (spec->beep_amp) { 207 const struct snd_kcontrol_new *knew; 208 knew = spec->analog_beep ? ad_beep2_mixer : ad_beep_mixer; 209 for ( ; knew->name; knew++) { 210 struct snd_kcontrol *kctl; 211 kctl = snd_ctl_new1(knew, codec); 212 if (!kctl) 213 return -ENOMEM; 214 kctl->private_value = spec->beep_amp; 215 err = snd_hda_ctl_add(codec, 0, kctl); 216 if (err < 0) 217 return err; 218 } 219 } 220 #endif 221 222 /* if we have no master control, let's create it */ 223 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) { 224 unsigned int vmaster_tlv[4]; 225 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid, 226 HDA_OUTPUT, vmaster_tlv); 227 err = __snd_hda_add_vmaster(codec, "Master Playback Volume", 228 vmaster_tlv, 229 (spec->slave_vols ? 230 spec->slave_vols : ad_slave_pfxs), 231 "Playback Volume", 232 !spec->avoid_init_slave_vol, NULL); 233 if (err < 0) 234 return err; 235 } 236 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) { 237 err = snd_hda_add_vmaster(codec, "Master Playback Switch", 238 NULL, 239 (spec->slave_sws ? 240 spec->slave_sws : ad_slave_pfxs), 241 "Playback Switch"); 242 if (err < 0) 243 return err; 244 } 245 246 ad198x_free_kctls(codec); /* no longer needed */ 247 248 /* assign Capture Source enums to NID */ 249 kctl = snd_hda_find_mixer_ctl(codec, "Capture Source"); 250 if (!kctl) 251 kctl = snd_hda_find_mixer_ctl(codec, "Input Source"); 252 for (i = 0; kctl && i < kctl->count; i++) { 253 err = snd_hda_add_nid(codec, kctl, i, spec->capsrc_nids[i]); 254 if (err < 0) 255 return err; 256 } 257 258 /* assign IEC958 enums to NID */ 259 kctl = snd_hda_find_mixer_ctl(codec, 260 SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source"); 261 if (kctl) { 262 err = snd_hda_add_nid(codec, kctl, 0, 263 spec->multiout.dig_out_nid); 264 if (err < 0) 265 return err; 266 } 267 268 return 0; 269 } 270 271 #ifdef CONFIG_SND_HDA_POWER_SAVE 272 static int ad198x_check_power_status(struct hda_codec *codec, hda_nid_t nid) 273 { 274 struct ad198x_spec *spec = codec->spec; 275 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid); 276 } 277 #endif 278 279 static void activate_ctl(struct hda_codec *codec, const char *name, int active) 280 { 281 struct snd_kcontrol *ctl = snd_hda_find_mixer_ctl(codec, name); 282 if (ctl) { 283 ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE; 284 ctl->vd[0].access |= active ? 0 : 285 SNDRV_CTL_ELEM_ACCESS_INACTIVE; 286 ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_WRITE; 287 ctl->vd[0].access |= active ? 288 SNDRV_CTL_ELEM_ACCESS_WRITE : 0; 289 snd_ctl_notify(codec->bus->card, 290 SNDRV_CTL_EVENT_MASK_INFO, &ctl->id); 291 } 292 } 293 294 static void set_stream_active(struct hda_codec *codec, bool active) 295 { 296 struct ad198x_spec *spec = codec->spec; 297 if (active) 298 spec->num_active_streams++; 299 else 300 spec->num_active_streams--; 301 activate_ctl(codec, "Independent HP", spec->num_active_streams == 0); 302 } 303 304 static int ad1988_independent_hp_info(struct snd_kcontrol *kcontrol, 305 struct snd_ctl_elem_info *uinfo) 306 { 307 static const char * const texts[] = { "OFF", "ON", NULL}; 308 int index; 309 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 310 uinfo->count = 1; 311 uinfo->value.enumerated.items = 2; 312 index = uinfo->value.enumerated.item; 313 if (index >= 2) 314 index = 1; 315 strcpy(uinfo->value.enumerated.name, texts[index]); 316 return 0; 317 } 318 319 static int ad1988_independent_hp_get(struct snd_kcontrol *kcontrol, 320 struct snd_ctl_elem_value *ucontrol) 321 { 322 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 323 struct ad198x_spec *spec = codec->spec; 324 ucontrol->value.enumerated.item[0] = spec->independent_hp; 325 return 0; 326 } 327 328 static int ad1988_independent_hp_put(struct snd_kcontrol *kcontrol, 329 struct snd_ctl_elem_value *ucontrol) 330 { 331 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 332 struct ad198x_spec *spec = codec->spec; 333 unsigned int select = ucontrol->value.enumerated.item[0]; 334 if (spec->independent_hp != select) { 335 spec->independent_hp = select; 336 if (spec->independent_hp) 337 spec->multiout.hp_nid = 0; 338 else 339 spec->multiout.hp_nid = spec->alt_dac_nid[0]; 340 return 1; 341 } 342 return 0; 343 } 344 345 /* 346 * Analog playback callbacks 347 */ 348 static int ad198x_playback_pcm_open(struct hda_pcm_stream *hinfo, 349 struct hda_codec *codec, 350 struct snd_pcm_substream *substream) 351 { 352 struct ad198x_spec *spec = codec->spec; 353 int err; 354 set_stream_active(codec, true); 355 err = snd_hda_multi_out_analog_open(codec, &spec->multiout, substream, 356 hinfo); 357 if (err < 0) { 358 set_stream_active(codec, false); 359 return err; 360 } 361 return 0; 362 } 363 364 static int ad198x_playback_pcm_prepare(struct hda_pcm_stream *hinfo, 365 struct hda_codec *codec, 366 unsigned int stream_tag, 367 unsigned int format, 368 struct snd_pcm_substream *substream) 369 { 370 struct ad198x_spec *spec = codec->spec; 371 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, stream_tag, 372 format, substream); 373 } 374 375 static int ad198x_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, 376 struct hda_codec *codec, 377 struct snd_pcm_substream *substream) 378 { 379 struct ad198x_spec *spec = codec->spec; 380 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); 381 } 382 383 static int ad198x_playback_pcm_close(struct hda_pcm_stream *hinfo, 384 struct hda_codec *codec, 385 struct snd_pcm_substream *substream) 386 { 387 set_stream_active(codec, false); 388 return 0; 389 } 390 391 static int ad1988_alt_playback_pcm_open(struct hda_pcm_stream *hinfo, 392 struct hda_codec *codec, 393 struct snd_pcm_substream *substream) 394 { 395 struct ad198x_spec *spec = codec->spec; 396 if (!spec->independent_hp) 397 return -EBUSY; 398 set_stream_active(codec, true); 399 return 0; 400 } 401 402 static int ad1988_alt_playback_pcm_close(struct hda_pcm_stream *hinfo, 403 struct hda_codec *codec, 404 struct snd_pcm_substream *substream) 405 { 406 set_stream_active(codec, false); 407 return 0; 408 } 409 410 static const struct hda_pcm_stream ad198x_pcm_analog_alt_playback = { 411 .substreams = 1, 412 .channels_min = 2, 413 .channels_max = 2, 414 .ops = { 415 .open = ad1988_alt_playback_pcm_open, 416 .close = ad1988_alt_playback_pcm_close 417 }, 418 }; 419 420 /* 421 * Digital out 422 */ 423 static int ad198x_dig_playback_pcm_open(struct hda_pcm_stream *hinfo, 424 struct hda_codec *codec, 425 struct snd_pcm_substream *substream) 426 { 427 struct ad198x_spec *spec = codec->spec; 428 return snd_hda_multi_out_dig_open(codec, &spec->multiout); 429 } 430 431 static int ad198x_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, 432 struct hda_codec *codec, 433 struct snd_pcm_substream *substream) 434 { 435 struct ad198x_spec *spec = codec->spec; 436 return snd_hda_multi_out_dig_close(codec, &spec->multiout); 437 } 438 439 static int ad198x_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, 440 struct hda_codec *codec, 441 unsigned int stream_tag, 442 unsigned int format, 443 struct snd_pcm_substream *substream) 444 { 445 struct ad198x_spec *spec = codec->spec; 446 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag, 447 format, substream); 448 } 449 450 static int ad198x_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, 451 struct hda_codec *codec, 452 struct snd_pcm_substream *substream) 453 { 454 struct ad198x_spec *spec = codec->spec; 455 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout); 456 } 457 458 /* 459 * Analog capture 460 */ 461 static int ad198x_capture_pcm_prepare(struct hda_pcm_stream *hinfo, 462 struct hda_codec *codec, 463 unsigned int stream_tag, 464 unsigned int format, 465 struct snd_pcm_substream *substream) 466 { 467 struct ad198x_spec *spec = codec->spec; 468 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number], 469 stream_tag, 0, format); 470 return 0; 471 } 472 473 static int ad198x_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, 474 struct hda_codec *codec, 475 struct snd_pcm_substream *substream) 476 { 477 struct ad198x_spec *spec = codec->spec; 478 snd_hda_codec_cleanup_stream(codec, spec->adc_nids[substream->number]); 479 return 0; 480 } 481 482 /* 483 */ 484 static const struct hda_pcm_stream ad198x_pcm_analog_playback = { 485 .substreams = 1, 486 .channels_min = 2, 487 .channels_max = 6, /* changed later */ 488 .nid = 0, /* fill later */ 489 .ops = { 490 .open = ad198x_playback_pcm_open, 491 .prepare = ad198x_playback_pcm_prepare, 492 .cleanup = ad198x_playback_pcm_cleanup, 493 .close = ad198x_playback_pcm_close 494 }, 495 }; 496 497 static const struct hda_pcm_stream ad198x_pcm_analog_capture = { 498 .substreams = 1, 499 .channels_min = 2, 500 .channels_max = 2, 501 .nid = 0, /* fill later */ 502 .ops = { 503 .prepare = ad198x_capture_pcm_prepare, 504 .cleanup = ad198x_capture_pcm_cleanup 505 }, 506 }; 507 508 static const struct hda_pcm_stream ad198x_pcm_digital_playback = { 509 .substreams = 1, 510 .channels_min = 2, 511 .channels_max = 2, 512 .nid = 0, /* fill later */ 513 .ops = { 514 .open = ad198x_dig_playback_pcm_open, 515 .close = ad198x_dig_playback_pcm_close, 516 .prepare = ad198x_dig_playback_pcm_prepare, 517 .cleanup = ad198x_dig_playback_pcm_cleanup 518 }, 519 }; 520 521 static const struct hda_pcm_stream ad198x_pcm_digital_capture = { 522 .substreams = 1, 523 .channels_min = 2, 524 .channels_max = 2, 525 /* NID is set in alc_build_pcms */ 526 }; 527 528 static int ad198x_build_pcms(struct hda_codec *codec) 529 { 530 struct ad198x_spec *spec = codec->spec; 531 struct hda_pcm *info = spec->pcm_rec; 532 533 codec->num_pcms = 1; 534 codec->pcm_info = info; 535 536 info->name = "AD198x Analog"; 537 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ad198x_pcm_analog_playback; 538 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->multiout.max_channels; 539 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0]; 540 info->stream[SNDRV_PCM_STREAM_CAPTURE] = ad198x_pcm_analog_capture; 541 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = spec->num_adc_nids; 542 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0]; 543 544 if (spec->multiout.dig_out_nid) { 545 info++; 546 codec->num_pcms++; 547 info->name = "AD198x Digital"; 548 info->pcm_type = HDA_PCM_TYPE_SPDIF; 549 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ad198x_pcm_digital_playback; 550 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid; 551 if (spec->dig_in_nid) { 552 info->stream[SNDRV_PCM_STREAM_CAPTURE] = ad198x_pcm_digital_capture; 553 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid; 554 } 555 } 556 557 if (spec->alt_dac_nid && spec->stream_analog_alt_playback) { 558 codec->num_pcms++; 559 info = spec->pcm_rec + 2; 560 info->name = "AD198x Headphone"; 561 info->pcm_type = HDA_PCM_TYPE_AUDIO; 562 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = 563 *spec->stream_analog_alt_playback; 564 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 565 spec->alt_dac_nid[0]; 566 } 567 568 return 0; 569 } 570 571 static void ad198x_free_kctls(struct hda_codec *codec) 572 { 573 struct ad198x_spec *spec = codec->spec; 574 575 if (spec->kctls.list) { 576 struct snd_kcontrol_new *kctl = spec->kctls.list; 577 int i; 578 for (i = 0; i < spec->kctls.used; i++) 579 kfree(kctl[i].name); 580 } 581 snd_array_free(&spec->kctls); 582 } 583 584 static void ad198x_power_eapd_write(struct hda_codec *codec, hda_nid_t front, 585 hda_nid_t hp) 586 { 587 struct ad198x_spec *spec = codec->spec; 588 if (snd_hda_query_pin_caps(codec, front) & AC_PINCAP_EAPD) 589 snd_hda_codec_write(codec, front, 0, AC_VERB_SET_EAPD_BTLENABLE, 590 !spec->inv_eapd ? 0x00 : 0x02); 591 if (snd_hda_query_pin_caps(codec, hp) & AC_PINCAP_EAPD) 592 snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_EAPD_BTLENABLE, 593 !spec->inv_eapd ? 0x00 : 0x02); 594 } 595 596 static void ad198x_power_eapd(struct hda_codec *codec) 597 { 598 /* We currently only handle front, HP */ 599 switch (codec->vendor_id) { 600 case 0x11d41882: 601 case 0x11d4882a: 602 case 0x11d41884: 603 case 0x11d41984: 604 case 0x11d41883: 605 case 0x11d4184a: 606 case 0x11d4194a: 607 case 0x11d4194b: 608 case 0x11d41988: 609 case 0x11d4198b: 610 case 0x11d4989a: 611 case 0x11d4989b: 612 ad198x_power_eapd_write(codec, 0x12, 0x11); 613 break; 614 case 0x11d41981: 615 case 0x11d41983: 616 ad198x_power_eapd_write(codec, 0x05, 0x06); 617 break; 618 case 0x11d41986: 619 ad198x_power_eapd_write(codec, 0x1b, 0x1a); 620 break; 621 } 622 } 623 624 static void ad198x_shutup(struct hda_codec *codec) 625 { 626 snd_hda_shutup_pins(codec); 627 ad198x_power_eapd(codec); 628 } 629 630 static void ad198x_free(struct hda_codec *codec) 631 { 632 struct ad198x_spec *spec = codec->spec; 633 634 if (!spec) 635 return; 636 637 ad198x_shutup(codec); 638 ad198x_free_kctls(codec); 639 kfree(spec); 640 snd_hda_detach_beep_device(codec); 641 } 642 643 #ifdef CONFIG_PM 644 static int ad198x_suspend(struct hda_codec *codec, pm_message_t state) 645 { 646 ad198x_shutup(codec); 647 return 0; 648 } 649 #endif 650 651 static const struct hda_codec_ops ad198x_patch_ops = { 652 .build_controls = ad198x_build_controls, 653 .build_pcms = ad198x_build_pcms, 654 .init = ad198x_init, 655 .free = ad198x_free, 656 #ifdef CONFIG_SND_HDA_POWER_SAVE 657 .check_power_status = ad198x_check_power_status, 658 #endif 659 #ifdef CONFIG_PM 660 .suspend = ad198x_suspend, 661 #endif 662 .reboot_notify = ad198x_shutup, 663 }; 664 665 666 /* 667 * EAPD control 668 * the private value = nid 669 */ 670 #define ad198x_eapd_info snd_ctl_boolean_mono_info 671 672 static int ad198x_eapd_get(struct snd_kcontrol *kcontrol, 673 struct snd_ctl_elem_value *ucontrol) 674 { 675 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 676 struct ad198x_spec *spec = codec->spec; 677 if (spec->inv_eapd) 678 ucontrol->value.integer.value[0] = ! spec->cur_eapd; 679 else 680 ucontrol->value.integer.value[0] = spec->cur_eapd; 681 return 0; 682 } 683 684 static int ad198x_eapd_put(struct snd_kcontrol *kcontrol, 685 struct snd_ctl_elem_value *ucontrol) 686 { 687 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 688 struct ad198x_spec *spec = codec->spec; 689 hda_nid_t nid = kcontrol->private_value & 0xff; 690 unsigned int eapd; 691 eapd = !!ucontrol->value.integer.value[0]; 692 if (spec->inv_eapd) 693 eapd = !eapd; 694 if (eapd == spec->cur_eapd) 695 return 0; 696 spec->cur_eapd = eapd; 697 snd_hda_codec_write_cache(codec, nid, 698 0, AC_VERB_SET_EAPD_BTLENABLE, 699 eapd ? 0x02 : 0x00); 700 return 1; 701 } 702 703 static int ad198x_ch_mode_info(struct snd_kcontrol *kcontrol, 704 struct snd_ctl_elem_info *uinfo); 705 static int ad198x_ch_mode_get(struct snd_kcontrol *kcontrol, 706 struct snd_ctl_elem_value *ucontrol); 707 static int ad198x_ch_mode_put(struct snd_kcontrol *kcontrol, 708 struct snd_ctl_elem_value *ucontrol); 709 710 711 /* 712 * AD1986A specific 713 */ 714 715 #define AD1986A_SPDIF_OUT 0x02 716 #define AD1986A_FRONT_DAC 0x03 717 #define AD1986A_SURR_DAC 0x04 718 #define AD1986A_CLFE_DAC 0x05 719 #define AD1986A_ADC 0x06 720 721 static const hda_nid_t ad1986a_dac_nids[3] = { 722 AD1986A_FRONT_DAC, AD1986A_SURR_DAC, AD1986A_CLFE_DAC 723 }; 724 static const hda_nid_t ad1986a_adc_nids[1] = { AD1986A_ADC }; 725 static const hda_nid_t ad1986a_capsrc_nids[1] = { 0x12 }; 726 727 static const struct hda_input_mux ad1986a_capture_source = { 728 .num_items = 7, 729 .items = { 730 { "Mic", 0x0 }, 731 { "CD", 0x1 }, 732 { "Aux", 0x3 }, 733 { "Line", 0x4 }, 734 { "Mix", 0x5 }, 735 { "Mono", 0x6 }, 736 { "Phone", 0x7 }, 737 }, 738 }; 739 740 741 static const struct hda_bind_ctls ad1986a_bind_pcm_vol = { 742 .ops = &snd_hda_bind_vol, 743 .values = { 744 HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT), 745 HDA_COMPOSE_AMP_VAL(AD1986A_SURR_DAC, 3, 0, HDA_OUTPUT), 746 HDA_COMPOSE_AMP_VAL(AD1986A_CLFE_DAC, 3, 0, HDA_OUTPUT), 747 0 748 }, 749 }; 750 751 static const struct hda_bind_ctls ad1986a_bind_pcm_sw = { 752 .ops = &snd_hda_bind_sw, 753 .values = { 754 HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT), 755 HDA_COMPOSE_AMP_VAL(AD1986A_SURR_DAC, 3, 0, HDA_OUTPUT), 756 HDA_COMPOSE_AMP_VAL(AD1986A_CLFE_DAC, 3, 0, HDA_OUTPUT), 757 0 758 }, 759 }; 760 761 /* 762 * mixers 763 */ 764 static const struct snd_kcontrol_new ad1986a_mixers[] = { 765 /* 766 * bind volumes/mutes of 3 DACs as a single PCM control for simplicity 767 */ 768 HDA_BIND_VOL("PCM Playback Volume", &ad1986a_bind_pcm_vol), 769 HDA_BIND_SW("PCM Playback Switch", &ad1986a_bind_pcm_sw), 770 HDA_CODEC_VOLUME("Front Playback Volume", 0x1b, 0x0, HDA_OUTPUT), 771 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 772 HDA_CODEC_VOLUME("Surround Playback Volume", 0x1c, 0x0, HDA_OUTPUT), 773 HDA_CODEC_MUTE("Surround Playback Switch", 0x1c, 0x0, HDA_OUTPUT), 774 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x1d, 1, 0x0, HDA_OUTPUT), 775 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x1d, 2, 0x0, HDA_OUTPUT), 776 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x1d, 1, 0x0, HDA_OUTPUT), 777 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x1d, 2, 0x0, HDA_OUTPUT), 778 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x1a, 0x0, HDA_OUTPUT), 779 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT), 780 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_OUTPUT), 781 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_OUTPUT), 782 HDA_CODEC_VOLUME("Line Playback Volume", 0x17, 0x0, HDA_OUTPUT), 783 HDA_CODEC_MUTE("Line Playback Switch", 0x17, 0x0, HDA_OUTPUT), 784 HDA_CODEC_VOLUME("Aux Playback Volume", 0x16, 0x0, HDA_OUTPUT), 785 HDA_CODEC_MUTE("Aux Playback Switch", 0x16, 0x0, HDA_OUTPUT), 786 HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT), 787 HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT), 788 HDA_CODEC_VOLUME("Mic Boost Volume", 0x0f, 0x0, HDA_OUTPUT), 789 HDA_CODEC_VOLUME("Mono Playback Volume", 0x1e, 0x0, HDA_OUTPUT), 790 HDA_CODEC_MUTE("Mono Playback Switch", 0x1e, 0x0, HDA_OUTPUT), 791 HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT), 792 HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT), 793 { 794 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 795 .name = "Capture Source", 796 .info = ad198x_mux_enum_info, 797 .get = ad198x_mux_enum_get, 798 .put = ad198x_mux_enum_put, 799 }, 800 HDA_CODEC_MUTE("Stereo Downmix Switch", 0x09, 0x0, HDA_OUTPUT), 801 { } /* end */ 802 }; 803 804 /* additional mixers for 3stack mode */ 805 static const struct snd_kcontrol_new ad1986a_3st_mixers[] = { 806 { 807 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 808 .name = "Channel Mode", 809 .info = ad198x_ch_mode_info, 810 .get = ad198x_ch_mode_get, 811 .put = ad198x_ch_mode_put, 812 }, 813 { } /* end */ 814 }; 815 816 /* laptop model - 2ch only */ 817 static const hda_nid_t ad1986a_laptop_dac_nids[1] = { AD1986A_FRONT_DAC }; 818 819 /* master controls both pins 0x1a and 0x1b */ 820 static const struct hda_bind_ctls ad1986a_laptop_master_vol = { 821 .ops = &snd_hda_bind_vol, 822 .values = { 823 HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT), 824 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT), 825 0, 826 }, 827 }; 828 829 static const struct hda_bind_ctls ad1986a_laptop_master_sw = { 830 .ops = &snd_hda_bind_sw, 831 .values = { 832 HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT), 833 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT), 834 0, 835 }, 836 }; 837 838 static const struct snd_kcontrol_new ad1986a_laptop_mixers[] = { 839 HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT), 840 HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT), 841 HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol), 842 HDA_BIND_SW("Master Playback Switch", &ad1986a_laptop_master_sw), 843 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_OUTPUT), 844 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_OUTPUT), 845 HDA_CODEC_VOLUME("Line Playback Volume", 0x17, 0x0, HDA_OUTPUT), 846 HDA_CODEC_MUTE("Line Playback Switch", 0x17, 0x0, HDA_OUTPUT), 847 HDA_CODEC_VOLUME("Aux Playback Volume", 0x16, 0x0, HDA_OUTPUT), 848 HDA_CODEC_MUTE("Aux Playback Switch", 0x16, 0x0, HDA_OUTPUT), 849 HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT), 850 HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT), 851 HDA_CODEC_VOLUME("Mic Boost Volume", 0x0f, 0x0, HDA_OUTPUT), 852 /* 853 HDA_CODEC_VOLUME("Mono Playback Volume", 0x1e, 0x0, HDA_OUTPUT), 854 HDA_CODEC_MUTE("Mono Playback Switch", 0x1e, 0x0, HDA_OUTPUT), */ 855 HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT), 856 HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT), 857 { 858 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 859 .name = "Capture Source", 860 .info = ad198x_mux_enum_info, 861 .get = ad198x_mux_enum_get, 862 .put = ad198x_mux_enum_put, 863 }, 864 { } /* end */ 865 }; 866 867 /* laptop-eapd model - 2ch only */ 868 869 static const struct hda_input_mux ad1986a_laptop_eapd_capture_source = { 870 .num_items = 3, 871 .items = { 872 { "Mic", 0x0 }, 873 { "Internal Mic", 0x4 }, 874 { "Mix", 0x5 }, 875 }, 876 }; 877 878 static const struct hda_input_mux ad1986a_automic_capture_source = { 879 .num_items = 2, 880 .items = { 881 { "Mic", 0x0 }, 882 { "Mix", 0x5 }, 883 }, 884 }; 885 886 static const struct snd_kcontrol_new ad1986a_laptop_master_mixers[] = { 887 HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol), 888 HDA_BIND_SW("Master Playback Switch", &ad1986a_laptop_master_sw), 889 { } /* end */ 890 }; 891 892 static const struct snd_kcontrol_new ad1986a_laptop_eapd_mixers[] = { 893 HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT), 894 HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT), 895 HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT), 896 HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT), 897 HDA_CODEC_VOLUME("Mic Boost Volume", 0x0f, 0x0, HDA_OUTPUT), 898 HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT), 899 HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT), 900 { 901 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 902 .name = "Capture Source", 903 .info = ad198x_mux_enum_info, 904 .get = ad198x_mux_enum_get, 905 .put = ad198x_mux_enum_put, 906 }, 907 { 908 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 909 .name = "External Amplifier", 910 .subdevice = HDA_SUBDEV_NID_FLAG | 0x1b, 911 .info = ad198x_eapd_info, 912 .get = ad198x_eapd_get, 913 .put = ad198x_eapd_put, 914 .private_value = 0x1b, /* port-D */ 915 }, 916 { } /* end */ 917 }; 918 919 static const struct snd_kcontrol_new ad1986a_laptop_intmic_mixers[] = { 920 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0, HDA_OUTPUT), 921 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x17, 0, HDA_OUTPUT), 922 { } /* end */ 923 }; 924 925 /* re-connect the mic boost input according to the jack sensing */ 926 static void ad1986a_automic(struct hda_codec *codec) 927 { 928 unsigned int present; 929 present = snd_hda_jack_detect(codec, 0x1f); 930 /* 0 = 0x1f, 2 = 0x1d, 4 = mixed */ 931 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_CONNECT_SEL, 932 present ? 0 : 2); 933 } 934 935 #define AD1986A_MIC_EVENT 0x36 936 937 static void ad1986a_automic_unsol_event(struct hda_codec *codec, 938 unsigned int res) 939 { 940 if ((res >> 26) != AD1986A_MIC_EVENT) 941 return; 942 ad1986a_automic(codec); 943 } 944 945 static int ad1986a_automic_init(struct hda_codec *codec) 946 { 947 ad198x_init(codec); 948 ad1986a_automic(codec); 949 return 0; 950 } 951 952 /* laptop-automute - 2ch only */ 953 954 static void ad1986a_update_hp(struct hda_codec *codec) 955 { 956 struct ad198x_spec *spec = codec->spec; 957 unsigned int mute; 958 959 if (spec->jack_present) 960 mute = HDA_AMP_MUTE; /* mute internal speaker */ 961 else 962 /* unmute internal speaker if necessary */ 963 mute = snd_hda_codec_amp_read(codec, 0x1a, 0, HDA_OUTPUT, 0); 964 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0, 965 HDA_AMP_MUTE, mute); 966 } 967 968 static void ad1986a_hp_automute(struct hda_codec *codec) 969 { 970 struct ad198x_spec *spec = codec->spec; 971 972 spec->jack_present = snd_hda_jack_detect(codec, 0x1a); 973 if (spec->inv_jack_detect) 974 spec->jack_present = !spec->jack_present; 975 ad1986a_update_hp(codec); 976 } 977 978 #define AD1986A_HP_EVENT 0x37 979 980 static void ad1986a_hp_unsol_event(struct hda_codec *codec, unsigned int res) 981 { 982 if ((res >> 26) != AD1986A_HP_EVENT) 983 return; 984 ad1986a_hp_automute(codec); 985 } 986 987 static int ad1986a_hp_init(struct hda_codec *codec) 988 { 989 ad198x_init(codec); 990 ad1986a_hp_automute(codec); 991 return 0; 992 } 993 994 /* bind hp and internal speaker mute (with plug check) */ 995 static int ad1986a_hp_master_sw_put(struct snd_kcontrol *kcontrol, 996 struct snd_ctl_elem_value *ucontrol) 997 { 998 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 999 long *valp = ucontrol->value.integer.value; 1000 int change; 1001 1002 change = snd_hda_codec_amp_update(codec, 0x1a, 0, HDA_OUTPUT, 0, 1003 HDA_AMP_MUTE, 1004 valp[0] ? 0 : HDA_AMP_MUTE); 1005 change |= snd_hda_codec_amp_update(codec, 0x1a, 1, HDA_OUTPUT, 0, 1006 HDA_AMP_MUTE, 1007 valp[1] ? 0 : HDA_AMP_MUTE); 1008 if (change) 1009 ad1986a_update_hp(codec); 1010 return change; 1011 } 1012 1013 static const struct snd_kcontrol_new ad1986a_automute_master_mixers[] = { 1014 HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol), 1015 { 1016 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1017 .name = "Master Playback Switch", 1018 .subdevice = HDA_SUBDEV_AMP_FLAG, 1019 .info = snd_hda_mixer_amp_switch_info, 1020 .get = snd_hda_mixer_amp_switch_get, 1021 .put = ad1986a_hp_master_sw_put, 1022 .private_value = HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT), 1023 }, 1024 { } /* end */ 1025 }; 1026 1027 1028 /* 1029 * initialization verbs 1030 */ 1031 static const struct hda_verb ad1986a_init_verbs[] = { 1032 /* Front, Surround, CLFE DAC; mute as default */ 1033 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 1034 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 1035 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 1036 /* Downmix - off */ 1037 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 1038 /* HP, Line-Out, Surround, CLFE selectors */ 1039 {0x0a, AC_VERB_SET_CONNECT_SEL, 0x0}, 1040 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x0}, 1041 {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0}, 1042 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0}, 1043 /* Mono selector */ 1044 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x0}, 1045 /* Mic selector: Mic 1/2 pin */ 1046 {0x0f, AC_VERB_SET_CONNECT_SEL, 0x0}, 1047 /* Line-in selector: Line-in */ 1048 {0x10, AC_VERB_SET_CONNECT_SEL, 0x0}, 1049 /* Mic 1/2 swap */ 1050 {0x11, AC_VERB_SET_CONNECT_SEL, 0x0}, 1051 /* Record selector: mic */ 1052 {0x12, AC_VERB_SET_CONNECT_SEL, 0x0}, 1053 /* Mic, Phone, CD, Aux, Line-In amp; mute as default */ 1054 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 1055 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 1056 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 1057 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 1058 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 1059 /* PC beep */ 1060 {0x18, AC_VERB_SET_CONNECT_SEL, 0x0}, 1061 /* HP, Line-Out, Surround, CLFE, Mono pins; mute as default */ 1062 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 1063 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 1064 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 1065 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 1066 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 1067 /* HP Pin */ 1068 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, 1069 /* Front, Surround, CLFE Pins */ 1070 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 1071 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 1072 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 1073 /* Mono Pin */ 1074 {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 1075 /* Mic Pin */ 1076 {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 1077 /* Line, Aux, CD, Beep-In Pin */ 1078 {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 1079 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 1080 {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 1081 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 1082 {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 1083 { } /* end */ 1084 }; 1085 1086 static const struct hda_verb ad1986a_ch2_init[] = { 1087 /* Surround out -> Line In */ 1088 { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 1089 /* Line-in selectors */ 1090 { 0x10, AC_VERB_SET_CONNECT_SEL, 0x1 }, 1091 /* CLFE -> Mic in */ 1092 { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 1093 /* Mic selector, mix C/LFE (backmic) and Mic (frontmic) */ 1094 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x4 }, 1095 { } /* end */ 1096 }; 1097 1098 static const struct hda_verb ad1986a_ch4_init[] = { 1099 /* Surround out -> Surround */ 1100 { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 1101 { 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 }, 1102 /* CLFE -> Mic in */ 1103 { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 1104 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x4 }, 1105 { } /* end */ 1106 }; 1107 1108 static const struct hda_verb ad1986a_ch6_init[] = { 1109 /* Surround out -> Surround out */ 1110 { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 1111 { 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 }, 1112 /* CLFE -> CLFE */ 1113 { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 1114 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x0 }, 1115 { } /* end */ 1116 }; 1117 1118 static const struct hda_channel_mode ad1986a_modes[3] = { 1119 { 2, ad1986a_ch2_init }, 1120 { 4, ad1986a_ch4_init }, 1121 { 6, ad1986a_ch6_init }, 1122 }; 1123 1124 /* eapd initialization */ 1125 static const struct hda_verb ad1986a_eapd_init_verbs[] = { 1126 {0x1b, AC_VERB_SET_EAPD_BTLENABLE, 0x00 }, 1127 {} 1128 }; 1129 1130 static const struct hda_verb ad1986a_automic_verbs[] = { 1131 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1132 {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1133 /*{0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},*/ 1134 {0x0f, AC_VERB_SET_CONNECT_SEL, 0x0}, 1135 {0x1f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1986A_MIC_EVENT}, 1136 {} 1137 }; 1138 1139 /* Ultra initialization */ 1140 static const struct hda_verb ad1986a_ultra_init[] = { 1141 /* eapd initialization */ 1142 { 0x1b, AC_VERB_SET_EAPD_BTLENABLE, 0x00 }, 1143 /* CLFE -> Mic in */ 1144 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x2 }, 1145 { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 1146 { 0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 }, 1147 { } /* end */ 1148 }; 1149 1150 /* pin sensing on HP jack */ 1151 static const struct hda_verb ad1986a_hp_init_verbs[] = { 1152 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1986A_HP_EVENT}, 1153 {} 1154 }; 1155 1156 static void ad1986a_samsung_p50_unsol_event(struct hda_codec *codec, 1157 unsigned int res) 1158 { 1159 switch (res >> 26) { 1160 case AD1986A_HP_EVENT: 1161 ad1986a_hp_automute(codec); 1162 break; 1163 case AD1986A_MIC_EVENT: 1164 ad1986a_automic(codec); 1165 break; 1166 } 1167 } 1168 1169 static int ad1986a_samsung_p50_init(struct hda_codec *codec) 1170 { 1171 ad198x_init(codec); 1172 ad1986a_hp_automute(codec); 1173 ad1986a_automic(codec); 1174 return 0; 1175 } 1176 1177 1178 /* models */ 1179 enum { 1180 AD1986A_6STACK, 1181 AD1986A_3STACK, 1182 AD1986A_LAPTOP, 1183 AD1986A_LAPTOP_EAPD, 1184 AD1986A_LAPTOP_AUTOMUTE, 1185 AD1986A_ULTRA, 1186 AD1986A_SAMSUNG, 1187 AD1986A_SAMSUNG_P50, 1188 AD1986A_MODELS 1189 }; 1190 1191 static const char * const ad1986a_models[AD1986A_MODELS] = { 1192 [AD1986A_6STACK] = "6stack", 1193 [AD1986A_3STACK] = "3stack", 1194 [AD1986A_LAPTOP] = "laptop", 1195 [AD1986A_LAPTOP_EAPD] = "laptop-eapd", 1196 [AD1986A_LAPTOP_AUTOMUTE] = "laptop-automute", 1197 [AD1986A_ULTRA] = "ultra", 1198 [AD1986A_SAMSUNG] = "samsung", 1199 [AD1986A_SAMSUNG_P50] = "samsung-p50", 1200 }; 1201 1202 static const struct snd_pci_quirk ad1986a_cfg_tbl[] = { 1203 SND_PCI_QUIRK(0x103c, 0x30af, "HP B2800", AD1986A_LAPTOP_EAPD), 1204 SND_PCI_QUIRK(0x1043, 0x1153, "ASUS M9", AD1986A_LAPTOP_EAPD), 1205 SND_PCI_QUIRK(0x1043, 0x11f7, "ASUS U5A", AD1986A_LAPTOP_EAPD), 1206 SND_PCI_QUIRK(0x1043, 0x1213, "ASUS A6J", AD1986A_LAPTOP_EAPD), 1207 SND_PCI_QUIRK(0x1043, 0x1263, "ASUS U5F", AD1986A_LAPTOP_EAPD), 1208 SND_PCI_QUIRK(0x1043, 0x1297, "ASUS Z62F", AD1986A_LAPTOP_EAPD), 1209 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS V1j", AD1986A_LAPTOP_EAPD), 1210 SND_PCI_QUIRK(0x1043, 0x1302, "ASUS W3j", AD1986A_LAPTOP_EAPD), 1211 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS VX1", AD1986A_LAPTOP), 1212 SND_PCI_QUIRK(0x1043, 0x1447, "ASUS A8J", AD1986A_3STACK), 1213 SND_PCI_QUIRK(0x1043, 0x817f, "ASUS P5", AD1986A_3STACK), 1214 SND_PCI_QUIRK(0x1043, 0x818f, "ASUS P5", AD1986A_LAPTOP), 1215 SND_PCI_QUIRK(0x1043, 0x81b3, "ASUS P5", AD1986A_3STACK), 1216 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS M2N", AD1986A_3STACK), 1217 SND_PCI_QUIRK(0x1043, 0x8234, "ASUS M2N", AD1986A_3STACK), 1218 SND_PCI_QUIRK(0x10de, 0xcb84, "ASUS A8N-VM", AD1986A_3STACK), 1219 SND_PCI_QUIRK(0x1179, 0xff40, "Toshiba Satellite L40-10Q", AD1986A_3STACK), 1220 SND_PCI_QUIRK(0x144d, 0xb03c, "Samsung R55", AD1986A_3STACK), 1221 SND_PCI_QUIRK(0x144d, 0xc01e, "FSC V2060", AD1986A_LAPTOP), 1222 SND_PCI_QUIRK(0x144d, 0xc024, "Samsung P50", AD1986A_SAMSUNG_P50), 1223 SND_PCI_QUIRK(0x144d, 0xc027, "Samsung Q1", AD1986A_ULTRA), 1224 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc000, "Samsung", AD1986A_SAMSUNG), 1225 SND_PCI_QUIRK(0x144d, 0xc504, "Samsung Q35", AD1986A_3STACK), 1226 SND_PCI_QUIRK(0x17aa, 0x1011, "Lenovo M55", AD1986A_LAPTOP), 1227 SND_PCI_QUIRK(0x17aa, 0x1017, "Lenovo A60", AD1986A_3STACK), 1228 SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo N100", AD1986A_LAPTOP_AUTOMUTE), 1229 SND_PCI_QUIRK(0x17c0, 0x2017, "Samsung M50", AD1986A_LAPTOP), 1230 {} 1231 }; 1232 1233 #ifdef CONFIG_SND_HDA_POWER_SAVE 1234 static const struct hda_amp_list ad1986a_loopbacks[] = { 1235 { 0x13, HDA_OUTPUT, 0 }, /* Mic */ 1236 { 0x14, HDA_OUTPUT, 0 }, /* Phone */ 1237 { 0x15, HDA_OUTPUT, 0 }, /* CD */ 1238 { 0x16, HDA_OUTPUT, 0 }, /* Aux */ 1239 { 0x17, HDA_OUTPUT, 0 }, /* Line */ 1240 { } /* end */ 1241 }; 1242 #endif 1243 1244 static int is_jack_available(struct hda_codec *codec, hda_nid_t nid) 1245 { 1246 unsigned int conf = snd_hda_codec_get_pincfg(codec, nid); 1247 return get_defcfg_connect(conf) != AC_JACK_PORT_NONE; 1248 } 1249 1250 static int patch_ad1986a(struct hda_codec *codec) 1251 { 1252 struct ad198x_spec *spec; 1253 int err, board_config; 1254 1255 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 1256 if (spec == NULL) 1257 return -ENOMEM; 1258 1259 codec->spec = spec; 1260 1261 err = snd_hda_attach_beep_device(codec, 0x19); 1262 if (err < 0) { 1263 ad198x_free(codec); 1264 return err; 1265 } 1266 set_beep_amp(spec, 0x18, 0, HDA_OUTPUT); 1267 1268 spec->multiout.max_channels = 6; 1269 spec->multiout.num_dacs = ARRAY_SIZE(ad1986a_dac_nids); 1270 spec->multiout.dac_nids = ad1986a_dac_nids; 1271 spec->multiout.dig_out_nid = AD1986A_SPDIF_OUT; 1272 spec->num_adc_nids = 1; 1273 spec->adc_nids = ad1986a_adc_nids; 1274 spec->capsrc_nids = ad1986a_capsrc_nids; 1275 spec->input_mux = &ad1986a_capture_source; 1276 spec->num_mixers = 1; 1277 spec->mixers[0] = ad1986a_mixers; 1278 spec->num_init_verbs = 1; 1279 spec->init_verbs[0] = ad1986a_init_verbs; 1280 #ifdef CONFIG_SND_HDA_POWER_SAVE 1281 spec->loopback.amplist = ad1986a_loopbacks; 1282 #endif 1283 spec->vmaster_nid = 0x1b; 1284 spec->inv_eapd = 1; /* AD1986A has the inverted EAPD implementation */ 1285 1286 codec->patch_ops = ad198x_patch_ops; 1287 1288 /* override some parameters */ 1289 board_config = snd_hda_check_board_config(codec, AD1986A_MODELS, 1290 ad1986a_models, 1291 ad1986a_cfg_tbl); 1292 switch (board_config) { 1293 case AD1986A_3STACK: 1294 spec->num_mixers = 2; 1295 spec->mixers[1] = ad1986a_3st_mixers; 1296 spec->num_init_verbs = 2; 1297 spec->init_verbs[1] = ad1986a_ch2_init; 1298 spec->channel_mode = ad1986a_modes; 1299 spec->num_channel_mode = ARRAY_SIZE(ad1986a_modes); 1300 spec->need_dac_fix = 1; 1301 spec->multiout.max_channels = 2; 1302 spec->multiout.num_dacs = 1; 1303 break; 1304 case AD1986A_LAPTOP: 1305 spec->mixers[0] = ad1986a_laptop_mixers; 1306 spec->multiout.max_channels = 2; 1307 spec->multiout.num_dacs = 1; 1308 spec->multiout.dac_nids = ad1986a_laptop_dac_nids; 1309 break; 1310 case AD1986A_LAPTOP_EAPD: 1311 spec->num_mixers = 3; 1312 spec->mixers[0] = ad1986a_laptop_master_mixers; 1313 spec->mixers[1] = ad1986a_laptop_eapd_mixers; 1314 spec->mixers[2] = ad1986a_laptop_intmic_mixers; 1315 spec->num_init_verbs = 2; 1316 spec->init_verbs[1] = ad1986a_eapd_init_verbs; 1317 spec->multiout.max_channels = 2; 1318 spec->multiout.num_dacs = 1; 1319 spec->multiout.dac_nids = ad1986a_laptop_dac_nids; 1320 if (!is_jack_available(codec, 0x25)) 1321 spec->multiout.dig_out_nid = 0; 1322 spec->input_mux = &ad1986a_laptop_eapd_capture_source; 1323 break; 1324 case AD1986A_SAMSUNG: 1325 spec->num_mixers = 2; 1326 spec->mixers[0] = ad1986a_laptop_master_mixers; 1327 spec->mixers[1] = ad1986a_laptop_eapd_mixers; 1328 spec->num_init_verbs = 3; 1329 spec->init_verbs[1] = ad1986a_eapd_init_verbs; 1330 spec->init_verbs[2] = ad1986a_automic_verbs; 1331 spec->multiout.max_channels = 2; 1332 spec->multiout.num_dacs = 1; 1333 spec->multiout.dac_nids = ad1986a_laptop_dac_nids; 1334 if (!is_jack_available(codec, 0x25)) 1335 spec->multiout.dig_out_nid = 0; 1336 spec->input_mux = &ad1986a_automic_capture_source; 1337 codec->patch_ops.unsol_event = ad1986a_automic_unsol_event; 1338 codec->patch_ops.init = ad1986a_automic_init; 1339 break; 1340 case AD1986A_SAMSUNG_P50: 1341 spec->num_mixers = 2; 1342 spec->mixers[0] = ad1986a_automute_master_mixers; 1343 spec->mixers[1] = ad1986a_laptop_eapd_mixers; 1344 spec->num_init_verbs = 4; 1345 spec->init_verbs[1] = ad1986a_eapd_init_verbs; 1346 spec->init_verbs[2] = ad1986a_automic_verbs; 1347 spec->init_verbs[3] = ad1986a_hp_init_verbs; 1348 spec->multiout.max_channels = 2; 1349 spec->multiout.num_dacs = 1; 1350 spec->multiout.dac_nids = ad1986a_laptop_dac_nids; 1351 if (!is_jack_available(codec, 0x25)) 1352 spec->multiout.dig_out_nid = 0; 1353 spec->input_mux = &ad1986a_automic_capture_source; 1354 codec->patch_ops.unsol_event = ad1986a_samsung_p50_unsol_event; 1355 codec->patch_ops.init = ad1986a_samsung_p50_init; 1356 break; 1357 case AD1986A_LAPTOP_AUTOMUTE: 1358 spec->num_mixers = 3; 1359 spec->mixers[0] = ad1986a_automute_master_mixers; 1360 spec->mixers[1] = ad1986a_laptop_eapd_mixers; 1361 spec->mixers[2] = ad1986a_laptop_intmic_mixers; 1362 spec->num_init_verbs = 3; 1363 spec->init_verbs[1] = ad1986a_eapd_init_verbs; 1364 spec->init_verbs[2] = ad1986a_hp_init_verbs; 1365 spec->multiout.max_channels = 2; 1366 spec->multiout.num_dacs = 1; 1367 spec->multiout.dac_nids = ad1986a_laptop_dac_nids; 1368 if (!is_jack_available(codec, 0x25)) 1369 spec->multiout.dig_out_nid = 0; 1370 spec->input_mux = &ad1986a_laptop_eapd_capture_source; 1371 codec->patch_ops.unsol_event = ad1986a_hp_unsol_event; 1372 codec->patch_ops.init = ad1986a_hp_init; 1373 /* Lenovo N100 seems to report the reversed bit 1374 * for HP jack-sensing 1375 */ 1376 spec->inv_jack_detect = 1; 1377 break; 1378 case AD1986A_ULTRA: 1379 spec->mixers[0] = ad1986a_laptop_eapd_mixers; 1380 spec->num_init_verbs = 2; 1381 spec->init_verbs[1] = ad1986a_ultra_init; 1382 spec->multiout.max_channels = 2; 1383 spec->multiout.num_dacs = 1; 1384 spec->multiout.dac_nids = ad1986a_laptop_dac_nids; 1385 spec->multiout.dig_out_nid = 0; 1386 break; 1387 } 1388 1389 /* AD1986A has a hardware problem that it can't share a stream 1390 * with multiple output pins. The copy of front to surrounds 1391 * causes noisy or silent outputs at a certain timing, e.g. 1392 * changing the volume. 1393 * So, let's disable the shared stream. 1394 */ 1395 spec->multiout.no_share_stream = 1; 1396 1397 codec->no_trigger_sense = 1; 1398 codec->no_sticky_stream = 1; 1399 1400 return 0; 1401 } 1402 1403 /* 1404 * AD1983 specific 1405 */ 1406 1407 #define AD1983_SPDIF_OUT 0x02 1408 #define AD1983_DAC 0x03 1409 #define AD1983_ADC 0x04 1410 1411 static const hda_nid_t ad1983_dac_nids[1] = { AD1983_DAC }; 1412 static const hda_nid_t ad1983_adc_nids[1] = { AD1983_ADC }; 1413 static const hda_nid_t ad1983_capsrc_nids[1] = { 0x15 }; 1414 1415 static const struct hda_input_mux ad1983_capture_source = { 1416 .num_items = 4, 1417 .items = { 1418 { "Mic", 0x0 }, 1419 { "Line", 0x1 }, 1420 { "Mix", 0x2 }, 1421 { "Mix Mono", 0x3 }, 1422 }, 1423 }; 1424 1425 /* 1426 * SPDIF playback route 1427 */ 1428 static int ad1983_spdif_route_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 1429 { 1430 static const char * const texts[] = { "PCM", "ADC" }; 1431 1432 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 1433 uinfo->count = 1; 1434 uinfo->value.enumerated.items = 2; 1435 if (uinfo->value.enumerated.item > 1) 1436 uinfo->value.enumerated.item = 1; 1437 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); 1438 return 0; 1439 } 1440 1441 static int ad1983_spdif_route_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 1442 { 1443 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 1444 struct ad198x_spec *spec = codec->spec; 1445 1446 ucontrol->value.enumerated.item[0] = spec->spdif_route; 1447 return 0; 1448 } 1449 1450 static int ad1983_spdif_route_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 1451 { 1452 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 1453 struct ad198x_spec *spec = codec->spec; 1454 1455 if (ucontrol->value.enumerated.item[0] > 1) 1456 return -EINVAL; 1457 if (spec->spdif_route != ucontrol->value.enumerated.item[0]) { 1458 spec->spdif_route = ucontrol->value.enumerated.item[0]; 1459 snd_hda_codec_write_cache(codec, spec->multiout.dig_out_nid, 0, 1460 AC_VERB_SET_CONNECT_SEL, 1461 spec->spdif_route); 1462 return 1; 1463 } 1464 return 0; 1465 } 1466 1467 static const struct snd_kcontrol_new ad1983_mixers[] = { 1468 HDA_CODEC_VOLUME("Front Playback Volume", 0x05, 0x0, HDA_OUTPUT), 1469 HDA_CODEC_MUTE("Front Playback Switch", 0x05, 0x0, HDA_OUTPUT), 1470 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x06, 0x0, HDA_OUTPUT), 1471 HDA_CODEC_MUTE("Headphone Playback Switch", 0x06, 0x0, HDA_OUTPUT), 1472 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x07, 1, 0x0, HDA_OUTPUT), 1473 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x07, 1, 0x0, HDA_OUTPUT), 1474 HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT), 1475 HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT), 1476 HDA_CODEC_VOLUME("Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT), 1477 HDA_CODEC_MUTE("Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT), 1478 HDA_CODEC_VOLUME("Line Playback Volume", 0x13, 0x0, HDA_OUTPUT), 1479 HDA_CODEC_MUTE("Line Playback Switch", 0x13, 0x0, HDA_OUTPUT), 1480 HDA_CODEC_VOLUME("Mic Boost Volume", 0x0c, 0x0, HDA_OUTPUT), 1481 HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT), 1482 HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT), 1483 { 1484 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1485 .name = "Capture Source", 1486 .info = ad198x_mux_enum_info, 1487 .get = ad198x_mux_enum_get, 1488 .put = ad198x_mux_enum_put, 1489 }, 1490 { 1491 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1492 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source", 1493 .info = ad1983_spdif_route_info, 1494 .get = ad1983_spdif_route_get, 1495 .put = ad1983_spdif_route_put, 1496 }, 1497 { } /* end */ 1498 }; 1499 1500 static const struct hda_verb ad1983_init_verbs[] = { 1501 /* Front, HP, Mono; mute as default */ 1502 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 1503 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 1504 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 1505 /* Beep, PCM, Mic, Line-In: mute */ 1506 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 1507 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 1508 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 1509 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 1510 /* Front, HP selectors; from Mix */ 1511 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01}, 1512 {0x06, AC_VERB_SET_CONNECT_SEL, 0x01}, 1513 /* Mono selector; from Mix */ 1514 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x03}, 1515 /* Mic selector; Mic */ 1516 {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0}, 1517 /* Line-in selector: Line-in */ 1518 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0}, 1519 /* Mic boost: 0dB */ 1520 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 1521 /* Record selector: mic */ 1522 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, 1523 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 1524 /* SPDIF route: PCM */ 1525 {0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, 1526 /* Front Pin */ 1527 {0x05, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 1528 /* HP Pin */ 1529 {0x06, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, 1530 /* Mono Pin */ 1531 {0x07, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 1532 /* Mic Pin */ 1533 {0x08, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 1534 /* Line Pin */ 1535 {0x09, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 1536 { } /* end */ 1537 }; 1538 1539 #ifdef CONFIG_SND_HDA_POWER_SAVE 1540 static const struct hda_amp_list ad1983_loopbacks[] = { 1541 { 0x12, HDA_OUTPUT, 0 }, /* Mic */ 1542 { 0x13, HDA_OUTPUT, 0 }, /* Line */ 1543 { } /* end */ 1544 }; 1545 #endif 1546 1547 static int patch_ad1983(struct hda_codec *codec) 1548 { 1549 struct ad198x_spec *spec; 1550 int err; 1551 1552 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 1553 if (spec == NULL) 1554 return -ENOMEM; 1555 1556 codec->spec = spec; 1557 1558 err = snd_hda_attach_beep_device(codec, 0x10); 1559 if (err < 0) { 1560 ad198x_free(codec); 1561 return err; 1562 } 1563 set_beep_amp(spec, 0x10, 0, HDA_OUTPUT); 1564 1565 spec->multiout.max_channels = 2; 1566 spec->multiout.num_dacs = ARRAY_SIZE(ad1983_dac_nids); 1567 spec->multiout.dac_nids = ad1983_dac_nids; 1568 spec->multiout.dig_out_nid = AD1983_SPDIF_OUT; 1569 spec->num_adc_nids = 1; 1570 spec->adc_nids = ad1983_adc_nids; 1571 spec->capsrc_nids = ad1983_capsrc_nids; 1572 spec->input_mux = &ad1983_capture_source; 1573 spec->num_mixers = 1; 1574 spec->mixers[0] = ad1983_mixers; 1575 spec->num_init_verbs = 1; 1576 spec->init_verbs[0] = ad1983_init_verbs; 1577 spec->spdif_route = 0; 1578 #ifdef CONFIG_SND_HDA_POWER_SAVE 1579 spec->loopback.amplist = ad1983_loopbacks; 1580 #endif 1581 spec->vmaster_nid = 0x05; 1582 1583 codec->patch_ops = ad198x_patch_ops; 1584 1585 codec->no_trigger_sense = 1; 1586 codec->no_sticky_stream = 1; 1587 1588 return 0; 1589 } 1590 1591 1592 /* 1593 * AD1981 HD specific 1594 */ 1595 1596 #define AD1981_SPDIF_OUT 0x02 1597 #define AD1981_DAC 0x03 1598 #define AD1981_ADC 0x04 1599 1600 static const hda_nid_t ad1981_dac_nids[1] = { AD1981_DAC }; 1601 static const hda_nid_t ad1981_adc_nids[1] = { AD1981_ADC }; 1602 static const hda_nid_t ad1981_capsrc_nids[1] = { 0x15 }; 1603 1604 /* 0x0c, 0x09, 0x0e, 0x0f, 0x19, 0x05, 0x18, 0x17 */ 1605 static const struct hda_input_mux ad1981_capture_source = { 1606 .num_items = 7, 1607 .items = { 1608 { "Front Mic", 0x0 }, 1609 { "Line", 0x1 }, 1610 { "Mix", 0x2 }, 1611 { "Mix Mono", 0x3 }, 1612 { "CD", 0x4 }, 1613 { "Mic", 0x6 }, 1614 { "Aux", 0x7 }, 1615 }, 1616 }; 1617 1618 static const struct snd_kcontrol_new ad1981_mixers[] = { 1619 HDA_CODEC_VOLUME("Front Playback Volume", 0x05, 0x0, HDA_OUTPUT), 1620 HDA_CODEC_MUTE("Front Playback Switch", 0x05, 0x0, HDA_OUTPUT), 1621 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x06, 0x0, HDA_OUTPUT), 1622 HDA_CODEC_MUTE("Headphone Playback Switch", 0x06, 0x0, HDA_OUTPUT), 1623 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x07, 1, 0x0, HDA_OUTPUT), 1624 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x07, 1, 0x0, HDA_OUTPUT), 1625 HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT), 1626 HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT), 1627 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT), 1628 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT), 1629 HDA_CODEC_VOLUME("Line Playback Volume", 0x13, 0x0, HDA_OUTPUT), 1630 HDA_CODEC_MUTE("Line Playback Switch", 0x13, 0x0, HDA_OUTPUT), 1631 HDA_CODEC_VOLUME("Aux Playback Volume", 0x1b, 0x0, HDA_OUTPUT), 1632 HDA_CODEC_MUTE("Aux Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 1633 HDA_CODEC_VOLUME("Mic Playback Volume", 0x1c, 0x0, HDA_OUTPUT), 1634 HDA_CODEC_MUTE("Mic Playback Switch", 0x1c, 0x0, HDA_OUTPUT), 1635 HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT), 1636 HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT), 1637 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x08, 0x0, HDA_INPUT), 1638 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x0, HDA_INPUT), 1639 HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT), 1640 HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT), 1641 { 1642 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1643 .name = "Capture Source", 1644 .info = ad198x_mux_enum_info, 1645 .get = ad198x_mux_enum_get, 1646 .put = ad198x_mux_enum_put, 1647 }, 1648 /* identical with AD1983 */ 1649 { 1650 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1651 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source", 1652 .info = ad1983_spdif_route_info, 1653 .get = ad1983_spdif_route_get, 1654 .put = ad1983_spdif_route_put, 1655 }, 1656 { } /* end */ 1657 }; 1658 1659 static const struct hda_verb ad1981_init_verbs[] = { 1660 /* Front, HP, Mono; mute as default */ 1661 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 1662 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 1663 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 1664 /* Beep, PCM, Front Mic, Line, Rear Mic, Aux, CD-In: mute */ 1665 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 1666 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 1667 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 1668 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 1669 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 1670 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 1671 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 1672 /* Front, HP selectors; from Mix */ 1673 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01}, 1674 {0x06, AC_VERB_SET_CONNECT_SEL, 0x01}, 1675 /* Mono selector; from Mix */ 1676 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x03}, 1677 /* Mic Mixer; select Front Mic */ 1678 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 1679 {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 1680 /* Mic boost: 0dB */ 1681 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1682 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1683 /* Record selector: Front mic */ 1684 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, 1685 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 1686 /* SPDIF route: PCM */ 1687 {0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, 1688 /* Front Pin */ 1689 {0x05, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 1690 /* HP Pin */ 1691 {0x06, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, 1692 /* Mono Pin */ 1693 {0x07, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 1694 /* Front & Rear Mic Pins */ 1695 {0x08, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 1696 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 1697 /* Line Pin */ 1698 {0x09, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 1699 /* Digital Beep */ 1700 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00}, 1701 /* Line-Out as Input: disabled */ 1702 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 1703 { } /* end */ 1704 }; 1705 1706 #ifdef CONFIG_SND_HDA_POWER_SAVE 1707 static const struct hda_amp_list ad1981_loopbacks[] = { 1708 { 0x12, HDA_OUTPUT, 0 }, /* Front Mic */ 1709 { 0x13, HDA_OUTPUT, 0 }, /* Line */ 1710 { 0x1b, HDA_OUTPUT, 0 }, /* Aux */ 1711 { 0x1c, HDA_OUTPUT, 0 }, /* Mic */ 1712 { 0x1d, HDA_OUTPUT, 0 }, /* CD */ 1713 { } /* end */ 1714 }; 1715 #endif 1716 1717 /* 1718 * Patch for HP nx6320 1719 * 1720 * nx6320 uses EAPD in the reverse way - EAPD-on means the internal 1721 * speaker output enabled _and_ mute-LED off. 1722 */ 1723 1724 #define AD1981_HP_EVENT 0x37 1725 #define AD1981_MIC_EVENT 0x38 1726 1727 static const struct hda_verb ad1981_hp_init_verbs[] = { 1728 {0x05, AC_VERB_SET_EAPD_BTLENABLE, 0x00 }, /* default off */ 1729 /* pin sensing on HP and Mic jacks */ 1730 {0x06, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_HP_EVENT}, 1731 {0x08, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_MIC_EVENT}, 1732 {} 1733 }; 1734 1735 /* turn on/off EAPD (+ mute HP) as a master switch */ 1736 static int ad1981_hp_master_sw_put(struct snd_kcontrol *kcontrol, 1737 struct snd_ctl_elem_value *ucontrol) 1738 { 1739 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 1740 struct ad198x_spec *spec = codec->spec; 1741 1742 if (! ad198x_eapd_put(kcontrol, ucontrol)) 1743 return 0; 1744 /* change speaker pin appropriately */ 1745 snd_hda_codec_write(codec, 0x05, 0, 1746 AC_VERB_SET_PIN_WIDGET_CONTROL, 1747 spec->cur_eapd ? PIN_OUT : 0); 1748 /* toggle HP mute appropriately */ 1749 snd_hda_codec_amp_stereo(codec, 0x06, HDA_OUTPUT, 0, 1750 HDA_AMP_MUTE, 1751 spec->cur_eapd ? 0 : HDA_AMP_MUTE); 1752 return 1; 1753 } 1754 1755 /* bind volumes of both NID 0x05 and 0x06 */ 1756 static const struct hda_bind_ctls ad1981_hp_bind_master_vol = { 1757 .ops = &snd_hda_bind_vol, 1758 .values = { 1759 HDA_COMPOSE_AMP_VAL(0x05, 3, 0, HDA_OUTPUT), 1760 HDA_COMPOSE_AMP_VAL(0x06, 3, 0, HDA_OUTPUT), 1761 0 1762 }, 1763 }; 1764 1765 /* mute internal speaker if HP is plugged */ 1766 static void ad1981_hp_automute(struct hda_codec *codec) 1767 { 1768 unsigned int present; 1769 1770 present = snd_hda_jack_detect(codec, 0x06); 1771 snd_hda_codec_amp_stereo(codec, 0x05, HDA_OUTPUT, 0, 1772 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 1773 } 1774 1775 /* toggle input of built-in and mic jack appropriately */ 1776 static void ad1981_hp_automic(struct hda_codec *codec) 1777 { 1778 static const struct hda_verb mic_jack_on[] = { 1779 {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 1780 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 1781 {} 1782 }; 1783 static const struct hda_verb mic_jack_off[] = { 1784 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 1785 {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 1786 {} 1787 }; 1788 unsigned int present; 1789 1790 present = snd_hda_jack_detect(codec, 0x08); 1791 if (present) 1792 snd_hda_sequence_write(codec, mic_jack_on); 1793 else 1794 snd_hda_sequence_write(codec, mic_jack_off); 1795 } 1796 1797 /* unsolicited event for HP jack sensing */ 1798 static void ad1981_hp_unsol_event(struct hda_codec *codec, 1799 unsigned int res) 1800 { 1801 res >>= 26; 1802 switch (res) { 1803 case AD1981_HP_EVENT: 1804 ad1981_hp_automute(codec); 1805 break; 1806 case AD1981_MIC_EVENT: 1807 ad1981_hp_automic(codec); 1808 break; 1809 } 1810 } 1811 1812 static const struct hda_input_mux ad1981_hp_capture_source = { 1813 .num_items = 3, 1814 .items = { 1815 { "Mic", 0x0 }, 1816 { "Docking-Station", 0x1 }, 1817 { "Mix", 0x2 }, 1818 }, 1819 }; 1820 1821 static const struct snd_kcontrol_new ad1981_hp_mixers[] = { 1822 HDA_BIND_VOL("Master Playback Volume", &ad1981_hp_bind_master_vol), 1823 { 1824 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1825 .subdevice = HDA_SUBDEV_NID_FLAG | 0x05, 1826 .name = "Master Playback Switch", 1827 .info = ad198x_eapd_info, 1828 .get = ad198x_eapd_get, 1829 .put = ad1981_hp_master_sw_put, 1830 .private_value = 0x05, 1831 }, 1832 HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT), 1833 HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT), 1834 #if 0 1835 /* FIXME: analog mic/line loopback doesn't work with my tests... 1836 * (although recording is OK) 1837 */ 1838 HDA_CODEC_VOLUME("Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT), 1839 HDA_CODEC_MUTE("Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT), 1840 HDA_CODEC_VOLUME("Docking-Station Playback Volume", 0x13, 0x0, HDA_OUTPUT), 1841 HDA_CODEC_MUTE("Docking-Station Playback Switch", 0x13, 0x0, HDA_OUTPUT), 1842 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x1c, 0x0, HDA_OUTPUT), 1843 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x1c, 0x0, HDA_OUTPUT), 1844 /* FIXME: does this laptop have analog CD connection? */ 1845 HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT), 1846 HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT), 1847 #endif 1848 HDA_CODEC_VOLUME("Mic Boost Volume", 0x08, 0x0, HDA_INPUT), 1849 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x18, 0x0, HDA_INPUT), 1850 HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT), 1851 HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT), 1852 { 1853 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1854 .name = "Capture Source", 1855 .info = ad198x_mux_enum_info, 1856 .get = ad198x_mux_enum_get, 1857 .put = ad198x_mux_enum_put, 1858 }, 1859 { } /* end */ 1860 }; 1861 1862 /* initialize jack-sensing, too */ 1863 static int ad1981_hp_init(struct hda_codec *codec) 1864 { 1865 ad198x_init(codec); 1866 ad1981_hp_automute(codec); 1867 ad1981_hp_automic(codec); 1868 return 0; 1869 } 1870 1871 /* configuration for Toshiba Laptops */ 1872 static const struct hda_verb ad1981_toshiba_init_verbs[] = { 1873 {0x05, AC_VERB_SET_EAPD_BTLENABLE, 0x01 }, /* default on */ 1874 /* pin sensing on HP and Mic jacks */ 1875 {0x06, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_HP_EVENT}, 1876 {0x08, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_MIC_EVENT}, 1877 {} 1878 }; 1879 1880 static const struct snd_kcontrol_new ad1981_toshiba_mixers[] = { 1881 HDA_CODEC_VOLUME("Amp Volume", 0x1a, 0x0, HDA_OUTPUT), 1882 HDA_CODEC_MUTE("Amp Switch", 0x1a, 0x0, HDA_OUTPUT), 1883 { } 1884 }; 1885 1886 /* configuration for Lenovo Thinkpad T60 */ 1887 static const struct snd_kcontrol_new ad1981_thinkpad_mixers[] = { 1888 HDA_CODEC_VOLUME("Master Playback Volume", 0x05, 0x0, HDA_OUTPUT), 1889 HDA_CODEC_MUTE("Master Playback Switch", 0x05, 0x0, HDA_OUTPUT), 1890 HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT), 1891 HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT), 1892 HDA_CODEC_VOLUME("Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT), 1893 HDA_CODEC_MUTE("Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT), 1894 HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT), 1895 HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT), 1896 HDA_CODEC_VOLUME("Mic Boost Volume", 0x08, 0x0, HDA_INPUT), 1897 HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT), 1898 HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT), 1899 { 1900 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1901 .name = "Capture Source", 1902 .info = ad198x_mux_enum_info, 1903 .get = ad198x_mux_enum_get, 1904 .put = ad198x_mux_enum_put, 1905 }, 1906 /* identical with AD1983 */ 1907 { 1908 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1909 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source", 1910 .info = ad1983_spdif_route_info, 1911 .get = ad1983_spdif_route_get, 1912 .put = ad1983_spdif_route_put, 1913 }, 1914 { } /* end */ 1915 }; 1916 1917 static const struct hda_input_mux ad1981_thinkpad_capture_source = { 1918 .num_items = 3, 1919 .items = { 1920 { "Mic", 0x0 }, 1921 { "Mix", 0x2 }, 1922 { "CD", 0x4 }, 1923 }, 1924 }; 1925 1926 /* models */ 1927 enum { 1928 AD1981_BASIC, 1929 AD1981_HP, 1930 AD1981_THINKPAD, 1931 AD1981_TOSHIBA, 1932 AD1981_MODELS 1933 }; 1934 1935 static const char * const ad1981_models[AD1981_MODELS] = { 1936 [AD1981_HP] = "hp", 1937 [AD1981_THINKPAD] = "thinkpad", 1938 [AD1981_BASIC] = "basic", 1939 [AD1981_TOSHIBA] = "toshiba" 1940 }; 1941 1942 static const struct snd_pci_quirk ad1981_cfg_tbl[] = { 1943 SND_PCI_QUIRK(0x1014, 0x0597, "Lenovo Z60", AD1981_THINKPAD), 1944 SND_PCI_QUIRK(0x1014, 0x05b7, "Lenovo Z60m", AD1981_THINKPAD), 1945 /* All HP models */ 1946 SND_PCI_QUIRK_VENDOR(0x103c, "HP nx", AD1981_HP), 1947 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba U205", AD1981_TOSHIBA), 1948 /* Lenovo Thinkpad T60/X60/Z6xx */ 1949 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo Thinkpad", AD1981_THINKPAD), 1950 /* HP nx6320 (reversed SSID, H/W bug) */ 1951 SND_PCI_QUIRK(0x30b0, 0x103c, "HP nx6320", AD1981_HP), 1952 {} 1953 }; 1954 1955 static int patch_ad1981(struct hda_codec *codec) 1956 { 1957 struct ad198x_spec *spec; 1958 int err, board_config; 1959 1960 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 1961 if (spec == NULL) 1962 return -ENOMEM; 1963 1964 codec->spec = spec; 1965 1966 err = snd_hda_attach_beep_device(codec, 0x10); 1967 if (err < 0) { 1968 ad198x_free(codec); 1969 return err; 1970 } 1971 set_beep_amp(spec, 0x0d, 0, HDA_OUTPUT); 1972 1973 spec->multiout.max_channels = 2; 1974 spec->multiout.num_dacs = ARRAY_SIZE(ad1981_dac_nids); 1975 spec->multiout.dac_nids = ad1981_dac_nids; 1976 spec->multiout.dig_out_nid = AD1981_SPDIF_OUT; 1977 spec->num_adc_nids = 1; 1978 spec->adc_nids = ad1981_adc_nids; 1979 spec->capsrc_nids = ad1981_capsrc_nids; 1980 spec->input_mux = &ad1981_capture_source; 1981 spec->num_mixers = 1; 1982 spec->mixers[0] = ad1981_mixers; 1983 spec->num_init_verbs = 1; 1984 spec->init_verbs[0] = ad1981_init_verbs; 1985 spec->spdif_route = 0; 1986 #ifdef CONFIG_SND_HDA_POWER_SAVE 1987 spec->loopback.amplist = ad1981_loopbacks; 1988 #endif 1989 spec->vmaster_nid = 0x05; 1990 1991 codec->patch_ops = ad198x_patch_ops; 1992 1993 /* override some parameters */ 1994 board_config = snd_hda_check_board_config(codec, AD1981_MODELS, 1995 ad1981_models, 1996 ad1981_cfg_tbl); 1997 switch (board_config) { 1998 case AD1981_HP: 1999 spec->mixers[0] = ad1981_hp_mixers; 2000 spec->num_init_verbs = 2; 2001 spec->init_verbs[1] = ad1981_hp_init_verbs; 2002 if (!is_jack_available(codec, 0x0a)) 2003 spec->multiout.dig_out_nid = 0; 2004 spec->input_mux = &ad1981_hp_capture_source; 2005 2006 codec->patch_ops.init = ad1981_hp_init; 2007 codec->patch_ops.unsol_event = ad1981_hp_unsol_event; 2008 /* set the upper-limit for mixer amp to 0dB for avoiding the 2009 * possible damage by overloading 2010 */ 2011 snd_hda_override_amp_caps(codec, 0x11, HDA_INPUT, 2012 (0x17 << AC_AMPCAP_OFFSET_SHIFT) | 2013 (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) | 2014 (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) | 2015 (1 << AC_AMPCAP_MUTE_SHIFT)); 2016 break; 2017 case AD1981_THINKPAD: 2018 spec->mixers[0] = ad1981_thinkpad_mixers; 2019 spec->input_mux = &ad1981_thinkpad_capture_source; 2020 /* set the upper-limit for mixer amp to 0dB for avoiding the 2021 * possible damage by overloading 2022 */ 2023 snd_hda_override_amp_caps(codec, 0x11, HDA_INPUT, 2024 (0x17 << AC_AMPCAP_OFFSET_SHIFT) | 2025 (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) | 2026 (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) | 2027 (1 << AC_AMPCAP_MUTE_SHIFT)); 2028 break; 2029 case AD1981_TOSHIBA: 2030 spec->mixers[0] = ad1981_hp_mixers; 2031 spec->mixers[1] = ad1981_toshiba_mixers; 2032 spec->num_init_verbs = 2; 2033 spec->init_verbs[1] = ad1981_toshiba_init_verbs; 2034 spec->multiout.dig_out_nid = 0; 2035 spec->input_mux = &ad1981_hp_capture_source; 2036 codec->patch_ops.init = ad1981_hp_init; 2037 codec->patch_ops.unsol_event = ad1981_hp_unsol_event; 2038 break; 2039 } 2040 2041 codec->no_trigger_sense = 1; 2042 codec->no_sticky_stream = 1; 2043 2044 return 0; 2045 } 2046 2047 2048 /* 2049 * AD1988 2050 * 2051 * Output pins and routes 2052 * 2053 * Pin Mix Sel DAC (*) 2054 * port-A 0x11 (mute/hp) <- 0x22 <- 0x37 <- 03/04/06 2055 * port-B 0x14 (mute/hp) <- 0x2b <- 0x30 <- 03/04/06 2056 * port-C 0x15 (mute) <- 0x2c <- 0x31 <- 05/0a 2057 * port-D 0x12 (mute/hp) <- 0x29 <- 04 2058 * port-E 0x17 (mute/hp) <- 0x26 <- 0x32 <- 05/0a 2059 * port-F 0x16 (mute) <- 0x2a <- 06 2060 * port-G 0x24 (mute) <- 0x27 <- 05 2061 * port-H 0x25 (mute) <- 0x28 <- 0a 2062 * mono 0x13 (mute/amp)<- 0x1e <- 0x36 <- 03/04/06 2063 * 2064 * DAC0 = 03h, DAC1 = 04h, DAC2 = 05h, DAC3 = 06h, DAC4 = 0ah 2065 * (*) DAC2/3/4 are swapped to DAC3/4/2 on AD198A rev.2 due to a h/w bug. 2066 * 2067 * Input pins and routes 2068 * 2069 * pin boost mix input # / adc input # 2070 * port-A 0x11 -> 0x38 -> mix 2, ADC 0 2071 * port-B 0x14 -> 0x39 -> mix 0, ADC 1 2072 * port-C 0x15 -> 0x3a -> 33:0 - mix 1, ADC 2 2073 * port-D 0x12 -> 0x3d -> mix 3, ADC 8 2074 * port-E 0x17 -> 0x3c -> 34:0 - mix 4, ADC 4 2075 * port-F 0x16 -> 0x3b -> mix 5, ADC 3 2076 * port-G 0x24 -> N/A -> 33:1 - mix 1, 34:1 - mix 4, ADC 6 2077 * port-H 0x25 -> N/A -> 33:2 - mix 1, 34:2 - mix 4, ADC 7 2078 * 2079 * 2080 * DAC assignment 2081 * 6stack - front/surr/CLFE/side/opt DACs - 04/06/05/0a/03 2082 * 3stack - front/surr/CLFE/opt DACs - 04/05/0a/03 2083 * 2084 * Inputs of Analog Mix (0x20) 2085 * 0:Port-B (front mic) 2086 * 1:Port-C/G/H (line-in) 2087 * 2:Port-A 2088 * 3:Port-D (line-in/2) 2089 * 4:Port-E/G/H (mic-in) 2090 * 5:Port-F (mic2-in) 2091 * 6:CD 2092 * 7:Beep 2093 * 2094 * ADC selection 2095 * 0:Port-A 2096 * 1:Port-B (front mic-in) 2097 * 2:Port-C (line-in) 2098 * 3:Port-F (mic2-in) 2099 * 4:Port-E (mic-in) 2100 * 5:CD 2101 * 6:Port-G 2102 * 7:Port-H 2103 * 8:Port-D (line-in/2) 2104 * 9:Mix 2105 * 2106 * Proposed pin assignments by the datasheet 2107 * 2108 * 6-stack 2109 * Port-A front headphone 2110 * B front mic-in 2111 * C rear line-in 2112 * D rear front-out 2113 * E rear mic-in 2114 * F rear surround 2115 * G rear CLFE 2116 * H rear side 2117 * 2118 * 3-stack 2119 * Port-A front headphone 2120 * B front mic 2121 * C rear line-in/surround 2122 * D rear front-out 2123 * E rear mic-in/CLFE 2124 * 2125 * laptop 2126 * Port-A headphone 2127 * B mic-in 2128 * C docking station 2129 * D internal speaker (with EAPD) 2130 * E/F quad mic array 2131 */ 2132 2133 2134 /* models */ 2135 enum { 2136 AD1988_6STACK, 2137 AD1988_6STACK_DIG, 2138 AD1988_3STACK, 2139 AD1988_3STACK_DIG, 2140 AD1988_LAPTOP, 2141 AD1988_LAPTOP_DIG, 2142 AD1988_AUTO, 2143 AD1988_MODEL_LAST, 2144 }; 2145 2146 /* reivision id to check workarounds */ 2147 #define AD1988A_REV2 0x100200 2148 2149 #define is_rev2(codec) \ 2150 ((codec)->vendor_id == 0x11d41988 && \ 2151 (codec)->revision_id == AD1988A_REV2) 2152 2153 /* 2154 * mixers 2155 */ 2156 2157 static const hda_nid_t ad1988_6stack_dac_nids[4] = { 2158 0x04, 0x06, 0x05, 0x0a 2159 }; 2160 2161 static const hda_nid_t ad1988_3stack_dac_nids[3] = { 2162 0x04, 0x05, 0x0a 2163 }; 2164 2165 /* for AD1988A revision-2, DAC2-4 are swapped */ 2166 static const hda_nid_t ad1988_6stack_dac_nids_rev2[4] = { 2167 0x04, 0x05, 0x0a, 0x06 2168 }; 2169 2170 static const hda_nid_t ad1988_alt_dac_nid[1] = { 2171 0x03 2172 }; 2173 2174 static const hda_nid_t ad1988_3stack_dac_nids_rev2[3] = { 2175 0x04, 0x0a, 0x06 2176 }; 2177 2178 static const hda_nid_t ad1988_adc_nids[3] = { 2179 0x08, 0x09, 0x0f 2180 }; 2181 2182 static const hda_nid_t ad1988_capsrc_nids[3] = { 2183 0x0c, 0x0d, 0x0e 2184 }; 2185 2186 #define AD1988_SPDIF_OUT 0x02 2187 #define AD1988_SPDIF_OUT_HDMI 0x0b 2188 #define AD1988_SPDIF_IN 0x07 2189 2190 static const hda_nid_t ad1989b_slave_dig_outs[] = { 2191 AD1988_SPDIF_OUT, AD1988_SPDIF_OUT_HDMI, 0 2192 }; 2193 2194 static const struct hda_input_mux ad1988_6stack_capture_source = { 2195 .num_items = 5, 2196 .items = { 2197 { "Front Mic", 0x1 }, /* port-B */ 2198 { "Line", 0x2 }, /* port-C */ 2199 { "Mic", 0x4 }, /* port-E */ 2200 { "CD", 0x5 }, 2201 { "Mix", 0x9 }, 2202 }, 2203 }; 2204 2205 static const struct hda_input_mux ad1988_laptop_capture_source = { 2206 .num_items = 3, 2207 .items = { 2208 { "Mic/Line", 0x1 }, /* port-B */ 2209 { "CD", 0x5 }, 2210 { "Mix", 0x9 }, 2211 }, 2212 }; 2213 2214 /* 2215 */ 2216 static int ad198x_ch_mode_info(struct snd_kcontrol *kcontrol, 2217 struct snd_ctl_elem_info *uinfo) 2218 { 2219 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2220 struct ad198x_spec *spec = codec->spec; 2221 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode, 2222 spec->num_channel_mode); 2223 } 2224 2225 static int ad198x_ch_mode_get(struct snd_kcontrol *kcontrol, 2226 struct snd_ctl_elem_value *ucontrol) 2227 { 2228 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2229 struct ad198x_spec *spec = codec->spec; 2230 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode, 2231 spec->num_channel_mode, spec->multiout.max_channels); 2232 } 2233 2234 static int ad198x_ch_mode_put(struct snd_kcontrol *kcontrol, 2235 struct snd_ctl_elem_value *ucontrol) 2236 { 2237 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2238 struct ad198x_spec *spec = codec->spec; 2239 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode, 2240 spec->num_channel_mode, 2241 &spec->multiout.max_channels); 2242 if (err >= 0 && spec->need_dac_fix) 2243 spec->multiout.num_dacs = spec->multiout.max_channels / 2; 2244 return err; 2245 } 2246 2247 static const struct snd_kcontrol_new ad1988_hp_mixers[] = { 2248 { 2249 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2250 .name = "Independent HP", 2251 .info = ad1988_independent_hp_info, 2252 .get = ad1988_independent_hp_get, 2253 .put = ad1988_independent_hp_put, 2254 }, 2255 { } /* end */ 2256 }; 2257 2258 /* 6-stack mode */ 2259 static const struct snd_kcontrol_new ad1988_6stack_mixers1[] = { 2260 HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT), 2261 HDA_CODEC_VOLUME("Surround Playback Volume", 0x06, 0x0, HDA_OUTPUT), 2262 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT), 2263 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x05, 2, 0x0, HDA_OUTPUT), 2264 HDA_CODEC_VOLUME("Side Playback Volume", 0x0a, 0x0, HDA_OUTPUT), 2265 { } /* end */ 2266 }; 2267 2268 static const struct snd_kcontrol_new ad1988_6stack_mixers1_rev2[] = { 2269 HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT), 2270 HDA_CODEC_VOLUME("Surround Playback Volume", 0x05, 0x0, HDA_OUTPUT), 2271 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), 2272 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0a, 2, 0x0, HDA_OUTPUT), 2273 HDA_CODEC_VOLUME("Side Playback Volume", 0x06, 0x0, HDA_OUTPUT), 2274 { } /* end */ 2275 }; 2276 2277 static const struct snd_kcontrol_new ad1988_6stack_mixers2[] = { 2278 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 2279 HDA_BIND_MUTE("Front Playback Switch", 0x29, 2, HDA_INPUT), 2280 HDA_BIND_MUTE("Surround Playback Switch", 0x2a, 2, HDA_INPUT), 2281 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x27, 1, 2, HDA_INPUT), 2282 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x27, 2, 2, HDA_INPUT), 2283 HDA_BIND_MUTE("Side Playback Switch", 0x28, 2, HDA_INPUT), 2284 HDA_BIND_MUTE("Headphone Playback Switch", 0x22, 2, HDA_INPUT), 2285 HDA_BIND_MUTE("Mono Playback Switch", 0x1e, 2, HDA_INPUT), 2286 2287 HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x6, HDA_INPUT), 2288 HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x6, HDA_INPUT), 2289 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x0, HDA_INPUT), 2290 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x0, HDA_INPUT), 2291 HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x1, HDA_INPUT), 2292 HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x1, HDA_INPUT), 2293 HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x4, HDA_INPUT), 2294 HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x4, HDA_INPUT), 2295 2296 HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT), 2297 HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT), 2298 2299 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x39, 0x0, HDA_OUTPUT), 2300 HDA_CODEC_VOLUME("Mic Boost Volume", 0x3c, 0x0, HDA_OUTPUT), 2301 { } /* end */ 2302 }; 2303 2304 /* 3-stack mode */ 2305 static const struct snd_kcontrol_new ad1988_3stack_mixers1[] = { 2306 HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT), 2307 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0a, 0x0, HDA_OUTPUT), 2308 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT), 2309 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x05, 2, 0x0, HDA_OUTPUT), 2310 { } /* end */ 2311 }; 2312 2313 static const struct snd_kcontrol_new ad1988_3stack_mixers1_rev2[] = { 2314 HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT), 2315 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0a, 0x0, HDA_OUTPUT), 2316 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x06, 1, 0x0, HDA_OUTPUT), 2317 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x06, 2, 0x0, HDA_OUTPUT), 2318 { } /* end */ 2319 }; 2320 2321 static const struct snd_kcontrol_new ad1988_3stack_mixers2[] = { 2322 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 2323 HDA_BIND_MUTE("Front Playback Switch", 0x29, 2, HDA_INPUT), 2324 HDA_BIND_MUTE("Surround Playback Switch", 0x2c, 2, HDA_INPUT), 2325 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x26, 1, 2, HDA_INPUT), 2326 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x26, 2, 2, HDA_INPUT), 2327 HDA_BIND_MUTE("Headphone Playback Switch", 0x22, 2, HDA_INPUT), 2328 HDA_BIND_MUTE("Mono Playback Switch", 0x1e, 2, HDA_INPUT), 2329 2330 HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x6, HDA_INPUT), 2331 HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x6, HDA_INPUT), 2332 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x0, HDA_INPUT), 2333 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x0, HDA_INPUT), 2334 HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x1, HDA_INPUT), 2335 HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x1, HDA_INPUT), 2336 HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x4, HDA_INPUT), 2337 HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x4, HDA_INPUT), 2338 2339 HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT), 2340 HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT), 2341 2342 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x39, 0x0, HDA_OUTPUT), 2343 HDA_CODEC_VOLUME("Mic Boost Volume", 0x3c, 0x0, HDA_OUTPUT), 2344 { 2345 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2346 .name = "Channel Mode", 2347 .info = ad198x_ch_mode_info, 2348 .get = ad198x_ch_mode_get, 2349 .put = ad198x_ch_mode_put, 2350 }, 2351 2352 { } /* end */ 2353 }; 2354 2355 /* laptop mode */ 2356 static const struct snd_kcontrol_new ad1988_laptop_mixers[] = { 2357 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 2358 HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT), 2359 HDA_CODEC_MUTE("PCM Playback Switch", 0x29, 0x0, HDA_INPUT), 2360 HDA_BIND_MUTE("Mono Playback Switch", 0x1e, 2, HDA_INPUT), 2361 2362 HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x6, HDA_INPUT), 2363 HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x6, HDA_INPUT), 2364 HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x0, HDA_INPUT), 2365 HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x0, HDA_INPUT), 2366 HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x1, HDA_INPUT), 2367 HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x1, HDA_INPUT), 2368 2369 HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT), 2370 HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT), 2371 2372 HDA_CODEC_VOLUME("Mic Boost Volume", 0x39, 0x0, HDA_OUTPUT), 2373 2374 { 2375 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2376 .name = "External Amplifier", 2377 .subdevice = HDA_SUBDEV_NID_FLAG | 0x12, 2378 .info = ad198x_eapd_info, 2379 .get = ad198x_eapd_get, 2380 .put = ad198x_eapd_put, 2381 .private_value = 0x12, /* port-D */ 2382 }, 2383 2384 { } /* end */ 2385 }; 2386 2387 /* capture */ 2388 static const struct snd_kcontrol_new ad1988_capture_mixers[] = { 2389 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), 2390 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), 2391 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT), 2392 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT), 2393 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x0e, 0x0, HDA_OUTPUT), 2394 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x0e, 0x0, HDA_OUTPUT), 2395 { 2396 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2397 /* The multiple "Capture Source" controls confuse alsamixer 2398 * So call somewhat different.. 2399 */ 2400 /* .name = "Capture Source", */ 2401 .name = "Input Source", 2402 .count = 3, 2403 .info = ad198x_mux_enum_info, 2404 .get = ad198x_mux_enum_get, 2405 .put = ad198x_mux_enum_put, 2406 }, 2407 { } /* end */ 2408 }; 2409 2410 static int ad1988_spdif_playback_source_info(struct snd_kcontrol *kcontrol, 2411 struct snd_ctl_elem_info *uinfo) 2412 { 2413 static const char * const texts[] = { 2414 "PCM", "ADC1", "ADC2", "ADC3" 2415 }; 2416 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 2417 uinfo->count = 1; 2418 uinfo->value.enumerated.items = 4; 2419 if (uinfo->value.enumerated.item >= 4) 2420 uinfo->value.enumerated.item = 3; 2421 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); 2422 return 0; 2423 } 2424 2425 static int ad1988_spdif_playback_source_get(struct snd_kcontrol *kcontrol, 2426 struct snd_ctl_elem_value *ucontrol) 2427 { 2428 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2429 unsigned int sel; 2430 2431 sel = snd_hda_codec_read(codec, 0x1d, 0, AC_VERB_GET_AMP_GAIN_MUTE, 2432 AC_AMP_GET_INPUT); 2433 if (!(sel & 0x80)) 2434 ucontrol->value.enumerated.item[0] = 0; 2435 else { 2436 sel = snd_hda_codec_read(codec, 0x0b, 0, 2437 AC_VERB_GET_CONNECT_SEL, 0); 2438 if (sel < 3) 2439 sel++; 2440 else 2441 sel = 0; 2442 ucontrol->value.enumerated.item[0] = sel; 2443 } 2444 return 0; 2445 } 2446 2447 static int ad1988_spdif_playback_source_put(struct snd_kcontrol *kcontrol, 2448 struct snd_ctl_elem_value *ucontrol) 2449 { 2450 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2451 unsigned int val, sel; 2452 int change; 2453 2454 val = ucontrol->value.enumerated.item[0]; 2455 if (val > 3) 2456 return -EINVAL; 2457 if (!val) { 2458 sel = snd_hda_codec_read(codec, 0x1d, 0, 2459 AC_VERB_GET_AMP_GAIN_MUTE, 2460 AC_AMP_GET_INPUT); 2461 change = sel & 0x80; 2462 if (change) { 2463 snd_hda_codec_write_cache(codec, 0x1d, 0, 2464 AC_VERB_SET_AMP_GAIN_MUTE, 2465 AMP_IN_UNMUTE(0)); 2466 snd_hda_codec_write_cache(codec, 0x1d, 0, 2467 AC_VERB_SET_AMP_GAIN_MUTE, 2468 AMP_IN_MUTE(1)); 2469 } 2470 } else { 2471 sel = snd_hda_codec_read(codec, 0x1d, 0, 2472 AC_VERB_GET_AMP_GAIN_MUTE, 2473 AC_AMP_GET_INPUT | 0x01); 2474 change = sel & 0x80; 2475 if (change) { 2476 snd_hda_codec_write_cache(codec, 0x1d, 0, 2477 AC_VERB_SET_AMP_GAIN_MUTE, 2478 AMP_IN_MUTE(0)); 2479 snd_hda_codec_write_cache(codec, 0x1d, 0, 2480 AC_VERB_SET_AMP_GAIN_MUTE, 2481 AMP_IN_UNMUTE(1)); 2482 } 2483 sel = snd_hda_codec_read(codec, 0x0b, 0, 2484 AC_VERB_GET_CONNECT_SEL, 0) + 1; 2485 change |= sel != val; 2486 if (change) 2487 snd_hda_codec_write_cache(codec, 0x0b, 0, 2488 AC_VERB_SET_CONNECT_SEL, 2489 val - 1); 2490 } 2491 return change; 2492 } 2493 2494 static const struct snd_kcontrol_new ad1988_spdif_out_mixers[] = { 2495 HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT), 2496 { 2497 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2498 .name = "IEC958 Playback Source", 2499 .subdevice = HDA_SUBDEV_NID_FLAG | 0x1b, 2500 .info = ad1988_spdif_playback_source_info, 2501 .get = ad1988_spdif_playback_source_get, 2502 .put = ad1988_spdif_playback_source_put, 2503 }, 2504 { } /* end */ 2505 }; 2506 2507 static const struct snd_kcontrol_new ad1988_spdif_in_mixers[] = { 2508 HDA_CODEC_VOLUME("IEC958 Capture Volume", 0x1c, 0x0, HDA_INPUT), 2509 { } /* end */ 2510 }; 2511 2512 static const struct snd_kcontrol_new ad1989_spdif_out_mixers[] = { 2513 HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT), 2514 HDA_CODEC_VOLUME("HDMI Playback Volume", 0x1d, 0x0, HDA_OUTPUT), 2515 { } /* end */ 2516 }; 2517 2518 /* 2519 * initialization verbs 2520 */ 2521 2522 /* 2523 * for 6-stack (+dig) 2524 */ 2525 static const struct hda_verb ad1988_6stack_init_verbs[] = { 2526 /* Front, Surround, CLFE, side DAC; unmute as default */ 2527 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2528 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2529 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2530 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2531 /* Port-A front headphon path */ 2532 {0x37, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC0:03h */ 2533 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 2534 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 2535 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2536 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 2537 /* Port-D line-out path */ 2538 {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 2539 {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 2540 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2541 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2542 /* Port-F surround path */ 2543 {0x2a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 2544 {0x2a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 2545 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2546 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2547 /* Port-G CLFE path */ 2548 {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 2549 {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 2550 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2551 {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2552 /* Port-H side path */ 2553 {0x28, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 2554 {0x28, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 2555 {0x25, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2556 {0x25, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2557 /* Mono out path */ 2558 {0x36, AC_VERB_SET_CONNECT_SEL, 0x1}, /* DAC1:04h */ 2559 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 2560 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 2561 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2562 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb01f}, /* unmute, 0dB */ 2563 /* Port-B front mic-in path */ 2564 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2565 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2566 {0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 2567 /* Port-C line-in path */ 2568 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2569 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2570 {0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 2571 {0x33, AC_VERB_SET_CONNECT_SEL, 0x0}, 2572 /* Port-E mic-in path */ 2573 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2574 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2575 {0x3c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 2576 {0x34, AC_VERB_SET_CONNECT_SEL, 0x0}, 2577 /* Analog CD Input */ 2578 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2579 /* Analog Mix output amp */ 2580 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */ 2581 2582 { } 2583 }; 2584 2585 static const struct hda_verb ad1988_6stack_fp_init_verbs[] = { 2586 /* Headphone; unmute as default */ 2587 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2588 /* Port-A front headphon path */ 2589 {0x37, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC0:03h */ 2590 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 2591 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 2592 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2593 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 2594 2595 { } 2596 }; 2597 2598 static const struct hda_verb ad1988_capture_init_verbs[] = { 2599 /* mute analog mix */ 2600 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 2601 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 2602 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 2603 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 2604 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 2605 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, 2606 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, 2607 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, 2608 /* select ADCs - front-mic */ 2609 {0x0c, AC_VERB_SET_CONNECT_SEL, 0x1}, 2610 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x1}, 2611 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x1}, 2612 2613 { } 2614 }; 2615 2616 static const struct hda_verb ad1988_spdif_init_verbs[] = { 2617 /* SPDIF out sel */ 2618 {0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, /* PCM */ 2619 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x0}, /* ADC1 */ 2620 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 2621 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 2622 /* SPDIF out pin */ 2623 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */ 2624 2625 { } 2626 }; 2627 2628 static const struct hda_verb ad1988_spdif_in_init_verbs[] = { 2629 /* unmute SPDIF input pin */ 2630 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 2631 { } 2632 }; 2633 2634 /* AD1989 has no ADC -> SPDIF route */ 2635 static const struct hda_verb ad1989_spdif_init_verbs[] = { 2636 /* SPDIF-1 out pin */ 2637 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 2638 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */ 2639 /* SPDIF-2/HDMI out pin */ 2640 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 2641 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */ 2642 { } 2643 }; 2644 2645 /* 2646 * verbs for 3stack (+dig) 2647 */ 2648 static const struct hda_verb ad1988_3stack_ch2_init[] = { 2649 /* set port-C to line-in */ 2650 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 2651 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 2652 /* set port-E to mic-in */ 2653 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 2654 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 2655 { } /* end */ 2656 }; 2657 2658 static const struct hda_verb ad1988_3stack_ch6_init[] = { 2659 /* set port-C to surround out */ 2660 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 2661 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 2662 /* set port-E to CLFE out */ 2663 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 2664 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 2665 { } /* end */ 2666 }; 2667 2668 static const struct hda_channel_mode ad1988_3stack_modes[2] = { 2669 { 2, ad1988_3stack_ch2_init }, 2670 { 6, ad1988_3stack_ch6_init }, 2671 }; 2672 2673 static const struct hda_verb ad1988_3stack_init_verbs[] = { 2674 /* Front, Surround, CLFE, side DAC; unmute as default */ 2675 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2676 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2677 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2678 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2679 /* Port-A front headphon path */ 2680 {0x37, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC0:03h */ 2681 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 2682 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 2683 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2684 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 2685 /* Port-D line-out path */ 2686 {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 2687 {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 2688 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2689 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2690 /* Mono out path */ 2691 {0x36, AC_VERB_SET_CONNECT_SEL, 0x1}, /* DAC1:04h */ 2692 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 2693 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 2694 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2695 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb01f}, /* unmute, 0dB */ 2696 /* Port-B front mic-in path */ 2697 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2698 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2699 {0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 2700 /* Port-C line-in/surround path - 6ch mode as default */ 2701 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2702 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2703 {0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 2704 {0x31, AC_VERB_SET_CONNECT_SEL, 0x0}, /* output sel: DAC 0x05 */ 2705 {0x33, AC_VERB_SET_CONNECT_SEL, 0x0}, 2706 /* Port-E mic-in/CLFE path - 6ch mode as default */ 2707 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2708 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2709 {0x3c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 2710 {0x32, AC_VERB_SET_CONNECT_SEL, 0x1}, /* output sel: DAC 0x0a */ 2711 {0x34, AC_VERB_SET_CONNECT_SEL, 0x0}, 2712 /* mute analog mix */ 2713 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 2714 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 2715 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 2716 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 2717 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 2718 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, 2719 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, 2720 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, 2721 /* select ADCs - front-mic */ 2722 {0x0c, AC_VERB_SET_CONNECT_SEL, 0x1}, 2723 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x1}, 2724 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x1}, 2725 /* Analog Mix output amp */ 2726 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */ 2727 { } 2728 }; 2729 2730 /* 2731 * verbs for laptop mode (+dig) 2732 */ 2733 static const struct hda_verb ad1988_laptop_hp_on[] = { 2734 /* unmute port-A and mute port-D */ 2735 { 0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 2736 { 0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 2737 { } /* end */ 2738 }; 2739 static const struct hda_verb ad1988_laptop_hp_off[] = { 2740 /* mute port-A and unmute port-D */ 2741 { 0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 2742 { 0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 2743 { } /* end */ 2744 }; 2745 2746 #define AD1988_HP_EVENT 0x01 2747 2748 static const struct hda_verb ad1988_laptop_init_verbs[] = { 2749 /* Front, Surround, CLFE, side DAC; unmute as default */ 2750 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2751 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2752 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2753 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2754 /* Port-A front headphon path */ 2755 {0x37, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC0:03h */ 2756 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 2757 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 2758 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2759 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 2760 /* unsolicited event for pin-sense */ 2761 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1988_HP_EVENT }, 2762 /* Port-D line-out path + EAPD */ 2763 {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 2764 {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 2765 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2766 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2767 {0x12, AC_VERB_SET_EAPD_BTLENABLE, 0x00}, /* EAPD-off */ 2768 /* Mono out path */ 2769 {0x36, AC_VERB_SET_CONNECT_SEL, 0x1}, /* DAC1:04h */ 2770 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 2771 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 2772 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2773 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb01f}, /* unmute, 0dB */ 2774 /* Port-B mic-in path */ 2775 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2776 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2777 {0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 2778 /* Port-C docking station - try to output */ 2779 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2780 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2781 {0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 2782 {0x33, AC_VERB_SET_CONNECT_SEL, 0x0}, 2783 /* mute analog mix */ 2784 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 2785 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 2786 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 2787 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 2788 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 2789 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, 2790 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, 2791 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, 2792 /* select ADCs - mic */ 2793 {0x0c, AC_VERB_SET_CONNECT_SEL, 0x1}, 2794 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x1}, 2795 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x1}, 2796 /* Analog Mix output amp */ 2797 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */ 2798 { } 2799 }; 2800 2801 static void ad1988_laptop_unsol_event(struct hda_codec *codec, unsigned int res) 2802 { 2803 if ((res >> 26) != AD1988_HP_EVENT) 2804 return; 2805 if (snd_hda_jack_detect(codec, 0x11)) 2806 snd_hda_sequence_write(codec, ad1988_laptop_hp_on); 2807 else 2808 snd_hda_sequence_write(codec, ad1988_laptop_hp_off); 2809 } 2810 2811 #ifdef CONFIG_SND_HDA_POWER_SAVE 2812 static const struct hda_amp_list ad1988_loopbacks[] = { 2813 { 0x20, HDA_INPUT, 0 }, /* Front Mic */ 2814 { 0x20, HDA_INPUT, 1 }, /* Line */ 2815 { 0x20, HDA_INPUT, 4 }, /* Mic */ 2816 { 0x20, HDA_INPUT, 6 }, /* CD */ 2817 { } /* end */ 2818 }; 2819 #endif 2820 2821 /* 2822 * Automatic parse of I/O pins from the BIOS configuration 2823 */ 2824 2825 enum { 2826 AD_CTL_WIDGET_VOL, 2827 AD_CTL_WIDGET_MUTE, 2828 AD_CTL_BIND_MUTE, 2829 }; 2830 static const struct snd_kcontrol_new ad1988_control_templates[] = { 2831 HDA_CODEC_VOLUME(NULL, 0, 0, 0), 2832 HDA_CODEC_MUTE(NULL, 0, 0, 0), 2833 HDA_BIND_MUTE(NULL, 0, 0, 0), 2834 }; 2835 2836 /* add dynamic controls */ 2837 static int add_control(struct ad198x_spec *spec, int type, const char *name, 2838 unsigned long val) 2839 { 2840 struct snd_kcontrol_new *knew; 2841 2842 snd_array_init(&spec->kctls, sizeof(*knew), 32); 2843 knew = snd_array_new(&spec->kctls); 2844 if (!knew) 2845 return -ENOMEM; 2846 *knew = ad1988_control_templates[type]; 2847 knew->name = kstrdup(name, GFP_KERNEL); 2848 if (! knew->name) 2849 return -ENOMEM; 2850 if (get_amp_nid_(val)) 2851 knew->subdevice = HDA_SUBDEV_AMP_FLAG; 2852 knew->private_value = val; 2853 return 0; 2854 } 2855 2856 #define AD1988_PIN_CD_NID 0x18 2857 #define AD1988_PIN_BEEP_NID 0x10 2858 2859 static const hda_nid_t ad1988_mixer_nids[8] = { 2860 /* A B C D E F G H */ 2861 0x22, 0x2b, 0x2c, 0x29, 0x26, 0x2a, 0x27, 0x28 2862 }; 2863 2864 static inline hda_nid_t ad1988_idx_to_dac(struct hda_codec *codec, int idx) 2865 { 2866 static const hda_nid_t idx_to_dac[8] = { 2867 /* A B C D E F G H */ 2868 0x03, 0x06, 0x05, 0x04, 0x0a, 0x06, 0x05, 0x0a 2869 }; 2870 static const hda_nid_t idx_to_dac_rev2[8] = { 2871 /* A B C D E F G H */ 2872 0x03, 0x05, 0x0a, 0x04, 0x06, 0x05, 0x0a, 0x06 2873 }; 2874 if (is_rev2(codec)) 2875 return idx_to_dac_rev2[idx]; 2876 else 2877 return idx_to_dac[idx]; 2878 } 2879 2880 static const hda_nid_t ad1988_boost_nids[8] = { 2881 0x38, 0x39, 0x3a, 0x3d, 0x3c, 0x3b, 0, 0 2882 }; 2883 2884 static int ad1988_pin_idx(hda_nid_t nid) 2885 { 2886 static const hda_nid_t ad1988_io_pins[8] = { 2887 0x11, 0x14, 0x15, 0x12, 0x17, 0x16, 0x24, 0x25 2888 }; 2889 int i; 2890 for (i = 0; i < ARRAY_SIZE(ad1988_io_pins); i++) 2891 if (ad1988_io_pins[i] == nid) 2892 return i; 2893 return 0; /* should be -1 */ 2894 } 2895 2896 static int ad1988_pin_to_loopback_idx(hda_nid_t nid) 2897 { 2898 static const int loopback_idx[8] = { 2899 2, 0, 1, 3, 4, 5, 1, 4 2900 }; 2901 switch (nid) { 2902 case AD1988_PIN_CD_NID: 2903 return 6; 2904 default: 2905 return loopback_idx[ad1988_pin_idx(nid)]; 2906 } 2907 } 2908 2909 static int ad1988_pin_to_adc_idx(hda_nid_t nid) 2910 { 2911 static const int adc_idx[8] = { 2912 0, 1, 2, 8, 4, 3, 6, 7 2913 }; 2914 switch (nid) { 2915 case AD1988_PIN_CD_NID: 2916 return 5; 2917 default: 2918 return adc_idx[ad1988_pin_idx(nid)]; 2919 } 2920 } 2921 2922 /* fill in the dac_nids table from the parsed pin configuration */ 2923 static int ad1988_auto_fill_dac_nids(struct hda_codec *codec, 2924 const struct auto_pin_cfg *cfg) 2925 { 2926 struct ad198x_spec *spec = codec->spec; 2927 int i, idx; 2928 2929 spec->multiout.dac_nids = spec->private_dac_nids; 2930 2931 /* check the pins hardwired to audio widget */ 2932 for (i = 0; i < cfg->line_outs; i++) { 2933 idx = ad1988_pin_idx(cfg->line_out_pins[i]); 2934 spec->private_dac_nids[i] = ad1988_idx_to_dac(codec, idx); 2935 } 2936 spec->multiout.num_dacs = cfg->line_outs; 2937 return 0; 2938 } 2939 2940 /* add playback controls from the parsed DAC table */ 2941 static int ad1988_auto_create_multi_out_ctls(struct ad198x_spec *spec, 2942 const struct auto_pin_cfg *cfg) 2943 { 2944 char name[32]; 2945 static const char * const chname[4] = { 2946 "Front", "Surround", NULL /*CLFE*/, "Side" 2947 }; 2948 hda_nid_t nid; 2949 int i, err; 2950 2951 for (i = 0; i < cfg->line_outs; i++) { 2952 hda_nid_t dac = spec->multiout.dac_nids[i]; 2953 if (! dac) 2954 continue; 2955 nid = ad1988_mixer_nids[ad1988_pin_idx(cfg->line_out_pins[i])]; 2956 if (i == 2) { 2957 /* Center/LFE */ 2958 err = add_control(spec, AD_CTL_WIDGET_VOL, 2959 "Center Playback Volume", 2960 HDA_COMPOSE_AMP_VAL(dac, 1, 0, HDA_OUTPUT)); 2961 if (err < 0) 2962 return err; 2963 err = add_control(spec, AD_CTL_WIDGET_VOL, 2964 "LFE Playback Volume", 2965 HDA_COMPOSE_AMP_VAL(dac, 2, 0, HDA_OUTPUT)); 2966 if (err < 0) 2967 return err; 2968 err = add_control(spec, AD_CTL_BIND_MUTE, 2969 "Center Playback Switch", 2970 HDA_COMPOSE_AMP_VAL(nid, 1, 2, HDA_INPUT)); 2971 if (err < 0) 2972 return err; 2973 err = add_control(spec, AD_CTL_BIND_MUTE, 2974 "LFE Playback Switch", 2975 HDA_COMPOSE_AMP_VAL(nid, 2, 2, HDA_INPUT)); 2976 if (err < 0) 2977 return err; 2978 } else { 2979 sprintf(name, "%s Playback Volume", chname[i]); 2980 err = add_control(spec, AD_CTL_WIDGET_VOL, name, 2981 HDA_COMPOSE_AMP_VAL(dac, 3, 0, HDA_OUTPUT)); 2982 if (err < 0) 2983 return err; 2984 sprintf(name, "%s Playback Switch", chname[i]); 2985 err = add_control(spec, AD_CTL_BIND_MUTE, name, 2986 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT)); 2987 if (err < 0) 2988 return err; 2989 } 2990 } 2991 return 0; 2992 } 2993 2994 /* add playback controls for speaker and HP outputs */ 2995 static int ad1988_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin, 2996 const char *pfx) 2997 { 2998 struct ad198x_spec *spec = codec->spec; 2999 hda_nid_t nid; 3000 int i, idx, err; 3001 char name[32]; 3002 3003 if (! pin) 3004 return 0; 3005 3006 idx = ad1988_pin_idx(pin); 3007 nid = ad1988_idx_to_dac(codec, idx); 3008 /* check whether the corresponding DAC was already taken */ 3009 for (i = 0; i < spec->autocfg.line_outs; i++) { 3010 hda_nid_t pin = spec->autocfg.line_out_pins[i]; 3011 hda_nid_t dac = ad1988_idx_to_dac(codec, ad1988_pin_idx(pin)); 3012 if (dac == nid) 3013 break; 3014 } 3015 if (i >= spec->autocfg.line_outs) { 3016 /* specify the DAC as the extra output */ 3017 if (!spec->multiout.hp_nid) 3018 spec->multiout.hp_nid = nid; 3019 else 3020 spec->multiout.extra_out_nid[0] = nid; 3021 /* control HP volume/switch on the output mixer amp */ 3022 sprintf(name, "%s Playback Volume", pfx); 3023 err = add_control(spec, AD_CTL_WIDGET_VOL, name, 3024 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); 3025 if (err < 0) 3026 return err; 3027 } 3028 nid = ad1988_mixer_nids[idx]; 3029 sprintf(name, "%s Playback Switch", pfx); 3030 if ((err = add_control(spec, AD_CTL_BIND_MUTE, name, 3031 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT))) < 0) 3032 return err; 3033 return 0; 3034 } 3035 3036 /* create input playback/capture controls for the given pin */ 3037 static int new_analog_input(struct ad198x_spec *spec, hda_nid_t pin, 3038 const char *ctlname, int ctlidx, int boost) 3039 { 3040 char name[32]; 3041 int err, idx; 3042 3043 sprintf(name, "%s Playback Volume", ctlname); 3044 idx = ad1988_pin_to_loopback_idx(pin); 3045 if ((err = add_control(spec, AD_CTL_WIDGET_VOL, name, 3046 HDA_COMPOSE_AMP_VAL(0x20, 3, idx, HDA_INPUT))) < 0) 3047 return err; 3048 sprintf(name, "%s Playback Switch", ctlname); 3049 if ((err = add_control(spec, AD_CTL_WIDGET_MUTE, name, 3050 HDA_COMPOSE_AMP_VAL(0x20, 3, idx, HDA_INPUT))) < 0) 3051 return err; 3052 if (boost) { 3053 hda_nid_t bnid; 3054 idx = ad1988_pin_idx(pin); 3055 bnid = ad1988_boost_nids[idx]; 3056 if (bnid) { 3057 sprintf(name, "%s Boost Volume", ctlname); 3058 return add_control(spec, AD_CTL_WIDGET_VOL, name, 3059 HDA_COMPOSE_AMP_VAL(bnid, 3, idx, HDA_OUTPUT)); 3060 3061 } 3062 } 3063 return 0; 3064 } 3065 3066 /* create playback/capture controls for input pins */ 3067 static int ad1988_auto_create_analog_input_ctls(struct hda_codec *codec, 3068 const struct auto_pin_cfg *cfg) 3069 { 3070 struct ad198x_spec *spec = codec->spec; 3071 struct hda_input_mux *imux = &spec->private_imux; 3072 int i, err, type, type_idx; 3073 3074 for (i = 0; i < cfg->num_inputs; i++) { 3075 const char *label; 3076 type = cfg->inputs[i].type; 3077 label = hda_get_autocfg_input_label(codec, cfg, i); 3078 snd_hda_add_imux_item(imux, label, 3079 ad1988_pin_to_adc_idx(cfg->inputs[i].pin), 3080 &type_idx); 3081 err = new_analog_input(spec, cfg->inputs[i].pin, 3082 label, type_idx, 3083 type == AUTO_PIN_MIC); 3084 if (err < 0) 3085 return err; 3086 } 3087 snd_hda_add_imux_item(imux, "Mix", 9, NULL); 3088 3089 if ((err = add_control(spec, AD_CTL_WIDGET_VOL, 3090 "Analog Mix Playback Volume", 3091 HDA_COMPOSE_AMP_VAL(0x21, 3, 0x0, HDA_OUTPUT))) < 0) 3092 return err; 3093 if ((err = add_control(spec, AD_CTL_WIDGET_MUTE, 3094 "Analog Mix Playback Switch", 3095 HDA_COMPOSE_AMP_VAL(0x21, 3, 0x0, HDA_OUTPUT))) < 0) 3096 return err; 3097 3098 return 0; 3099 } 3100 3101 static void ad1988_auto_set_output_and_unmute(struct hda_codec *codec, 3102 hda_nid_t nid, int pin_type, 3103 int dac_idx) 3104 { 3105 /* set as output */ 3106 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type); 3107 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); 3108 switch (nid) { 3109 case 0x11: /* port-A - DAC 03 */ 3110 snd_hda_codec_write(codec, 0x37, 0, AC_VERB_SET_CONNECT_SEL, 0x00); 3111 break; 3112 case 0x14: /* port-B - DAC 06 */ 3113 snd_hda_codec_write(codec, 0x30, 0, AC_VERB_SET_CONNECT_SEL, 0x02); 3114 break; 3115 case 0x15: /* port-C - DAC 05 */ 3116 snd_hda_codec_write(codec, 0x31, 0, AC_VERB_SET_CONNECT_SEL, 0x00); 3117 break; 3118 case 0x17: /* port-E - DAC 0a */ 3119 snd_hda_codec_write(codec, 0x32, 0, AC_VERB_SET_CONNECT_SEL, 0x01); 3120 break; 3121 case 0x13: /* mono - DAC 04 */ 3122 snd_hda_codec_write(codec, 0x36, 0, AC_VERB_SET_CONNECT_SEL, 0x01); 3123 break; 3124 } 3125 } 3126 3127 static void ad1988_auto_init_multi_out(struct hda_codec *codec) 3128 { 3129 struct ad198x_spec *spec = codec->spec; 3130 int i; 3131 3132 for (i = 0; i < spec->autocfg.line_outs; i++) { 3133 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 3134 ad1988_auto_set_output_and_unmute(codec, nid, PIN_OUT, i); 3135 } 3136 } 3137 3138 static void ad1988_auto_init_extra_out(struct hda_codec *codec) 3139 { 3140 struct ad198x_spec *spec = codec->spec; 3141 hda_nid_t pin; 3142 3143 pin = spec->autocfg.speaker_pins[0]; 3144 if (pin) /* connect to front */ 3145 ad1988_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0); 3146 pin = spec->autocfg.hp_pins[0]; 3147 if (pin) /* connect to front */ 3148 ad1988_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); 3149 } 3150 3151 static void ad1988_auto_init_analog_input(struct hda_codec *codec) 3152 { 3153 struct ad198x_spec *spec = codec->spec; 3154 const struct auto_pin_cfg *cfg = &spec->autocfg; 3155 int i, idx; 3156 3157 for (i = 0; i < cfg->num_inputs; i++) { 3158 hda_nid_t nid = cfg->inputs[i].pin; 3159 int type = cfg->inputs[i].type; 3160 switch (nid) { 3161 case 0x15: /* port-C */ 3162 snd_hda_codec_write(codec, 0x33, 0, AC_VERB_SET_CONNECT_SEL, 0x0); 3163 break; 3164 case 0x17: /* port-E */ 3165 snd_hda_codec_write(codec, 0x34, 0, AC_VERB_SET_CONNECT_SEL, 0x0); 3166 break; 3167 } 3168 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 3169 type == AUTO_PIN_MIC ? PIN_VREF80 : PIN_IN); 3170 if (nid != AD1988_PIN_CD_NID) 3171 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, 3172 AMP_OUT_MUTE); 3173 idx = ad1988_pin_idx(nid); 3174 if (ad1988_boost_nids[idx]) 3175 snd_hda_codec_write(codec, ad1988_boost_nids[idx], 0, 3176 AC_VERB_SET_AMP_GAIN_MUTE, 3177 AMP_OUT_ZERO); 3178 } 3179 } 3180 3181 /* parse the BIOS configuration and set up the alc_spec */ 3182 /* return 1 if successful, 0 if the proper config is not found, or a negative error code */ 3183 static int ad1988_parse_auto_config(struct hda_codec *codec) 3184 { 3185 struct ad198x_spec *spec = codec->spec; 3186 int err; 3187 3188 if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL)) < 0) 3189 return err; 3190 if ((err = ad1988_auto_fill_dac_nids(codec, &spec->autocfg)) < 0) 3191 return err; 3192 if (! spec->autocfg.line_outs) 3193 return 0; /* can't find valid BIOS pin config */ 3194 if ((err = ad1988_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 || 3195 (err = ad1988_auto_create_extra_out(codec, 3196 spec->autocfg.speaker_pins[0], 3197 "Speaker")) < 0 || 3198 (err = ad1988_auto_create_extra_out(codec, spec->autocfg.hp_pins[0], 3199 "Headphone")) < 0 || 3200 (err = ad1988_auto_create_analog_input_ctls(codec, &spec->autocfg)) < 0) 3201 return err; 3202 3203 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 3204 3205 if (spec->autocfg.dig_outs) 3206 spec->multiout.dig_out_nid = AD1988_SPDIF_OUT; 3207 if (spec->autocfg.dig_in_pin) 3208 spec->dig_in_nid = AD1988_SPDIF_IN; 3209 3210 if (spec->kctls.list) 3211 spec->mixers[spec->num_mixers++] = spec->kctls.list; 3212 3213 spec->init_verbs[spec->num_init_verbs++] = ad1988_6stack_init_verbs; 3214 3215 spec->input_mux = &spec->private_imux; 3216 3217 return 1; 3218 } 3219 3220 /* init callback for auto-configuration model -- overriding the default init */ 3221 static int ad1988_auto_init(struct hda_codec *codec) 3222 { 3223 ad198x_init(codec); 3224 ad1988_auto_init_multi_out(codec); 3225 ad1988_auto_init_extra_out(codec); 3226 ad1988_auto_init_analog_input(codec); 3227 return 0; 3228 } 3229 3230 /* 3231 */ 3232 3233 static const char * const ad1988_models[AD1988_MODEL_LAST] = { 3234 [AD1988_6STACK] = "6stack", 3235 [AD1988_6STACK_DIG] = "6stack-dig", 3236 [AD1988_3STACK] = "3stack", 3237 [AD1988_3STACK_DIG] = "3stack-dig", 3238 [AD1988_LAPTOP] = "laptop", 3239 [AD1988_LAPTOP_DIG] = "laptop-dig", 3240 [AD1988_AUTO] = "auto", 3241 }; 3242 3243 static const struct snd_pci_quirk ad1988_cfg_tbl[] = { 3244 SND_PCI_QUIRK(0x1043, 0x81ec, "Asus P5B-DLX", AD1988_6STACK_DIG), 3245 SND_PCI_QUIRK(0x1043, 0x81f6, "Asus M2N-SLI", AD1988_6STACK_DIG), 3246 SND_PCI_QUIRK(0x1043, 0x8277, "Asus P5K-E/WIFI-AP", AD1988_6STACK_DIG), 3247 SND_PCI_QUIRK(0x1043, 0x82c0, "Asus M3N-HT Deluxe", AD1988_6STACK_DIG), 3248 SND_PCI_QUIRK(0x1043, 0x8311, "Asus P5Q-Premium/Pro", AD1988_6STACK_DIG), 3249 {} 3250 }; 3251 3252 static int patch_ad1988(struct hda_codec *codec) 3253 { 3254 struct ad198x_spec *spec; 3255 int err, board_config; 3256 3257 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 3258 if (spec == NULL) 3259 return -ENOMEM; 3260 3261 codec->spec = spec; 3262 3263 if (is_rev2(codec)) 3264 snd_printk(KERN_INFO "patch_analog: AD1988A rev.2 is detected, enable workarounds\n"); 3265 3266 board_config = snd_hda_check_board_config(codec, AD1988_MODEL_LAST, 3267 ad1988_models, ad1988_cfg_tbl); 3268 if (board_config < 0) { 3269 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 3270 codec->chip_name); 3271 board_config = AD1988_AUTO; 3272 } 3273 3274 if (board_config == AD1988_AUTO) { 3275 /* automatic parse from the BIOS config */ 3276 err = ad1988_parse_auto_config(codec); 3277 if (err < 0) { 3278 ad198x_free(codec); 3279 return err; 3280 } else if (! err) { 3281 printk(KERN_INFO "hda_codec: Cannot set up configuration from BIOS. Using 6-stack mode...\n"); 3282 board_config = AD1988_6STACK; 3283 } 3284 } 3285 3286 err = snd_hda_attach_beep_device(codec, 0x10); 3287 if (err < 0) { 3288 ad198x_free(codec); 3289 return err; 3290 } 3291 set_beep_amp(spec, 0x10, 0, HDA_OUTPUT); 3292 3293 if (!spec->multiout.hp_nid) 3294 spec->multiout.hp_nid = ad1988_alt_dac_nid[0]; 3295 switch (board_config) { 3296 case AD1988_6STACK: 3297 case AD1988_6STACK_DIG: 3298 spec->multiout.max_channels = 8; 3299 spec->multiout.num_dacs = 4; 3300 if (is_rev2(codec)) 3301 spec->multiout.dac_nids = ad1988_6stack_dac_nids_rev2; 3302 else 3303 spec->multiout.dac_nids = ad1988_6stack_dac_nids; 3304 spec->input_mux = &ad1988_6stack_capture_source; 3305 spec->num_mixers = 2; 3306 if (is_rev2(codec)) 3307 spec->mixers[0] = ad1988_6stack_mixers1_rev2; 3308 else 3309 spec->mixers[0] = ad1988_6stack_mixers1; 3310 spec->mixers[1] = ad1988_6stack_mixers2; 3311 spec->num_init_verbs = 1; 3312 spec->init_verbs[0] = ad1988_6stack_init_verbs; 3313 if (board_config == AD1988_6STACK_DIG) { 3314 spec->multiout.dig_out_nid = AD1988_SPDIF_OUT; 3315 spec->dig_in_nid = AD1988_SPDIF_IN; 3316 } 3317 break; 3318 case AD1988_3STACK: 3319 case AD1988_3STACK_DIG: 3320 spec->multiout.max_channels = 6; 3321 spec->multiout.num_dacs = 3; 3322 if (is_rev2(codec)) 3323 spec->multiout.dac_nids = ad1988_3stack_dac_nids_rev2; 3324 else 3325 spec->multiout.dac_nids = ad1988_3stack_dac_nids; 3326 spec->input_mux = &ad1988_6stack_capture_source; 3327 spec->channel_mode = ad1988_3stack_modes; 3328 spec->num_channel_mode = ARRAY_SIZE(ad1988_3stack_modes); 3329 spec->num_mixers = 2; 3330 if (is_rev2(codec)) 3331 spec->mixers[0] = ad1988_3stack_mixers1_rev2; 3332 else 3333 spec->mixers[0] = ad1988_3stack_mixers1; 3334 spec->mixers[1] = ad1988_3stack_mixers2; 3335 spec->num_init_verbs = 1; 3336 spec->init_verbs[0] = ad1988_3stack_init_verbs; 3337 if (board_config == AD1988_3STACK_DIG) 3338 spec->multiout.dig_out_nid = AD1988_SPDIF_OUT; 3339 break; 3340 case AD1988_LAPTOP: 3341 case AD1988_LAPTOP_DIG: 3342 spec->multiout.max_channels = 2; 3343 spec->multiout.num_dacs = 1; 3344 spec->multiout.dac_nids = ad1988_3stack_dac_nids; 3345 spec->input_mux = &ad1988_laptop_capture_source; 3346 spec->num_mixers = 1; 3347 spec->mixers[0] = ad1988_laptop_mixers; 3348 spec->inv_eapd = 1; /* inverted EAPD */ 3349 spec->num_init_verbs = 1; 3350 spec->init_verbs[0] = ad1988_laptop_init_verbs; 3351 if (board_config == AD1988_LAPTOP_DIG) 3352 spec->multiout.dig_out_nid = AD1988_SPDIF_OUT; 3353 break; 3354 } 3355 3356 if (spec->autocfg.hp_pins[0]) { 3357 spec->mixers[spec->num_mixers++] = ad1988_hp_mixers; 3358 spec->slave_vols = ad1988_6stack_fp_slave_pfxs; 3359 spec->slave_sws = ad1988_6stack_fp_slave_pfxs; 3360 spec->alt_dac_nid = ad1988_alt_dac_nid; 3361 spec->stream_analog_alt_playback = 3362 &ad198x_pcm_analog_alt_playback; 3363 } 3364 3365 spec->num_adc_nids = ARRAY_SIZE(ad1988_adc_nids); 3366 spec->adc_nids = ad1988_adc_nids; 3367 spec->capsrc_nids = ad1988_capsrc_nids; 3368 spec->mixers[spec->num_mixers++] = ad1988_capture_mixers; 3369 spec->init_verbs[spec->num_init_verbs++] = ad1988_capture_init_verbs; 3370 if (spec->multiout.dig_out_nid) { 3371 if (codec->vendor_id >= 0x11d4989a) { 3372 spec->mixers[spec->num_mixers++] = 3373 ad1989_spdif_out_mixers; 3374 spec->init_verbs[spec->num_init_verbs++] = 3375 ad1989_spdif_init_verbs; 3376 codec->slave_dig_outs = ad1989b_slave_dig_outs; 3377 } else { 3378 spec->mixers[spec->num_mixers++] = 3379 ad1988_spdif_out_mixers; 3380 spec->init_verbs[spec->num_init_verbs++] = 3381 ad1988_spdif_init_verbs; 3382 } 3383 } 3384 if (spec->dig_in_nid && codec->vendor_id < 0x11d4989a) { 3385 spec->mixers[spec->num_mixers++] = ad1988_spdif_in_mixers; 3386 spec->init_verbs[spec->num_init_verbs++] = 3387 ad1988_spdif_in_init_verbs; 3388 } 3389 3390 codec->patch_ops = ad198x_patch_ops; 3391 switch (board_config) { 3392 case AD1988_AUTO: 3393 codec->patch_ops.init = ad1988_auto_init; 3394 break; 3395 case AD1988_LAPTOP: 3396 case AD1988_LAPTOP_DIG: 3397 codec->patch_ops.unsol_event = ad1988_laptop_unsol_event; 3398 break; 3399 } 3400 #ifdef CONFIG_SND_HDA_POWER_SAVE 3401 spec->loopback.amplist = ad1988_loopbacks; 3402 #endif 3403 spec->vmaster_nid = 0x04; 3404 3405 codec->no_trigger_sense = 1; 3406 codec->no_sticky_stream = 1; 3407 3408 return 0; 3409 } 3410 3411 3412 /* 3413 * AD1884 / AD1984 3414 * 3415 * port-B - front line/mic-in 3416 * port-E - aux in/out 3417 * port-F - aux in/out 3418 * port-C - rear line/mic-in 3419 * port-D - rear line/hp-out 3420 * port-A - front line/hp-out 3421 * 3422 * AD1984 = AD1884 + two digital mic-ins 3423 * 3424 * FIXME: 3425 * For simplicity, we share the single DAC for both HP and line-outs 3426 * right now. The inidividual playbacks could be easily implemented, 3427 * but no build-up framework is given, so far. 3428 */ 3429 3430 static const hda_nid_t ad1884_dac_nids[1] = { 3431 0x04, 3432 }; 3433 3434 static const hda_nid_t ad1884_adc_nids[2] = { 3435 0x08, 0x09, 3436 }; 3437 3438 static const hda_nid_t ad1884_capsrc_nids[2] = { 3439 0x0c, 0x0d, 3440 }; 3441 3442 #define AD1884_SPDIF_OUT 0x02 3443 3444 static const struct hda_input_mux ad1884_capture_source = { 3445 .num_items = 4, 3446 .items = { 3447 { "Front Mic", 0x0 }, 3448 { "Mic", 0x1 }, 3449 { "CD", 0x2 }, 3450 { "Mix", 0x3 }, 3451 }, 3452 }; 3453 3454 static const struct snd_kcontrol_new ad1884_base_mixers[] = { 3455 HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT), 3456 /* HDA_CODEC_VOLUME_IDX("PCM Playback Volume", 1, 0x03, 0x0, HDA_OUTPUT), */ 3457 HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT), 3458 HDA_CODEC_MUTE("Front Playback Switch", 0x12, 0x0, HDA_OUTPUT), 3459 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT), 3460 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT), 3461 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT), 3462 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT), 3463 HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x01, HDA_INPUT), 3464 HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x01, HDA_INPUT), 3465 HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x02, HDA_INPUT), 3466 HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x02, HDA_INPUT), 3467 HDA_CODEC_VOLUME("Mic Boost Volume", 0x15, 0x0, HDA_INPUT), 3468 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x14, 0x0, HDA_INPUT), 3469 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), 3470 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), 3471 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT), 3472 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT), 3473 { 3474 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 3475 /* The multiple "Capture Source" controls confuse alsamixer 3476 * So call somewhat different.. 3477 */ 3478 /* .name = "Capture Source", */ 3479 .name = "Input Source", 3480 .count = 2, 3481 .info = ad198x_mux_enum_info, 3482 .get = ad198x_mux_enum_get, 3483 .put = ad198x_mux_enum_put, 3484 }, 3485 /* SPDIF controls */ 3486 HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT), 3487 { 3488 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 3489 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source", 3490 /* identical with ad1983 */ 3491 .info = ad1983_spdif_route_info, 3492 .get = ad1983_spdif_route_get, 3493 .put = ad1983_spdif_route_put, 3494 }, 3495 { } /* end */ 3496 }; 3497 3498 static const struct snd_kcontrol_new ad1984_dmic_mixers[] = { 3499 HDA_CODEC_VOLUME("Digital Mic Capture Volume", 0x05, 0x0, HDA_INPUT), 3500 HDA_CODEC_MUTE("Digital Mic Capture Switch", 0x05, 0x0, HDA_INPUT), 3501 HDA_CODEC_VOLUME_IDX("Digital Mic Capture Volume", 1, 0x06, 0x0, 3502 HDA_INPUT), 3503 HDA_CODEC_MUTE_IDX("Digital Mic Capture Switch", 1, 0x06, 0x0, 3504 HDA_INPUT), 3505 { } /* end */ 3506 }; 3507 3508 /* 3509 * initialization verbs 3510 */ 3511 static const struct hda_verb ad1884_init_verbs[] = { 3512 /* DACs; mute as default */ 3513 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3514 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3515 /* Port-A (HP) mixer */ 3516 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3517 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 3518 /* Port-A pin */ 3519 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3520 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3521 /* HP selector - select DAC2 */ 3522 {0x22, AC_VERB_SET_CONNECT_SEL, 0x1}, 3523 /* Port-D (Line-out) mixer */ 3524 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3525 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 3526 /* Port-D pin */ 3527 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3528 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3529 /* Mono-out mixer */ 3530 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3531 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 3532 /* Mono-out pin */ 3533 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3534 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3535 /* Mono selector */ 3536 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x1}, 3537 /* Port-B (front mic) pin */ 3538 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3539 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3540 /* Port-C (rear mic) pin */ 3541 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3542 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3543 /* Analog mixer; mute as default */ 3544 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3545 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 3546 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 3547 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 3548 /* Analog Mix output amp */ 3549 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */ 3550 /* SPDIF output selector */ 3551 {0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, /* PCM */ 3552 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */ 3553 { } /* end */ 3554 }; 3555 3556 #ifdef CONFIG_SND_HDA_POWER_SAVE 3557 static const struct hda_amp_list ad1884_loopbacks[] = { 3558 { 0x20, HDA_INPUT, 0 }, /* Front Mic */ 3559 { 0x20, HDA_INPUT, 1 }, /* Mic */ 3560 { 0x20, HDA_INPUT, 2 }, /* CD */ 3561 { 0x20, HDA_INPUT, 4 }, /* Docking */ 3562 { } /* end */ 3563 }; 3564 #endif 3565 3566 static const char * const ad1884_slave_vols[] = { 3567 "PCM", "Mic", "Mono", "Front Mic", "Mic", "CD", 3568 "Internal Mic", "Docking Mic", /* "Beep", */ "IEC958", 3569 NULL 3570 }; 3571 3572 static int patch_ad1884(struct hda_codec *codec) 3573 { 3574 struct ad198x_spec *spec; 3575 int err; 3576 3577 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 3578 if (spec == NULL) 3579 return -ENOMEM; 3580 3581 codec->spec = spec; 3582 3583 err = snd_hda_attach_beep_device(codec, 0x10); 3584 if (err < 0) { 3585 ad198x_free(codec); 3586 return err; 3587 } 3588 set_beep_amp(spec, 0x10, 0, HDA_OUTPUT); 3589 3590 spec->multiout.max_channels = 2; 3591 spec->multiout.num_dacs = ARRAY_SIZE(ad1884_dac_nids); 3592 spec->multiout.dac_nids = ad1884_dac_nids; 3593 spec->multiout.dig_out_nid = AD1884_SPDIF_OUT; 3594 spec->num_adc_nids = ARRAY_SIZE(ad1884_adc_nids); 3595 spec->adc_nids = ad1884_adc_nids; 3596 spec->capsrc_nids = ad1884_capsrc_nids; 3597 spec->input_mux = &ad1884_capture_source; 3598 spec->num_mixers = 1; 3599 spec->mixers[0] = ad1884_base_mixers; 3600 spec->num_init_verbs = 1; 3601 spec->init_verbs[0] = ad1884_init_verbs; 3602 spec->spdif_route = 0; 3603 #ifdef CONFIG_SND_HDA_POWER_SAVE 3604 spec->loopback.amplist = ad1884_loopbacks; 3605 #endif 3606 spec->vmaster_nid = 0x04; 3607 /* we need to cover all playback volumes */ 3608 spec->slave_vols = ad1884_slave_vols; 3609 /* slaves may contain input volumes, so we can't raise to 0dB blindly */ 3610 spec->avoid_init_slave_vol = 1; 3611 3612 codec->patch_ops = ad198x_patch_ops; 3613 3614 codec->no_trigger_sense = 1; 3615 codec->no_sticky_stream = 1; 3616 3617 return 0; 3618 } 3619 3620 /* 3621 * Lenovo Thinkpad T61/X61 3622 */ 3623 static const struct hda_input_mux ad1984_thinkpad_capture_source = { 3624 .num_items = 4, 3625 .items = { 3626 { "Mic", 0x0 }, 3627 { "Internal Mic", 0x1 }, 3628 { "Mix", 0x3 }, 3629 { "Docking-Station", 0x4 }, 3630 }, 3631 }; 3632 3633 3634 /* 3635 * Dell Precision T3400 3636 */ 3637 static const struct hda_input_mux ad1984_dell_desktop_capture_source = { 3638 .num_items = 3, 3639 .items = { 3640 { "Front Mic", 0x0 }, 3641 { "Line-In", 0x1 }, 3642 { "Mix", 0x3 }, 3643 }, 3644 }; 3645 3646 3647 static const struct snd_kcontrol_new ad1984_thinkpad_mixers[] = { 3648 HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT), 3649 /* HDA_CODEC_VOLUME_IDX("PCM Playback Volume", 1, 0x03, 0x0, HDA_OUTPUT), */ 3650 HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT), 3651 HDA_CODEC_MUTE("Speaker Playback Switch", 0x12, 0x0, HDA_OUTPUT), 3652 HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x00, HDA_INPUT), 3653 HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x00, HDA_INPUT), 3654 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x20, 0x01, HDA_INPUT), 3655 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x20, 0x01, HDA_INPUT), 3656 HDA_CODEC_VOLUME("Beep Playback Volume", 0x20, 0x03, HDA_INPUT), 3657 HDA_CODEC_MUTE("Beep Playback Switch", 0x20, 0x03, HDA_INPUT), 3658 HDA_CODEC_VOLUME("Docking Mic Playback Volume", 0x20, 0x04, HDA_INPUT), 3659 HDA_CODEC_MUTE("Docking Mic Playback Switch", 0x20, 0x04, HDA_INPUT), 3660 HDA_CODEC_VOLUME("Mic Boost Volume", 0x14, 0x0, HDA_INPUT), 3661 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x15, 0x0, HDA_INPUT), 3662 HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x25, 0x0, HDA_OUTPUT), 3663 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), 3664 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), 3665 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT), 3666 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT), 3667 { 3668 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 3669 /* The multiple "Capture Source" controls confuse alsamixer 3670 * So call somewhat different.. 3671 */ 3672 /* .name = "Capture Source", */ 3673 .name = "Input Source", 3674 .count = 2, 3675 .info = ad198x_mux_enum_info, 3676 .get = ad198x_mux_enum_get, 3677 .put = ad198x_mux_enum_put, 3678 }, 3679 /* SPDIF controls */ 3680 HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT), 3681 { 3682 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 3683 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source", 3684 /* identical with ad1983 */ 3685 .info = ad1983_spdif_route_info, 3686 .get = ad1983_spdif_route_get, 3687 .put = ad1983_spdif_route_put, 3688 }, 3689 { } /* end */ 3690 }; 3691 3692 /* additional verbs */ 3693 static const struct hda_verb ad1984_thinkpad_init_verbs[] = { 3694 /* Port-E (docking station mic) pin */ 3695 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3696 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3697 /* docking mic boost */ 3698 {0x25, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3699 /* Analog PC Beeper - allow firmware/ACPI beeps */ 3700 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3) | 0x1a}, 3701 /* Analog mixer - docking mic; mute as default */ 3702 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 3703 /* enable EAPD bit */ 3704 {0x12, AC_VERB_SET_EAPD_BTLENABLE, 0x02}, 3705 { } /* end */ 3706 }; 3707 3708 /* 3709 * Dell Precision T3400 3710 */ 3711 static const struct snd_kcontrol_new ad1984_dell_desktop_mixers[] = { 3712 HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT), 3713 HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT), 3714 HDA_CODEC_MUTE("Speaker Playback Switch", 0x12, 0x0, HDA_OUTPUT), 3715 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT), 3716 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT), 3717 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT), 3718 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT), 3719 HDA_CODEC_VOLUME("Line-In Playback Volume", 0x20, 0x01, HDA_INPUT), 3720 HDA_CODEC_MUTE("Line-In Playback Switch", 0x20, 0x01, HDA_INPUT), 3721 HDA_CODEC_VOLUME("Line-In Boost Volume", 0x15, 0x0, HDA_INPUT), 3722 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x14, 0x0, HDA_INPUT), 3723 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), 3724 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), 3725 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT), 3726 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT), 3727 { 3728 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 3729 /* The multiple "Capture Source" controls confuse alsamixer 3730 * So call somewhat different.. 3731 */ 3732 /* .name = "Capture Source", */ 3733 .name = "Input Source", 3734 .count = 2, 3735 .info = ad198x_mux_enum_info, 3736 .get = ad198x_mux_enum_get, 3737 .put = ad198x_mux_enum_put, 3738 }, 3739 { } /* end */ 3740 }; 3741 3742 /* Digial MIC ADC NID 0x05 + 0x06 */ 3743 static int ad1984_pcm_dmic_prepare(struct hda_pcm_stream *hinfo, 3744 struct hda_codec *codec, 3745 unsigned int stream_tag, 3746 unsigned int format, 3747 struct snd_pcm_substream *substream) 3748 { 3749 snd_hda_codec_setup_stream(codec, 0x05 + substream->number, 3750 stream_tag, 0, format); 3751 return 0; 3752 } 3753 3754 static int ad1984_pcm_dmic_cleanup(struct hda_pcm_stream *hinfo, 3755 struct hda_codec *codec, 3756 struct snd_pcm_substream *substream) 3757 { 3758 snd_hda_codec_cleanup_stream(codec, 0x05 + substream->number); 3759 return 0; 3760 } 3761 3762 static const struct hda_pcm_stream ad1984_pcm_dmic_capture = { 3763 .substreams = 2, 3764 .channels_min = 2, 3765 .channels_max = 2, 3766 .nid = 0x05, 3767 .ops = { 3768 .prepare = ad1984_pcm_dmic_prepare, 3769 .cleanup = ad1984_pcm_dmic_cleanup 3770 }, 3771 }; 3772 3773 static int ad1984_build_pcms(struct hda_codec *codec) 3774 { 3775 struct ad198x_spec *spec = codec->spec; 3776 struct hda_pcm *info; 3777 int err; 3778 3779 err = ad198x_build_pcms(codec); 3780 if (err < 0) 3781 return err; 3782 3783 info = spec->pcm_rec + codec->num_pcms; 3784 codec->num_pcms++; 3785 info->name = "AD1984 Digital Mic"; 3786 info->stream[SNDRV_PCM_STREAM_CAPTURE] = ad1984_pcm_dmic_capture; 3787 return 0; 3788 } 3789 3790 /* models */ 3791 enum { 3792 AD1984_BASIC, 3793 AD1984_THINKPAD, 3794 AD1984_DELL_DESKTOP, 3795 AD1984_MODELS 3796 }; 3797 3798 static const char * const ad1984_models[AD1984_MODELS] = { 3799 [AD1984_BASIC] = "basic", 3800 [AD1984_THINKPAD] = "thinkpad", 3801 [AD1984_DELL_DESKTOP] = "dell_desktop", 3802 }; 3803 3804 static const struct snd_pci_quirk ad1984_cfg_tbl[] = { 3805 /* Lenovo Thinkpad T61/X61 */ 3806 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo Thinkpad", AD1984_THINKPAD), 3807 SND_PCI_QUIRK(0x1028, 0x0214, "Dell T3400", AD1984_DELL_DESKTOP), 3808 SND_PCI_QUIRK(0x1028, 0x0233, "Dell Latitude E6400", AD1984_DELL_DESKTOP), 3809 {} 3810 }; 3811 3812 static int patch_ad1984(struct hda_codec *codec) 3813 { 3814 struct ad198x_spec *spec; 3815 int board_config, err; 3816 3817 err = patch_ad1884(codec); 3818 if (err < 0) 3819 return err; 3820 spec = codec->spec; 3821 board_config = snd_hda_check_board_config(codec, AD1984_MODELS, 3822 ad1984_models, ad1984_cfg_tbl); 3823 switch (board_config) { 3824 case AD1984_BASIC: 3825 /* additional digital mics */ 3826 spec->mixers[spec->num_mixers++] = ad1984_dmic_mixers; 3827 codec->patch_ops.build_pcms = ad1984_build_pcms; 3828 break; 3829 case AD1984_THINKPAD: 3830 if (codec->subsystem_id == 0x17aa20fb) { 3831 /* Thinpad X300 does not have the ability to do SPDIF, 3832 or attach to docking station to use SPDIF */ 3833 spec->multiout.dig_out_nid = 0; 3834 } else 3835 spec->multiout.dig_out_nid = AD1884_SPDIF_OUT; 3836 spec->input_mux = &ad1984_thinkpad_capture_source; 3837 spec->mixers[0] = ad1984_thinkpad_mixers; 3838 spec->init_verbs[spec->num_init_verbs++] = ad1984_thinkpad_init_verbs; 3839 spec->analog_beep = 1; 3840 break; 3841 case AD1984_DELL_DESKTOP: 3842 spec->multiout.dig_out_nid = 0; 3843 spec->input_mux = &ad1984_dell_desktop_capture_source; 3844 spec->mixers[0] = ad1984_dell_desktop_mixers; 3845 break; 3846 } 3847 return 0; 3848 } 3849 3850 3851 /* 3852 * AD1883 / AD1884A / AD1984A / AD1984B 3853 * 3854 * port-B (0x14) - front mic-in 3855 * port-E (0x1c) - rear mic-in 3856 * port-F (0x16) - CD / ext out 3857 * port-C (0x15) - rear line-in 3858 * port-D (0x12) - rear line-out 3859 * port-A (0x11) - front hp-out 3860 * 3861 * AD1984A = AD1884A + digital-mic 3862 * AD1883 = equivalent with AD1984A 3863 * AD1984B = AD1984A + extra SPDIF-out 3864 * 3865 * FIXME: 3866 * We share the single DAC for both HP and line-outs (see AD1884/1984). 3867 */ 3868 3869 static const hda_nid_t ad1884a_dac_nids[1] = { 3870 0x03, 3871 }; 3872 3873 #define ad1884a_adc_nids ad1884_adc_nids 3874 #define ad1884a_capsrc_nids ad1884_capsrc_nids 3875 3876 #define AD1884A_SPDIF_OUT 0x02 3877 3878 static const struct hda_input_mux ad1884a_capture_source = { 3879 .num_items = 5, 3880 .items = { 3881 { "Front Mic", 0x0 }, 3882 { "Mic", 0x4 }, 3883 { "Line", 0x1 }, 3884 { "CD", 0x2 }, 3885 { "Mix", 0x3 }, 3886 }, 3887 }; 3888 3889 static const struct snd_kcontrol_new ad1884a_base_mixers[] = { 3890 HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT), 3891 HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT), 3892 HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT), 3893 HDA_CODEC_MUTE("Front Playback Switch", 0x12, 0x0, HDA_OUTPUT), 3894 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT), 3895 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT), 3896 HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT), 3897 HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT), 3898 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT), 3899 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT), 3900 HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x01, HDA_INPUT), 3901 HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x01, HDA_INPUT), 3902 HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x04, HDA_INPUT), 3903 HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x04, HDA_INPUT), 3904 HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x02, HDA_INPUT), 3905 HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x02, HDA_INPUT), 3906 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x14, 0x0, HDA_INPUT), 3907 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x0, HDA_INPUT), 3908 HDA_CODEC_VOLUME("Mic Boost Volume", 0x25, 0x0, HDA_OUTPUT), 3909 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), 3910 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), 3911 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT), 3912 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT), 3913 { 3914 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 3915 /* The multiple "Capture Source" controls confuse alsamixer 3916 * So call somewhat different.. 3917 */ 3918 /* .name = "Capture Source", */ 3919 .name = "Input Source", 3920 .count = 2, 3921 .info = ad198x_mux_enum_info, 3922 .get = ad198x_mux_enum_get, 3923 .put = ad198x_mux_enum_put, 3924 }, 3925 /* SPDIF controls */ 3926 HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT), 3927 { 3928 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 3929 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source", 3930 /* identical with ad1983 */ 3931 .info = ad1983_spdif_route_info, 3932 .get = ad1983_spdif_route_get, 3933 .put = ad1983_spdif_route_put, 3934 }, 3935 { } /* end */ 3936 }; 3937 3938 /* 3939 * initialization verbs 3940 */ 3941 static const struct hda_verb ad1884a_init_verbs[] = { 3942 /* DACs; unmute as default */ 3943 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */ 3944 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */ 3945 /* Port-A (HP) mixer - route only from analog mixer */ 3946 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3947 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 3948 /* Port-A pin */ 3949 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3950 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3951 /* Port-D (Line-out) mixer - route only from analog mixer */ 3952 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3953 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 3954 /* Port-D pin */ 3955 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3956 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3957 /* Mono-out mixer - route only from analog mixer */ 3958 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3959 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 3960 /* Mono-out pin */ 3961 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3962 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3963 /* Port-B (front mic) pin */ 3964 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3965 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3966 /* Port-C (rear line-in) pin */ 3967 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3968 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3969 /* Port-E (rear mic) pin */ 3970 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3971 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3972 {0x25, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, /* no boost */ 3973 /* Port-F (CD) pin */ 3974 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3975 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3976 /* Analog mixer; mute as default */ 3977 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3978 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 3979 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 3980 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 3981 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, /* aux */ 3982 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, 3983 /* Analog Mix output amp */ 3984 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3985 /* capture sources */ 3986 {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0}, 3987 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3988 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0}, 3989 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3990 /* SPDIF output amp */ 3991 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */ 3992 { } /* end */ 3993 }; 3994 3995 #ifdef CONFIG_SND_HDA_POWER_SAVE 3996 static const struct hda_amp_list ad1884a_loopbacks[] = { 3997 { 0x20, HDA_INPUT, 0 }, /* Front Mic */ 3998 { 0x20, HDA_INPUT, 1 }, /* Mic */ 3999 { 0x20, HDA_INPUT, 2 }, /* CD */ 4000 { 0x20, HDA_INPUT, 4 }, /* Docking */ 4001 { } /* end */ 4002 }; 4003 #endif 4004 4005 /* 4006 * Laptop model 4007 * 4008 * Port A: Headphone jack 4009 * Port B: MIC jack 4010 * Port C: Internal MIC 4011 * Port D: Dock Line Out (if enabled) 4012 * Port E: Dock Line In (if enabled) 4013 * Port F: Internal speakers 4014 */ 4015 4016 static int ad1884a_mobile_master_sw_put(struct snd_kcontrol *kcontrol, 4017 struct snd_ctl_elem_value *ucontrol) 4018 { 4019 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 4020 int ret = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol); 4021 int mute = (!ucontrol->value.integer.value[0] && 4022 !ucontrol->value.integer.value[1]); 4023 /* toggle GPIO1 according to the mute state */ 4024 snd_hda_codec_write_cache(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 4025 mute ? 0x02 : 0x0); 4026 return ret; 4027 } 4028 4029 static const struct snd_kcontrol_new ad1884a_laptop_mixers[] = { 4030 HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT), 4031 { 4032 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 4033 .name = "Master Playback Switch", 4034 .subdevice = HDA_SUBDEV_AMP_FLAG, 4035 .info = snd_hda_mixer_amp_switch_info, 4036 .get = snd_hda_mixer_amp_switch_get, 4037 .put = ad1884a_mobile_master_sw_put, 4038 .private_value = HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT), 4039 }, 4040 HDA_CODEC_MUTE("Dock Playback Switch", 0x12, 0x0, HDA_OUTPUT), 4041 HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT), 4042 HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT), 4043 HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x00, HDA_INPUT), 4044 HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x00, HDA_INPUT), 4045 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x20, 0x01, HDA_INPUT), 4046 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x20, 0x01, HDA_INPUT), 4047 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x20, 0x04, HDA_INPUT), 4048 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x20, 0x04, HDA_INPUT), 4049 HDA_CODEC_VOLUME("Mic Boost Volume", 0x14, 0x0, HDA_INPUT), 4050 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x15, 0x0, HDA_INPUT), 4051 HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x25, 0x0, HDA_OUTPUT), 4052 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), 4053 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), 4054 { } /* end */ 4055 }; 4056 4057 static const struct snd_kcontrol_new ad1884a_mobile_mixers[] = { 4058 HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT), 4059 /*HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),*/ 4060 { 4061 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 4062 .name = "Master Playback Switch", 4063 .subdevice = HDA_SUBDEV_AMP_FLAG, 4064 .info = snd_hda_mixer_amp_switch_info, 4065 .get = snd_hda_mixer_amp_switch_get, 4066 .put = ad1884a_mobile_master_sw_put, 4067 .private_value = HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT), 4068 }, 4069 HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT), 4070 HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT), 4071 HDA_CODEC_VOLUME("Mic Capture Volume", 0x14, 0x0, HDA_INPUT), 4072 HDA_CODEC_VOLUME("Internal Mic Capture Volume", 0x15, 0x0, HDA_INPUT), 4073 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), 4074 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), 4075 { } /* end */ 4076 }; 4077 4078 /* mute internal speaker if HP is plugged */ 4079 static void ad1884a_hp_automute(struct hda_codec *codec) 4080 { 4081 unsigned int present; 4082 4083 present = snd_hda_jack_detect(codec, 0x11); 4084 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0, 4085 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 4086 snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_EAPD_BTLENABLE, 4087 present ? 0x00 : 0x02); 4088 } 4089 4090 /* switch to external mic if plugged */ 4091 static void ad1884a_hp_automic(struct hda_codec *codec) 4092 { 4093 unsigned int present; 4094 4095 present = snd_hda_jack_detect(codec, 0x14); 4096 snd_hda_codec_write(codec, 0x0c, 0, AC_VERB_SET_CONNECT_SEL, 4097 present ? 0 : 1); 4098 } 4099 4100 #define AD1884A_HP_EVENT 0x37 4101 #define AD1884A_MIC_EVENT 0x36 4102 4103 /* unsolicited event for HP jack sensing */ 4104 static void ad1884a_hp_unsol_event(struct hda_codec *codec, unsigned int res) 4105 { 4106 switch (res >> 26) { 4107 case AD1884A_HP_EVENT: 4108 ad1884a_hp_automute(codec); 4109 break; 4110 case AD1884A_MIC_EVENT: 4111 ad1884a_hp_automic(codec); 4112 break; 4113 } 4114 } 4115 4116 /* initialize jack-sensing, too */ 4117 static int ad1884a_hp_init(struct hda_codec *codec) 4118 { 4119 ad198x_init(codec); 4120 ad1884a_hp_automute(codec); 4121 ad1884a_hp_automic(codec); 4122 return 0; 4123 } 4124 4125 /* mute internal speaker if HP or docking HP is plugged */ 4126 static void ad1884a_laptop_automute(struct hda_codec *codec) 4127 { 4128 unsigned int present; 4129 4130 present = snd_hda_jack_detect(codec, 0x11); 4131 if (!present) 4132 present = snd_hda_jack_detect(codec, 0x12); 4133 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0, 4134 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 4135 snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_EAPD_BTLENABLE, 4136 present ? 0x00 : 0x02); 4137 } 4138 4139 /* switch to external mic if plugged */ 4140 static void ad1884a_laptop_automic(struct hda_codec *codec) 4141 { 4142 unsigned int idx; 4143 4144 if (snd_hda_jack_detect(codec, 0x14)) 4145 idx = 0; 4146 else if (snd_hda_jack_detect(codec, 0x1c)) 4147 idx = 4; 4148 else 4149 idx = 1; 4150 snd_hda_codec_write(codec, 0x0c, 0, AC_VERB_SET_CONNECT_SEL, idx); 4151 } 4152 4153 /* unsolicited event for HP jack sensing */ 4154 static void ad1884a_laptop_unsol_event(struct hda_codec *codec, 4155 unsigned int res) 4156 { 4157 switch (res >> 26) { 4158 case AD1884A_HP_EVENT: 4159 ad1884a_laptop_automute(codec); 4160 break; 4161 case AD1884A_MIC_EVENT: 4162 ad1884a_laptop_automic(codec); 4163 break; 4164 } 4165 } 4166 4167 /* initialize jack-sensing, too */ 4168 static int ad1884a_laptop_init(struct hda_codec *codec) 4169 { 4170 ad198x_init(codec); 4171 ad1884a_laptop_automute(codec); 4172 ad1884a_laptop_automic(codec); 4173 return 0; 4174 } 4175 4176 /* additional verbs for laptop model */ 4177 static const struct hda_verb ad1884a_laptop_verbs[] = { 4178 /* Port-A (HP) pin - always unmuted */ 4179 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4180 /* Port-F (int speaker) mixer - route only from analog mixer */ 4181 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4182 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4183 /* Port-F (int speaker) pin */ 4184 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4185 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 4186 /* required for compaq 6530s/6531s speaker output */ 4187 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4188 /* Port-C pin - internal mic-in */ 4189 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 4190 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */ 4191 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */ 4192 /* Port-D (docking line-out) pin - default unmuted */ 4193 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4194 /* analog mix */ 4195 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 4196 /* unsolicited event for pin-sense */ 4197 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT}, 4198 {0x12, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT}, 4199 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_MIC_EVENT}, 4200 {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_MIC_EVENT}, 4201 /* allow to touch GPIO1 (for mute control) */ 4202 {0x01, AC_VERB_SET_GPIO_MASK, 0x02}, 4203 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02}, 4204 {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, /* first muted */ 4205 { } /* end */ 4206 }; 4207 4208 static const struct hda_verb ad1884a_mobile_verbs[] = { 4209 /* DACs; unmute as default */ 4210 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */ 4211 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */ 4212 /* Port-A (HP) mixer - route only from analog mixer */ 4213 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4214 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4215 /* Port-A pin */ 4216 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 4217 /* Port-A (HP) pin - always unmuted */ 4218 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4219 /* Port-B (mic jack) pin */ 4220 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 4221 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */ 4222 /* Port-C (int mic) pin */ 4223 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 4224 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */ 4225 /* Port-F (int speaker) mixer - route only from analog mixer */ 4226 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4227 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4228 /* Port-F pin */ 4229 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 4230 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 4231 /* Analog mixer; mute as default */ 4232 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4233 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4234 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 4235 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 4236 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 4237 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, 4238 /* Analog Mix output amp */ 4239 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 4240 /* capture sources */ 4241 /* {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0}, */ /* set via unsol */ 4242 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 4243 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0}, 4244 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 4245 /* unsolicited event for pin-sense */ 4246 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT}, 4247 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_MIC_EVENT}, 4248 /* allow to touch GPIO1 (for mute control) */ 4249 {0x01, AC_VERB_SET_GPIO_MASK, 0x02}, 4250 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02}, 4251 {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, /* first muted */ 4252 { } /* end */ 4253 }; 4254 4255 /* 4256 * Thinkpad X300 4257 * 0x11 - HP 4258 * 0x12 - speaker 4259 * 0x14 - mic-in 4260 * 0x17 - built-in mic 4261 */ 4262 4263 static const struct hda_verb ad1984a_thinkpad_verbs[] = { 4264 /* HP unmute */ 4265 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4266 /* analog mix */ 4267 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 4268 /* turn on EAPD */ 4269 {0x12, AC_VERB_SET_EAPD_BTLENABLE, 0x02}, 4270 /* unsolicited event for pin-sense */ 4271 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT}, 4272 /* internal mic - dmic */ 4273 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 4274 /* set magic COEFs for dmic */ 4275 {0x01, AC_VERB_SET_COEF_INDEX, 0x13f7}, 4276 {0x01, AC_VERB_SET_PROC_COEF, 0x08}, 4277 { } /* end */ 4278 }; 4279 4280 static const struct snd_kcontrol_new ad1984a_thinkpad_mixers[] = { 4281 HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT), 4282 HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT), 4283 HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT), 4284 HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT), 4285 HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x00, HDA_INPUT), 4286 HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x00, HDA_INPUT), 4287 HDA_CODEC_VOLUME("Mic Boost Volume", 0x14, 0x0, HDA_INPUT), 4288 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x17, 0x0, HDA_INPUT), 4289 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), 4290 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), 4291 { 4292 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 4293 .name = "Capture Source", 4294 .info = ad198x_mux_enum_info, 4295 .get = ad198x_mux_enum_get, 4296 .put = ad198x_mux_enum_put, 4297 }, 4298 { } /* end */ 4299 }; 4300 4301 static const struct hda_input_mux ad1984a_thinkpad_capture_source = { 4302 .num_items = 3, 4303 .items = { 4304 { "Mic", 0x0 }, 4305 { "Internal Mic", 0x5 }, 4306 { "Mix", 0x3 }, 4307 }, 4308 }; 4309 4310 /* mute internal speaker if HP is plugged */ 4311 static void ad1984a_thinkpad_automute(struct hda_codec *codec) 4312 { 4313 unsigned int present; 4314 4315 present = snd_hda_jack_detect(codec, 0x11); 4316 snd_hda_codec_amp_stereo(codec, 0x12, HDA_OUTPUT, 0, 4317 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 4318 } 4319 4320 /* unsolicited event for HP jack sensing */ 4321 static void ad1984a_thinkpad_unsol_event(struct hda_codec *codec, 4322 unsigned int res) 4323 { 4324 if ((res >> 26) != AD1884A_HP_EVENT) 4325 return; 4326 ad1984a_thinkpad_automute(codec); 4327 } 4328 4329 /* initialize jack-sensing, too */ 4330 static int ad1984a_thinkpad_init(struct hda_codec *codec) 4331 { 4332 ad198x_init(codec); 4333 ad1984a_thinkpad_automute(codec); 4334 return 0; 4335 } 4336 4337 /* 4338 * Precision R5500 4339 * 0x12 - HP/line-out 4340 * 0x13 - speaker (mono) 4341 * 0x15 - mic-in 4342 */ 4343 4344 static const struct hda_verb ad1984a_precision_verbs[] = { 4345 /* Unmute main output path */ 4346 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */ 4347 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE + 0x1f}, /* 0dB */ 4348 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) + 0x17}, /* 0dB */ 4349 /* Analog mixer; mute as default */ 4350 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4351 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4352 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 4353 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 4354 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 4355 /* Select mic as input */ 4356 {0x0c, AC_VERB_SET_CONNECT_SEL, 0x1}, 4357 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE + 0x27}, /* 0dB */ 4358 /* Configure as mic */ 4359 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 4360 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */ 4361 /* HP unmute */ 4362 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4363 /* turn on EAPD */ 4364 {0x13, AC_VERB_SET_EAPD_BTLENABLE, 0x02}, 4365 /* unsolicited event for pin-sense */ 4366 {0x12, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT}, 4367 { } /* end */ 4368 }; 4369 4370 static const struct snd_kcontrol_new ad1984a_precision_mixers[] = { 4371 HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT), 4372 HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT), 4373 HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT), 4374 HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT), 4375 HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x01, HDA_INPUT), 4376 HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x01, HDA_INPUT), 4377 HDA_CODEC_VOLUME("Mic Boost Volume", 0x15, 0x0, HDA_INPUT), 4378 HDA_CODEC_MUTE("Front Playback Switch", 0x12, 0x0, HDA_OUTPUT), 4379 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x13, 0x0, HDA_OUTPUT), 4380 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), 4381 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), 4382 { } /* end */ 4383 }; 4384 4385 4386 /* mute internal speaker if HP is plugged */ 4387 static void ad1984a_precision_automute(struct hda_codec *codec) 4388 { 4389 unsigned int present; 4390 4391 present = snd_hda_jack_detect(codec, 0x12); 4392 snd_hda_codec_amp_stereo(codec, 0x13, HDA_OUTPUT, 0, 4393 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 4394 } 4395 4396 4397 /* unsolicited event for HP jack sensing */ 4398 static void ad1984a_precision_unsol_event(struct hda_codec *codec, 4399 unsigned int res) 4400 { 4401 if ((res >> 26) != AD1884A_HP_EVENT) 4402 return; 4403 ad1984a_precision_automute(codec); 4404 } 4405 4406 /* initialize jack-sensing, too */ 4407 static int ad1984a_precision_init(struct hda_codec *codec) 4408 { 4409 ad198x_init(codec); 4410 ad1984a_precision_automute(codec); 4411 return 0; 4412 } 4413 4414 4415 /* 4416 * HP Touchsmart 4417 * port-A (0x11) - front hp-out 4418 * port-B (0x14) - unused 4419 * port-C (0x15) - unused 4420 * port-D (0x12) - rear line out 4421 * port-E (0x1c) - front mic-in 4422 * port-F (0x16) - Internal speakers 4423 * digital-mic (0x17) - Internal mic 4424 */ 4425 4426 static const struct hda_verb ad1984a_touchsmart_verbs[] = { 4427 /* DACs; unmute as default */ 4428 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */ 4429 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */ 4430 /* Port-A (HP) mixer - route only from analog mixer */ 4431 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4432 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4433 /* Port-A pin */ 4434 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 4435 /* Port-A (HP) pin - always unmuted */ 4436 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4437 /* Port-E (int speaker) mixer - route only from analog mixer */ 4438 {0x25, AC_VERB_SET_AMP_GAIN_MUTE, 0x03}, 4439 /* Port-E pin */ 4440 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 4441 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4442 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 4443 /* Port-F (int speaker) mixer - route only from analog mixer */ 4444 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4445 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4446 /* Port-F pin */ 4447 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 4448 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 4449 /* Analog mixer; mute as default */ 4450 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4451 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4452 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 4453 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 4454 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 4455 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, 4456 /* Analog Mix output amp */ 4457 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 4458 /* capture sources */ 4459 /* {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0}, */ /* set via unsol */ 4460 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 4461 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0}, 4462 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 4463 /* unsolicited event for pin-sense */ 4464 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT}, 4465 {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_MIC_EVENT}, 4466 /* allow to touch GPIO1 (for mute control) */ 4467 {0x01, AC_VERB_SET_GPIO_MASK, 0x02}, 4468 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02}, 4469 {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, /* first muted */ 4470 /* internal mic - dmic */ 4471 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 4472 /* set magic COEFs for dmic */ 4473 {0x01, AC_VERB_SET_COEF_INDEX, 0x13f7}, 4474 {0x01, AC_VERB_SET_PROC_COEF, 0x08}, 4475 { } /* end */ 4476 }; 4477 4478 static const struct snd_kcontrol_new ad1984a_touchsmart_mixers[] = { 4479 HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT), 4480 /* HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),*/ 4481 { 4482 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 4483 .subdevice = HDA_SUBDEV_AMP_FLAG, 4484 .name = "Master Playback Switch", 4485 .info = snd_hda_mixer_amp_switch_info, 4486 .get = snd_hda_mixer_amp_switch_get, 4487 .put = ad1884a_mobile_master_sw_put, 4488 .private_value = HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT), 4489 }, 4490 HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT), 4491 HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT), 4492 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), 4493 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), 4494 HDA_CODEC_VOLUME("Mic Boost Volume", 0x25, 0x0, HDA_OUTPUT), 4495 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x17, 0x0, HDA_INPUT), 4496 { } /* end */ 4497 }; 4498 4499 /* switch to external mic if plugged */ 4500 static void ad1984a_touchsmart_automic(struct hda_codec *codec) 4501 { 4502 if (snd_hda_jack_detect(codec, 0x1c)) 4503 snd_hda_codec_write(codec, 0x0c, 0, 4504 AC_VERB_SET_CONNECT_SEL, 0x4); 4505 else 4506 snd_hda_codec_write(codec, 0x0c, 0, 4507 AC_VERB_SET_CONNECT_SEL, 0x5); 4508 } 4509 4510 4511 /* unsolicited event for HP jack sensing */ 4512 static void ad1984a_touchsmart_unsol_event(struct hda_codec *codec, 4513 unsigned int res) 4514 { 4515 switch (res >> 26) { 4516 case AD1884A_HP_EVENT: 4517 ad1884a_hp_automute(codec); 4518 break; 4519 case AD1884A_MIC_EVENT: 4520 ad1984a_touchsmart_automic(codec); 4521 break; 4522 } 4523 } 4524 4525 /* initialize jack-sensing, too */ 4526 static int ad1984a_touchsmart_init(struct hda_codec *codec) 4527 { 4528 ad198x_init(codec); 4529 ad1884a_hp_automute(codec); 4530 ad1984a_touchsmart_automic(codec); 4531 return 0; 4532 } 4533 4534 4535 /* 4536 */ 4537 4538 enum { 4539 AD1884A_DESKTOP, 4540 AD1884A_LAPTOP, 4541 AD1884A_MOBILE, 4542 AD1884A_THINKPAD, 4543 AD1984A_TOUCHSMART, 4544 AD1984A_PRECISION, 4545 AD1884A_MODELS 4546 }; 4547 4548 static const char * const ad1884a_models[AD1884A_MODELS] = { 4549 [AD1884A_DESKTOP] = "desktop", 4550 [AD1884A_LAPTOP] = "laptop", 4551 [AD1884A_MOBILE] = "mobile", 4552 [AD1884A_THINKPAD] = "thinkpad", 4553 [AD1984A_TOUCHSMART] = "touchsmart", 4554 [AD1984A_PRECISION] = "precision", 4555 }; 4556 4557 static const struct snd_pci_quirk ad1884a_cfg_tbl[] = { 4558 SND_PCI_QUIRK(0x1028, 0x04ac, "Precision R5500", AD1984A_PRECISION), 4559 SND_PCI_QUIRK(0x103c, 0x3030, "HP", AD1884A_MOBILE), 4560 SND_PCI_QUIRK(0x103c, 0x3037, "HP 2230s", AD1884A_LAPTOP), 4561 SND_PCI_QUIRK(0x103c, 0x3056, "HP", AD1884A_MOBILE), 4562 SND_PCI_QUIRK_MASK(0x103c, 0xfff0, 0x3070, "HP", AD1884A_MOBILE), 4563 SND_PCI_QUIRK_MASK(0x103c, 0xfff0, 0x30d0, "HP laptop", AD1884A_LAPTOP), 4564 SND_PCI_QUIRK_MASK(0x103c, 0xfff0, 0x30e0, "HP laptop", AD1884A_LAPTOP), 4565 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3600, "HP laptop", AD1884A_LAPTOP), 4566 SND_PCI_QUIRK_MASK(0x103c, 0xfff0, 0x7010, "HP laptop", AD1884A_MOBILE), 4567 SND_PCI_QUIRK(0x17aa, 0x20ac, "Thinkpad X300", AD1884A_THINKPAD), 4568 SND_PCI_QUIRK(0x103c, 0x2a82, "Touchsmart", AD1984A_TOUCHSMART), 4569 {} 4570 }; 4571 4572 static int patch_ad1884a(struct hda_codec *codec) 4573 { 4574 struct ad198x_spec *spec; 4575 int err, board_config; 4576 4577 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 4578 if (spec == NULL) 4579 return -ENOMEM; 4580 4581 codec->spec = spec; 4582 4583 err = snd_hda_attach_beep_device(codec, 0x10); 4584 if (err < 0) { 4585 ad198x_free(codec); 4586 return err; 4587 } 4588 set_beep_amp(spec, 0x10, 0, HDA_OUTPUT); 4589 4590 spec->multiout.max_channels = 2; 4591 spec->multiout.num_dacs = ARRAY_SIZE(ad1884a_dac_nids); 4592 spec->multiout.dac_nids = ad1884a_dac_nids; 4593 spec->multiout.dig_out_nid = AD1884A_SPDIF_OUT; 4594 spec->num_adc_nids = ARRAY_SIZE(ad1884a_adc_nids); 4595 spec->adc_nids = ad1884a_adc_nids; 4596 spec->capsrc_nids = ad1884a_capsrc_nids; 4597 spec->input_mux = &ad1884a_capture_source; 4598 spec->num_mixers = 1; 4599 spec->mixers[0] = ad1884a_base_mixers; 4600 spec->num_init_verbs = 1; 4601 spec->init_verbs[0] = ad1884a_init_verbs; 4602 spec->spdif_route = 0; 4603 #ifdef CONFIG_SND_HDA_POWER_SAVE 4604 spec->loopback.amplist = ad1884a_loopbacks; 4605 #endif 4606 codec->patch_ops = ad198x_patch_ops; 4607 4608 /* override some parameters */ 4609 board_config = snd_hda_check_board_config(codec, AD1884A_MODELS, 4610 ad1884a_models, 4611 ad1884a_cfg_tbl); 4612 switch (board_config) { 4613 case AD1884A_LAPTOP: 4614 spec->mixers[0] = ad1884a_laptop_mixers; 4615 spec->init_verbs[spec->num_init_verbs++] = ad1884a_laptop_verbs; 4616 spec->multiout.dig_out_nid = 0; 4617 codec->patch_ops.unsol_event = ad1884a_laptop_unsol_event; 4618 codec->patch_ops.init = ad1884a_laptop_init; 4619 /* set the upper-limit for mixer amp to 0dB for avoiding the 4620 * possible damage by overloading 4621 */ 4622 snd_hda_override_amp_caps(codec, 0x20, HDA_INPUT, 4623 (0x17 << AC_AMPCAP_OFFSET_SHIFT) | 4624 (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) | 4625 (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) | 4626 (1 << AC_AMPCAP_MUTE_SHIFT)); 4627 break; 4628 case AD1884A_MOBILE: 4629 spec->mixers[0] = ad1884a_mobile_mixers; 4630 spec->init_verbs[0] = ad1884a_mobile_verbs; 4631 spec->multiout.dig_out_nid = 0; 4632 codec->patch_ops.unsol_event = ad1884a_hp_unsol_event; 4633 codec->patch_ops.init = ad1884a_hp_init; 4634 /* set the upper-limit for mixer amp to 0dB for avoiding the 4635 * possible damage by overloading 4636 */ 4637 snd_hda_override_amp_caps(codec, 0x20, HDA_INPUT, 4638 (0x17 << AC_AMPCAP_OFFSET_SHIFT) | 4639 (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) | 4640 (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) | 4641 (1 << AC_AMPCAP_MUTE_SHIFT)); 4642 break; 4643 case AD1884A_THINKPAD: 4644 spec->mixers[0] = ad1984a_thinkpad_mixers; 4645 spec->init_verbs[spec->num_init_verbs++] = 4646 ad1984a_thinkpad_verbs; 4647 spec->multiout.dig_out_nid = 0; 4648 spec->input_mux = &ad1984a_thinkpad_capture_source; 4649 codec->patch_ops.unsol_event = ad1984a_thinkpad_unsol_event; 4650 codec->patch_ops.init = ad1984a_thinkpad_init; 4651 break; 4652 case AD1984A_PRECISION: 4653 spec->mixers[0] = ad1984a_precision_mixers; 4654 spec->init_verbs[spec->num_init_verbs++] = 4655 ad1984a_precision_verbs; 4656 spec->multiout.dig_out_nid = 0; 4657 codec->patch_ops.unsol_event = ad1984a_precision_unsol_event; 4658 codec->patch_ops.init = ad1984a_precision_init; 4659 break; 4660 case AD1984A_TOUCHSMART: 4661 spec->mixers[0] = ad1984a_touchsmart_mixers; 4662 spec->init_verbs[0] = ad1984a_touchsmart_verbs; 4663 spec->multiout.dig_out_nid = 0; 4664 codec->patch_ops.unsol_event = ad1984a_touchsmart_unsol_event; 4665 codec->patch_ops.init = ad1984a_touchsmart_init; 4666 /* set the upper-limit for mixer amp to 0dB for avoiding the 4667 * possible damage by overloading 4668 */ 4669 snd_hda_override_amp_caps(codec, 0x20, HDA_INPUT, 4670 (0x17 << AC_AMPCAP_OFFSET_SHIFT) | 4671 (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) | 4672 (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) | 4673 (1 << AC_AMPCAP_MUTE_SHIFT)); 4674 break; 4675 } 4676 4677 codec->no_trigger_sense = 1; 4678 codec->no_sticky_stream = 1; 4679 4680 return 0; 4681 } 4682 4683 4684 /* 4685 * AD1882 / AD1882A 4686 * 4687 * port-A - front hp-out 4688 * port-B - front mic-in 4689 * port-C - rear line-in, shared surr-out (3stack) 4690 * port-D - rear line-out 4691 * port-E - rear mic-in, shared clfe-out (3stack) 4692 * port-F - rear surr-out (6stack) 4693 * port-G - rear clfe-out (6stack) 4694 */ 4695 4696 static const hda_nid_t ad1882_dac_nids[3] = { 4697 0x04, 0x03, 0x05 4698 }; 4699 4700 static const hda_nid_t ad1882_adc_nids[2] = { 4701 0x08, 0x09, 4702 }; 4703 4704 static const hda_nid_t ad1882_capsrc_nids[2] = { 4705 0x0c, 0x0d, 4706 }; 4707 4708 #define AD1882_SPDIF_OUT 0x02 4709 4710 /* list: 0x11, 0x39, 0x3a, 0x18, 0x3c, 0x3b, 0x12, 0x20 */ 4711 static const struct hda_input_mux ad1882_capture_source = { 4712 .num_items = 5, 4713 .items = { 4714 { "Front Mic", 0x1 }, 4715 { "Mic", 0x4 }, 4716 { "Line", 0x2 }, 4717 { "CD", 0x3 }, 4718 { "Mix", 0x7 }, 4719 }, 4720 }; 4721 4722 /* list: 0x11, 0x39, 0x3a, 0x3c, 0x18, 0x1f, 0x12, 0x20 */ 4723 static const struct hda_input_mux ad1882a_capture_source = { 4724 .num_items = 5, 4725 .items = { 4726 { "Front Mic", 0x1 }, 4727 { "Mic", 0x4}, 4728 { "Line", 0x2 }, 4729 { "Digital Mic", 0x06 }, 4730 { "Mix", 0x7 }, 4731 }, 4732 }; 4733 4734 static const struct snd_kcontrol_new ad1882_base_mixers[] = { 4735 HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT), 4736 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT), 4737 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT), 4738 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x05, 2, 0x0, HDA_OUTPUT), 4739 HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT), 4740 HDA_CODEC_MUTE("Front Playback Switch", 0x12, 0x0, HDA_OUTPUT), 4741 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT), 4742 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT), 4743 4744 HDA_CODEC_VOLUME("Mic Boost Volume", 0x3c, 0x0, HDA_OUTPUT), 4745 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x39, 0x0, HDA_OUTPUT), 4746 HDA_CODEC_VOLUME("Line-In Boost Volume", 0x3a, 0x0, HDA_OUTPUT), 4747 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), 4748 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), 4749 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT), 4750 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT), 4751 { 4752 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 4753 /* The multiple "Capture Source" controls confuse alsamixer 4754 * So call somewhat different.. 4755 */ 4756 /* .name = "Capture Source", */ 4757 .name = "Input Source", 4758 .count = 2, 4759 .info = ad198x_mux_enum_info, 4760 .get = ad198x_mux_enum_get, 4761 .put = ad198x_mux_enum_put, 4762 }, 4763 /* SPDIF controls */ 4764 HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT), 4765 { 4766 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 4767 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source", 4768 /* identical with ad1983 */ 4769 .info = ad1983_spdif_route_info, 4770 .get = ad1983_spdif_route_get, 4771 .put = ad1983_spdif_route_put, 4772 }, 4773 { } /* end */ 4774 }; 4775 4776 static const struct snd_kcontrol_new ad1882_loopback_mixers[] = { 4777 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT), 4778 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT), 4779 HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x01, HDA_INPUT), 4780 HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x01, HDA_INPUT), 4781 HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x04, HDA_INPUT), 4782 HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x04, HDA_INPUT), 4783 HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x06, HDA_INPUT), 4784 HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x06, HDA_INPUT), 4785 { } /* end */ 4786 }; 4787 4788 static const struct snd_kcontrol_new ad1882a_loopback_mixers[] = { 4789 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT), 4790 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT), 4791 HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x04, HDA_INPUT), 4792 HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x04, HDA_INPUT), 4793 HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x01, HDA_INPUT), 4794 HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x01, HDA_INPUT), 4795 HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x06, HDA_INPUT), 4796 HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x06, HDA_INPUT), 4797 HDA_CODEC_VOLUME("Digital Mic Boost Volume", 0x1f, 0x0, HDA_INPUT), 4798 { } /* end */ 4799 }; 4800 4801 static const struct snd_kcontrol_new ad1882_3stack_mixers[] = { 4802 HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT), 4803 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x17, 1, 0x0, HDA_OUTPUT), 4804 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x17, 2, 0x0, HDA_OUTPUT), 4805 { 4806 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 4807 .name = "Channel Mode", 4808 .info = ad198x_ch_mode_info, 4809 .get = ad198x_ch_mode_get, 4810 .put = ad198x_ch_mode_put, 4811 }, 4812 { } /* end */ 4813 }; 4814 4815 static const struct snd_kcontrol_new ad1882_6stack_mixers[] = { 4816 HDA_CODEC_MUTE("Surround Playback Switch", 0x16, 0x0, HDA_OUTPUT), 4817 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x24, 1, 0x0, HDA_OUTPUT), 4818 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x24, 2, 0x0, HDA_OUTPUT), 4819 { } /* end */ 4820 }; 4821 4822 static const struct hda_verb ad1882_ch2_init[] = { 4823 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 4824 {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4825 {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4826 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 4827 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4828 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4829 { } /* end */ 4830 }; 4831 4832 static const struct hda_verb ad1882_ch4_init[] = { 4833 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4834 {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4835 {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4836 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 4837 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4838 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4839 { } /* end */ 4840 }; 4841 4842 static const struct hda_verb ad1882_ch6_init[] = { 4843 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4844 {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4845 {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4846 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4847 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4848 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4849 { } /* end */ 4850 }; 4851 4852 static const struct hda_channel_mode ad1882_modes[3] = { 4853 { 2, ad1882_ch2_init }, 4854 { 4, ad1882_ch4_init }, 4855 { 6, ad1882_ch6_init }, 4856 }; 4857 4858 /* 4859 * initialization verbs 4860 */ 4861 static const struct hda_verb ad1882_init_verbs[] = { 4862 /* DACs; mute as default */ 4863 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4864 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4865 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4866 /* Port-A (HP) mixer */ 4867 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4868 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4869 /* Port-A pin */ 4870 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 4871 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 4872 /* HP selector - select DAC2 */ 4873 {0x37, AC_VERB_SET_CONNECT_SEL, 0x1}, 4874 /* Port-D (Line-out) mixer */ 4875 {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4876 {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4877 /* Port-D pin */ 4878 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 4879 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 4880 /* Mono-out mixer */ 4881 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4882 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4883 /* Mono-out pin */ 4884 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 4885 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 4886 /* Port-B (front mic) pin */ 4887 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 4888 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 4889 {0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, /* boost */ 4890 /* Port-C (line-in) pin */ 4891 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 4892 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 4893 {0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, /* boost */ 4894 /* Port-C mixer - mute as input */ 4895 {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4896 {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4897 /* Port-E (mic-in) pin */ 4898 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 4899 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 4900 {0x3c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, /* boost */ 4901 /* Port-E mixer - mute as input */ 4902 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4903 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4904 /* Port-F (surround) */ 4905 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4906 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 4907 /* Port-G (CLFE) */ 4908 {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4909 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 4910 /* Analog mixer; mute as default */ 4911 /* list: 0x39, 0x3a, 0x11, 0x12, 0x3c, 0x3b, 0x18, 0x1a */ 4912 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4913 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4914 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 4915 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 4916 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 4917 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, 4918 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, 4919 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, 4920 /* Analog Mix output amp */ 4921 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */ 4922 /* SPDIF output selector */ 4923 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */ 4924 {0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, /* PCM */ 4925 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */ 4926 { } /* end */ 4927 }; 4928 4929 #ifdef CONFIG_SND_HDA_POWER_SAVE 4930 static const struct hda_amp_list ad1882_loopbacks[] = { 4931 { 0x20, HDA_INPUT, 0 }, /* Front Mic */ 4932 { 0x20, HDA_INPUT, 1 }, /* Mic */ 4933 { 0x20, HDA_INPUT, 4 }, /* Line */ 4934 { 0x20, HDA_INPUT, 6 }, /* CD */ 4935 { } /* end */ 4936 }; 4937 #endif 4938 4939 /* models */ 4940 enum { 4941 AD1882_3STACK, 4942 AD1882_6STACK, 4943 AD1882_MODELS 4944 }; 4945 4946 static const char * const ad1882_models[AD1986A_MODELS] = { 4947 [AD1882_3STACK] = "3stack", 4948 [AD1882_6STACK] = "6stack", 4949 }; 4950 4951 4952 static int patch_ad1882(struct hda_codec *codec) 4953 { 4954 struct ad198x_spec *spec; 4955 int err, board_config; 4956 4957 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 4958 if (spec == NULL) 4959 return -ENOMEM; 4960 4961 codec->spec = spec; 4962 4963 err = snd_hda_attach_beep_device(codec, 0x10); 4964 if (err < 0) { 4965 ad198x_free(codec); 4966 return err; 4967 } 4968 set_beep_amp(spec, 0x10, 0, HDA_OUTPUT); 4969 4970 spec->multiout.max_channels = 6; 4971 spec->multiout.num_dacs = 3; 4972 spec->multiout.dac_nids = ad1882_dac_nids; 4973 spec->multiout.dig_out_nid = AD1882_SPDIF_OUT; 4974 spec->num_adc_nids = ARRAY_SIZE(ad1882_adc_nids); 4975 spec->adc_nids = ad1882_adc_nids; 4976 spec->capsrc_nids = ad1882_capsrc_nids; 4977 if (codec->vendor_id == 0x11d41882) 4978 spec->input_mux = &ad1882_capture_source; 4979 else 4980 spec->input_mux = &ad1882a_capture_source; 4981 spec->num_mixers = 2; 4982 spec->mixers[0] = ad1882_base_mixers; 4983 if (codec->vendor_id == 0x11d41882) 4984 spec->mixers[1] = ad1882_loopback_mixers; 4985 else 4986 spec->mixers[1] = ad1882a_loopback_mixers; 4987 spec->num_init_verbs = 1; 4988 spec->init_verbs[0] = ad1882_init_verbs; 4989 spec->spdif_route = 0; 4990 #ifdef CONFIG_SND_HDA_POWER_SAVE 4991 spec->loopback.amplist = ad1882_loopbacks; 4992 #endif 4993 spec->vmaster_nid = 0x04; 4994 4995 codec->patch_ops = ad198x_patch_ops; 4996 4997 /* override some parameters */ 4998 board_config = snd_hda_check_board_config(codec, AD1882_MODELS, 4999 ad1882_models, NULL); 5000 switch (board_config) { 5001 default: 5002 case AD1882_3STACK: 5003 spec->num_mixers = 3; 5004 spec->mixers[2] = ad1882_3stack_mixers; 5005 spec->channel_mode = ad1882_modes; 5006 spec->num_channel_mode = ARRAY_SIZE(ad1882_modes); 5007 spec->need_dac_fix = 1; 5008 spec->multiout.max_channels = 2; 5009 spec->multiout.num_dacs = 1; 5010 break; 5011 case AD1882_6STACK: 5012 spec->num_mixers = 3; 5013 spec->mixers[2] = ad1882_6stack_mixers; 5014 break; 5015 } 5016 5017 codec->no_trigger_sense = 1; 5018 codec->no_sticky_stream = 1; 5019 5020 return 0; 5021 } 5022 5023 5024 /* 5025 * patch entries 5026 */ 5027 static const struct hda_codec_preset snd_hda_preset_analog[] = { 5028 { .id = 0x11d4184a, .name = "AD1884A", .patch = patch_ad1884a }, 5029 { .id = 0x11d41882, .name = "AD1882", .patch = patch_ad1882 }, 5030 { .id = 0x11d41883, .name = "AD1883", .patch = patch_ad1884a }, 5031 { .id = 0x11d41884, .name = "AD1884", .patch = patch_ad1884 }, 5032 { .id = 0x11d4194a, .name = "AD1984A", .patch = patch_ad1884a }, 5033 { .id = 0x11d4194b, .name = "AD1984B", .patch = patch_ad1884a }, 5034 { .id = 0x11d41981, .name = "AD1981", .patch = patch_ad1981 }, 5035 { .id = 0x11d41983, .name = "AD1983", .patch = patch_ad1983 }, 5036 { .id = 0x11d41984, .name = "AD1984", .patch = patch_ad1984 }, 5037 { .id = 0x11d41986, .name = "AD1986A", .patch = patch_ad1986a }, 5038 { .id = 0x11d41988, .name = "AD1988", .patch = patch_ad1988 }, 5039 { .id = 0x11d4198b, .name = "AD1988B", .patch = patch_ad1988 }, 5040 { .id = 0x11d4882a, .name = "AD1882A", .patch = patch_ad1882 }, 5041 { .id = 0x11d4989a, .name = "AD1989A", .patch = patch_ad1988 }, 5042 { .id = 0x11d4989b, .name = "AD1989B", .patch = patch_ad1988 }, 5043 {} /* terminator */ 5044 }; 5045 5046 MODULE_ALIAS("snd-hda-codec-id:11d4*"); 5047 5048 MODULE_LICENSE("GPL"); 5049 MODULE_DESCRIPTION("Analog Devices HD-audio codec"); 5050 5051 static struct hda_codec_preset_list analog_list = { 5052 .preset = snd_hda_preset_analog, 5053 .owner = THIS_MODULE, 5054 }; 5055 5056 static int __init patch_analog_init(void) 5057 { 5058 return snd_hda_add_codec_preset(&analog_list); 5059 } 5060 5061 static void __exit patch_analog_exit(void) 5062 { 5063 snd_hda_delete_codec_preset(&analog_list); 5064 } 5065 5066 module_init(patch_analog_init) 5067 module_exit(patch_analog_exit) 5068