1 /* 2 * HD audio interface patch for Conexant HDA audio codec 3 * 4 * Copyright (c) 2006 Pototskiy Akex <alex.pototskiy@gmail.com> 5 * Takashi Iwai <tiwai@suse.de> 6 * Tobin Davis <tdavis@dsl-only.net> 7 * 8 * This driver is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 * 13 * This driver is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 */ 22 23 #include <linux/init.h> 24 #include <linux/delay.h> 25 #include <linux/slab.h> 26 #include <linux/pci.h> 27 #include <sound/core.h> 28 #include <sound/jack.h> 29 30 #include "hda_codec.h" 31 #include "hda_local.h" 32 #include "hda_beep.h" 33 34 #define CXT_PIN_DIR_IN 0x00 35 #define CXT_PIN_DIR_OUT 0x01 36 #define CXT_PIN_DIR_INOUT 0x02 37 #define CXT_PIN_DIR_IN_NOMICBIAS 0x03 38 #define CXT_PIN_DIR_INOUT_NOMICBIAS 0x04 39 40 #define CONEXANT_HP_EVENT 0x37 41 #define CONEXANT_MIC_EVENT 0x38 42 #define CONEXANT_LINE_EVENT 0x39 43 44 /* Conexant 5051 specific */ 45 46 #define CXT5051_SPDIF_OUT 0x12 47 #define CXT5051_PORTB_EVENT 0x38 48 #define CXT5051_PORTC_EVENT 0x39 49 50 #define AUTO_MIC_PORTB (1 << 1) 51 #define AUTO_MIC_PORTC (1 << 2) 52 53 struct pin_dac_pair { 54 hda_nid_t pin; 55 hda_nid_t dac; 56 int type; 57 }; 58 59 struct imux_info { 60 hda_nid_t pin; /* input pin NID */ 61 hda_nid_t adc; /* connected ADC NID */ 62 hda_nid_t boost; /* optional boost volume NID */ 63 int index; /* corresponding to autocfg.input */ 64 }; 65 66 struct conexant_spec { 67 68 const struct snd_kcontrol_new *mixers[5]; 69 int num_mixers; 70 hda_nid_t vmaster_nid; 71 72 const struct hda_verb *init_verbs[5]; /* initialization verbs 73 * don't forget NULL 74 * termination! 75 */ 76 unsigned int num_init_verbs; 77 78 /* playback */ 79 struct hda_multi_out multiout; /* playback set-up 80 * max_channels, dacs must be set 81 * dig_out_nid and hp_nid are optional 82 */ 83 unsigned int cur_eapd; 84 unsigned int hp_present; 85 unsigned int line_present; 86 unsigned int auto_mic; 87 int auto_mic_ext; /* imux_pins[] index for ext mic */ 88 int auto_mic_dock; /* imux_pins[] index for dock mic */ 89 int auto_mic_int; /* imux_pins[] index for int mic */ 90 unsigned int need_dac_fix; 91 hda_nid_t slave_dig_outs[2]; 92 93 /* capture */ 94 unsigned int num_adc_nids; 95 const hda_nid_t *adc_nids; 96 hda_nid_t dig_in_nid; /* digital-in NID; optional */ 97 98 unsigned int cur_adc_idx; 99 hda_nid_t cur_adc; 100 unsigned int cur_adc_stream_tag; 101 unsigned int cur_adc_format; 102 103 const struct hda_pcm_stream *capture_stream; 104 105 /* capture source */ 106 const struct hda_input_mux *input_mux; 107 const hda_nid_t *capsrc_nids; 108 unsigned int cur_mux[3]; 109 110 /* channel model */ 111 const struct hda_channel_mode *channel_mode; 112 int num_channel_mode; 113 114 /* PCM information */ 115 struct hda_pcm pcm_rec[2]; /* used in build_pcms() */ 116 117 unsigned int spdif_route; 118 119 /* dynamic controls, init_verbs and input_mux */ 120 struct auto_pin_cfg autocfg; 121 struct hda_input_mux private_imux; 122 struct imux_info imux_info[HDA_MAX_NUM_INPUTS]; 123 hda_nid_t private_adc_nids[HDA_MAX_NUM_INPUTS]; 124 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; 125 struct pin_dac_pair dac_info[8]; 126 int dac_info_filled; 127 128 unsigned int port_d_mode; 129 unsigned int auto_mute:1; /* used in auto-parser */ 130 unsigned int detect_line:1; /* Line-out detection enabled */ 131 unsigned int automute_lines:1; /* automute line-out as well */ 132 unsigned int automute_hp_lo:1; /* both HP and LO available */ 133 unsigned int dell_automute:1; 134 unsigned int dell_vostro:1; 135 unsigned int ideapad:1; 136 unsigned int thinkpad:1; 137 unsigned int hp_laptop:1; 138 unsigned int asus:1; 139 140 unsigned int adc_switching:1; 141 142 unsigned int ext_mic_present; 143 unsigned int recording; 144 void (*capture_prepare)(struct hda_codec *codec); 145 void (*capture_cleanup)(struct hda_codec *codec); 146 147 /* OLPC XO-1.5 supports DC input mode (e.g. for use with analog sensors) 148 * through the microphone jack. 149 * When the user enables this through a mixer switch, both internal and 150 * external microphones are disabled. Gain is fixed at 0dB. In this mode, 151 * we also allow the bias to be configured through a separate mixer 152 * control. */ 153 unsigned int dc_enable; 154 unsigned int dc_input_bias; /* offset into cxt5066_olpc_dc_bias */ 155 unsigned int mic_boost; /* offset into cxt5066_analog_mic_boost */ 156 157 unsigned int beep_amp; 158 159 /* extra EAPD pins */ 160 unsigned int num_eapds; 161 hda_nid_t eapds[4]; 162 }; 163 164 static int conexant_playback_pcm_open(struct hda_pcm_stream *hinfo, 165 struct hda_codec *codec, 166 struct snd_pcm_substream *substream) 167 { 168 struct conexant_spec *spec = codec->spec; 169 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream, 170 hinfo); 171 } 172 173 static int conexant_playback_pcm_prepare(struct hda_pcm_stream *hinfo, 174 struct hda_codec *codec, 175 unsigned int stream_tag, 176 unsigned int format, 177 struct snd_pcm_substream *substream) 178 { 179 struct conexant_spec *spec = codec->spec; 180 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, 181 stream_tag, 182 format, substream); 183 } 184 185 static int conexant_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, 186 struct hda_codec *codec, 187 struct snd_pcm_substream *substream) 188 { 189 struct conexant_spec *spec = codec->spec; 190 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); 191 } 192 193 /* 194 * Digital out 195 */ 196 static int conexant_dig_playback_pcm_open(struct hda_pcm_stream *hinfo, 197 struct hda_codec *codec, 198 struct snd_pcm_substream *substream) 199 { 200 struct conexant_spec *spec = codec->spec; 201 return snd_hda_multi_out_dig_open(codec, &spec->multiout); 202 } 203 204 static int conexant_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, 205 struct hda_codec *codec, 206 struct snd_pcm_substream *substream) 207 { 208 struct conexant_spec *spec = codec->spec; 209 return snd_hda_multi_out_dig_close(codec, &spec->multiout); 210 } 211 212 static int conexant_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, 213 struct hda_codec *codec, 214 unsigned int stream_tag, 215 unsigned int format, 216 struct snd_pcm_substream *substream) 217 { 218 struct conexant_spec *spec = codec->spec; 219 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, 220 stream_tag, 221 format, substream); 222 } 223 224 /* 225 * Analog capture 226 */ 227 static int conexant_capture_pcm_prepare(struct hda_pcm_stream *hinfo, 228 struct hda_codec *codec, 229 unsigned int stream_tag, 230 unsigned int format, 231 struct snd_pcm_substream *substream) 232 { 233 struct conexant_spec *spec = codec->spec; 234 if (spec->capture_prepare) 235 spec->capture_prepare(codec); 236 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number], 237 stream_tag, 0, format); 238 return 0; 239 } 240 241 static int conexant_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, 242 struct hda_codec *codec, 243 struct snd_pcm_substream *substream) 244 { 245 struct conexant_spec *spec = codec->spec; 246 snd_hda_codec_cleanup_stream(codec, spec->adc_nids[substream->number]); 247 if (spec->capture_cleanup) 248 spec->capture_cleanup(codec); 249 return 0; 250 } 251 252 253 254 static const struct hda_pcm_stream conexant_pcm_analog_playback = { 255 .substreams = 1, 256 .channels_min = 2, 257 .channels_max = 2, 258 .nid = 0, /* fill later */ 259 .ops = { 260 .open = conexant_playback_pcm_open, 261 .prepare = conexant_playback_pcm_prepare, 262 .cleanup = conexant_playback_pcm_cleanup 263 }, 264 }; 265 266 static const struct hda_pcm_stream conexant_pcm_analog_capture = { 267 .substreams = 1, 268 .channels_min = 2, 269 .channels_max = 2, 270 .nid = 0, /* fill later */ 271 .ops = { 272 .prepare = conexant_capture_pcm_prepare, 273 .cleanup = conexant_capture_pcm_cleanup 274 }, 275 }; 276 277 278 static const struct hda_pcm_stream conexant_pcm_digital_playback = { 279 .substreams = 1, 280 .channels_min = 2, 281 .channels_max = 2, 282 .nid = 0, /* fill later */ 283 .ops = { 284 .open = conexant_dig_playback_pcm_open, 285 .close = conexant_dig_playback_pcm_close, 286 .prepare = conexant_dig_playback_pcm_prepare 287 }, 288 }; 289 290 static const struct hda_pcm_stream conexant_pcm_digital_capture = { 291 .substreams = 1, 292 .channels_min = 2, 293 .channels_max = 2, 294 /* NID is set in alc_build_pcms */ 295 }; 296 297 static int cx5051_capture_pcm_prepare(struct hda_pcm_stream *hinfo, 298 struct hda_codec *codec, 299 unsigned int stream_tag, 300 unsigned int format, 301 struct snd_pcm_substream *substream) 302 { 303 struct conexant_spec *spec = codec->spec; 304 spec->cur_adc = spec->adc_nids[spec->cur_adc_idx]; 305 spec->cur_adc_stream_tag = stream_tag; 306 spec->cur_adc_format = format; 307 snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format); 308 return 0; 309 } 310 311 static int cx5051_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, 312 struct hda_codec *codec, 313 struct snd_pcm_substream *substream) 314 { 315 struct conexant_spec *spec = codec->spec; 316 snd_hda_codec_cleanup_stream(codec, spec->cur_adc); 317 spec->cur_adc = 0; 318 return 0; 319 } 320 321 static const struct hda_pcm_stream cx5051_pcm_analog_capture = { 322 .substreams = 1, 323 .channels_min = 2, 324 .channels_max = 2, 325 .nid = 0, /* fill later */ 326 .ops = { 327 .prepare = cx5051_capture_pcm_prepare, 328 .cleanup = cx5051_capture_pcm_cleanup 329 }, 330 }; 331 332 static int conexant_build_pcms(struct hda_codec *codec) 333 { 334 struct conexant_spec *spec = codec->spec; 335 struct hda_pcm *info = spec->pcm_rec; 336 337 codec->num_pcms = 1; 338 codec->pcm_info = info; 339 340 info->name = "CONEXANT Analog"; 341 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = conexant_pcm_analog_playback; 342 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 343 spec->multiout.max_channels; 344 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 345 spec->multiout.dac_nids[0]; 346 if (spec->capture_stream) 347 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *spec->capture_stream; 348 else { 349 if (codec->vendor_id == 0x14f15051) 350 info->stream[SNDRV_PCM_STREAM_CAPTURE] = 351 cx5051_pcm_analog_capture; 352 else { 353 info->stream[SNDRV_PCM_STREAM_CAPTURE] = 354 conexant_pcm_analog_capture; 355 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = 356 spec->num_adc_nids; 357 } 358 } 359 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0]; 360 361 if (spec->multiout.dig_out_nid) { 362 info++; 363 codec->num_pcms++; 364 info->name = "Conexant Digital"; 365 info->pcm_type = HDA_PCM_TYPE_SPDIF; 366 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = 367 conexant_pcm_digital_playback; 368 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 369 spec->multiout.dig_out_nid; 370 if (spec->dig_in_nid) { 371 info->stream[SNDRV_PCM_STREAM_CAPTURE] = 372 conexant_pcm_digital_capture; 373 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 374 spec->dig_in_nid; 375 } 376 if (spec->slave_dig_outs[0]) 377 codec->slave_dig_outs = spec->slave_dig_outs; 378 } 379 380 return 0; 381 } 382 383 static int conexant_mux_enum_info(struct snd_kcontrol *kcontrol, 384 struct snd_ctl_elem_info *uinfo) 385 { 386 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 387 struct conexant_spec *spec = codec->spec; 388 389 return snd_hda_input_mux_info(spec->input_mux, uinfo); 390 } 391 392 static int conexant_mux_enum_get(struct snd_kcontrol *kcontrol, 393 struct snd_ctl_elem_value *ucontrol) 394 { 395 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 396 struct conexant_spec *spec = codec->spec; 397 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 398 399 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx]; 400 return 0; 401 } 402 403 static int conexant_mux_enum_put(struct snd_kcontrol *kcontrol, 404 struct snd_ctl_elem_value *ucontrol) 405 { 406 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 407 struct conexant_spec *spec = codec->spec; 408 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 409 410 return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol, 411 spec->capsrc_nids[adc_idx], 412 &spec->cur_mux[adc_idx]); 413 } 414 415 static int conexant_init_jacks(struct hda_codec *codec) 416 { 417 #ifdef CONFIG_SND_HDA_INPUT_JACK 418 struct conexant_spec *spec = codec->spec; 419 int i; 420 421 for (i = 0; i < spec->num_init_verbs; i++) { 422 const struct hda_verb *hv; 423 424 hv = spec->init_verbs[i]; 425 while (hv->nid) { 426 int err = 0; 427 switch (hv->param ^ AC_USRSP_EN) { 428 case CONEXANT_HP_EVENT: 429 err = snd_hda_input_jack_add(codec, hv->nid, 430 SND_JACK_HEADPHONE, NULL); 431 snd_hda_input_jack_report(codec, hv->nid); 432 break; 433 case CXT5051_PORTC_EVENT: 434 case CONEXANT_MIC_EVENT: 435 err = snd_hda_input_jack_add(codec, hv->nid, 436 SND_JACK_MICROPHONE, NULL); 437 snd_hda_input_jack_report(codec, hv->nid); 438 break; 439 } 440 if (err < 0) 441 return err; 442 ++hv; 443 } 444 } 445 #endif /* CONFIG_SND_HDA_INPUT_JACK */ 446 return 0; 447 } 448 449 static int conexant_init(struct hda_codec *codec) 450 { 451 struct conexant_spec *spec = codec->spec; 452 int i; 453 454 for (i = 0; i < spec->num_init_verbs; i++) 455 snd_hda_sequence_write(codec, spec->init_verbs[i]); 456 return 0; 457 } 458 459 static void conexant_free(struct hda_codec *codec) 460 { 461 snd_hda_input_jack_free(codec); 462 snd_hda_detach_beep_device(codec); 463 kfree(codec->spec); 464 } 465 466 static const struct snd_kcontrol_new cxt_capture_mixers[] = { 467 { 468 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 469 .name = "Capture Source", 470 .info = conexant_mux_enum_info, 471 .get = conexant_mux_enum_get, 472 .put = conexant_mux_enum_put 473 }, 474 {} 475 }; 476 477 #ifdef CONFIG_SND_HDA_INPUT_BEEP 478 /* additional beep mixers; the actual parameters are overwritten at build */ 479 static const struct snd_kcontrol_new cxt_beep_mixer[] = { 480 HDA_CODEC_VOLUME_MONO("Beep Playback Volume", 0, 1, 0, HDA_OUTPUT), 481 HDA_CODEC_MUTE_BEEP_MONO("Beep Playback Switch", 0, 1, 0, HDA_OUTPUT), 482 { } /* end */ 483 }; 484 #endif 485 486 static const char * const slave_vols[] = { 487 "Headphone Playback Volume", 488 "Speaker Playback Volume", 489 "Front Playback Volume", 490 "Surround Playback Volume", 491 "CLFE Playback Volume", 492 NULL 493 }; 494 495 static const char * const slave_sws[] = { 496 "Headphone Playback Switch", 497 "Speaker Playback Switch", 498 "Front Playback Switch", 499 "Surround Playback Switch", 500 "CLFE Playback Switch", 501 NULL 502 }; 503 504 static int conexant_build_controls(struct hda_codec *codec) 505 { 506 struct conexant_spec *spec = codec->spec; 507 unsigned int i; 508 int err; 509 510 for (i = 0; i < spec->num_mixers; i++) { 511 err = snd_hda_add_new_ctls(codec, spec->mixers[i]); 512 if (err < 0) 513 return err; 514 } 515 if (spec->multiout.dig_out_nid) { 516 err = snd_hda_create_spdif_out_ctls(codec, 517 spec->multiout.dig_out_nid, 518 spec->multiout.dig_out_nid); 519 if (err < 0) 520 return err; 521 err = snd_hda_create_spdif_share_sw(codec, 522 &spec->multiout); 523 if (err < 0) 524 return err; 525 spec->multiout.share_spdif = 1; 526 } 527 if (spec->dig_in_nid) { 528 err = snd_hda_create_spdif_in_ctls(codec,spec->dig_in_nid); 529 if (err < 0) 530 return err; 531 } 532 533 /* if we have no master control, let's create it */ 534 if (spec->vmaster_nid && 535 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) { 536 unsigned int vmaster_tlv[4]; 537 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid, 538 HDA_OUTPUT, vmaster_tlv); 539 err = snd_hda_add_vmaster(codec, "Master Playback Volume", 540 vmaster_tlv, slave_vols); 541 if (err < 0) 542 return err; 543 } 544 if (spec->vmaster_nid && 545 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) { 546 err = snd_hda_add_vmaster(codec, "Master Playback Switch", 547 NULL, slave_sws); 548 if (err < 0) 549 return err; 550 } 551 552 if (spec->input_mux) { 553 err = snd_hda_add_new_ctls(codec, cxt_capture_mixers); 554 if (err < 0) 555 return err; 556 } 557 558 #ifdef CONFIG_SND_HDA_INPUT_BEEP 559 /* create beep controls if needed */ 560 if (spec->beep_amp) { 561 const struct snd_kcontrol_new *knew; 562 for (knew = cxt_beep_mixer; knew->name; knew++) { 563 struct snd_kcontrol *kctl; 564 kctl = snd_ctl_new1(knew, codec); 565 if (!kctl) 566 return -ENOMEM; 567 kctl->private_value = spec->beep_amp; 568 err = snd_hda_ctl_add(codec, 0, kctl); 569 if (err < 0) 570 return err; 571 } 572 } 573 #endif 574 575 return 0; 576 } 577 578 #ifdef CONFIG_SND_HDA_POWER_SAVE 579 static int conexant_suspend(struct hda_codec *codec, pm_message_t state) 580 { 581 snd_hda_shutup_pins(codec); 582 return 0; 583 } 584 #endif 585 586 static const struct hda_codec_ops conexant_patch_ops = { 587 .build_controls = conexant_build_controls, 588 .build_pcms = conexant_build_pcms, 589 .init = conexant_init, 590 .free = conexant_free, 591 #ifdef CONFIG_SND_HDA_POWER_SAVE 592 .suspend = conexant_suspend, 593 #endif 594 .reboot_notify = snd_hda_shutup_pins, 595 }; 596 597 #ifdef CONFIG_SND_HDA_INPUT_BEEP 598 #define set_beep_amp(spec, nid, idx, dir) \ 599 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 1, idx, dir)) 600 #else 601 #define set_beep_amp(spec, nid, idx, dir) /* NOP */ 602 #endif 603 604 static int patch_conexant_auto(struct hda_codec *codec); 605 /* 606 * EAPD control 607 * the private value = nid | (invert << 8) 608 */ 609 610 #define cxt_eapd_info snd_ctl_boolean_mono_info 611 612 static int cxt_eapd_get(struct snd_kcontrol *kcontrol, 613 struct snd_ctl_elem_value *ucontrol) 614 { 615 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 616 struct conexant_spec *spec = codec->spec; 617 int invert = (kcontrol->private_value >> 8) & 1; 618 if (invert) 619 ucontrol->value.integer.value[0] = !spec->cur_eapd; 620 else 621 ucontrol->value.integer.value[0] = spec->cur_eapd; 622 return 0; 623 624 } 625 626 static int cxt_eapd_put(struct snd_kcontrol *kcontrol, 627 struct snd_ctl_elem_value *ucontrol) 628 { 629 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 630 struct conexant_spec *spec = codec->spec; 631 int invert = (kcontrol->private_value >> 8) & 1; 632 hda_nid_t nid = kcontrol->private_value & 0xff; 633 unsigned int eapd; 634 635 eapd = !!ucontrol->value.integer.value[0]; 636 if (invert) 637 eapd = !eapd; 638 if (eapd == spec->cur_eapd) 639 return 0; 640 641 spec->cur_eapd = eapd; 642 snd_hda_codec_write_cache(codec, nid, 643 0, AC_VERB_SET_EAPD_BTLENABLE, 644 eapd ? 0x02 : 0x00); 645 return 1; 646 } 647 648 /* controls for test mode */ 649 #ifdef CONFIG_SND_DEBUG 650 651 #define CXT_EAPD_SWITCH(xname, nid, mask) \ 652 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 653 .info = cxt_eapd_info, \ 654 .get = cxt_eapd_get, \ 655 .put = cxt_eapd_put, \ 656 .private_value = nid | (mask<<16) } 657 658 659 660 static int conexant_ch_mode_info(struct snd_kcontrol *kcontrol, 661 struct snd_ctl_elem_info *uinfo) 662 { 663 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 664 struct conexant_spec *spec = codec->spec; 665 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode, 666 spec->num_channel_mode); 667 } 668 669 static int conexant_ch_mode_get(struct snd_kcontrol *kcontrol, 670 struct snd_ctl_elem_value *ucontrol) 671 { 672 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 673 struct conexant_spec *spec = codec->spec; 674 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode, 675 spec->num_channel_mode, 676 spec->multiout.max_channels); 677 } 678 679 static int conexant_ch_mode_put(struct snd_kcontrol *kcontrol, 680 struct snd_ctl_elem_value *ucontrol) 681 { 682 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 683 struct conexant_spec *spec = codec->spec; 684 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode, 685 spec->num_channel_mode, 686 &spec->multiout.max_channels); 687 if (err >= 0 && spec->need_dac_fix) 688 spec->multiout.num_dacs = spec->multiout.max_channels / 2; 689 return err; 690 } 691 692 #define CXT_PIN_MODE(xname, nid, dir) \ 693 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 694 .info = conexant_ch_mode_info, \ 695 .get = conexant_ch_mode_get, \ 696 .put = conexant_ch_mode_put, \ 697 .private_value = nid | (dir<<16) } 698 699 #endif /* CONFIG_SND_DEBUG */ 700 701 /* Conexant 5045 specific */ 702 703 static const hda_nid_t cxt5045_dac_nids[1] = { 0x19 }; 704 static const hda_nid_t cxt5045_adc_nids[1] = { 0x1a }; 705 static const hda_nid_t cxt5045_capsrc_nids[1] = { 0x1a }; 706 #define CXT5045_SPDIF_OUT 0x18 707 708 static const struct hda_channel_mode cxt5045_modes[1] = { 709 { 2, NULL }, 710 }; 711 712 static const struct hda_input_mux cxt5045_capture_source = { 713 .num_items = 2, 714 .items = { 715 { "IntMic", 0x1 }, 716 { "ExtMic", 0x2 }, 717 } 718 }; 719 720 static const struct hda_input_mux cxt5045_capture_source_benq = { 721 .num_items = 5, 722 .items = { 723 { "IntMic", 0x1 }, 724 { "ExtMic", 0x2 }, 725 { "LineIn", 0x3 }, 726 { "CD", 0x4 }, 727 { "Mixer", 0x0 }, 728 } 729 }; 730 731 static const struct hda_input_mux cxt5045_capture_source_hp530 = { 732 .num_items = 2, 733 .items = { 734 { "ExtMic", 0x1 }, 735 { "IntMic", 0x2 }, 736 } 737 }; 738 739 /* turn on/off EAPD (+ mute HP) as a master switch */ 740 static int cxt5045_hp_master_sw_put(struct snd_kcontrol *kcontrol, 741 struct snd_ctl_elem_value *ucontrol) 742 { 743 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 744 struct conexant_spec *spec = codec->spec; 745 unsigned int bits; 746 747 if (!cxt_eapd_put(kcontrol, ucontrol)) 748 return 0; 749 750 /* toggle internal speakers mute depending of presence of 751 * the headphone jack 752 */ 753 bits = (!spec->hp_present && spec->cur_eapd) ? 0 : HDA_AMP_MUTE; 754 snd_hda_codec_amp_stereo(codec, 0x10, HDA_OUTPUT, 0, 755 HDA_AMP_MUTE, bits); 756 757 bits = spec->cur_eapd ? 0 : HDA_AMP_MUTE; 758 snd_hda_codec_amp_stereo(codec, 0x11, HDA_OUTPUT, 0, 759 HDA_AMP_MUTE, bits); 760 return 1; 761 } 762 763 /* bind volumes of both NID 0x10 and 0x11 */ 764 static const struct hda_bind_ctls cxt5045_hp_bind_master_vol = { 765 .ops = &snd_hda_bind_vol, 766 .values = { 767 HDA_COMPOSE_AMP_VAL(0x10, 3, 0, HDA_OUTPUT), 768 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT), 769 0 770 }, 771 }; 772 773 /* toggle input of built-in and mic jack appropriately */ 774 static void cxt5045_hp_automic(struct hda_codec *codec) 775 { 776 static const struct hda_verb mic_jack_on[] = { 777 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 778 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 779 {} 780 }; 781 static const struct hda_verb mic_jack_off[] = { 782 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 783 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 784 {} 785 }; 786 unsigned int present; 787 788 present = snd_hda_jack_detect(codec, 0x12); 789 if (present) 790 snd_hda_sequence_write(codec, mic_jack_on); 791 else 792 snd_hda_sequence_write(codec, mic_jack_off); 793 } 794 795 796 /* mute internal speaker if HP is plugged */ 797 static void cxt5045_hp_automute(struct hda_codec *codec) 798 { 799 struct conexant_spec *spec = codec->spec; 800 unsigned int bits; 801 802 spec->hp_present = snd_hda_jack_detect(codec, 0x11); 803 804 bits = (spec->hp_present || !spec->cur_eapd) ? HDA_AMP_MUTE : 0; 805 snd_hda_codec_amp_stereo(codec, 0x10, HDA_OUTPUT, 0, 806 HDA_AMP_MUTE, bits); 807 } 808 809 /* unsolicited event for HP jack sensing */ 810 static void cxt5045_hp_unsol_event(struct hda_codec *codec, 811 unsigned int res) 812 { 813 res >>= 26; 814 switch (res) { 815 case CONEXANT_HP_EVENT: 816 cxt5045_hp_automute(codec); 817 break; 818 case CONEXANT_MIC_EVENT: 819 cxt5045_hp_automic(codec); 820 break; 821 822 } 823 } 824 825 static const struct snd_kcontrol_new cxt5045_mixers[] = { 826 HDA_CODEC_VOLUME("Internal Mic Capture Volume", 0x1a, 0x01, HDA_INPUT), 827 HDA_CODEC_MUTE("Internal Mic Capture Switch", 0x1a, 0x01, HDA_INPUT), 828 HDA_CODEC_VOLUME("Mic Capture Volume", 0x1a, 0x02, HDA_INPUT), 829 HDA_CODEC_MUTE("Mic Capture Switch", 0x1a, 0x02, HDA_INPUT), 830 HDA_CODEC_VOLUME("PCM Playback Volume", 0x17, 0x0, HDA_INPUT), 831 HDA_CODEC_MUTE("PCM Playback Switch", 0x17, 0x0, HDA_INPUT), 832 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0x1, HDA_INPUT), 833 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x17, 0x1, HDA_INPUT), 834 HDA_CODEC_VOLUME("Mic Playback Volume", 0x17, 0x2, HDA_INPUT), 835 HDA_CODEC_MUTE("Mic Playback Switch", 0x17, 0x2, HDA_INPUT), 836 HDA_BIND_VOL("Master Playback Volume", &cxt5045_hp_bind_master_vol), 837 { 838 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 839 .name = "Master Playback Switch", 840 .info = cxt_eapd_info, 841 .get = cxt_eapd_get, 842 .put = cxt5045_hp_master_sw_put, 843 .private_value = 0x10, 844 }, 845 846 {} 847 }; 848 849 static const struct snd_kcontrol_new cxt5045_benq_mixers[] = { 850 HDA_CODEC_VOLUME("CD Capture Volume", 0x1a, 0x04, HDA_INPUT), 851 HDA_CODEC_MUTE("CD Capture Switch", 0x1a, 0x04, HDA_INPUT), 852 HDA_CODEC_VOLUME("CD Playback Volume", 0x17, 0x4, HDA_INPUT), 853 HDA_CODEC_MUTE("CD Playback Switch", 0x17, 0x4, HDA_INPUT), 854 855 HDA_CODEC_VOLUME("Line In Capture Volume", 0x1a, 0x03, HDA_INPUT), 856 HDA_CODEC_MUTE("Line In Capture Switch", 0x1a, 0x03, HDA_INPUT), 857 HDA_CODEC_VOLUME("Line In Playback Volume", 0x17, 0x3, HDA_INPUT), 858 HDA_CODEC_MUTE("Line In Playback Switch", 0x17, 0x3, HDA_INPUT), 859 860 HDA_CODEC_VOLUME("Mixer Capture Volume", 0x1a, 0x0, HDA_INPUT), 861 HDA_CODEC_MUTE("Mixer Capture Switch", 0x1a, 0x0, HDA_INPUT), 862 863 {} 864 }; 865 866 static const struct snd_kcontrol_new cxt5045_mixers_hp530[] = { 867 HDA_CODEC_VOLUME("Internal Mic Capture Volume", 0x1a, 0x02, HDA_INPUT), 868 HDA_CODEC_MUTE("Internal Mic Capture Switch", 0x1a, 0x02, HDA_INPUT), 869 HDA_CODEC_VOLUME("Mic Capture Volume", 0x1a, 0x01, HDA_INPUT), 870 HDA_CODEC_MUTE("Mic Capture Switch", 0x1a, 0x01, HDA_INPUT), 871 HDA_CODEC_VOLUME("PCM Playback Volume", 0x17, 0x0, HDA_INPUT), 872 HDA_CODEC_MUTE("PCM Playback Switch", 0x17, 0x0, HDA_INPUT), 873 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0x2, HDA_INPUT), 874 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x17, 0x2, HDA_INPUT), 875 HDA_CODEC_VOLUME("Mic Playback Volume", 0x17, 0x1, HDA_INPUT), 876 HDA_CODEC_MUTE("Mic Playback Switch", 0x17, 0x1, HDA_INPUT), 877 HDA_BIND_VOL("Master Playback Volume", &cxt5045_hp_bind_master_vol), 878 { 879 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 880 .name = "Master Playback Switch", 881 .info = cxt_eapd_info, 882 .get = cxt_eapd_get, 883 .put = cxt5045_hp_master_sw_put, 884 .private_value = 0x10, 885 }, 886 887 {} 888 }; 889 890 static const struct hda_verb cxt5045_init_verbs[] = { 891 /* Line in, Mic */ 892 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 }, 893 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 }, 894 /* HP, Amp */ 895 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 896 {0x10, AC_VERB_SET_CONNECT_SEL, 0x1}, 897 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 898 {0x11, AC_VERB_SET_CONNECT_SEL, 0x1}, 899 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 900 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 901 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 902 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 903 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 904 /* Record selector: Internal mic */ 905 {0x1a, AC_VERB_SET_CONNECT_SEL,0x1}, 906 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 907 AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17}, 908 /* SPDIF route: PCM */ 909 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 910 { 0x13, AC_VERB_SET_CONNECT_SEL, 0x0 }, 911 /* EAPD */ 912 {0x10, AC_VERB_SET_EAPD_BTLENABLE, 0x2 }, /* default on */ 913 { } /* end */ 914 }; 915 916 static const struct hda_verb cxt5045_benq_init_verbs[] = { 917 /* Internal Mic, Mic */ 918 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 }, 919 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 }, 920 /* Line In,HP, Amp */ 921 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 922 {0x10, AC_VERB_SET_CONNECT_SEL, 0x1}, 923 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 924 {0x11, AC_VERB_SET_CONNECT_SEL, 0x1}, 925 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 926 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 927 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 928 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 929 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 930 /* Record selector: Internal mic */ 931 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x1}, 932 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 933 AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17}, 934 /* SPDIF route: PCM */ 935 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 936 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0}, 937 /* EAPD */ 938 {0x10, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */ 939 { } /* end */ 940 }; 941 942 static const struct hda_verb cxt5045_hp_sense_init_verbs[] = { 943 /* pin sensing on HP jack */ 944 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT}, 945 { } /* end */ 946 }; 947 948 static const struct hda_verb cxt5045_mic_sense_init_verbs[] = { 949 /* pin sensing on HP jack */ 950 {0x12, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT}, 951 { } /* end */ 952 }; 953 954 #ifdef CONFIG_SND_DEBUG 955 /* Test configuration for debugging, modelled after the ALC260 test 956 * configuration. 957 */ 958 static const struct hda_input_mux cxt5045_test_capture_source = { 959 .num_items = 5, 960 .items = { 961 { "MIXER", 0x0 }, 962 { "MIC1 pin", 0x1 }, 963 { "LINE1 pin", 0x2 }, 964 { "HP-OUT pin", 0x3 }, 965 { "CD pin", 0x4 }, 966 }, 967 }; 968 969 static const struct snd_kcontrol_new cxt5045_test_mixer[] = { 970 971 /* Output controls */ 972 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x10, 0x0, HDA_OUTPUT), 973 HDA_CODEC_MUTE("Speaker Playback Switch", 0x10, 0x0, HDA_OUTPUT), 974 HDA_CODEC_VOLUME("Node 11 Playback Volume", 0x11, 0x0, HDA_OUTPUT), 975 HDA_CODEC_MUTE("Node 11 Playback Switch", 0x11, 0x0, HDA_OUTPUT), 976 HDA_CODEC_VOLUME("Node 12 Playback Volume", 0x12, 0x0, HDA_OUTPUT), 977 HDA_CODEC_MUTE("Node 12 Playback Switch", 0x12, 0x0, HDA_OUTPUT), 978 979 /* Modes for retasking pin widgets */ 980 CXT_PIN_MODE("HP-OUT pin mode", 0x11, CXT_PIN_DIR_INOUT), 981 CXT_PIN_MODE("LINE1 pin mode", 0x12, CXT_PIN_DIR_INOUT), 982 983 /* EAPD Switch Control */ 984 CXT_EAPD_SWITCH("External Amplifier", 0x10, 0x0), 985 986 /* Loopback mixer controls */ 987 988 HDA_CODEC_VOLUME("Mixer-1 Volume", 0x17, 0x0, HDA_INPUT), 989 HDA_CODEC_MUTE("Mixer-1 Switch", 0x17, 0x0, HDA_INPUT), 990 HDA_CODEC_VOLUME("Mixer-2 Volume", 0x17, 0x1, HDA_INPUT), 991 HDA_CODEC_MUTE("Mixer-2 Switch", 0x17, 0x1, HDA_INPUT), 992 HDA_CODEC_VOLUME("Mixer-3 Volume", 0x17, 0x2, HDA_INPUT), 993 HDA_CODEC_MUTE("Mixer-3 Switch", 0x17, 0x2, HDA_INPUT), 994 HDA_CODEC_VOLUME("Mixer-4 Volume", 0x17, 0x3, HDA_INPUT), 995 HDA_CODEC_MUTE("Mixer-4 Switch", 0x17, 0x3, HDA_INPUT), 996 HDA_CODEC_VOLUME("Mixer-5 Volume", 0x17, 0x4, HDA_INPUT), 997 HDA_CODEC_MUTE("Mixer-5 Switch", 0x17, 0x4, HDA_INPUT), 998 { 999 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1000 .name = "Input Source", 1001 .info = conexant_mux_enum_info, 1002 .get = conexant_mux_enum_get, 1003 .put = conexant_mux_enum_put, 1004 }, 1005 /* Audio input controls */ 1006 HDA_CODEC_VOLUME("Input-1 Volume", 0x1a, 0x0, HDA_INPUT), 1007 HDA_CODEC_MUTE("Input-1 Switch", 0x1a, 0x0, HDA_INPUT), 1008 HDA_CODEC_VOLUME("Input-2 Volume", 0x1a, 0x1, HDA_INPUT), 1009 HDA_CODEC_MUTE("Input-2 Switch", 0x1a, 0x1, HDA_INPUT), 1010 HDA_CODEC_VOLUME("Input-3 Volume", 0x1a, 0x2, HDA_INPUT), 1011 HDA_CODEC_MUTE("Input-3 Switch", 0x1a, 0x2, HDA_INPUT), 1012 HDA_CODEC_VOLUME("Input-4 Volume", 0x1a, 0x3, HDA_INPUT), 1013 HDA_CODEC_MUTE("Input-4 Switch", 0x1a, 0x3, HDA_INPUT), 1014 HDA_CODEC_VOLUME("Input-5 Volume", 0x1a, 0x4, HDA_INPUT), 1015 HDA_CODEC_MUTE("Input-5 Switch", 0x1a, 0x4, HDA_INPUT), 1016 { } /* end */ 1017 }; 1018 1019 static const struct hda_verb cxt5045_test_init_verbs[] = { 1020 /* Set connections */ 1021 { 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 }, 1022 { 0x11, AC_VERB_SET_CONNECT_SEL, 0x0 }, 1023 { 0x12, AC_VERB_SET_CONNECT_SEL, 0x0 }, 1024 /* Enable retasking pins as output, initially without power amp */ 1025 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1026 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1027 1028 /* Disable digital (SPDIF) pins initially, but users can enable 1029 * them via a mixer switch. In the case of SPDIF-out, this initverb 1030 * payload also sets the generation to 0, output to be in "consumer" 1031 * PCM format, copyright asserted, no pre-emphasis and no validity 1032 * control. 1033 */ 1034 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1035 {0x18, AC_VERB_SET_DIGI_CONVERT_1, 0}, 1036 1037 /* Start with output sum widgets muted and their output gains at min */ 1038 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 1039 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 1040 1041 /* Unmute retasking pin widget output buffers since the default 1042 * state appears to be output. As the pin mode is changed by the 1043 * user the pin mode control will take care of enabling the pin's 1044 * input/output buffers as needed. 1045 */ 1046 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1047 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1048 1049 /* Mute capture amp left and right */ 1050 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 1051 1052 /* Set ADC connection select to match default mixer setting (mic1 1053 * pin) 1054 */ 1055 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00}, 1056 {0x17, AC_VERB_SET_CONNECT_SEL, 0x00}, 1057 1058 /* Mute all inputs to mixer widget (even unconnected ones) */ 1059 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* Mixer pin */ 1060 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* Mic1 pin */ 1061 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* Line pin */ 1062 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* HP pin */ 1063 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */ 1064 1065 { } 1066 }; 1067 #endif 1068 1069 1070 /* initialize jack-sensing, too */ 1071 static int cxt5045_init(struct hda_codec *codec) 1072 { 1073 conexant_init(codec); 1074 cxt5045_hp_automute(codec); 1075 return 0; 1076 } 1077 1078 1079 enum { 1080 CXT5045_LAPTOP_HPSENSE, 1081 CXT5045_LAPTOP_MICSENSE, 1082 CXT5045_LAPTOP_HPMICSENSE, 1083 CXT5045_BENQ, 1084 CXT5045_LAPTOP_HP530, 1085 #ifdef CONFIG_SND_DEBUG 1086 CXT5045_TEST, 1087 #endif 1088 CXT5045_AUTO, 1089 CXT5045_MODELS 1090 }; 1091 1092 static const char * const cxt5045_models[CXT5045_MODELS] = { 1093 [CXT5045_LAPTOP_HPSENSE] = "laptop-hpsense", 1094 [CXT5045_LAPTOP_MICSENSE] = "laptop-micsense", 1095 [CXT5045_LAPTOP_HPMICSENSE] = "laptop-hpmicsense", 1096 [CXT5045_BENQ] = "benq", 1097 [CXT5045_LAPTOP_HP530] = "laptop-hp530", 1098 #ifdef CONFIG_SND_DEBUG 1099 [CXT5045_TEST] = "test", 1100 #endif 1101 [CXT5045_AUTO] = "auto", 1102 }; 1103 1104 static const struct snd_pci_quirk cxt5045_cfg_tbl[] = { 1105 SND_PCI_QUIRK(0x103c, 0x30d5, "HP 530", CXT5045_LAPTOP_HP530), 1106 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP DV Series", 1107 CXT5045_LAPTOP_HPSENSE), 1108 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba P105", CXT5045_LAPTOP_MICSENSE), 1109 SND_PCI_QUIRK(0x152d, 0x0753, "Benq R55E", CXT5045_BENQ), 1110 SND_PCI_QUIRK(0x1734, 0x10ad, "Fujitsu Si1520", CXT5045_LAPTOP_MICSENSE), 1111 SND_PCI_QUIRK(0x1734, 0x10cb, "Fujitsu Si3515", CXT5045_LAPTOP_HPMICSENSE), 1112 SND_PCI_QUIRK(0x1734, 0x110e, "Fujitsu V5505", 1113 CXT5045_LAPTOP_HPMICSENSE), 1114 SND_PCI_QUIRK(0x1509, 0x1e40, "FIC", CXT5045_LAPTOP_HPMICSENSE), 1115 SND_PCI_QUIRK(0x1509, 0x2f05, "FIC", CXT5045_LAPTOP_HPMICSENSE), 1116 SND_PCI_QUIRK(0x1509, 0x2f06, "FIC", CXT5045_LAPTOP_HPMICSENSE), 1117 SND_PCI_QUIRK_MASK(0x1631, 0xff00, 0xc100, "Packard Bell", 1118 CXT5045_LAPTOP_HPMICSENSE), 1119 SND_PCI_QUIRK(0x8086, 0x2111, "Conexant Reference board", CXT5045_LAPTOP_HPSENSE), 1120 {} 1121 }; 1122 1123 static int patch_cxt5045(struct hda_codec *codec) 1124 { 1125 struct conexant_spec *spec; 1126 int board_config; 1127 1128 board_config = snd_hda_check_board_config(codec, CXT5045_MODELS, 1129 cxt5045_models, 1130 cxt5045_cfg_tbl); 1131 if (board_config < 0) 1132 board_config = CXT5045_AUTO; /* model=auto as default */ 1133 if (board_config == CXT5045_AUTO) 1134 return patch_conexant_auto(codec); 1135 1136 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 1137 if (!spec) 1138 return -ENOMEM; 1139 codec->spec = spec; 1140 codec->pin_amp_workaround = 1; 1141 1142 spec->multiout.max_channels = 2; 1143 spec->multiout.num_dacs = ARRAY_SIZE(cxt5045_dac_nids); 1144 spec->multiout.dac_nids = cxt5045_dac_nids; 1145 spec->multiout.dig_out_nid = CXT5045_SPDIF_OUT; 1146 spec->num_adc_nids = 1; 1147 spec->adc_nids = cxt5045_adc_nids; 1148 spec->capsrc_nids = cxt5045_capsrc_nids; 1149 spec->input_mux = &cxt5045_capture_source; 1150 spec->num_mixers = 1; 1151 spec->mixers[0] = cxt5045_mixers; 1152 spec->num_init_verbs = 1; 1153 spec->init_verbs[0] = cxt5045_init_verbs; 1154 spec->spdif_route = 0; 1155 spec->num_channel_mode = ARRAY_SIZE(cxt5045_modes); 1156 spec->channel_mode = cxt5045_modes; 1157 1158 set_beep_amp(spec, 0x16, 0, 1); 1159 1160 codec->patch_ops = conexant_patch_ops; 1161 1162 switch (board_config) { 1163 case CXT5045_LAPTOP_HPSENSE: 1164 codec->patch_ops.unsol_event = cxt5045_hp_unsol_event; 1165 spec->input_mux = &cxt5045_capture_source; 1166 spec->num_init_verbs = 2; 1167 spec->init_verbs[1] = cxt5045_hp_sense_init_verbs; 1168 spec->mixers[0] = cxt5045_mixers; 1169 codec->patch_ops.init = cxt5045_init; 1170 break; 1171 case CXT5045_LAPTOP_MICSENSE: 1172 codec->patch_ops.unsol_event = cxt5045_hp_unsol_event; 1173 spec->input_mux = &cxt5045_capture_source; 1174 spec->num_init_verbs = 2; 1175 spec->init_verbs[1] = cxt5045_mic_sense_init_verbs; 1176 spec->mixers[0] = cxt5045_mixers; 1177 codec->patch_ops.init = cxt5045_init; 1178 break; 1179 default: 1180 case CXT5045_LAPTOP_HPMICSENSE: 1181 codec->patch_ops.unsol_event = cxt5045_hp_unsol_event; 1182 spec->input_mux = &cxt5045_capture_source; 1183 spec->num_init_verbs = 3; 1184 spec->init_verbs[1] = cxt5045_hp_sense_init_verbs; 1185 spec->init_verbs[2] = cxt5045_mic_sense_init_verbs; 1186 spec->mixers[0] = cxt5045_mixers; 1187 codec->patch_ops.init = cxt5045_init; 1188 break; 1189 case CXT5045_BENQ: 1190 codec->patch_ops.unsol_event = cxt5045_hp_unsol_event; 1191 spec->input_mux = &cxt5045_capture_source_benq; 1192 spec->num_init_verbs = 1; 1193 spec->init_verbs[0] = cxt5045_benq_init_verbs; 1194 spec->mixers[0] = cxt5045_mixers; 1195 spec->mixers[1] = cxt5045_benq_mixers; 1196 spec->num_mixers = 2; 1197 codec->patch_ops.init = cxt5045_init; 1198 break; 1199 case CXT5045_LAPTOP_HP530: 1200 codec->patch_ops.unsol_event = cxt5045_hp_unsol_event; 1201 spec->input_mux = &cxt5045_capture_source_hp530; 1202 spec->num_init_verbs = 2; 1203 spec->init_verbs[1] = cxt5045_hp_sense_init_verbs; 1204 spec->mixers[0] = cxt5045_mixers_hp530; 1205 codec->patch_ops.init = cxt5045_init; 1206 break; 1207 #ifdef CONFIG_SND_DEBUG 1208 case CXT5045_TEST: 1209 spec->input_mux = &cxt5045_test_capture_source; 1210 spec->mixers[0] = cxt5045_test_mixer; 1211 spec->init_verbs[0] = cxt5045_test_init_verbs; 1212 break; 1213 1214 #endif 1215 } 1216 1217 switch (codec->subsystem_id >> 16) { 1218 case 0x103c: 1219 case 0x1631: 1220 case 0x1734: 1221 case 0x17aa: 1222 /* HP, Packard Bell, Fujitsu-Siemens & Lenovo laptops have 1223 * really bad sound over 0dB on NID 0x17. Fix max PCM level to 1224 * 0 dB (originally it has 0x2b steps with 0dB offset 0x14) 1225 */ 1226 snd_hda_override_amp_caps(codec, 0x17, HDA_INPUT, 1227 (0x14 << AC_AMPCAP_OFFSET_SHIFT) | 1228 (0x14 << AC_AMPCAP_NUM_STEPS_SHIFT) | 1229 (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) | 1230 (1 << AC_AMPCAP_MUTE_SHIFT)); 1231 break; 1232 } 1233 1234 if (spec->beep_amp) 1235 snd_hda_attach_beep_device(codec, spec->beep_amp); 1236 1237 return 0; 1238 } 1239 1240 1241 /* Conexant 5047 specific */ 1242 #define CXT5047_SPDIF_OUT 0x11 1243 1244 static const hda_nid_t cxt5047_dac_nids[1] = { 0x10 }; /* 0x1c */ 1245 static const hda_nid_t cxt5047_adc_nids[1] = { 0x12 }; 1246 static const hda_nid_t cxt5047_capsrc_nids[1] = { 0x1a }; 1247 1248 static const struct hda_channel_mode cxt5047_modes[1] = { 1249 { 2, NULL }, 1250 }; 1251 1252 static const struct hda_input_mux cxt5047_toshiba_capture_source = { 1253 .num_items = 2, 1254 .items = { 1255 { "ExtMic", 0x2 }, 1256 { "Line-In", 0x1 }, 1257 } 1258 }; 1259 1260 /* turn on/off EAPD (+ mute HP) as a master switch */ 1261 static int cxt5047_hp_master_sw_put(struct snd_kcontrol *kcontrol, 1262 struct snd_ctl_elem_value *ucontrol) 1263 { 1264 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 1265 struct conexant_spec *spec = codec->spec; 1266 unsigned int bits; 1267 1268 if (!cxt_eapd_put(kcontrol, ucontrol)) 1269 return 0; 1270 1271 /* toggle internal speakers mute depending of presence of 1272 * the headphone jack 1273 */ 1274 bits = (!spec->hp_present && spec->cur_eapd) ? 0 : HDA_AMP_MUTE; 1275 /* NOTE: Conexat codec needs the index for *OUTPUT* amp of 1276 * pin widgets unlike other codecs. In this case, we need to 1277 * set index 0x01 for the volume from the mixer amp 0x19. 1278 */ 1279 snd_hda_codec_amp_stereo(codec, 0x1d, HDA_OUTPUT, 0x01, 1280 HDA_AMP_MUTE, bits); 1281 bits = spec->cur_eapd ? 0 : HDA_AMP_MUTE; 1282 snd_hda_codec_amp_stereo(codec, 0x13, HDA_OUTPUT, 0, 1283 HDA_AMP_MUTE, bits); 1284 return 1; 1285 } 1286 1287 /* mute internal speaker if HP is plugged */ 1288 static void cxt5047_hp_automute(struct hda_codec *codec) 1289 { 1290 struct conexant_spec *spec = codec->spec; 1291 unsigned int bits; 1292 1293 spec->hp_present = snd_hda_jack_detect(codec, 0x13); 1294 1295 bits = (spec->hp_present || !spec->cur_eapd) ? HDA_AMP_MUTE : 0; 1296 /* See the note in cxt5047_hp_master_sw_put */ 1297 snd_hda_codec_amp_stereo(codec, 0x1d, HDA_OUTPUT, 0x01, 1298 HDA_AMP_MUTE, bits); 1299 } 1300 1301 /* toggle input of built-in and mic jack appropriately */ 1302 static void cxt5047_hp_automic(struct hda_codec *codec) 1303 { 1304 static const struct hda_verb mic_jack_on[] = { 1305 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1306 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1307 {} 1308 }; 1309 static const struct hda_verb mic_jack_off[] = { 1310 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1311 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1312 {} 1313 }; 1314 unsigned int present; 1315 1316 present = snd_hda_jack_detect(codec, 0x15); 1317 if (present) 1318 snd_hda_sequence_write(codec, mic_jack_on); 1319 else 1320 snd_hda_sequence_write(codec, mic_jack_off); 1321 } 1322 1323 /* unsolicited event for HP jack sensing */ 1324 static void cxt5047_hp_unsol_event(struct hda_codec *codec, 1325 unsigned int res) 1326 { 1327 switch (res >> 26) { 1328 case CONEXANT_HP_EVENT: 1329 cxt5047_hp_automute(codec); 1330 break; 1331 case CONEXANT_MIC_EVENT: 1332 cxt5047_hp_automic(codec); 1333 break; 1334 } 1335 } 1336 1337 static const struct snd_kcontrol_new cxt5047_base_mixers[] = { 1338 HDA_CODEC_VOLUME("Mic Playback Volume", 0x19, 0x02, HDA_INPUT), 1339 HDA_CODEC_MUTE("Mic Playback Switch", 0x19, 0x02, HDA_INPUT), 1340 HDA_CODEC_VOLUME("Mic Boost Volume", 0x1a, 0x0, HDA_OUTPUT), 1341 HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x03, HDA_INPUT), 1342 HDA_CODEC_MUTE("Capture Switch", 0x12, 0x03, HDA_INPUT), 1343 HDA_CODEC_VOLUME("PCM Volume", 0x10, 0x00, HDA_OUTPUT), 1344 HDA_CODEC_MUTE("PCM Switch", 0x10, 0x00, HDA_OUTPUT), 1345 { 1346 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1347 .name = "Master Playback Switch", 1348 .info = cxt_eapd_info, 1349 .get = cxt_eapd_get, 1350 .put = cxt5047_hp_master_sw_put, 1351 .private_value = 0x13, 1352 }, 1353 1354 {} 1355 }; 1356 1357 static const struct snd_kcontrol_new cxt5047_hp_spk_mixers[] = { 1358 /* See the note in cxt5047_hp_master_sw_put */ 1359 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x1d, 0x01, HDA_OUTPUT), 1360 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x13, 0x00, HDA_OUTPUT), 1361 {} 1362 }; 1363 1364 static const struct snd_kcontrol_new cxt5047_hp_only_mixers[] = { 1365 HDA_CODEC_VOLUME("Master Playback Volume", 0x13, 0x00, HDA_OUTPUT), 1366 { } /* end */ 1367 }; 1368 1369 static const struct hda_verb cxt5047_init_verbs[] = { 1370 /* Line in, Mic, Built-in Mic */ 1371 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 1372 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_50 }, 1373 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_50 }, 1374 /* HP, Speaker */ 1375 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, 1376 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0}, /* mixer(0x19) */ 1377 {0x1d, AC_VERB_SET_CONNECT_SEL, 0x1}, /* mixer(0x19) */ 1378 /* Record selector: Mic */ 1379 {0x12, AC_VERB_SET_CONNECT_SEL,0x03}, 1380 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 1381 AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17}, 1382 {0x1A, AC_VERB_SET_CONNECT_SEL,0x02}, 1383 {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, 1384 AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x00}, 1385 {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, 1386 AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x03}, 1387 /* SPDIF route: PCM */ 1388 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x0 }, 1389 /* Enable unsolicited events */ 1390 {0x13, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT}, 1391 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT}, 1392 { } /* end */ 1393 }; 1394 1395 /* configuration for Toshiba Laptops */ 1396 static const struct hda_verb cxt5047_toshiba_init_verbs[] = { 1397 {0x13, AC_VERB_SET_EAPD_BTLENABLE, 0x0}, /* default off */ 1398 {} 1399 }; 1400 1401 /* Test configuration for debugging, modelled after the ALC260 test 1402 * configuration. 1403 */ 1404 #ifdef CONFIG_SND_DEBUG 1405 static const struct hda_input_mux cxt5047_test_capture_source = { 1406 .num_items = 4, 1407 .items = { 1408 { "LINE1 pin", 0x0 }, 1409 { "MIC1 pin", 0x1 }, 1410 { "MIC2 pin", 0x2 }, 1411 { "CD pin", 0x3 }, 1412 }, 1413 }; 1414 1415 static const struct snd_kcontrol_new cxt5047_test_mixer[] = { 1416 1417 /* Output only controls */ 1418 HDA_CODEC_VOLUME("OutAmp-1 Volume", 0x10, 0x0, HDA_OUTPUT), 1419 HDA_CODEC_MUTE("OutAmp-1 Switch", 0x10,0x0, HDA_OUTPUT), 1420 HDA_CODEC_VOLUME("OutAmp-2 Volume", 0x1c, 0x0, HDA_OUTPUT), 1421 HDA_CODEC_MUTE("OutAmp-2 Switch", 0x1c, 0x0, HDA_OUTPUT), 1422 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x1d, 0x0, HDA_OUTPUT), 1423 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1d, 0x0, HDA_OUTPUT), 1424 HDA_CODEC_VOLUME("HeadPhone Playback Volume", 0x13, 0x0, HDA_OUTPUT), 1425 HDA_CODEC_MUTE("HeadPhone Playback Switch", 0x13, 0x0, HDA_OUTPUT), 1426 HDA_CODEC_VOLUME("Line1-Out Playback Volume", 0x14, 0x0, HDA_OUTPUT), 1427 HDA_CODEC_MUTE("Line1-Out Playback Switch", 0x14, 0x0, HDA_OUTPUT), 1428 HDA_CODEC_VOLUME("Line2-Out Playback Volume", 0x15, 0x0, HDA_OUTPUT), 1429 HDA_CODEC_MUTE("Line2-Out Playback Switch", 0x15, 0x0, HDA_OUTPUT), 1430 1431 /* Modes for retasking pin widgets */ 1432 CXT_PIN_MODE("LINE1 pin mode", 0x14, CXT_PIN_DIR_INOUT), 1433 CXT_PIN_MODE("MIC1 pin mode", 0x15, CXT_PIN_DIR_INOUT), 1434 1435 /* EAPD Switch Control */ 1436 CXT_EAPD_SWITCH("External Amplifier", 0x13, 0x0), 1437 1438 /* Loopback mixer controls */ 1439 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x12, 0x01, HDA_INPUT), 1440 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x12, 0x01, HDA_INPUT), 1441 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x12, 0x02, HDA_INPUT), 1442 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x12, 0x02, HDA_INPUT), 1443 HDA_CODEC_VOLUME("LINE Playback Volume", 0x12, 0x0, HDA_INPUT), 1444 HDA_CODEC_MUTE("LINE Playback Switch", 0x12, 0x0, HDA_INPUT), 1445 HDA_CODEC_VOLUME("CD Playback Volume", 0x12, 0x04, HDA_INPUT), 1446 HDA_CODEC_MUTE("CD Playback Switch", 0x12, 0x04, HDA_INPUT), 1447 1448 HDA_CODEC_VOLUME("Capture-1 Volume", 0x19, 0x0, HDA_INPUT), 1449 HDA_CODEC_MUTE("Capture-1 Switch", 0x19, 0x0, HDA_INPUT), 1450 HDA_CODEC_VOLUME("Capture-2 Volume", 0x19, 0x1, HDA_INPUT), 1451 HDA_CODEC_MUTE("Capture-2 Switch", 0x19, 0x1, HDA_INPUT), 1452 HDA_CODEC_VOLUME("Capture-3 Volume", 0x19, 0x2, HDA_INPUT), 1453 HDA_CODEC_MUTE("Capture-3 Switch", 0x19, 0x2, HDA_INPUT), 1454 HDA_CODEC_VOLUME("Capture-4 Volume", 0x19, 0x3, HDA_INPUT), 1455 HDA_CODEC_MUTE("Capture-4 Switch", 0x19, 0x3, HDA_INPUT), 1456 { 1457 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1458 .name = "Input Source", 1459 .info = conexant_mux_enum_info, 1460 .get = conexant_mux_enum_get, 1461 .put = conexant_mux_enum_put, 1462 }, 1463 HDA_CODEC_VOLUME("Mic Boost Volume", 0x1a, 0x0, HDA_OUTPUT), 1464 1465 { } /* end */ 1466 }; 1467 1468 static const struct hda_verb cxt5047_test_init_verbs[] = { 1469 /* Enable retasking pins as output, initially without power amp */ 1470 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1471 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1472 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1473 1474 /* Disable digital (SPDIF) pins initially, but users can enable 1475 * them via a mixer switch. In the case of SPDIF-out, this initverb 1476 * payload also sets the generation to 0, output to be in "consumer" 1477 * PCM format, copyright asserted, no pre-emphasis and no validity 1478 * control. 1479 */ 1480 {0x18, AC_VERB_SET_DIGI_CONVERT_1, 0}, 1481 1482 /* Ensure mic1, mic2, line1 pin widgets take input from the 1483 * OUT1 sum bus when acting as an output. 1484 */ 1485 {0x1a, AC_VERB_SET_CONNECT_SEL, 0}, 1486 {0x1b, AC_VERB_SET_CONNECT_SEL, 0}, 1487 1488 /* Start with output sum widgets muted and their output gains at min */ 1489 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 1490 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 1491 1492 /* Unmute retasking pin widget output buffers since the default 1493 * state appears to be output. As the pin mode is changed by the 1494 * user the pin mode control will take care of enabling the pin's 1495 * input/output buffers as needed. 1496 */ 1497 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1498 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1499 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1500 1501 /* Mute capture amp left and right */ 1502 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 1503 1504 /* Set ADC connection select to match default mixer setting (mic1 1505 * pin) 1506 */ 1507 {0x12, AC_VERB_SET_CONNECT_SEL, 0x00}, 1508 1509 /* Mute all inputs to mixer widget (even unconnected ones) */ 1510 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */ 1511 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */ 1512 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */ 1513 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */ 1514 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */ 1515 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */ 1516 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */ 1517 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */ 1518 1519 { } 1520 }; 1521 #endif 1522 1523 1524 /* initialize jack-sensing, too */ 1525 static int cxt5047_hp_init(struct hda_codec *codec) 1526 { 1527 conexant_init(codec); 1528 cxt5047_hp_automute(codec); 1529 return 0; 1530 } 1531 1532 1533 enum { 1534 CXT5047_LAPTOP, /* Laptops w/o EAPD support */ 1535 CXT5047_LAPTOP_HP, /* Some HP laptops */ 1536 CXT5047_LAPTOP_EAPD, /* Laptops with EAPD support */ 1537 #ifdef CONFIG_SND_DEBUG 1538 CXT5047_TEST, 1539 #endif 1540 CXT5047_AUTO, 1541 CXT5047_MODELS 1542 }; 1543 1544 static const char * const cxt5047_models[CXT5047_MODELS] = { 1545 [CXT5047_LAPTOP] = "laptop", 1546 [CXT5047_LAPTOP_HP] = "laptop-hp", 1547 [CXT5047_LAPTOP_EAPD] = "laptop-eapd", 1548 #ifdef CONFIG_SND_DEBUG 1549 [CXT5047_TEST] = "test", 1550 #endif 1551 [CXT5047_AUTO] = "auto", 1552 }; 1553 1554 static const struct snd_pci_quirk cxt5047_cfg_tbl[] = { 1555 SND_PCI_QUIRK(0x103c, 0x30a5, "HP DV5200T/DV8000T", CXT5047_LAPTOP_HP), 1556 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP DV Series", 1557 CXT5047_LAPTOP), 1558 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba P100", CXT5047_LAPTOP_EAPD), 1559 {} 1560 }; 1561 1562 static int patch_cxt5047(struct hda_codec *codec) 1563 { 1564 struct conexant_spec *spec; 1565 int board_config; 1566 1567 board_config = snd_hda_check_board_config(codec, CXT5047_MODELS, 1568 cxt5047_models, 1569 cxt5047_cfg_tbl); 1570 if (board_config < 0) 1571 board_config = CXT5047_AUTO; /* model=auto as default */ 1572 if (board_config == CXT5047_AUTO) 1573 return patch_conexant_auto(codec); 1574 1575 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 1576 if (!spec) 1577 return -ENOMEM; 1578 codec->spec = spec; 1579 codec->pin_amp_workaround = 1; 1580 1581 spec->multiout.max_channels = 2; 1582 spec->multiout.num_dacs = ARRAY_SIZE(cxt5047_dac_nids); 1583 spec->multiout.dac_nids = cxt5047_dac_nids; 1584 spec->multiout.dig_out_nid = CXT5047_SPDIF_OUT; 1585 spec->num_adc_nids = 1; 1586 spec->adc_nids = cxt5047_adc_nids; 1587 spec->capsrc_nids = cxt5047_capsrc_nids; 1588 spec->num_mixers = 1; 1589 spec->mixers[0] = cxt5047_base_mixers; 1590 spec->num_init_verbs = 1; 1591 spec->init_verbs[0] = cxt5047_init_verbs; 1592 spec->spdif_route = 0; 1593 spec->num_channel_mode = ARRAY_SIZE(cxt5047_modes), 1594 spec->channel_mode = cxt5047_modes, 1595 1596 codec->patch_ops = conexant_patch_ops; 1597 1598 switch (board_config) { 1599 case CXT5047_LAPTOP: 1600 spec->num_mixers = 2; 1601 spec->mixers[1] = cxt5047_hp_spk_mixers; 1602 codec->patch_ops.unsol_event = cxt5047_hp_unsol_event; 1603 break; 1604 case CXT5047_LAPTOP_HP: 1605 spec->num_mixers = 2; 1606 spec->mixers[1] = cxt5047_hp_only_mixers; 1607 codec->patch_ops.unsol_event = cxt5047_hp_unsol_event; 1608 codec->patch_ops.init = cxt5047_hp_init; 1609 break; 1610 case CXT5047_LAPTOP_EAPD: 1611 spec->input_mux = &cxt5047_toshiba_capture_source; 1612 spec->num_mixers = 2; 1613 spec->mixers[1] = cxt5047_hp_spk_mixers; 1614 spec->num_init_verbs = 2; 1615 spec->init_verbs[1] = cxt5047_toshiba_init_verbs; 1616 codec->patch_ops.unsol_event = cxt5047_hp_unsol_event; 1617 break; 1618 #ifdef CONFIG_SND_DEBUG 1619 case CXT5047_TEST: 1620 spec->input_mux = &cxt5047_test_capture_source; 1621 spec->mixers[0] = cxt5047_test_mixer; 1622 spec->init_verbs[0] = cxt5047_test_init_verbs; 1623 codec->patch_ops.unsol_event = cxt5047_hp_unsol_event; 1624 #endif 1625 } 1626 spec->vmaster_nid = 0x13; 1627 1628 switch (codec->subsystem_id >> 16) { 1629 case 0x103c: 1630 /* HP laptops have really bad sound over 0 dB on NID 0x10. 1631 * Fix max PCM level to 0 dB (originally it has 0x1e steps 1632 * with 0 dB offset 0x17) 1633 */ 1634 snd_hda_override_amp_caps(codec, 0x10, HDA_INPUT, 1635 (0x17 << AC_AMPCAP_OFFSET_SHIFT) | 1636 (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) | 1637 (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) | 1638 (1 << AC_AMPCAP_MUTE_SHIFT)); 1639 break; 1640 } 1641 1642 return 0; 1643 } 1644 1645 /* Conexant 5051 specific */ 1646 static const hda_nid_t cxt5051_dac_nids[1] = { 0x10 }; 1647 static const hda_nid_t cxt5051_adc_nids[2] = { 0x14, 0x15 }; 1648 1649 static const struct hda_channel_mode cxt5051_modes[1] = { 1650 { 2, NULL }, 1651 }; 1652 1653 static void cxt5051_update_speaker(struct hda_codec *codec) 1654 { 1655 struct conexant_spec *spec = codec->spec; 1656 unsigned int pinctl; 1657 /* headphone pin */ 1658 pinctl = (spec->hp_present && spec->cur_eapd) ? PIN_HP : 0; 1659 snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 1660 pinctl); 1661 /* speaker pin */ 1662 pinctl = (!spec->hp_present && spec->cur_eapd) ? PIN_OUT : 0; 1663 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 1664 pinctl); 1665 /* on ideapad there is an aditional speaker (subwoofer) to mute */ 1666 if (spec->ideapad) 1667 snd_hda_codec_write(codec, 0x1b, 0, 1668 AC_VERB_SET_PIN_WIDGET_CONTROL, 1669 pinctl); 1670 } 1671 1672 /* turn on/off EAPD (+ mute HP) as a master switch */ 1673 static int cxt5051_hp_master_sw_put(struct snd_kcontrol *kcontrol, 1674 struct snd_ctl_elem_value *ucontrol) 1675 { 1676 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 1677 1678 if (!cxt_eapd_put(kcontrol, ucontrol)) 1679 return 0; 1680 cxt5051_update_speaker(codec); 1681 return 1; 1682 } 1683 1684 /* toggle input of built-in and mic jack appropriately */ 1685 static void cxt5051_portb_automic(struct hda_codec *codec) 1686 { 1687 struct conexant_spec *spec = codec->spec; 1688 unsigned int present; 1689 1690 if (!(spec->auto_mic & AUTO_MIC_PORTB)) 1691 return; 1692 present = snd_hda_jack_detect(codec, 0x17); 1693 snd_hda_codec_write(codec, 0x14, 0, 1694 AC_VERB_SET_CONNECT_SEL, 1695 present ? 0x01 : 0x00); 1696 } 1697 1698 /* switch the current ADC according to the jack state */ 1699 static void cxt5051_portc_automic(struct hda_codec *codec) 1700 { 1701 struct conexant_spec *spec = codec->spec; 1702 unsigned int present; 1703 hda_nid_t new_adc; 1704 1705 if (!(spec->auto_mic & AUTO_MIC_PORTC)) 1706 return; 1707 present = snd_hda_jack_detect(codec, 0x18); 1708 if (present) 1709 spec->cur_adc_idx = 1; 1710 else 1711 spec->cur_adc_idx = 0; 1712 new_adc = spec->adc_nids[spec->cur_adc_idx]; 1713 if (spec->cur_adc && spec->cur_adc != new_adc) { 1714 /* stream is running, let's swap the current ADC */ 1715 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1); 1716 spec->cur_adc = new_adc; 1717 snd_hda_codec_setup_stream(codec, new_adc, 1718 spec->cur_adc_stream_tag, 0, 1719 spec->cur_adc_format); 1720 } 1721 } 1722 1723 /* mute internal speaker if HP is plugged */ 1724 static void cxt5051_hp_automute(struct hda_codec *codec) 1725 { 1726 struct conexant_spec *spec = codec->spec; 1727 1728 spec->hp_present = snd_hda_jack_detect(codec, 0x16); 1729 cxt5051_update_speaker(codec); 1730 } 1731 1732 /* unsolicited event for HP jack sensing */ 1733 static void cxt5051_hp_unsol_event(struct hda_codec *codec, 1734 unsigned int res) 1735 { 1736 int nid = (res & AC_UNSOL_RES_SUBTAG) >> 20; 1737 switch (res >> 26) { 1738 case CONEXANT_HP_EVENT: 1739 cxt5051_hp_automute(codec); 1740 break; 1741 case CXT5051_PORTB_EVENT: 1742 cxt5051_portb_automic(codec); 1743 break; 1744 case CXT5051_PORTC_EVENT: 1745 cxt5051_portc_automic(codec); 1746 break; 1747 } 1748 snd_hda_input_jack_report(codec, nid); 1749 } 1750 1751 static const struct snd_kcontrol_new cxt5051_playback_mixers[] = { 1752 HDA_CODEC_VOLUME("Master Playback Volume", 0x10, 0x00, HDA_OUTPUT), 1753 { 1754 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1755 .name = "Master Playback Switch", 1756 .info = cxt_eapd_info, 1757 .get = cxt_eapd_get, 1758 .put = cxt5051_hp_master_sw_put, 1759 .private_value = 0x1a, 1760 }, 1761 {} 1762 }; 1763 1764 static const struct snd_kcontrol_new cxt5051_capture_mixers[] = { 1765 HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT), 1766 HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT), 1767 HDA_CODEC_VOLUME("Mic Volume", 0x14, 0x01, HDA_INPUT), 1768 HDA_CODEC_MUTE("Mic Switch", 0x14, 0x01, HDA_INPUT), 1769 HDA_CODEC_VOLUME("Docking Mic Volume", 0x15, 0x00, HDA_INPUT), 1770 HDA_CODEC_MUTE("Docking Mic Switch", 0x15, 0x00, HDA_INPUT), 1771 {} 1772 }; 1773 1774 static const struct snd_kcontrol_new cxt5051_hp_mixers[] = { 1775 HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT), 1776 HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT), 1777 HDA_CODEC_VOLUME("Mic Volume", 0x15, 0x00, HDA_INPUT), 1778 HDA_CODEC_MUTE("Mic Switch", 0x15, 0x00, HDA_INPUT), 1779 {} 1780 }; 1781 1782 static const struct snd_kcontrol_new cxt5051_hp_dv6736_mixers[] = { 1783 HDA_CODEC_VOLUME("Capture Volume", 0x14, 0x00, HDA_INPUT), 1784 HDA_CODEC_MUTE("Capture Switch", 0x14, 0x00, HDA_INPUT), 1785 {} 1786 }; 1787 1788 static const struct snd_kcontrol_new cxt5051_f700_mixers[] = { 1789 HDA_CODEC_VOLUME("Capture Volume", 0x14, 0x01, HDA_INPUT), 1790 HDA_CODEC_MUTE("Capture Switch", 0x14, 0x01, HDA_INPUT), 1791 {} 1792 }; 1793 1794 static const struct snd_kcontrol_new cxt5051_toshiba_mixers[] = { 1795 HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT), 1796 HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT), 1797 HDA_CODEC_VOLUME("Mic Volume", 0x14, 0x01, HDA_INPUT), 1798 HDA_CODEC_MUTE("Mic Switch", 0x14, 0x01, HDA_INPUT), 1799 {} 1800 }; 1801 1802 static const struct hda_verb cxt5051_init_verbs[] = { 1803 /* Line in, Mic */ 1804 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03}, 1805 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1806 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03}, 1807 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1808 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1809 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03}, 1810 /* SPK */ 1811 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1812 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00}, 1813 /* HP, Amp */ 1814 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1815 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, 1816 /* DAC1 */ 1817 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1818 /* Record selector: Internal mic */ 1819 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44}, 1820 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44}, 1821 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44}, 1822 /* SPDIF route: PCM */ 1823 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1824 {0x1c, AC_VERB_SET_CONNECT_SEL, 0x0}, 1825 /* EAPD */ 1826 {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */ 1827 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT}, 1828 { } /* end */ 1829 }; 1830 1831 static const struct hda_verb cxt5051_hp_dv6736_init_verbs[] = { 1832 /* Line in, Mic */ 1833 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03}, 1834 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1835 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0}, 1836 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0}, 1837 /* SPK */ 1838 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1839 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00}, 1840 /* HP, Amp */ 1841 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1842 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, 1843 /* DAC1 */ 1844 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1845 /* Record selector: Internal mic */ 1846 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44}, 1847 {0x14, AC_VERB_SET_CONNECT_SEL, 0x1}, 1848 /* SPDIF route: PCM */ 1849 {0x1c, AC_VERB_SET_CONNECT_SEL, 0x0}, 1850 /* EAPD */ 1851 {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */ 1852 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT}, 1853 { } /* end */ 1854 }; 1855 1856 static const struct hda_verb cxt5051_lenovo_x200_init_verbs[] = { 1857 /* Line in, Mic */ 1858 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03}, 1859 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1860 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03}, 1861 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1862 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1863 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03}, 1864 /* SPK */ 1865 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1866 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00}, 1867 /* HP, Amp */ 1868 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1869 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, 1870 /* Docking HP */ 1871 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1872 {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, 1873 /* DAC1 */ 1874 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1875 /* Record selector: Internal mic */ 1876 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44}, 1877 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44}, 1878 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44}, 1879 /* SPDIF route: PCM */ 1880 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* needed for W500 Advanced Mini Dock 250410 */ 1881 {0x1c, AC_VERB_SET_CONNECT_SEL, 0x0}, 1882 /* EAPD */ 1883 {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */ 1884 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT}, 1885 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT}, 1886 { } /* end */ 1887 }; 1888 1889 static const struct hda_verb cxt5051_f700_init_verbs[] = { 1890 /* Line in, Mic */ 1891 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03}, 1892 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1893 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0}, 1894 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0}, 1895 /* SPK */ 1896 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1897 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00}, 1898 /* HP, Amp */ 1899 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1900 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, 1901 /* DAC1 */ 1902 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1903 /* Record selector: Internal mic */ 1904 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44}, 1905 {0x14, AC_VERB_SET_CONNECT_SEL, 0x1}, 1906 /* SPDIF route: PCM */ 1907 {0x1c, AC_VERB_SET_CONNECT_SEL, 0x0}, 1908 /* EAPD */ 1909 {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */ 1910 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT}, 1911 { } /* end */ 1912 }; 1913 1914 static void cxt5051_init_mic_port(struct hda_codec *codec, hda_nid_t nid, 1915 unsigned int event) 1916 { 1917 snd_hda_codec_write(codec, nid, 0, 1918 AC_VERB_SET_UNSOLICITED_ENABLE, 1919 AC_USRSP_EN | event); 1920 snd_hda_input_jack_add(codec, nid, SND_JACK_MICROPHONE, NULL); 1921 snd_hda_input_jack_report(codec, nid); 1922 } 1923 1924 static const struct hda_verb cxt5051_ideapad_init_verbs[] = { 1925 /* Subwoofer */ 1926 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1927 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 1928 { } /* end */ 1929 }; 1930 1931 /* initialize jack-sensing, too */ 1932 static int cxt5051_init(struct hda_codec *codec) 1933 { 1934 struct conexant_spec *spec = codec->spec; 1935 1936 conexant_init(codec); 1937 conexant_init_jacks(codec); 1938 1939 if (spec->auto_mic & AUTO_MIC_PORTB) 1940 cxt5051_init_mic_port(codec, 0x17, CXT5051_PORTB_EVENT); 1941 if (spec->auto_mic & AUTO_MIC_PORTC) 1942 cxt5051_init_mic_port(codec, 0x18, CXT5051_PORTC_EVENT); 1943 1944 if (codec->patch_ops.unsol_event) { 1945 cxt5051_hp_automute(codec); 1946 cxt5051_portb_automic(codec); 1947 cxt5051_portc_automic(codec); 1948 } 1949 return 0; 1950 } 1951 1952 1953 enum { 1954 CXT5051_LAPTOP, /* Laptops w/ EAPD support */ 1955 CXT5051_HP, /* no docking */ 1956 CXT5051_HP_DV6736, /* HP without mic switch */ 1957 CXT5051_LENOVO_X200, /* Lenovo X200 laptop, also used for Advanced Mini Dock 250410 */ 1958 CXT5051_F700, /* HP Compaq Presario F700 */ 1959 CXT5051_TOSHIBA, /* Toshiba M300 & co */ 1960 CXT5051_IDEAPAD, /* Lenovo IdeaPad Y430 */ 1961 CXT5051_AUTO, /* auto-parser */ 1962 CXT5051_MODELS 1963 }; 1964 1965 static const char *const cxt5051_models[CXT5051_MODELS] = { 1966 [CXT5051_LAPTOP] = "laptop", 1967 [CXT5051_HP] = "hp", 1968 [CXT5051_HP_DV6736] = "hp-dv6736", 1969 [CXT5051_LENOVO_X200] = "lenovo-x200", 1970 [CXT5051_F700] = "hp-700", 1971 [CXT5051_TOSHIBA] = "toshiba", 1972 [CXT5051_IDEAPAD] = "ideapad", 1973 [CXT5051_AUTO] = "auto", 1974 }; 1975 1976 static const struct snd_pci_quirk cxt5051_cfg_tbl[] = { 1977 SND_PCI_QUIRK(0x103c, 0x30cf, "HP DV6736", CXT5051_HP_DV6736), 1978 SND_PCI_QUIRK(0x103c, 0x360b, "Compaq Presario CQ60", CXT5051_HP), 1979 SND_PCI_QUIRK(0x103c, 0x30ea, "Compaq Presario F700", CXT5051_F700), 1980 SND_PCI_QUIRK(0x1179, 0xff50, "Toshiba M30x", CXT5051_TOSHIBA), 1981 SND_PCI_QUIRK(0x14f1, 0x0101, "Conexant Reference board", 1982 CXT5051_LAPTOP), 1983 SND_PCI_QUIRK(0x14f1, 0x5051, "HP Spartan 1.1", CXT5051_HP), 1984 SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo X200", CXT5051_LENOVO_X200), 1985 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo IdeaPad", CXT5051_IDEAPAD), 1986 {} 1987 }; 1988 1989 static int patch_cxt5051(struct hda_codec *codec) 1990 { 1991 struct conexant_spec *spec; 1992 int board_config; 1993 1994 board_config = snd_hda_check_board_config(codec, CXT5051_MODELS, 1995 cxt5051_models, 1996 cxt5051_cfg_tbl); 1997 if (board_config < 0) 1998 board_config = CXT5051_AUTO; /* model=auto as default */ 1999 if (board_config == CXT5051_AUTO) 2000 return patch_conexant_auto(codec); 2001 2002 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 2003 if (!spec) 2004 return -ENOMEM; 2005 codec->spec = spec; 2006 codec->pin_amp_workaround = 1; 2007 2008 codec->patch_ops = conexant_patch_ops; 2009 codec->patch_ops.init = cxt5051_init; 2010 2011 spec->multiout.max_channels = 2; 2012 spec->multiout.num_dacs = ARRAY_SIZE(cxt5051_dac_nids); 2013 spec->multiout.dac_nids = cxt5051_dac_nids; 2014 spec->multiout.dig_out_nid = CXT5051_SPDIF_OUT; 2015 spec->num_adc_nids = 1; /* not 2; via auto-mic switch */ 2016 spec->adc_nids = cxt5051_adc_nids; 2017 spec->num_mixers = 2; 2018 spec->mixers[0] = cxt5051_capture_mixers; 2019 spec->mixers[1] = cxt5051_playback_mixers; 2020 spec->num_init_verbs = 1; 2021 spec->init_verbs[0] = cxt5051_init_verbs; 2022 spec->spdif_route = 0; 2023 spec->num_channel_mode = ARRAY_SIZE(cxt5051_modes); 2024 spec->channel_mode = cxt5051_modes; 2025 spec->cur_adc = 0; 2026 spec->cur_adc_idx = 0; 2027 2028 set_beep_amp(spec, 0x13, 0, HDA_OUTPUT); 2029 2030 codec->patch_ops.unsol_event = cxt5051_hp_unsol_event; 2031 2032 spec->auto_mic = AUTO_MIC_PORTB | AUTO_MIC_PORTC; 2033 switch (board_config) { 2034 case CXT5051_HP: 2035 spec->mixers[0] = cxt5051_hp_mixers; 2036 break; 2037 case CXT5051_HP_DV6736: 2038 spec->init_verbs[0] = cxt5051_hp_dv6736_init_verbs; 2039 spec->mixers[0] = cxt5051_hp_dv6736_mixers; 2040 spec->auto_mic = 0; 2041 break; 2042 case CXT5051_LENOVO_X200: 2043 spec->init_verbs[0] = cxt5051_lenovo_x200_init_verbs; 2044 /* Thinkpad X301 does not have S/PDIF wired and no ability 2045 to use a docking station. */ 2046 if (codec->subsystem_id == 0x17aa211f) 2047 spec->multiout.dig_out_nid = 0; 2048 break; 2049 case CXT5051_F700: 2050 spec->init_verbs[0] = cxt5051_f700_init_verbs; 2051 spec->mixers[0] = cxt5051_f700_mixers; 2052 spec->auto_mic = 0; 2053 break; 2054 case CXT5051_TOSHIBA: 2055 spec->mixers[0] = cxt5051_toshiba_mixers; 2056 spec->auto_mic = AUTO_MIC_PORTB; 2057 break; 2058 case CXT5051_IDEAPAD: 2059 spec->init_verbs[spec->num_init_verbs++] = 2060 cxt5051_ideapad_init_verbs; 2061 spec->ideapad = 1; 2062 break; 2063 } 2064 2065 if (spec->beep_amp) 2066 snd_hda_attach_beep_device(codec, spec->beep_amp); 2067 2068 return 0; 2069 } 2070 2071 /* Conexant 5066 specific */ 2072 2073 static const hda_nid_t cxt5066_dac_nids[1] = { 0x10 }; 2074 static const hda_nid_t cxt5066_adc_nids[3] = { 0x14, 0x15, 0x16 }; 2075 static const hda_nid_t cxt5066_capsrc_nids[1] = { 0x17 }; 2076 static const hda_nid_t cxt5066_digout_pin_nids[2] = { 0x20, 0x22 }; 2077 2078 /* OLPC's microphone port is DC coupled for use with external sensors, 2079 * therefore we use a 50% mic bias in order to center the input signal with 2080 * the DC input range of the codec. */ 2081 #define CXT5066_OLPC_EXT_MIC_BIAS PIN_VREF50 2082 2083 static const struct hda_channel_mode cxt5066_modes[1] = { 2084 { 2, NULL }, 2085 }; 2086 2087 #define HP_PRESENT_PORT_A (1 << 0) 2088 #define HP_PRESENT_PORT_D (1 << 1) 2089 #define hp_port_a_present(spec) ((spec)->hp_present & HP_PRESENT_PORT_A) 2090 #define hp_port_d_present(spec) ((spec)->hp_present & HP_PRESENT_PORT_D) 2091 2092 static void cxt5066_update_speaker(struct hda_codec *codec) 2093 { 2094 struct conexant_spec *spec = codec->spec; 2095 unsigned int pinctl; 2096 2097 snd_printdd("CXT5066: update speaker, hp_present=%d, cur_eapd=%d\n", 2098 spec->hp_present, spec->cur_eapd); 2099 2100 /* Port A (HP) */ 2101 pinctl = (hp_port_a_present(spec) && spec->cur_eapd) ? PIN_HP : 0; 2102 snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 2103 pinctl); 2104 2105 /* Port D (HP/LO) */ 2106 pinctl = spec->cur_eapd ? spec->port_d_mode : 0; 2107 if (spec->dell_automute || spec->thinkpad) { 2108 /* Mute if Port A is connected */ 2109 if (hp_port_a_present(spec)) 2110 pinctl = 0; 2111 } else { 2112 /* Thinkpad/Dell doesn't give pin-D status */ 2113 if (!hp_port_d_present(spec)) 2114 pinctl = 0; 2115 } 2116 snd_hda_codec_write(codec, 0x1c, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 2117 pinctl); 2118 2119 /* CLASS_D AMP */ 2120 pinctl = (!spec->hp_present && spec->cur_eapd) ? PIN_OUT : 0; 2121 snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 2122 pinctl); 2123 } 2124 2125 /* turn on/off EAPD (+ mute HP) as a master switch */ 2126 static int cxt5066_hp_master_sw_put(struct snd_kcontrol *kcontrol, 2127 struct snd_ctl_elem_value *ucontrol) 2128 { 2129 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2130 2131 if (!cxt_eapd_put(kcontrol, ucontrol)) 2132 return 0; 2133 2134 cxt5066_update_speaker(codec); 2135 return 1; 2136 } 2137 2138 static const struct hda_input_mux cxt5066_olpc_dc_bias = { 2139 .num_items = 3, 2140 .items = { 2141 { "Off", PIN_IN }, 2142 { "50%", PIN_VREF50 }, 2143 { "80%", PIN_VREF80 }, 2144 }, 2145 }; 2146 2147 static int cxt5066_set_olpc_dc_bias(struct hda_codec *codec) 2148 { 2149 struct conexant_spec *spec = codec->spec; 2150 /* Even though port F is the DC input, the bias is controlled on port B. 2151 * we also leave that port as an active input (but unselected) in DC mode 2152 * just in case that is necessary to make the bias setting take effect. */ 2153 return snd_hda_codec_write_cache(codec, 0x1a, 0, 2154 AC_VERB_SET_PIN_WIDGET_CONTROL, 2155 cxt5066_olpc_dc_bias.items[spec->dc_input_bias].index); 2156 } 2157 2158 /* OLPC defers mic widget control until when capture is started because the 2159 * microphone LED comes on as soon as these settings are put in place. if we 2160 * did this before recording, it would give the false indication that recording 2161 * is happening when it is not. */ 2162 static void cxt5066_olpc_select_mic(struct hda_codec *codec) 2163 { 2164 struct conexant_spec *spec = codec->spec; 2165 if (!spec->recording) 2166 return; 2167 2168 if (spec->dc_enable) { 2169 /* in DC mode we ignore presence detection and just use the jack 2170 * through our special DC port */ 2171 const struct hda_verb enable_dc_mode[] = { 2172 /* disble internal mic, port C */ 2173 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 2174 2175 /* enable DC capture, port F */ 2176 {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2177 {}, 2178 }; 2179 2180 snd_hda_sequence_write(codec, enable_dc_mode); 2181 /* port B input disabled (and bias set) through the following call */ 2182 cxt5066_set_olpc_dc_bias(codec); 2183 return; 2184 } 2185 2186 /* disable DC (port F) */ 2187 snd_hda_codec_write(codec, 0x1e, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 0); 2188 2189 /* external mic, port B */ 2190 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 2191 spec->ext_mic_present ? CXT5066_OLPC_EXT_MIC_BIAS : 0); 2192 2193 /* internal mic, port C */ 2194 snd_hda_codec_write(codec, 0x1b, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 2195 spec->ext_mic_present ? 0 : PIN_VREF80); 2196 } 2197 2198 /* toggle input of built-in and mic jack appropriately */ 2199 static void cxt5066_olpc_automic(struct hda_codec *codec) 2200 { 2201 struct conexant_spec *spec = codec->spec; 2202 unsigned int present; 2203 2204 if (spec->dc_enable) /* don't do presence detection in DC mode */ 2205 return; 2206 2207 present = snd_hda_codec_read(codec, 0x1a, 0, 2208 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 2209 if (present) 2210 snd_printdd("CXT5066: external microphone detected\n"); 2211 else 2212 snd_printdd("CXT5066: external microphone absent\n"); 2213 2214 snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_CONNECT_SEL, 2215 present ? 0 : 1); 2216 spec->ext_mic_present = !!present; 2217 2218 cxt5066_olpc_select_mic(codec); 2219 } 2220 2221 /* toggle input of built-in digital mic and mic jack appropriately */ 2222 static void cxt5066_vostro_automic(struct hda_codec *codec) 2223 { 2224 unsigned int present; 2225 2226 struct hda_verb ext_mic_present[] = { 2227 /* enable external mic, port B */ 2228 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2229 2230 /* switch to external mic input */ 2231 {0x17, AC_VERB_SET_CONNECT_SEL, 0}, 2232 {0x14, AC_VERB_SET_CONNECT_SEL, 0}, 2233 2234 /* disable internal digital mic */ 2235 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 2236 {} 2237 }; 2238 static const struct hda_verb ext_mic_absent[] = { 2239 /* enable internal mic, port C */ 2240 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2241 2242 /* switch to internal mic input */ 2243 {0x14, AC_VERB_SET_CONNECT_SEL, 2}, 2244 2245 /* disable external mic, port B */ 2246 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 2247 {} 2248 }; 2249 2250 present = snd_hda_jack_detect(codec, 0x1a); 2251 if (present) { 2252 snd_printdd("CXT5066: external microphone detected\n"); 2253 snd_hda_sequence_write(codec, ext_mic_present); 2254 } else { 2255 snd_printdd("CXT5066: external microphone absent\n"); 2256 snd_hda_sequence_write(codec, ext_mic_absent); 2257 } 2258 } 2259 2260 /* toggle input of built-in digital mic and mic jack appropriately */ 2261 static void cxt5066_ideapad_automic(struct hda_codec *codec) 2262 { 2263 unsigned int present; 2264 2265 struct hda_verb ext_mic_present[] = { 2266 {0x14, AC_VERB_SET_CONNECT_SEL, 0}, 2267 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2268 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 2269 {} 2270 }; 2271 static const struct hda_verb ext_mic_absent[] = { 2272 {0x14, AC_VERB_SET_CONNECT_SEL, 2}, 2273 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2274 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 2275 {} 2276 }; 2277 2278 present = snd_hda_jack_detect(codec, 0x1b); 2279 if (present) { 2280 snd_printdd("CXT5066: external microphone detected\n"); 2281 snd_hda_sequence_write(codec, ext_mic_present); 2282 } else { 2283 snd_printdd("CXT5066: external microphone absent\n"); 2284 snd_hda_sequence_write(codec, ext_mic_absent); 2285 } 2286 } 2287 2288 2289 /* toggle input of built-in digital mic and mic jack appropriately */ 2290 static void cxt5066_asus_automic(struct hda_codec *codec) 2291 { 2292 unsigned int present; 2293 2294 present = snd_hda_jack_detect(codec, 0x1b); 2295 snd_printdd("CXT5066: external microphone present=%d\n", present); 2296 snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_CONNECT_SEL, 2297 present ? 1 : 0); 2298 } 2299 2300 2301 /* toggle input of built-in digital mic and mic jack appropriately */ 2302 static void cxt5066_hp_laptop_automic(struct hda_codec *codec) 2303 { 2304 unsigned int present; 2305 2306 present = snd_hda_jack_detect(codec, 0x1b); 2307 snd_printdd("CXT5066: external microphone present=%d\n", present); 2308 snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_CONNECT_SEL, 2309 present ? 1 : 3); 2310 } 2311 2312 2313 /* toggle input of built-in digital mic and mic jack appropriately 2314 order is: external mic -> dock mic -> interal mic */ 2315 static void cxt5066_thinkpad_automic(struct hda_codec *codec) 2316 { 2317 unsigned int ext_present, dock_present; 2318 2319 static const struct hda_verb ext_mic_present[] = { 2320 {0x14, AC_VERB_SET_CONNECT_SEL, 0}, 2321 {0x17, AC_VERB_SET_CONNECT_SEL, 1}, 2322 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2323 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 2324 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 2325 {} 2326 }; 2327 static const struct hda_verb dock_mic_present[] = { 2328 {0x14, AC_VERB_SET_CONNECT_SEL, 0}, 2329 {0x17, AC_VERB_SET_CONNECT_SEL, 0}, 2330 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2331 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 2332 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 2333 {} 2334 }; 2335 static const struct hda_verb ext_mic_absent[] = { 2336 {0x14, AC_VERB_SET_CONNECT_SEL, 2}, 2337 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2338 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 2339 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 2340 {} 2341 }; 2342 2343 ext_present = snd_hda_jack_detect(codec, 0x1b); 2344 dock_present = snd_hda_jack_detect(codec, 0x1a); 2345 if (ext_present) { 2346 snd_printdd("CXT5066: external microphone detected\n"); 2347 snd_hda_sequence_write(codec, ext_mic_present); 2348 } else if (dock_present) { 2349 snd_printdd("CXT5066: dock microphone detected\n"); 2350 snd_hda_sequence_write(codec, dock_mic_present); 2351 } else { 2352 snd_printdd("CXT5066: external microphone absent\n"); 2353 snd_hda_sequence_write(codec, ext_mic_absent); 2354 } 2355 } 2356 2357 /* mute internal speaker if HP is plugged */ 2358 static void cxt5066_hp_automute(struct hda_codec *codec) 2359 { 2360 struct conexant_spec *spec = codec->spec; 2361 unsigned int portA, portD; 2362 2363 /* Port A */ 2364 portA = snd_hda_jack_detect(codec, 0x19); 2365 2366 /* Port D */ 2367 portD = snd_hda_jack_detect(codec, 0x1c); 2368 2369 spec->hp_present = portA ? HP_PRESENT_PORT_A : 0; 2370 spec->hp_present |= portD ? HP_PRESENT_PORT_D : 0; 2371 snd_printdd("CXT5066: hp automute portA=%x portD=%x present=%d\n", 2372 portA, portD, spec->hp_present); 2373 cxt5066_update_speaker(codec); 2374 } 2375 2376 /* Dispatch the right mic autoswitch function */ 2377 static void cxt5066_automic(struct hda_codec *codec) 2378 { 2379 struct conexant_spec *spec = codec->spec; 2380 2381 if (spec->dell_vostro) 2382 cxt5066_vostro_automic(codec); 2383 else if (spec->ideapad) 2384 cxt5066_ideapad_automic(codec); 2385 else if (spec->thinkpad) 2386 cxt5066_thinkpad_automic(codec); 2387 else if (spec->hp_laptop) 2388 cxt5066_hp_laptop_automic(codec); 2389 else if (spec->asus) 2390 cxt5066_asus_automic(codec); 2391 } 2392 2393 /* unsolicited event for jack sensing */ 2394 static void cxt5066_olpc_unsol_event(struct hda_codec *codec, unsigned int res) 2395 { 2396 struct conexant_spec *spec = codec->spec; 2397 snd_printdd("CXT5066: unsol event %x (%x)\n", res, res >> 26); 2398 switch (res >> 26) { 2399 case CONEXANT_HP_EVENT: 2400 cxt5066_hp_automute(codec); 2401 break; 2402 case CONEXANT_MIC_EVENT: 2403 /* ignore mic events in DC mode; we're always using the jack */ 2404 if (!spec->dc_enable) 2405 cxt5066_olpc_automic(codec); 2406 break; 2407 } 2408 } 2409 2410 /* unsolicited event for jack sensing */ 2411 static void cxt5066_unsol_event(struct hda_codec *codec, unsigned int res) 2412 { 2413 snd_printdd("CXT5066: unsol event %x (%x)\n", res, res >> 26); 2414 switch (res >> 26) { 2415 case CONEXANT_HP_EVENT: 2416 cxt5066_hp_automute(codec); 2417 break; 2418 case CONEXANT_MIC_EVENT: 2419 cxt5066_automic(codec); 2420 break; 2421 } 2422 } 2423 2424 2425 static const struct hda_input_mux cxt5066_analog_mic_boost = { 2426 .num_items = 5, 2427 .items = { 2428 { "0dB", 0 }, 2429 { "10dB", 1 }, 2430 { "20dB", 2 }, 2431 { "30dB", 3 }, 2432 { "40dB", 4 }, 2433 }, 2434 }; 2435 2436 static void cxt5066_set_mic_boost(struct hda_codec *codec) 2437 { 2438 struct conexant_spec *spec = codec->spec; 2439 snd_hda_codec_write_cache(codec, 0x17, 0, 2440 AC_VERB_SET_AMP_GAIN_MUTE, 2441 AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT | AC_AMP_SET_OUTPUT | 2442 cxt5066_analog_mic_boost.items[spec->mic_boost].index); 2443 if (spec->ideapad || spec->thinkpad) { 2444 /* adjust the internal mic as well...it is not through 0x17 */ 2445 snd_hda_codec_write_cache(codec, 0x23, 0, 2446 AC_VERB_SET_AMP_GAIN_MUTE, 2447 AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT | AC_AMP_SET_INPUT | 2448 cxt5066_analog_mic_boost. 2449 items[spec->mic_boost].index); 2450 } 2451 } 2452 2453 static int cxt5066_mic_boost_mux_enum_info(struct snd_kcontrol *kcontrol, 2454 struct snd_ctl_elem_info *uinfo) 2455 { 2456 return snd_hda_input_mux_info(&cxt5066_analog_mic_boost, uinfo); 2457 } 2458 2459 static int cxt5066_mic_boost_mux_enum_get(struct snd_kcontrol *kcontrol, 2460 struct snd_ctl_elem_value *ucontrol) 2461 { 2462 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2463 struct conexant_spec *spec = codec->spec; 2464 ucontrol->value.enumerated.item[0] = spec->mic_boost; 2465 return 0; 2466 } 2467 2468 static int cxt5066_mic_boost_mux_enum_put(struct snd_kcontrol *kcontrol, 2469 struct snd_ctl_elem_value *ucontrol) 2470 { 2471 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2472 struct conexant_spec *spec = codec->spec; 2473 const struct hda_input_mux *imux = &cxt5066_analog_mic_boost; 2474 unsigned int idx; 2475 idx = ucontrol->value.enumerated.item[0]; 2476 if (idx >= imux->num_items) 2477 idx = imux->num_items - 1; 2478 2479 spec->mic_boost = idx; 2480 if (!spec->dc_enable) 2481 cxt5066_set_mic_boost(codec); 2482 return 1; 2483 } 2484 2485 static void cxt5066_enable_dc(struct hda_codec *codec) 2486 { 2487 const struct hda_verb enable_dc_mode[] = { 2488 /* disable gain */ 2489 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2490 2491 /* switch to DC input */ 2492 {0x17, AC_VERB_SET_CONNECT_SEL, 3}, 2493 {} 2494 }; 2495 2496 /* configure as input source */ 2497 snd_hda_sequence_write(codec, enable_dc_mode); 2498 cxt5066_olpc_select_mic(codec); /* also sets configured bias */ 2499 } 2500 2501 static void cxt5066_disable_dc(struct hda_codec *codec) 2502 { 2503 /* reconfigure input source */ 2504 cxt5066_set_mic_boost(codec); 2505 /* automic also selects the right mic if we're recording */ 2506 cxt5066_olpc_automic(codec); 2507 } 2508 2509 static int cxt5066_olpc_dc_get(struct snd_kcontrol *kcontrol, 2510 struct snd_ctl_elem_value *ucontrol) 2511 { 2512 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2513 struct conexant_spec *spec = codec->spec; 2514 ucontrol->value.integer.value[0] = spec->dc_enable; 2515 return 0; 2516 } 2517 2518 static int cxt5066_olpc_dc_put(struct snd_kcontrol *kcontrol, 2519 struct snd_ctl_elem_value *ucontrol) 2520 { 2521 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2522 struct conexant_spec *spec = codec->spec; 2523 int dc_enable = !!ucontrol->value.integer.value[0]; 2524 2525 if (dc_enable == spec->dc_enable) 2526 return 0; 2527 2528 spec->dc_enable = dc_enable; 2529 if (dc_enable) 2530 cxt5066_enable_dc(codec); 2531 else 2532 cxt5066_disable_dc(codec); 2533 2534 return 1; 2535 } 2536 2537 static int cxt5066_olpc_dc_bias_enum_info(struct snd_kcontrol *kcontrol, 2538 struct snd_ctl_elem_info *uinfo) 2539 { 2540 return snd_hda_input_mux_info(&cxt5066_olpc_dc_bias, uinfo); 2541 } 2542 2543 static int cxt5066_olpc_dc_bias_enum_get(struct snd_kcontrol *kcontrol, 2544 struct snd_ctl_elem_value *ucontrol) 2545 { 2546 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2547 struct conexant_spec *spec = codec->spec; 2548 ucontrol->value.enumerated.item[0] = spec->dc_input_bias; 2549 return 0; 2550 } 2551 2552 static int cxt5066_olpc_dc_bias_enum_put(struct snd_kcontrol *kcontrol, 2553 struct snd_ctl_elem_value *ucontrol) 2554 { 2555 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2556 struct conexant_spec *spec = codec->spec; 2557 const struct hda_input_mux *imux = &cxt5066_analog_mic_boost; 2558 unsigned int idx; 2559 2560 idx = ucontrol->value.enumerated.item[0]; 2561 if (idx >= imux->num_items) 2562 idx = imux->num_items - 1; 2563 2564 spec->dc_input_bias = idx; 2565 if (spec->dc_enable) 2566 cxt5066_set_olpc_dc_bias(codec); 2567 return 1; 2568 } 2569 2570 static void cxt5066_olpc_capture_prepare(struct hda_codec *codec) 2571 { 2572 struct conexant_spec *spec = codec->spec; 2573 /* mark as recording and configure the microphone widget so that the 2574 * recording LED comes on. */ 2575 spec->recording = 1; 2576 cxt5066_olpc_select_mic(codec); 2577 } 2578 2579 static void cxt5066_olpc_capture_cleanup(struct hda_codec *codec) 2580 { 2581 struct conexant_spec *spec = codec->spec; 2582 const struct hda_verb disable_mics[] = { 2583 /* disable external mic, port B */ 2584 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 2585 2586 /* disble internal mic, port C */ 2587 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 2588 2589 /* disable DC capture, port F */ 2590 {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 2591 {}, 2592 }; 2593 2594 snd_hda_sequence_write(codec, disable_mics); 2595 spec->recording = 0; 2596 } 2597 2598 static void conexant_check_dig_outs(struct hda_codec *codec, 2599 const hda_nid_t *dig_pins, 2600 int num_pins) 2601 { 2602 struct conexant_spec *spec = codec->spec; 2603 hda_nid_t *nid_loc = &spec->multiout.dig_out_nid; 2604 int i; 2605 2606 for (i = 0; i < num_pins; i++, dig_pins++) { 2607 unsigned int cfg = snd_hda_codec_get_pincfg(codec, *dig_pins); 2608 if (get_defcfg_connect(cfg) == AC_JACK_PORT_NONE) 2609 continue; 2610 if (snd_hda_get_connections(codec, *dig_pins, nid_loc, 1) != 1) 2611 continue; 2612 if (spec->slave_dig_outs[0]) 2613 nid_loc++; 2614 else 2615 nid_loc = spec->slave_dig_outs; 2616 } 2617 } 2618 2619 static const struct hda_input_mux cxt5066_capture_source = { 2620 .num_items = 4, 2621 .items = { 2622 { "Mic B", 0 }, 2623 { "Mic C", 1 }, 2624 { "Mic E", 2 }, 2625 { "Mic F", 3 }, 2626 }, 2627 }; 2628 2629 static const struct hda_bind_ctls cxt5066_bind_capture_vol_others = { 2630 .ops = &snd_hda_bind_vol, 2631 .values = { 2632 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_INPUT), 2633 HDA_COMPOSE_AMP_VAL(0x14, 3, 2, HDA_INPUT), 2634 0 2635 }, 2636 }; 2637 2638 static const struct hda_bind_ctls cxt5066_bind_capture_sw_others = { 2639 .ops = &snd_hda_bind_sw, 2640 .values = { 2641 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_INPUT), 2642 HDA_COMPOSE_AMP_VAL(0x14, 3, 2, HDA_INPUT), 2643 0 2644 }, 2645 }; 2646 2647 static const struct snd_kcontrol_new cxt5066_mixer_master[] = { 2648 HDA_CODEC_VOLUME("Master Playback Volume", 0x10, 0x00, HDA_OUTPUT), 2649 {} 2650 }; 2651 2652 static const struct snd_kcontrol_new cxt5066_mixer_master_olpc[] = { 2653 { 2654 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2655 .name = "Master Playback Volume", 2656 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | 2657 SNDRV_CTL_ELEM_ACCESS_TLV_READ | 2658 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK, 2659 .subdevice = HDA_SUBDEV_AMP_FLAG, 2660 .info = snd_hda_mixer_amp_volume_info, 2661 .get = snd_hda_mixer_amp_volume_get, 2662 .put = snd_hda_mixer_amp_volume_put, 2663 .tlv = { .c = snd_hda_mixer_amp_tlv }, 2664 /* offset by 28 volume steps to limit minimum gain to -46dB */ 2665 .private_value = 2666 HDA_COMPOSE_AMP_VAL_OFS(0x10, 3, 0, HDA_OUTPUT, 28), 2667 }, 2668 {} 2669 }; 2670 2671 static const struct snd_kcontrol_new cxt5066_mixer_olpc_dc[] = { 2672 { 2673 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2674 .name = "DC Mode Enable Switch", 2675 .info = snd_ctl_boolean_mono_info, 2676 .get = cxt5066_olpc_dc_get, 2677 .put = cxt5066_olpc_dc_put, 2678 }, 2679 { 2680 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2681 .name = "DC Input Bias Enum", 2682 .info = cxt5066_olpc_dc_bias_enum_info, 2683 .get = cxt5066_olpc_dc_bias_enum_get, 2684 .put = cxt5066_olpc_dc_bias_enum_put, 2685 }, 2686 {} 2687 }; 2688 2689 static const struct snd_kcontrol_new cxt5066_mixers[] = { 2690 { 2691 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2692 .name = "Master Playback Switch", 2693 .info = cxt_eapd_info, 2694 .get = cxt_eapd_get, 2695 .put = cxt5066_hp_master_sw_put, 2696 .private_value = 0x1d, 2697 }, 2698 2699 { 2700 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2701 .name = "Analog Mic Boost Capture Enum", 2702 .info = cxt5066_mic_boost_mux_enum_info, 2703 .get = cxt5066_mic_boost_mux_enum_get, 2704 .put = cxt5066_mic_boost_mux_enum_put, 2705 }, 2706 2707 HDA_BIND_VOL("Capture Volume", &cxt5066_bind_capture_vol_others), 2708 HDA_BIND_SW("Capture Switch", &cxt5066_bind_capture_sw_others), 2709 {} 2710 }; 2711 2712 static const struct snd_kcontrol_new cxt5066_vostro_mixers[] = { 2713 { 2714 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2715 .name = "Internal Mic Boost Capture Enum", 2716 .info = cxt5066_mic_boost_mux_enum_info, 2717 .get = cxt5066_mic_boost_mux_enum_get, 2718 .put = cxt5066_mic_boost_mux_enum_put, 2719 .private_value = 0x23 | 0x100, 2720 }, 2721 {} 2722 }; 2723 2724 static const struct hda_verb cxt5066_init_verbs[] = { 2725 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port B */ 2726 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port C */ 2727 {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port F */ 2728 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port E */ 2729 2730 /* Speakers */ 2731 {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2732 {0x1f, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */ 2733 2734 /* HP, Amp */ 2735 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 2736 {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */ 2737 2738 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 2739 {0x1c, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */ 2740 2741 /* DAC1 */ 2742 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2743 2744 /* Node 14 connections: 0x17 0x18 0x23 0x24 0x27 */ 2745 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x50}, 2746 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 2747 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2) | 0x50}, 2748 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 2749 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 2750 2751 /* no digital microphone support yet */ 2752 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 2753 2754 /* Audio input selector */ 2755 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x3}, 2756 2757 /* SPDIF route: PCM */ 2758 {0x20, AC_VERB_SET_CONNECT_SEL, 0x0}, 2759 {0x22, AC_VERB_SET_CONNECT_SEL, 0x0}, 2760 2761 {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2762 {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2763 2764 /* EAPD */ 2765 {0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */ 2766 2767 /* not handling these yet */ 2768 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, 0}, 2769 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, 0}, 2770 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, 0}, 2771 {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, 0}, 2772 {0x1d, AC_VERB_SET_UNSOLICITED_ENABLE, 0}, 2773 {0x1e, AC_VERB_SET_UNSOLICITED_ENABLE, 0}, 2774 {0x20, AC_VERB_SET_UNSOLICITED_ENABLE, 0}, 2775 {0x22, AC_VERB_SET_UNSOLICITED_ENABLE, 0}, 2776 { } /* end */ 2777 }; 2778 2779 static const struct hda_verb cxt5066_init_verbs_olpc[] = { 2780 /* Port A: headphones */ 2781 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 2782 {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */ 2783 2784 /* Port B: external microphone */ 2785 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 2786 2787 /* Port C: internal microphone */ 2788 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 2789 2790 /* Port D: unused */ 2791 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 2792 2793 /* Port E: unused, but has primary EAPD */ 2794 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 2795 {0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */ 2796 2797 /* Port F: external DC input through microphone port */ 2798 {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 2799 2800 /* Port G: internal speakers */ 2801 {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2802 {0x1f, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */ 2803 2804 /* DAC1 */ 2805 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2806 2807 /* DAC2: unused */ 2808 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2809 2810 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x50}, 2811 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 2812 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 2813 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 2814 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 2815 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 2816 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 2817 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 2818 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 2819 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 2820 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 2821 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 2822 2823 /* Disable digital microphone port */ 2824 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 2825 2826 /* Audio input selectors */ 2827 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x3}, 2828 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 2829 2830 /* Disable SPDIF */ 2831 {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 2832 {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 2833 2834 /* enable unsolicited events for Port A and B */ 2835 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT}, 2836 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT}, 2837 { } /* end */ 2838 }; 2839 2840 static const struct hda_verb cxt5066_init_verbs_vostro[] = { 2841 /* Port A: headphones */ 2842 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 2843 {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */ 2844 2845 /* Port B: external microphone */ 2846 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 2847 2848 /* Port C: unused */ 2849 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 2850 2851 /* Port D: unused */ 2852 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 2853 2854 /* Port E: unused, but has primary EAPD */ 2855 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 2856 {0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */ 2857 2858 /* Port F: unused */ 2859 {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 2860 2861 /* Port G: internal speakers */ 2862 {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2863 {0x1f, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */ 2864 2865 /* DAC1 */ 2866 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2867 2868 /* DAC2: unused */ 2869 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2870 2871 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 2872 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 2873 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 2874 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 2875 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 2876 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 2877 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 2878 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 2879 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 2880 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 2881 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 2882 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 2883 2884 /* Digital microphone port */ 2885 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2886 2887 /* Audio input selectors */ 2888 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x3}, 2889 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 2890 2891 /* Disable SPDIF */ 2892 {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 2893 {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 2894 2895 /* enable unsolicited events for Port A and B */ 2896 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT}, 2897 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT}, 2898 { } /* end */ 2899 }; 2900 2901 static const struct hda_verb cxt5066_init_verbs_ideapad[] = { 2902 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port B */ 2903 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port C */ 2904 {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port F */ 2905 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port E */ 2906 2907 /* Speakers */ 2908 {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2909 {0x1f, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */ 2910 2911 /* HP, Amp */ 2912 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 2913 {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */ 2914 2915 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 2916 {0x1c, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */ 2917 2918 /* DAC1 */ 2919 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2920 2921 /* Node 14 connections: 0x17 0x18 0x23 0x24 0x27 */ 2922 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x50}, 2923 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 2924 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2) | 0x50}, 2925 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 2926 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 2927 {0x14, AC_VERB_SET_CONNECT_SEL, 2}, /* default to internal mic */ 2928 2929 /* Audio input selector */ 2930 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x2}, 2931 {0x17, AC_VERB_SET_CONNECT_SEL, 1}, /* route ext mic */ 2932 2933 /* SPDIF route: PCM */ 2934 {0x20, AC_VERB_SET_CONNECT_SEL, 0x0}, 2935 {0x22, AC_VERB_SET_CONNECT_SEL, 0x0}, 2936 2937 {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2938 {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2939 2940 /* internal microphone */ 2941 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* enable internal mic */ 2942 2943 /* EAPD */ 2944 {0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */ 2945 2946 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT}, 2947 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT}, 2948 { } /* end */ 2949 }; 2950 2951 static const struct hda_verb cxt5066_init_verbs_thinkpad[] = { 2952 {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port F */ 2953 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port E */ 2954 2955 /* Port G: internal speakers */ 2956 {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2957 {0x1f, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */ 2958 2959 /* Port A: HP, Amp */ 2960 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 2961 {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */ 2962 2963 /* Port B: Mic Dock */ 2964 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 2965 2966 /* Port C: Mic */ 2967 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 2968 2969 /* Port D: HP Dock, Amp */ 2970 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 2971 {0x1c, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */ 2972 2973 /* DAC1 */ 2974 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2975 2976 /* Node 14 connections: 0x17 0x18 0x23 0x24 0x27 */ 2977 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x50}, 2978 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 2979 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2) | 0x50}, 2980 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 2981 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 2982 {0x14, AC_VERB_SET_CONNECT_SEL, 2}, /* default to internal mic */ 2983 2984 /* Audio input selector */ 2985 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x2}, 2986 {0x17, AC_VERB_SET_CONNECT_SEL, 1}, /* route ext mic */ 2987 2988 /* SPDIF route: PCM */ 2989 {0x20, AC_VERB_SET_CONNECT_SEL, 0x0}, 2990 {0x22, AC_VERB_SET_CONNECT_SEL, 0x0}, 2991 2992 {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2993 {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2994 2995 /* internal microphone */ 2996 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* enable internal mic */ 2997 2998 /* EAPD */ 2999 {0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */ 3000 3001 /* enable unsolicited events for Port A, B, C and D */ 3002 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT}, 3003 {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT}, 3004 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT}, 3005 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT}, 3006 { } /* end */ 3007 }; 3008 3009 static const struct hda_verb cxt5066_init_verbs_portd_lo[] = { 3010 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3011 { } /* end */ 3012 }; 3013 3014 3015 static const struct hda_verb cxt5066_init_verbs_hp_laptop[] = { 3016 {0x14, AC_VERB_SET_CONNECT_SEL, 0x0}, 3017 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT}, 3018 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT}, 3019 { } /* end */ 3020 }; 3021 3022 /* initialize jack-sensing, too */ 3023 static int cxt5066_init(struct hda_codec *codec) 3024 { 3025 snd_printdd("CXT5066: init\n"); 3026 conexant_init(codec); 3027 if (codec->patch_ops.unsol_event) { 3028 cxt5066_hp_automute(codec); 3029 cxt5066_automic(codec); 3030 } 3031 cxt5066_set_mic_boost(codec); 3032 return 0; 3033 } 3034 3035 static int cxt5066_olpc_init(struct hda_codec *codec) 3036 { 3037 struct conexant_spec *spec = codec->spec; 3038 snd_printdd("CXT5066: init\n"); 3039 conexant_init(codec); 3040 cxt5066_hp_automute(codec); 3041 if (!spec->dc_enable) { 3042 cxt5066_set_mic_boost(codec); 3043 cxt5066_olpc_automic(codec); 3044 } else { 3045 cxt5066_enable_dc(codec); 3046 } 3047 return 0; 3048 } 3049 3050 enum { 3051 CXT5066_LAPTOP, /* Laptops w/ EAPD support */ 3052 CXT5066_DELL_LAPTOP, /* Dell Laptop */ 3053 CXT5066_OLPC_XO_1_5, /* OLPC XO 1.5 */ 3054 CXT5066_DELL_VOSTRO, /* Dell Vostro 1015i */ 3055 CXT5066_IDEAPAD, /* Lenovo IdeaPad U150 */ 3056 CXT5066_THINKPAD, /* Lenovo ThinkPad T410s, others? */ 3057 CXT5066_ASUS, /* Asus K52JU, Lenovo G560 - Int mic at 0x1a and Ext mic at 0x1b */ 3058 CXT5066_HP_LAPTOP, /* HP Laptop */ 3059 CXT5066_AUTO, /* BIOS auto-parser */ 3060 CXT5066_MODELS 3061 }; 3062 3063 static const char * const cxt5066_models[CXT5066_MODELS] = { 3064 [CXT5066_LAPTOP] = "laptop", 3065 [CXT5066_DELL_LAPTOP] = "dell-laptop", 3066 [CXT5066_OLPC_XO_1_5] = "olpc-xo-1_5", 3067 [CXT5066_DELL_VOSTRO] = "dell-vostro", 3068 [CXT5066_IDEAPAD] = "ideapad", 3069 [CXT5066_THINKPAD] = "thinkpad", 3070 [CXT5066_ASUS] = "asus", 3071 [CXT5066_HP_LAPTOP] = "hp-laptop", 3072 [CXT5066_AUTO] = "auto", 3073 }; 3074 3075 static const struct snd_pci_quirk cxt5066_cfg_tbl[] = { 3076 SND_PCI_QUIRK(0x1025, 0x054c, "Acer Aspire 3830TG", CXT5066_AUTO), 3077 SND_PCI_QUIRK_MASK(0x1025, 0xff00, 0x0400, "Acer", CXT5066_IDEAPAD), 3078 SND_PCI_QUIRK(0x1028, 0x02d8, "Dell Vostro", CXT5066_DELL_VOSTRO), 3079 SND_PCI_QUIRK(0x1028, 0x02f5, "Dell Vostro 320", CXT5066_IDEAPAD), 3080 SND_PCI_QUIRK(0x1028, 0x0401, "Dell Vostro 1014", CXT5066_DELL_VOSTRO), 3081 SND_PCI_QUIRK(0x1028, 0x0402, "Dell Vostro", CXT5066_DELL_VOSTRO), 3082 SND_PCI_QUIRK(0x1028, 0x0408, "Dell Inspiron One 19T", CXT5066_IDEAPAD), 3083 SND_PCI_QUIRK(0x1028, 0x050f, "Dell Inspiron", CXT5066_IDEAPAD), 3084 SND_PCI_QUIRK(0x1028, 0x0510, "Dell Vostro", CXT5066_IDEAPAD), 3085 SND_PCI_QUIRK(0x103c, 0x360b, "HP G60", CXT5066_HP_LAPTOP), 3086 SND_PCI_QUIRK(0x1043, 0x13f3, "Asus A52J", CXT5066_ASUS), 3087 SND_PCI_QUIRK(0x1043, 0x1643, "Asus K52JU", CXT5066_ASUS), 3088 SND_PCI_QUIRK(0x1043, 0x1993, "Asus U50F", CXT5066_ASUS), 3089 SND_PCI_QUIRK(0x1179, 0xff1e, "Toshiba Satellite C650D", CXT5066_IDEAPAD), 3090 SND_PCI_QUIRK(0x1179, 0xff50, "Toshiba Satellite P500-PSPGSC-01800T", CXT5066_OLPC_XO_1_5), 3091 SND_PCI_QUIRK(0x1179, 0xffe0, "Toshiba Satellite Pro T130-15F", CXT5066_OLPC_XO_1_5), 3092 SND_PCI_QUIRK(0x14f1, 0x0101, "Conexant Reference board", 3093 CXT5066_LAPTOP), 3094 SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5), 3095 SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400s", CXT5066_THINKPAD), 3096 SND_PCI_QUIRK(0x17aa, 0x21c5, "Thinkpad Edge 13", CXT5066_THINKPAD), 3097 SND_PCI_QUIRK(0x17aa, 0x21c6, "Thinkpad Edge 13", CXT5066_ASUS), 3098 SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo Thinkpad", CXT5066_THINKPAD), 3099 SND_PCI_QUIRK(0x17aa, 0x21da, "Lenovo X220", CXT5066_THINKPAD), 3100 SND_PCI_QUIRK(0x17aa, 0x21db, "Lenovo X220-tablet", CXT5066_THINKPAD), 3101 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo U350", CXT5066_ASUS), 3102 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo G560", CXT5066_ASUS), 3103 SND_PCI_QUIRK(0x17aa, 0x3938, "Lenovo G565", CXT5066_AUTO), 3104 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", CXT5066_IDEAPAD), /* Fallback for Lenovos without dock mic */ 3105 SND_PCI_QUIRK(0x1b0a, 0x2092, "CyberpowerPC Gamer Xplorer N57001", CXT5066_AUTO), 3106 {} 3107 }; 3108 3109 static int patch_cxt5066(struct hda_codec *codec) 3110 { 3111 struct conexant_spec *spec; 3112 int board_config; 3113 3114 board_config = snd_hda_check_board_config(codec, CXT5066_MODELS, 3115 cxt5066_models, cxt5066_cfg_tbl); 3116 if (board_config < 0) 3117 board_config = CXT5066_AUTO; /* model=auto as default */ 3118 if (board_config == CXT5066_AUTO) 3119 return patch_conexant_auto(codec); 3120 3121 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 3122 if (!spec) 3123 return -ENOMEM; 3124 codec->spec = spec; 3125 3126 codec->patch_ops = conexant_patch_ops; 3127 codec->patch_ops.init = conexant_init; 3128 3129 spec->dell_automute = 0; 3130 spec->multiout.max_channels = 2; 3131 spec->multiout.num_dacs = ARRAY_SIZE(cxt5066_dac_nids); 3132 spec->multiout.dac_nids = cxt5066_dac_nids; 3133 conexant_check_dig_outs(codec, cxt5066_digout_pin_nids, 3134 ARRAY_SIZE(cxt5066_digout_pin_nids)); 3135 spec->num_adc_nids = 1; 3136 spec->adc_nids = cxt5066_adc_nids; 3137 spec->capsrc_nids = cxt5066_capsrc_nids; 3138 spec->input_mux = &cxt5066_capture_source; 3139 3140 spec->port_d_mode = PIN_HP; 3141 3142 spec->num_init_verbs = 1; 3143 spec->init_verbs[0] = cxt5066_init_verbs; 3144 spec->num_channel_mode = ARRAY_SIZE(cxt5066_modes); 3145 spec->channel_mode = cxt5066_modes; 3146 spec->cur_adc = 0; 3147 spec->cur_adc_idx = 0; 3148 3149 set_beep_amp(spec, 0x13, 0, HDA_OUTPUT); 3150 3151 switch (board_config) { 3152 default: 3153 case CXT5066_LAPTOP: 3154 spec->mixers[spec->num_mixers++] = cxt5066_mixer_master; 3155 spec->mixers[spec->num_mixers++] = cxt5066_mixers; 3156 break; 3157 case CXT5066_DELL_LAPTOP: 3158 spec->mixers[spec->num_mixers++] = cxt5066_mixer_master; 3159 spec->mixers[spec->num_mixers++] = cxt5066_mixers; 3160 3161 spec->port_d_mode = PIN_OUT; 3162 spec->init_verbs[spec->num_init_verbs] = cxt5066_init_verbs_portd_lo; 3163 spec->num_init_verbs++; 3164 spec->dell_automute = 1; 3165 break; 3166 case CXT5066_ASUS: 3167 case CXT5066_HP_LAPTOP: 3168 codec->patch_ops.init = cxt5066_init; 3169 codec->patch_ops.unsol_event = cxt5066_unsol_event; 3170 spec->init_verbs[spec->num_init_verbs] = 3171 cxt5066_init_verbs_hp_laptop; 3172 spec->num_init_verbs++; 3173 spec->hp_laptop = board_config == CXT5066_HP_LAPTOP; 3174 spec->asus = board_config == CXT5066_ASUS; 3175 spec->mixers[spec->num_mixers++] = cxt5066_mixer_master; 3176 spec->mixers[spec->num_mixers++] = cxt5066_mixers; 3177 /* no S/PDIF out */ 3178 if (board_config == CXT5066_HP_LAPTOP) 3179 spec->multiout.dig_out_nid = 0; 3180 /* input source automatically selected */ 3181 spec->input_mux = NULL; 3182 spec->port_d_mode = 0; 3183 spec->mic_boost = 3; /* default 30dB gain */ 3184 break; 3185 3186 case CXT5066_OLPC_XO_1_5: 3187 codec->patch_ops.init = cxt5066_olpc_init; 3188 codec->patch_ops.unsol_event = cxt5066_olpc_unsol_event; 3189 spec->init_verbs[0] = cxt5066_init_verbs_olpc; 3190 spec->mixers[spec->num_mixers++] = cxt5066_mixer_master_olpc; 3191 spec->mixers[spec->num_mixers++] = cxt5066_mixer_olpc_dc; 3192 spec->mixers[spec->num_mixers++] = cxt5066_mixers; 3193 spec->port_d_mode = 0; 3194 spec->mic_boost = 3; /* default 30dB gain */ 3195 3196 /* no S/PDIF out */ 3197 spec->multiout.dig_out_nid = 0; 3198 3199 /* input source automatically selected */ 3200 spec->input_mux = NULL; 3201 3202 /* our capture hooks which allow us to turn on the microphone LED 3203 * at the right time */ 3204 spec->capture_prepare = cxt5066_olpc_capture_prepare; 3205 spec->capture_cleanup = cxt5066_olpc_capture_cleanup; 3206 break; 3207 case CXT5066_DELL_VOSTRO: 3208 codec->patch_ops.init = cxt5066_init; 3209 codec->patch_ops.unsol_event = cxt5066_unsol_event; 3210 spec->init_verbs[0] = cxt5066_init_verbs_vostro; 3211 spec->mixers[spec->num_mixers++] = cxt5066_mixer_master_olpc; 3212 spec->mixers[spec->num_mixers++] = cxt5066_mixers; 3213 spec->mixers[spec->num_mixers++] = cxt5066_vostro_mixers; 3214 spec->port_d_mode = 0; 3215 spec->dell_vostro = 1; 3216 spec->mic_boost = 3; /* default 30dB gain */ 3217 3218 /* no S/PDIF out */ 3219 spec->multiout.dig_out_nid = 0; 3220 3221 /* input source automatically selected */ 3222 spec->input_mux = NULL; 3223 break; 3224 case CXT5066_IDEAPAD: 3225 codec->patch_ops.init = cxt5066_init; 3226 codec->patch_ops.unsol_event = cxt5066_unsol_event; 3227 spec->mixers[spec->num_mixers++] = cxt5066_mixer_master; 3228 spec->mixers[spec->num_mixers++] = cxt5066_mixers; 3229 spec->init_verbs[0] = cxt5066_init_verbs_ideapad; 3230 spec->port_d_mode = 0; 3231 spec->ideapad = 1; 3232 spec->mic_boost = 2; /* default 20dB gain */ 3233 3234 /* no S/PDIF out */ 3235 spec->multiout.dig_out_nid = 0; 3236 3237 /* input source automatically selected */ 3238 spec->input_mux = NULL; 3239 break; 3240 case CXT5066_THINKPAD: 3241 codec->patch_ops.init = cxt5066_init; 3242 codec->patch_ops.unsol_event = cxt5066_unsol_event; 3243 spec->mixers[spec->num_mixers++] = cxt5066_mixer_master; 3244 spec->mixers[spec->num_mixers++] = cxt5066_mixers; 3245 spec->init_verbs[0] = cxt5066_init_verbs_thinkpad; 3246 spec->thinkpad = 1; 3247 spec->port_d_mode = PIN_OUT; 3248 spec->mic_boost = 2; /* default 20dB gain */ 3249 3250 /* no S/PDIF out */ 3251 spec->multiout.dig_out_nid = 0; 3252 3253 /* input source automatically selected */ 3254 spec->input_mux = NULL; 3255 break; 3256 } 3257 3258 if (spec->beep_amp) 3259 snd_hda_attach_beep_device(codec, spec->beep_amp); 3260 3261 return 0; 3262 } 3263 3264 /* 3265 * Automatic parser for CX20641 & co 3266 */ 3267 3268 static int cx_auto_capture_pcm_prepare(struct hda_pcm_stream *hinfo, 3269 struct hda_codec *codec, 3270 unsigned int stream_tag, 3271 unsigned int format, 3272 struct snd_pcm_substream *substream) 3273 { 3274 struct conexant_spec *spec = codec->spec; 3275 hda_nid_t adc = spec->imux_info[spec->cur_mux[0]].adc; 3276 if (spec->adc_switching) { 3277 spec->cur_adc = adc; 3278 spec->cur_adc_stream_tag = stream_tag; 3279 spec->cur_adc_format = format; 3280 } 3281 snd_hda_codec_setup_stream(codec, adc, stream_tag, 0, format); 3282 return 0; 3283 } 3284 3285 static int cx_auto_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, 3286 struct hda_codec *codec, 3287 struct snd_pcm_substream *substream) 3288 { 3289 struct conexant_spec *spec = codec->spec; 3290 snd_hda_codec_cleanup_stream(codec, spec->cur_adc); 3291 spec->cur_adc = 0; 3292 return 0; 3293 } 3294 3295 static const struct hda_pcm_stream cx_auto_pcm_analog_capture = { 3296 .substreams = 1, 3297 .channels_min = 2, 3298 .channels_max = 2, 3299 .nid = 0, /* fill later */ 3300 .ops = { 3301 .prepare = cx_auto_capture_pcm_prepare, 3302 .cleanup = cx_auto_capture_pcm_cleanup 3303 }, 3304 }; 3305 3306 static const hda_nid_t cx_auto_adc_nids[] = { 0x14 }; 3307 3308 #define get_connection_index(codec, mux, nid)\ 3309 snd_hda_get_conn_index(codec, mux, nid, 0) 3310 3311 /* get an unassigned DAC from the given list. 3312 * Return the nid if found and reduce the DAC list, or return zero if 3313 * not found 3314 */ 3315 static hda_nid_t get_unassigned_dac(struct hda_codec *codec, hda_nid_t pin, 3316 hda_nid_t *dacs, int *num_dacs) 3317 { 3318 int i, nums = *num_dacs; 3319 hda_nid_t ret = 0; 3320 3321 for (i = 0; i < nums; i++) { 3322 if (get_connection_index(codec, pin, dacs[i]) >= 0) { 3323 ret = dacs[i]; 3324 break; 3325 } 3326 } 3327 if (!ret) 3328 return 0; 3329 if (--nums > 0) 3330 memmove(dacs, dacs + 1, nums * sizeof(hda_nid_t)); 3331 *num_dacs = nums; 3332 return ret; 3333 } 3334 3335 #define MAX_AUTO_DACS 5 3336 3337 /* fill analog DAC list from the widget tree */ 3338 static int fill_cx_auto_dacs(struct hda_codec *codec, hda_nid_t *dacs) 3339 { 3340 hda_nid_t nid, end_nid; 3341 int nums = 0; 3342 3343 end_nid = codec->start_nid + codec->num_nodes; 3344 for (nid = codec->start_nid; nid < end_nid; nid++) { 3345 unsigned int wcaps = get_wcaps(codec, nid); 3346 unsigned int type = get_wcaps_type(wcaps); 3347 if (type == AC_WID_AUD_OUT && !(wcaps & AC_WCAP_DIGITAL)) { 3348 dacs[nums++] = nid; 3349 if (nums >= MAX_AUTO_DACS) 3350 break; 3351 } 3352 } 3353 return nums; 3354 } 3355 3356 /* fill pin_dac_pair list from the pin and dac list */ 3357 static int fill_dacs_for_pins(struct hda_codec *codec, hda_nid_t *pins, 3358 int num_pins, hda_nid_t *dacs, int *rest, 3359 struct pin_dac_pair *filled, int type) 3360 { 3361 int i, nums; 3362 3363 nums = 0; 3364 for (i = 0; i < num_pins; i++) { 3365 filled[nums].pin = pins[i]; 3366 filled[nums].type = type; 3367 filled[nums].dac = get_unassigned_dac(codec, pins[i], dacs, rest); 3368 nums++; 3369 } 3370 return nums; 3371 } 3372 3373 /* parse analog output paths */ 3374 static void cx_auto_parse_output(struct hda_codec *codec) 3375 { 3376 struct conexant_spec *spec = codec->spec; 3377 struct auto_pin_cfg *cfg = &spec->autocfg; 3378 hda_nid_t dacs[MAX_AUTO_DACS]; 3379 int i, j, nums, rest; 3380 3381 rest = fill_cx_auto_dacs(codec, dacs); 3382 /* parse all analog output pins */ 3383 nums = fill_dacs_for_pins(codec, cfg->line_out_pins, cfg->line_outs, 3384 dacs, &rest, spec->dac_info, 3385 AUTO_PIN_LINE_OUT); 3386 nums += fill_dacs_for_pins(codec, cfg->hp_pins, cfg->hp_outs, 3387 dacs, &rest, spec->dac_info + nums, 3388 AUTO_PIN_HP_OUT); 3389 nums += fill_dacs_for_pins(codec, cfg->speaker_pins, cfg->speaker_outs, 3390 dacs, &rest, spec->dac_info + nums, 3391 AUTO_PIN_SPEAKER_OUT); 3392 spec->dac_info_filled = nums; 3393 /* fill multiout struct */ 3394 for (i = 0; i < nums; i++) { 3395 hda_nid_t dac = spec->dac_info[i].dac; 3396 if (!dac) 3397 continue; 3398 switch (spec->dac_info[i].type) { 3399 case AUTO_PIN_LINE_OUT: 3400 spec->private_dac_nids[spec->multiout.num_dacs] = dac; 3401 spec->multiout.num_dacs++; 3402 break; 3403 case AUTO_PIN_HP_OUT: 3404 case AUTO_PIN_SPEAKER_OUT: 3405 if (!spec->multiout.hp_nid) { 3406 spec->multiout.hp_nid = dac; 3407 break; 3408 } 3409 for (j = 0; j < ARRAY_SIZE(spec->multiout.extra_out_nid); j++) 3410 if (!spec->multiout.extra_out_nid[j]) { 3411 spec->multiout.extra_out_nid[j] = dac; 3412 break; 3413 } 3414 break; 3415 } 3416 } 3417 spec->multiout.dac_nids = spec->private_dac_nids; 3418 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 3419 3420 for (i = 0; i < cfg->hp_outs; i++) { 3421 if (is_jack_detectable(codec, cfg->hp_pins[i])) { 3422 spec->auto_mute = 1; 3423 break; 3424 } 3425 } 3426 if (spec->auto_mute && 3427 cfg->line_out_pins[0] && 3428 cfg->line_out_type != AUTO_PIN_SPEAKER_OUT && 3429 cfg->line_out_pins[0] != cfg->hp_pins[0] && 3430 cfg->line_out_pins[0] != cfg->speaker_pins[0]) { 3431 for (i = 0; i < cfg->line_outs; i++) { 3432 if (is_jack_detectable(codec, cfg->line_out_pins[i])) { 3433 spec->detect_line = 1; 3434 break; 3435 } 3436 } 3437 spec->automute_lines = spec->detect_line; 3438 } 3439 3440 spec->vmaster_nid = spec->private_dac_nids[0]; 3441 } 3442 3443 static void cx_auto_turn_eapd(struct hda_codec *codec, int num_pins, 3444 hda_nid_t *pins, bool on); 3445 3446 static void do_automute(struct hda_codec *codec, int num_pins, 3447 hda_nid_t *pins, bool on) 3448 { 3449 int i; 3450 for (i = 0; i < num_pins; i++) 3451 snd_hda_codec_write(codec, pins[i], 0, 3452 AC_VERB_SET_PIN_WIDGET_CONTROL, 3453 on ? PIN_OUT : 0); 3454 cx_auto_turn_eapd(codec, num_pins, pins, on); 3455 } 3456 3457 static int detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins) 3458 { 3459 int i, present = 0; 3460 3461 for (i = 0; i < num_pins; i++) { 3462 hda_nid_t nid = pins[i]; 3463 if (!nid || !is_jack_detectable(codec, nid)) 3464 break; 3465 snd_hda_input_jack_report(codec, nid); 3466 present |= snd_hda_jack_detect(codec, nid); 3467 } 3468 return present; 3469 } 3470 3471 /* auto-mute/unmute speaker and line outs according to headphone jack */ 3472 static void cx_auto_update_speakers(struct hda_codec *codec) 3473 { 3474 struct conexant_spec *spec = codec->spec; 3475 struct auto_pin_cfg *cfg = &spec->autocfg; 3476 int on = 1; 3477 3478 /* turn on HP EAPD when HP jacks are present */ 3479 if (spec->auto_mute) 3480 on = spec->hp_present; 3481 cx_auto_turn_eapd(codec, cfg->hp_outs, cfg->hp_pins, on); 3482 /* mute speakers in auto-mode if HP or LO jacks are plugged */ 3483 if (spec->auto_mute) 3484 on = !(spec->hp_present || 3485 (spec->detect_line && spec->line_present)); 3486 do_automute(codec, cfg->speaker_outs, cfg->speaker_pins, on); 3487 3488 /* toggle line-out mutes if needed, too */ 3489 /* if LO is a copy of either HP or Speaker, don't need to handle it */ 3490 if (cfg->line_out_pins[0] == cfg->hp_pins[0] || 3491 cfg->line_out_pins[0] == cfg->speaker_pins[0]) 3492 return; 3493 if (spec->auto_mute) { 3494 /* mute LO in auto-mode when HP jack is present */ 3495 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT || 3496 spec->automute_lines) 3497 on = !spec->hp_present; 3498 else 3499 on = 1; 3500 } 3501 do_automute(codec, cfg->line_outs, cfg->line_out_pins, on); 3502 } 3503 3504 static void cx_auto_hp_automute(struct hda_codec *codec) 3505 { 3506 struct conexant_spec *spec = codec->spec; 3507 struct auto_pin_cfg *cfg = &spec->autocfg; 3508 3509 if (!spec->auto_mute) 3510 return; 3511 spec->hp_present = detect_jacks(codec, cfg->hp_outs, cfg->hp_pins); 3512 cx_auto_update_speakers(codec); 3513 } 3514 3515 static void cx_auto_line_automute(struct hda_codec *codec) 3516 { 3517 struct conexant_spec *spec = codec->spec; 3518 struct auto_pin_cfg *cfg = &spec->autocfg; 3519 3520 if (!spec->auto_mute || !spec->detect_line) 3521 return; 3522 spec->line_present = detect_jacks(codec, cfg->line_outs, 3523 cfg->line_out_pins); 3524 cx_auto_update_speakers(codec); 3525 } 3526 3527 static int cx_automute_mode_info(struct snd_kcontrol *kcontrol, 3528 struct snd_ctl_elem_info *uinfo) 3529 { 3530 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 3531 struct conexant_spec *spec = codec->spec; 3532 static const char * const texts2[] = { 3533 "Disabled", "Enabled" 3534 }; 3535 static const char * const texts3[] = { 3536 "Disabled", "Speaker Only", "Line-Out+Speaker" 3537 }; 3538 const char * const *texts; 3539 3540 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 3541 uinfo->count = 1; 3542 if (spec->automute_hp_lo) { 3543 uinfo->value.enumerated.items = 3; 3544 texts = texts3; 3545 } else { 3546 uinfo->value.enumerated.items = 2; 3547 texts = texts2; 3548 } 3549 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) 3550 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; 3551 strcpy(uinfo->value.enumerated.name, 3552 texts[uinfo->value.enumerated.item]); 3553 return 0; 3554 } 3555 3556 static int cx_automute_mode_get(struct snd_kcontrol *kcontrol, 3557 struct snd_ctl_elem_value *ucontrol) 3558 { 3559 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 3560 struct conexant_spec *spec = codec->spec; 3561 unsigned int val; 3562 if (!spec->auto_mute) 3563 val = 0; 3564 else if (!spec->automute_lines) 3565 val = 1; 3566 else 3567 val = 2; 3568 ucontrol->value.enumerated.item[0] = val; 3569 return 0; 3570 } 3571 3572 static int cx_automute_mode_put(struct snd_kcontrol *kcontrol, 3573 struct snd_ctl_elem_value *ucontrol) 3574 { 3575 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 3576 struct conexant_spec *spec = codec->spec; 3577 3578 switch (ucontrol->value.enumerated.item[0]) { 3579 case 0: 3580 if (!spec->auto_mute) 3581 return 0; 3582 spec->auto_mute = 0; 3583 break; 3584 case 1: 3585 if (spec->auto_mute && !spec->automute_lines) 3586 return 0; 3587 spec->auto_mute = 1; 3588 spec->automute_lines = 0; 3589 break; 3590 case 2: 3591 if (!spec->automute_hp_lo) 3592 return -EINVAL; 3593 if (spec->auto_mute && spec->automute_lines) 3594 return 0; 3595 spec->auto_mute = 1; 3596 spec->automute_lines = 1; 3597 break; 3598 default: 3599 return -EINVAL; 3600 } 3601 cx_auto_update_speakers(codec); 3602 return 1; 3603 } 3604 3605 static const struct snd_kcontrol_new cx_automute_mode_enum[] = { 3606 { 3607 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 3608 .name = "Auto-Mute Mode", 3609 .info = cx_automute_mode_info, 3610 .get = cx_automute_mode_get, 3611 .put = cx_automute_mode_put, 3612 }, 3613 { } 3614 }; 3615 3616 static int cx_auto_mux_enum_info(struct snd_kcontrol *kcontrol, 3617 struct snd_ctl_elem_info *uinfo) 3618 { 3619 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 3620 struct conexant_spec *spec = codec->spec; 3621 3622 return snd_hda_input_mux_info(&spec->private_imux, uinfo); 3623 } 3624 3625 static int cx_auto_mux_enum_get(struct snd_kcontrol *kcontrol, 3626 struct snd_ctl_elem_value *ucontrol) 3627 { 3628 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 3629 struct conexant_spec *spec = codec->spec; 3630 3631 ucontrol->value.enumerated.item[0] = spec->cur_mux[0]; 3632 return 0; 3633 } 3634 3635 /* look for the route the given pin from mux and return the index; 3636 * if do_select is set, actually select the route. 3637 */ 3638 static int __select_input_connection(struct hda_codec *codec, hda_nid_t mux, 3639 hda_nid_t pin, hda_nid_t *srcp, 3640 bool do_select, int depth) 3641 { 3642 hda_nid_t conn[HDA_MAX_NUM_INPUTS]; 3643 int i, nums; 3644 3645 switch (get_wcaps_type(get_wcaps(codec, mux))) { 3646 case AC_WID_AUD_IN: 3647 case AC_WID_AUD_SEL: 3648 case AC_WID_AUD_MIX: 3649 break; 3650 default: 3651 return -1; 3652 } 3653 3654 nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn)); 3655 for (i = 0; i < nums; i++) 3656 if (conn[i] == pin) { 3657 if (do_select) 3658 snd_hda_codec_write(codec, mux, 0, 3659 AC_VERB_SET_CONNECT_SEL, i); 3660 if (srcp) 3661 *srcp = mux; 3662 return i; 3663 } 3664 depth++; 3665 if (depth == 2) 3666 return -1; 3667 for (i = 0; i < nums; i++) { 3668 int ret = __select_input_connection(codec, conn[i], pin, srcp, 3669 do_select, depth); 3670 if (ret >= 0) { 3671 if (do_select) 3672 snd_hda_codec_write(codec, mux, 0, 3673 AC_VERB_SET_CONNECT_SEL, i); 3674 return i; 3675 } 3676 } 3677 return -1; 3678 } 3679 3680 static void select_input_connection(struct hda_codec *codec, hda_nid_t mux, 3681 hda_nid_t pin) 3682 { 3683 __select_input_connection(codec, mux, pin, NULL, true, 0); 3684 } 3685 3686 static int get_input_connection(struct hda_codec *codec, hda_nid_t mux, 3687 hda_nid_t pin) 3688 { 3689 return __select_input_connection(codec, mux, pin, NULL, false, 0); 3690 } 3691 3692 static int cx_auto_mux_enum_update(struct hda_codec *codec, 3693 const struct hda_input_mux *imux, 3694 unsigned int idx) 3695 { 3696 struct conexant_spec *spec = codec->spec; 3697 hda_nid_t adc; 3698 int changed = 1; 3699 3700 if (!imux->num_items) 3701 return 0; 3702 if (idx >= imux->num_items) 3703 idx = imux->num_items - 1; 3704 if (spec->cur_mux[0] == idx) 3705 changed = 0; 3706 adc = spec->imux_info[idx].adc; 3707 select_input_connection(codec, spec->imux_info[idx].adc, 3708 spec->imux_info[idx].pin); 3709 if (spec->cur_adc && spec->cur_adc != adc) { 3710 /* stream is running, let's swap the current ADC */ 3711 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1); 3712 spec->cur_adc = adc; 3713 snd_hda_codec_setup_stream(codec, adc, 3714 spec->cur_adc_stream_tag, 0, 3715 spec->cur_adc_format); 3716 } 3717 spec->cur_mux[0] = idx; 3718 return changed; 3719 } 3720 3721 static int cx_auto_mux_enum_put(struct snd_kcontrol *kcontrol, 3722 struct snd_ctl_elem_value *ucontrol) 3723 { 3724 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 3725 struct conexant_spec *spec = codec->spec; 3726 3727 return cx_auto_mux_enum_update(codec, &spec->private_imux, 3728 ucontrol->value.enumerated.item[0]); 3729 } 3730 3731 static const struct snd_kcontrol_new cx_auto_capture_mixers[] = { 3732 { 3733 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 3734 .name = "Capture Source", 3735 .info = cx_auto_mux_enum_info, 3736 .get = cx_auto_mux_enum_get, 3737 .put = cx_auto_mux_enum_put 3738 }, 3739 {} 3740 }; 3741 3742 static bool select_automic(struct hda_codec *codec, int idx, bool detect) 3743 { 3744 struct conexant_spec *spec = codec->spec; 3745 if (idx < 0) 3746 return false; 3747 if (detect && !snd_hda_jack_detect(codec, spec->imux_info[idx].pin)) 3748 return false; 3749 cx_auto_mux_enum_update(codec, &spec->private_imux, idx); 3750 return true; 3751 } 3752 3753 /* automatic switch internal and external mic */ 3754 static void cx_auto_automic(struct hda_codec *codec) 3755 { 3756 struct conexant_spec *spec = codec->spec; 3757 3758 if (!spec->auto_mic) 3759 return; 3760 if (!select_automic(codec, spec->auto_mic_ext, true)) 3761 if (!select_automic(codec, spec->auto_mic_dock, true)) 3762 select_automic(codec, spec->auto_mic_int, false); 3763 } 3764 3765 static void cx_auto_unsol_event(struct hda_codec *codec, unsigned int res) 3766 { 3767 int nid = (res & AC_UNSOL_RES_SUBTAG) >> 20; 3768 switch (res >> 26) { 3769 case CONEXANT_HP_EVENT: 3770 cx_auto_hp_automute(codec); 3771 break; 3772 case CONEXANT_LINE_EVENT: 3773 cx_auto_line_automute(codec); 3774 break; 3775 case CONEXANT_MIC_EVENT: 3776 cx_auto_automic(codec); 3777 snd_hda_input_jack_report(codec, nid); 3778 break; 3779 } 3780 } 3781 3782 /* check whether the pin config is suitable for auto-mic switching; 3783 * auto-mic is enabled only when one int-mic and one ext- and/or 3784 * one dock-mic exist 3785 */ 3786 static void cx_auto_check_auto_mic(struct hda_codec *codec) 3787 { 3788 struct conexant_spec *spec = codec->spec; 3789 int pset[INPUT_PIN_ATTR_NORMAL + 1]; 3790 int i; 3791 3792 for (i = 0; i < ARRAY_SIZE(pset); i++) 3793 pset[i] = -1; 3794 for (i = 0; i < spec->private_imux.num_items; i++) { 3795 hda_nid_t pin = spec->imux_info[i].pin; 3796 unsigned int def_conf = snd_hda_codec_get_pincfg(codec, pin); 3797 int type, attr; 3798 attr = snd_hda_get_input_pin_attr(def_conf); 3799 if (attr == INPUT_PIN_ATTR_UNUSED) 3800 return; /* invalid entry */ 3801 if (attr > INPUT_PIN_ATTR_NORMAL) 3802 attr = INPUT_PIN_ATTR_NORMAL; 3803 if (attr != INPUT_PIN_ATTR_INT && 3804 !is_jack_detectable(codec, pin)) 3805 return; /* non-detectable pin */ 3806 type = get_defcfg_device(def_conf); 3807 if (type != AC_JACK_MIC_IN && 3808 (attr != INPUT_PIN_ATTR_DOCK || type != AC_JACK_LINE_IN)) 3809 return; /* no valid input type */ 3810 if (pset[attr] >= 0) 3811 return; /* already occupied */ 3812 pset[attr] = i; 3813 } 3814 if (pset[INPUT_PIN_ATTR_INT] < 0 || 3815 (pset[INPUT_PIN_ATTR_NORMAL] < 0 && pset[INPUT_PIN_ATTR_DOCK])) 3816 return; /* no input to switch*/ 3817 spec->auto_mic = 1; 3818 spec->auto_mic_ext = pset[INPUT_PIN_ATTR_NORMAL]; 3819 spec->auto_mic_dock = pset[INPUT_PIN_ATTR_DOCK]; 3820 spec->auto_mic_int = pset[INPUT_PIN_ATTR_INT]; 3821 } 3822 3823 static void cx_auto_parse_input(struct hda_codec *codec) 3824 { 3825 struct conexant_spec *spec = codec->spec; 3826 struct auto_pin_cfg *cfg = &spec->autocfg; 3827 struct hda_input_mux *imux; 3828 int i, j; 3829 3830 imux = &spec->private_imux; 3831 for (i = 0; i < cfg->num_inputs; i++) { 3832 for (j = 0; j < spec->num_adc_nids; j++) { 3833 hda_nid_t adc = spec->adc_nids[j]; 3834 int idx = get_input_connection(codec, adc, 3835 cfg->inputs[i].pin); 3836 if (idx >= 0) { 3837 const char *label; 3838 label = hda_get_autocfg_input_label(codec, cfg, i); 3839 spec->imux_info[imux->num_items].index = i; 3840 spec->imux_info[imux->num_items].boost = 0; 3841 spec->imux_info[imux->num_items].adc = adc; 3842 spec->imux_info[imux->num_items].pin = 3843 cfg->inputs[i].pin; 3844 snd_hda_add_imux_item(imux, label, idx, NULL); 3845 break; 3846 } 3847 } 3848 } 3849 if (imux->num_items >= 2 && cfg->num_inputs == imux->num_items) 3850 cx_auto_check_auto_mic(codec); 3851 if (imux->num_items > 1 && !spec->auto_mic) { 3852 for (i = 1; i < imux->num_items; i++) { 3853 if (spec->imux_info[i].adc != spec->imux_info[0].adc) { 3854 spec->adc_switching = 1; 3855 break; 3856 } 3857 } 3858 } 3859 } 3860 3861 /* get digital-input audio widget corresponding to the given pin */ 3862 static hda_nid_t cx_auto_get_dig_in(struct hda_codec *codec, hda_nid_t pin) 3863 { 3864 hda_nid_t nid, end_nid; 3865 3866 end_nid = codec->start_nid + codec->num_nodes; 3867 for (nid = codec->start_nid; nid < end_nid; nid++) { 3868 unsigned int wcaps = get_wcaps(codec, nid); 3869 unsigned int type = get_wcaps_type(wcaps); 3870 if (type == AC_WID_AUD_IN && (wcaps & AC_WCAP_DIGITAL)) { 3871 if (get_connection_index(codec, nid, pin) >= 0) 3872 return nid; 3873 } 3874 } 3875 return 0; 3876 } 3877 3878 static void cx_auto_parse_digital(struct hda_codec *codec) 3879 { 3880 struct conexant_spec *spec = codec->spec; 3881 struct auto_pin_cfg *cfg = &spec->autocfg; 3882 hda_nid_t nid; 3883 3884 if (cfg->dig_outs && 3885 snd_hda_get_connections(codec, cfg->dig_out_pins[0], &nid, 1) == 1) 3886 spec->multiout.dig_out_nid = nid; 3887 if (cfg->dig_in_pin) 3888 spec->dig_in_nid = cx_auto_get_dig_in(codec, cfg->dig_in_pin); 3889 } 3890 3891 #ifdef CONFIG_SND_HDA_INPUT_BEEP 3892 static void cx_auto_parse_beep(struct hda_codec *codec) 3893 { 3894 struct conexant_spec *spec = codec->spec; 3895 hda_nid_t nid, end_nid; 3896 3897 end_nid = codec->start_nid + codec->num_nodes; 3898 for (nid = codec->start_nid; nid < end_nid; nid++) 3899 if (get_wcaps_type(get_wcaps(codec, nid)) == AC_WID_BEEP) { 3900 set_beep_amp(spec, nid, 0, HDA_OUTPUT); 3901 break; 3902 } 3903 } 3904 #else 3905 #define cx_auto_parse_beep(codec) 3906 #endif 3907 3908 static bool found_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums) 3909 { 3910 int i; 3911 for (i = 0; i < nums; i++) 3912 if (list[i] == nid) 3913 return true; 3914 return false; 3915 } 3916 3917 /* parse extra-EAPD that aren't assigned to any pins */ 3918 static void cx_auto_parse_eapd(struct hda_codec *codec) 3919 { 3920 struct conexant_spec *spec = codec->spec; 3921 struct auto_pin_cfg *cfg = &spec->autocfg; 3922 hda_nid_t nid, end_nid; 3923 3924 end_nid = codec->start_nid + codec->num_nodes; 3925 for (nid = codec->start_nid; nid < end_nid; nid++) { 3926 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN) 3927 continue; 3928 if (!(snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)) 3929 continue; 3930 if (found_in_nid_list(nid, cfg->line_out_pins, cfg->line_outs) || 3931 found_in_nid_list(nid, cfg->hp_pins, cfg->hp_outs) || 3932 found_in_nid_list(nid, cfg->speaker_pins, cfg->speaker_outs)) 3933 continue; 3934 spec->eapds[spec->num_eapds++] = nid; 3935 if (spec->num_eapds >= ARRAY_SIZE(spec->eapds)) 3936 break; 3937 } 3938 } 3939 3940 static int cx_auto_parse_auto_config(struct hda_codec *codec) 3941 { 3942 struct conexant_spec *spec = codec->spec; 3943 int err; 3944 3945 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL); 3946 if (err < 0) 3947 return err; 3948 3949 cx_auto_parse_output(codec); 3950 cx_auto_parse_input(codec); 3951 cx_auto_parse_digital(codec); 3952 cx_auto_parse_beep(codec); 3953 cx_auto_parse_eapd(codec); 3954 return 0; 3955 } 3956 3957 static void cx_auto_turn_eapd(struct hda_codec *codec, int num_pins, 3958 hda_nid_t *pins, bool on) 3959 { 3960 int i; 3961 for (i = 0; i < num_pins; i++) { 3962 if (snd_hda_query_pin_caps(codec, pins[i]) & AC_PINCAP_EAPD) 3963 snd_hda_codec_write(codec, pins[i], 0, 3964 AC_VERB_SET_EAPD_BTLENABLE, 3965 on ? 0x02 : 0); 3966 } 3967 } 3968 3969 static void select_connection(struct hda_codec *codec, hda_nid_t pin, 3970 hda_nid_t src) 3971 { 3972 int idx = get_connection_index(codec, pin, src); 3973 if (idx >= 0) 3974 snd_hda_codec_write(codec, pin, 0, 3975 AC_VERB_SET_CONNECT_SEL, idx); 3976 } 3977 3978 static void mute_outputs(struct hda_codec *codec, int num_nids, 3979 const hda_nid_t *nids) 3980 { 3981 int i, val; 3982 3983 for (i = 0; i < num_nids; i++) { 3984 hda_nid_t nid = nids[i]; 3985 if (!(get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)) 3986 continue; 3987 if (query_amp_caps(codec, nid, HDA_OUTPUT) & AC_AMPCAP_MUTE) 3988 val = AMP_OUT_MUTE; 3989 else 3990 val = AMP_OUT_ZERO; 3991 snd_hda_codec_write(codec, nid, 0, 3992 AC_VERB_SET_AMP_GAIN_MUTE, val); 3993 } 3994 } 3995 3996 static void enable_unsol_pins(struct hda_codec *codec, int num_pins, 3997 hda_nid_t *pins, unsigned int tag) 3998 { 3999 int i; 4000 for (i = 0; i < num_pins; i++) 4001 snd_hda_codec_write(codec, pins[i], 0, 4002 AC_VERB_SET_UNSOLICITED_ENABLE, 4003 AC_USRSP_EN | tag); 4004 } 4005 4006 static void cx_auto_init_output(struct hda_codec *codec) 4007 { 4008 struct conexant_spec *spec = codec->spec; 4009 struct auto_pin_cfg *cfg = &spec->autocfg; 4010 hda_nid_t nid; 4011 int i; 4012 4013 mute_outputs(codec, spec->multiout.num_dacs, spec->multiout.dac_nids); 4014 for (i = 0; i < cfg->hp_outs; i++) 4015 snd_hda_codec_write(codec, cfg->hp_pins[i], 0, 4016 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP); 4017 mute_outputs(codec, cfg->hp_outs, cfg->hp_pins); 4018 mute_outputs(codec, cfg->line_outs, cfg->line_out_pins); 4019 mute_outputs(codec, cfg->speaker_outs, cfg->speaker_pins); 4020 for (i = 0; i < spec->dac_info_filled; i++) { 4021 nid = spec->dac_info[i].dac; 4022 if (!nid) 4023 nid = spec->multiout.dac_nids[0]; 4024 select_connection(codec, spec->dac_info[i].pin, nid); 4025 } 4026 if (spec->auto_mute) { 4027 enable_unsol_pins(codec, cfg->hp_outs, cfg->hp_pins, 4028 CONEXANT_HP_EVENT); 4029 spec->hp_present = detect_jacks(codec, cfg->hp_outs, 4030 cfg->hp_pins); 4031 if (spec->detect_line) { 4032 enable_unsol_pins(codec, cfg->line_outs, 4033 cfg->line_out_pins, 4034 CONEXANT_LINE_EVENT); 4035 spec->line_present = 4036 detect_jacks(codec, cfg->line_outs, 4037 cfg->line_out_pins); 4038 } 4039 } 4040 cx_auto_update_speakers(codec); 4041 /* turn on/off extra EAPDs, too */ 4042 cx_auto_turn_eapd(codec, spec->num_eapds, spec->eapds, true); 4043 } 4044 4045 static void cx_auto_init_input(struct hda_codec *codec) 4046 { 4047 struct conexant_spec *spec = codec->spec; 4048 struct auto_pin_cfg *cfg = &spec->autocfg; 4049 int i, val; 4050 4051 for (i = 0; i < spec->num_adc_nids; i++) { 4052 hda_nid_t nid = spec->adc_nids[i]; 4053 if (!(get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) 4054 continue; 4055 if (query_amp_caps(codec, nid, HDA_INPUT) & AC_AMPCAP_MUTE) 4056 val = AMP_IN_MUTE(0); 4057 else 4058 val = AMP_IN_UNMUTE(0); 4059 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, 4060 val); 4061 } 4062 4063 for (i = 0; i < cfg->num_inputs; i++) { 4064 unsigned int type; 4065 if (cfg->inputs[i].type == AUTO_PIN_MIC) 4066 type = PIN_VREF80; 4067 else 4068 type = PIN_IN; 4069 snd_hda_codec_write(codec, cfg->inputs[i].pin, 0, 4070 AC_VERB_SET_PIN_WIDGET_CONTROL, type); 4071 } 4072 4073 if (spec->auto_mic) { 4074 if (spec->auto_mic_ext >= 0) { 4075 snd_hda_codec_write(codec, 4076 cfg->inputs[spec->auto_mic_ext].pin, 0, 4077 AC_VERB_SET_UNSOLICITED_ENABLE, 4078 AC_USRSP_EN | CONEXANT_MIC_EVENT); 4079 } 4080 if (spec->auto_mic_dock >= 0) { 4081 snd_hda_codec_write(codec, 4082 cfg->inputs[spec->auto_mic_dock].pin, 0, 4083 AC_VERB_SET_UNSOLICITED_ENABLE, 4084 AC_USRSP_EN | CONEXANT_MIC_EVENT); 4085 } 4086 cx_auto_automic(codec); 4087 } else { 4088 select_input_connection(codec, spec->imux_info[0].adc, 4089 spec->imux_info[0].pin); 4090 } 4091 } 4092 4093 static void cx_auto_init_digital(struct hda_codec *codec) 4094 { 4095 struct conexant_spec *spec = codec->spec; 4096 struct auto_pin_cfg *cfg = &spec->autocfg; 4097 4098 if (spec->multiout.dig_out_nid) 4099 snd_hda_codec_write(codec, cfg->dig_out_pins[0], 0, 4100 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); 4101 if (spec->dig_in_nid) 4102 snd_hda_codec_write(codec, cfg->dig_in_pin, 0, 4103 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN); 4104 } 4105 4106 static int cx_auto_init(struct hda_codec *codec) 4107 { 4108 /*snd_hda_sequence_write(codec, cx_auto_init_verbs);*/ 4109 cx_auto_init_output(codec); 4110 cx_auto_init_input(codec); 4111 cx_auto_init_digital(codec); 4112 return 0; 4113 } 4114 4115 static int cx_auto_add_volume_idx(struct hda_codec *codec, const char *basename, 4116 const char *dir, int cidx, 4117 hda_nid_t nid, int hda_dir, int amp_idx) 4118 { 4119 static char name[32]; 4120 static struct snd_kcontrol_new knew[] = { 4121 HDA_CODEC_VOLUME(name, 0, 0, 0), 4122 HDA_CODEC_MUTE(name, 0, 0, 0), 4123 }; 4124 static const char * const sfx[2] = { "Volume", "Switch" }; 4125 int i, err; 4126 4127 for (i = 0; i < 2; i++) { 4128 struct snd_kcontrol *kctl; 4129 knew[i].private_value = HDA_COMPOSE_AMP_VAL(nid, 3, amp_idx, 4130 hda_dir); 4131 knew[i].subdevice = HDA_SUBDEV_AMP_FLAG; 4132 knew[i].index = cidx; 4133 snprintf(name, sizeof(name), "%s%s %s", basename, dir, sfx[i]); 4134 kctl = snd_ctl_new1(&knew[i], codec); 4135 if (!kctl) 4136 return -ENOMEM; 4137 err = snd_hda_ctl_add(codec, nid, kctl); 4138 if (err < 0) 4139 return err; 4140 if (!(query_amp_caps(codec, nid, hda_dir) & AC_AMPCAP_MUTE)) 4141 break; 4142 } 4143 return 0; 4144 } 4145 4146 #define cx_auto_add_volume(codec, str, dir, cidx, nid, hda_dir) \ 4147 cx_auto_add_volume_idx(codec, str, dir, cidx, nid, hda_dir, 0) 4148 4149 #define cx_auto_add_pb_volume(codec, nid, str, idx) \ 4150 cx_auto_add_volume(codec, str, " Playback", idx, nid, HDA_OUTPUT) 4151 4152 static int try_add_pb_volume(struct hda_codec *codec, hda_nid_t dac, 4153 hda_nid_t pin, const char *name, int idx) 4154 { 4155 unsigned int caps; 4156 caps = query_amp_caps(codec, dac, HDA_OUTPUT); 4157 if (caps & AC_AMPCAP_NUM_STEPS) 4158 return cx_auto_add_pb_volume(codec, dac, name, idx); 4159 caps = query_amp_caps(codec, pin, HDA_OUTPUT); 4160 if (caps & AC_AMPCAP_NUM_STEPS) 4161 return cx_auto_add_pb_volume(codec, pin, name, idx); 4162 return 0; 4163 } 4164 4165 static int cx_auto_build_output_controls(struct hda_codec *codec) 4166 { 4167 struct conexant_spec *spec = codec->spec; 4168 int i, err; 4169 int num_line = 0, num_hp = 0, num_spk = 0; 4170 static const char * const texts[3] = { "Front", "Surround", "CLFE" }; 4171 4172 if (spec->dac_info_filled == 1) 4173 return try_add_pb_volume(codec, spec->dac_info[0].dac, 4174 spec->dac_info[0].pin, 4175 "Master", 0); 4176 4177 for (i = 0; i < spec->dac_info_filled; i++) { 4178 const char *label; 4179 int idx, type; 4180 if (!spec->dac_info[i].dac) 4181 continue; 4182 type = spec->dac_info[i].type; 4183 if (type == AUTO_PIN_LINE_OUT) 4184 type = spec->autocfg.line_out_type; 4185 switch (type) { 4186 case AUTO_PIN_LINE_OUT: 4187 default: 4188 label = texts[num_line++]; 4189 idx = 0; 4190 break; 4191 case AUTO_PIN_HP_OUT: 4192 label = "Headphone"; 4193 idx = num_hp++; 4194 break; 4195 case AUTO_PIN_SPEAKER_OUT: 4196 label = "Speaker"; 4197 idx = num_spk++; 4198 break; 4199 } 4200 err = try_add_pb_volume(codec, spec->dac_info[i].dac, 4201 spec->dac_info[i].pin, 4202 label, idx); 4203 if (err < 0) 4204 return err; 4205 } 4206 4207 if (spec->auto_mute) { 4208 err = snd_hda_add_new_ctls(codec, cx_automute_mode_enum); 4209 if (err < 0) 4210 return err; 4211 } 4212 4213 return 0; 4214 } 4215 4216 static int cx_auto_add_capture_volume(struct hda_codec *codec, hda_nid_t nid, 4217 const char *label, const char *pfx, 4218 int cidx) 4219 { 4220 struct conexant_spec *spec = codec->spec; 4221 int i; 4222 4223 for (i = 0; i < spec->num_adc_nids; i++) { 4224 hda_nid_t adc_nid = spec->adc_nids[i]; 4225 int idx = get_input_connection(codec, adc_nid, nid); 4226 if (idx < 0) 4227 continue; 4228 return cx_auto_add_volume_idx(codec, label, pfx, 4229 cidx, adc_nid, HDA_INPUT, idx); 4230 } 4231 return 0; 4232 } 4233 4234 static int cx_auto_add_boost_volume(struct hda_codec *codec, int idx, 4235 const char *label, int cidx) 4236 { 4237 struct conexant_spec *spec = codec->spec; 4238 hda_nid_t mux, nid; 4239 int i, con; 4240 4241 nid = spec->imux_info[idx].pin; 4242 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) 4243 return cx_auto_add_volume(codec, label, " Boost", cidx, 4244 nid, HDA_INPUT); 4245 con = __select_input_connection(codec, spec->imux_info[idx].adc, nid, 4246 &mux, false, 0); 4247 if (con < 0) 4248 return 0; 4249 for (i = 0; i < idx; i++) { 4250 if (spec->imux_info[i].boost == mux) 4251 return 0; /* already present */ 4252 } 4253 4254 if (get_wcaps(codec, mux) & AC_WCAP_OUT_AMP) { 4255 spec->imux_info[idx].boost = mux; 4256 return cx_auto_add_volume(codec, label, " Boost", 0, 4257 mux, HDA_OUTPUT); 4258 } 4259 return 0; 4260 } 4261 4262 static int cx_auto_build_input_controls(struct hda_codec *codec) 4263 { 4264 struct conexant_spec *spec = codec->spec; 4265 struct hda_input_mux *imux = &spec->private_imux; 4266 const char *prev_label; 4267 int input_conn[HDA_MAX_NUM_INPUTS]; 4268 int i, err, cidx; 4269 int multi_connection; 4270 4271 multi_connection = 0; 4272 for (i = 0; i < imux->num_items; i++) { 4273 cidx = get_input_connection(codec, spec->imux_info[i].adc, 4274 spec->imux_info[i].pin); 4275 input_conn[i] = (spec->imux_info[i].adc << 8) | cidx; 4276 if (i > 0 && input_conn[i] != input_conn[0]) 4277 multi_connection = 1; 4278 } 4279 4280 prev_label = NULL; 4281 cidx = 0; 4282 for (i = 0; i < imux->num_items; i++) { 4283 hda_nid_t nid = spec->imux_info[i].pin; 4284 const char *label; 4285 4286 label = hda_get_autocfg_input_label(codec, &spec->autocfg, 4287 spec->imux_info[i].index); 4288 if (label == prev_label) 4289 cidx++; 4290 else 4291 cidx = 0; 4292 prev_label = label; 4293 4294 err = cx_auto_add_boost_volume(codec, i, label, cidx); 4295 if (err < 0) 4296 return err; 4297 4298 if (!multi_connection) { 4299 if (i > 0) 4300 continue; 4301 err = cx_auto_add_capture_volume(codec, nid, 4302 "Capture", "", cidx); 4303 } else { 4304 err = cx_auto_add_capture_volume(codec, nid, 4305 label, " Capture", cidx); 4306 } 4307 if (err < 0) 4308 return err; 4309 } 4310 4311 if (spec->private_imux.num_items > 1 && !spec->auto_mic) { 4312 err = snd_hda_add_new_ctls(codec, cx_auto_capture_mixers); 4313 if (err < 0) 4314 return err; 4315 } 4316 4317 return 0; 4318 } 4319 4320 static int cx_auto_build_controls(struct hda_codec *codec) 4321 { 4322 int err; 4323 4324 err = cx_auto_build_output_controls(codec); 4325 if (err < 0) 4326 return err; 4327 err = cx_auto_build_input_controls(codec); 4328 if (err < 0) 4329 return err; 4330 return conexant_build_controls(codec); 4331 } 4332 4333 static int cx_auto_search_adcs(struct hda_codec *codec) 4334 { 4335 struct conexant_spec *spec = codec->spec; 4336 hda_nid_t nid, end_nid; 4337 4338 end_nid = codec->start_nid + codec->num_nodes; 4339 for (nid = codec->start_nid; nid < end_nid; nid++) { 4340 unsigned int caps = get_wcaps(codec, nid); 4341 if (get_wcaps_type(caps) != AC_WID_AUD_IN) 4342 continue; 4343 if (caps & AC_WCAP_DIGITAL) 4344 continue; 4345 if (snd_BUG_ON(spec->num_adc_nids >= 4346 ARRAY_SIZE(spec->private_adc_nids))) 4347 break; 4348 spec->private_adc_nids[spec->num_adc_nids++] = nid; 4349 } 4350 spec->adc_nids = spec->private_adc_nids; 4351 return 0; 4352 } 4353 4354 4355 static const struct hda_codec_ops cx_auto_patch_ops = { 4356 .build_controls = cx_auto_build_controls, 4357 .build_pcms = conexant_build_pcms, 4358 .init = cx_auto_init, 4359 .free = conexant_free, 4360 .unsol_event = cx_auto_unsol_event, 4361 #ifdef CONFIG_SND_HDA_POWER_SAVE 4362 .suspend = conexant_suspend, 4363 #endif 4364 .reboot_notify = snd_hda_shutup_pins, 4365 }; 4366 4367 static int patch_conexant_auto(struct hda_codec *codec) 4368 { 4369 struct conexant_spec *spec; 4370 int err; 4371 4372 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 4373 codec->chip_name); 4374 4375 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 4376 if (!spec) 4377 return -ENOMEM; 4378 codec->spec = spec; 4379 codec->pin_amp_workaround = 1; 4380 err = cx_auto_search_adcs(codec); 4381 if (err < 0) 4382 return err; 4383 err = cx_auto_parse_auto_config(codec); 4384 if (err < 0) { 4385 kfree(codec->spec); 4386 codec->spec = NULL; 4387 return err; 4388 } 4389 spec->capture_stream = &cx_auto_pcm_analog_capture; 4390 codec->patch_ops = cx_auto_patch_ops; 4391 if (spec->beep_amp) 4392 snd_hda_attach_beep_device(codec, spec->beep_amp); 4393 return 0; 4394 } 4395 4396 /* 4397 */ 4398 4399 static const struct hda_codec_preset snd_hda_preset_conexant[] = { 4400 { .id = 0x14f15045, .name = "CX20549 (Venice)", 4401 .patch = patch_cxt5045 }, 4402 { .id = 0x14f15047, .name = "CX20551 (Waikiki)", 4403 .patch = patch_cxt5047 }, 4404 { .id = 0x14f15051, .name = "CX20561 (Hermosa)", 4405 .patch = patch_cxt5051 }, 4406 { .id = 0x14f15066, .name = "CX20582 (Pebble)", 4407 .patch = patch_cxt5066 }, 4408 { .id = 0x14f15067, .name = "CX20583 (Pebble HSF)", 4409 .patch = patch_cxt5066 }, 4410 { .id = 0x14f15068, .name = "CX20584", 4411 .patch = patch_cxt5066 }, 4412 { .id = 0x14f15069, .name = "CX20585", 4413 .patch = patch_cxt5066 }, 4414 { .id = 0x14f1506c, .name = "CX20588", 4415 .patch = patch_cxt5066 }, 4416 { .id = 0x14f1506e, .name = "CX20590", 4417 .patch = patch_cxt5066 }, 4418 { .id = 0x14f15097, .name = "CX20631", 4419 .patch = patch_conexant_auto }, 4420 { .id = 0x14f15098, .name = "CX20632", 4421 .patch = patch_conexant_auto }, 4422 { .id = 0x14f150a1, .name = "CX20641", 4423 .patch = patch_conexant_auto }, 4424 { .id = 0x14f150a2, .name = "CX20642", 4425 .patch = patch_conexant_auto }, 4426 { .id = 0x14f150ab, .name = "CX20651", 4427 .patch = patch_conexant_auto }, 4428 { .id = 0x14f150ac, .name = "CX20652", 4429 .patch = patch_conexant_auto }, 4430 { .id = 0x14f150b8, .name = "CX20664", 4431 .patch = patch_conexant_auto }, 4432 { .id = 0x14f150b9, .name = "CX20665", 4433 .patch = patch_conexant_auto }, 4434 {} /* terminator */ 4435 }; 4436 4437 MODULE_ALIAS("snd-hda-codec-id:14f15045"); 4438 MODULE_ALIAS("snd-hda-codec-id:14f15047"); 4439 MODULE_ALIAS("snd-hda-codec-id:14f15051"); 4440 MODULE_ALIAS("snd-hda-codec-id:14f15066"); 4441 MODULE_ALIAS("snd-hda-codec-id:14f15067"); 4442 MODULE_ALIAS("snd-hda-codec-id:14f15068"); 4443 MODULE_ALIAS("snd-hda-codec-id:14f15069"); 4444 MODULE_ALIAS("snd-hda-codec-id:14f1506c"); 4445 MODULE_ALIAS("snd-hda-codec-id:14f1506e"); 4446 MODULE_ALIAS("snd-hda-codec-id:14f15097"); 4447 MODULE_ALIAS("snd-hda-codec-id:14f15098"); 4448 MODULE_ALIAS("snd-hda-codec-id:14f150a1"); 4449 MODULE_ALIAS("snd-hda-codec-id:14f150a2"); 4450 MODULE_ALIAS("snd-hda-codec-id:14f150ab"); 4451 MODULE_ALIAS("snd-hda-codec-id:14f150ac"); 4452 MODULE_ALIAS("snd-hda-codec-id:14f150b8"); 4453 MODULE_ALIAS("snd-hda-codec-id:14f150b9"); 4454 4455 MODULE_LICENSE("GPL"); 4456 MODULE_DESCRIPTION("Conexant HD-audio codec"); 4457 4458 static struct hda_codec_preset_list conexant_list = { 4459 .preset = snd_hda_preset_conexant, 4460 .owner = THIS_MODULE, 4461 }; 4462 4463 static int __init patch_conexant_init(void) 4464 { 4465 return snd_hda_add_codec_preset(&conexant_list); 4466 } 4467 4468 static void __exit patch_conexant_exit(void) 4469 { 4470 snd_hda_delete_codec_preset(&conexant_list); 4471 } 4472 4473 module_init(patch_conexant_init) 4474 module_exit(patch_conexant_exit) 4475