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