1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Cirrus Logic CS421x HD-audio codec 4 */ 5 6 #include <linux/init.h> 7 #include <linux/slab.h> 8 #include <linux/module.h> 9 #include <sound/core.h> 10 #include <linux/pci.h> 11 #include <sound/tlv.h> 12 #include <sound/hda_codec.h> 13 #include "hda_local.h" 14 #include "hda_auto_parser.h" 15 #include "hda_jack.h" 16 #include "../generic.h" 17 18 struct cs_spec { 19 struct hda_gen_spec gen; 20 21 unsigned int gpio_mask; 22 unsigned int gpio_dir; 23 unsigned int gpio_data; 24 unsigned int gpio_eapd_hp; /* EAPD GPIO bit for headphones */ 25 unsigned int gpio_eapd_speaker; /* EAPD GPIO bit for speakers */ 26 27 /* CS421x */ 28 unsigned int spdif_detect:1; 29 unsigned int spdif_present:1; 30 unsigned int sense_b:1; 31 hda_nid_t vendor_nid; 32 33 /* for MBP SPDIF control */ 34 int (*spdif_sw_put)(struct snd_kcontrol *kcontrol, 35 struct snd_ctl_elem_value *ucontrol); 36 }; 37 38 /* CS421x boards */ 39 enum { 40 CS421X_CDB4210, 41 CS421X_SENSE_B, 42 CS421X_STUMPY, 43 }; 44 45 /* Vendor-specific processing widget */ 46 #define CS_DIG_OUT1_PIN_NID 0x10 47 #define CS_DIG_OUT2_PIN_NID 0x15 48 #define CS_DMIC1_PIN_NID 0x0e 49 #define CS_DMIC2_PIN_NID 0x12 50 51 /* coef indices */ 52 #define IDX_SPDIF_STAT 0x0000 53 #define IDX_SPDIF_CTL 0x0001 54 #define IDX_ADC_CFG 0x0002 55 /* SZC bitmask, 4 modes below: 56 * 0 = immediate, 57 * 1 = digital immediate, analog zero-cross 58 * 2 = digtail & analog soft-ramp 59 * 3 = digital soft-ramp, analog zero-cross 60 */ 61 #define CS_COEF_ADC_SZC_MASK (3 << 0) 62 #define CS_COEF_ADC_MIC_SZC_MODE (3 << 0) /* SZC setup for mic */ 63 #define CS_COEF_ADC_LI_SZC_MODE (3 << 0) /* SZC setup for line-in */ 64 /* PGA mode: 0 = differential, 1 = signle-ended */ 65 #define CS_COEF_ADC_MIC_PGA_MODE (1 << 5) /* PGA setup for mic */ 66 #define CS_COEF_ADC_LI_PGA_MODE (1 << 6) /* PGA setup for line-in */ 67 #define IDX_DAC_CFG 0x0003 68 /* SZC bitmask, 4 modes below: 69 * 0 = Immediate 70 * 1 = zero-cross 71 * 2 = soft-ramp 72 * 3 = soft-ramp on zero-cross 73 */ 74 #define CS_COEF_DAC_HP_SZC_MODE (3 << 0) /* nid 0x02 */ 75 #define CS_COEF_DAC_LO_SZC_MODE (3 << 2) /* nid 0x03 */ 76 #define CS_COEF_DAC_SPK_SZC_MODE (3 << 4) /* nid 0x04 */ 77 78 #define IDX_BEEP_CFG 0x0004 79 /* 0x0008 - test reg key */ 80 /* 0x0009 - 0x0014 -> 12 test regs */ 81 /* 0x0015 - visibility reg */ 82 83 /* 84 * Cirrus Logic CS4210 85 * 86 * 1 DAC => HP(sense) / Speakers, 87 * 1 ADC <= LineIn(sense) / MicIn / DMicIn, 88 * 1 SPDIF OUT => SPDIF Transmitter(sense) 89 */ 90 #define CS4210_DAC_NID 0x02 91 #define CS4210_ADC_NID 0x03 92 #define CS4210_VENDOR_NID 0x0B 93 #define CS421X_DMIC_PIN_NID 0x09 /* Port E */ 94 #define CS421X_SPDIF_PIN_NID 0x0A /* Port H */ 95 96 #define CS421X_IDX_DEV_CFG 0x01 97 #define CS421X_IDX_ADC_CFG 0x02 98 #define CS421X_IDX_DAC_CFG 0x03 99 #define CS421X_IDX_SPK_CTL 0x04 100 101 /* Cirrus Logic CS4213 is like CS4210 but does not have SPDIF input/output */ 102 #define CS4213_VENDOR_NID 0x09 103 104 105 static inline int cs_vendor_coef_get(struct hda_codec *codec, unsigned int idx) 106 { 107 struct cs_spec *spec = codec->spec; 108 109 snd_hda_codec_write(codec, spec->vendor_nid, 0, 110 AC_VERB_SET_COEF_INDEX, idx); 111 return snd_hda_codec_read(codec, spec->vendor_nid, 0, 112 AC_VERB_GET_PROC_COEF, 0); 113 } 114 115 static inline void cs_vendor_coef_set(struct hda_codec *codec, unsigned int idx, 116 unsigned int coef) 117 { 118 struct cs_spec *spec = codec->spec; 119 120 snd_hda_codec_write(codec, spec->vendor_nid, 0, 121 AC_VERB_SET_COEF_INDEX, idx); 122 snd_hda_codec_write(codec, spec->vendor_nid, 0, 123 AC_VERB_SET_PROC_COEF, coef); 124 } 125 126 /* 127 * auto-mute and auto-mic switching 128 * CS421x auto-output redirecting 129 * HP/SPK/SPDIF 130 */ 131 132 static void cs_automute(struct hda_codec *codec) 133 { 134 struct cs_spec *spec = codec->spec; 135 136 /* mute HPs if spdif jack (SENSE_B) is present */ 137 spec->gen.master_mute = !!(spec->spdif_present && spec->sense_b); 138 139 snd_hda_gen_update_outputs(codec); 140 141 if (spec->gpio_eapd_hp || spec->gpio_eapd_speaker) { 142 if (spec->gen.automute_speaker) 143 spec->gpio_data = spec->gen.hp_jack_present ? 144 spec->gpio_eapd_hp : spec->gpio_eapd_speaker; 145 else 146 spec->gpio_data = 147 spec->gpio_eapd_hp | spec->gpio_eapd_speaker; 148 snd_hda_codec_write(codec, 0x01, 0, 149 AC_VERB_SET_GPIO_DATA, spec->gpio_data); 150 } 151 } 152 153 static bool is_active_pin(struct hda_codec *codec, hda_nid_t nid) 154 { 155 unsigned int val; 156 157 val = snd_hda_codec_get_pincfg(codec, nid); 158 return (get_defcfg_connect(val) != AC_JACK_PORT_NONE); 159 } 160 161 static struct cs_spec *cs_alloc_spec(struct hda_codec *codec, int vendor_nid) 162 { 163 struct cs_spec *spec; 164 165 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 166 if (!spec) 167 return NULL; 168 codec->spec = spec; 169 spec->vendor_nid = vendor_nid; 170 codec->power_save_node = 1; 171 snd_hda_gen_spec_init(&spec->gen); 172 173 return spec; 174 } 175 176 /* 177 * Cirrus Logic CS4210 178 * 179 * 1 DAC => HP(sense) / Speakers, 180 * 1 ADC <= LineIn(sense) / MicIn / DMicIn, 181 * 1 SPDIF OUT => SPDIF Transmitter(sense) 182 */ 183 184 /* CS4210 board names */ 185 static const struct hda_model_fixup cs421x_models[] = { 186 { .id = CS421X_CDB4210, .name = "cdb4210" }, 187 { .id = CS421X_STUMPY, .name = "stumpy" }, 188 {} 189 }; 190 191 static const struct hda_quirk cs421x_fixup_tbl[] = { 192 /* Test Intel board + CDB2410 */ 193 SND_PCI_QUIRK(0x8086, 0x5001, "DP45SG/CDB4210", CS421X_CDB4210), 194 {} /* terminator */ 195 }; 196 197 /* CS4210 board pinconfigs */ 198 /* Default CS4210 (CDB4210)*/ 199 static const struct hda_pintbl cdb4210_pincfgs[] = { 200 { 0x05, 0x0321401f }, 201 { 0x06, 0x90170010 }, 202 { 0x07, 0x03813031 }, 203 { 0x08, 0xb7a70037 }, 204 { 0x09, 0xb7a6003e }, 205 { 0x0a, 0x034510f0 }, 206 {} /* terminator */ 207 }; 208 209 /* Stumpy ChromeBox */ 210 static const struct hda_pintbl stumpy_pincfgs[] = { 211 { 0x05, 0x022120f0 }, 212 { 0x06, 0x901700f0 }, 213 { 0x07, 0x02a120f0 }, 214 { 0x08, 0x77a70037 }, 215 { 0x09, 0x77a6003e }, 216 { 0x0a, 0x434510f0 }, 217 {} /* terminator */ 218 }; 219 220 /* Setup GPIO/SENSE for each board (if used) */ 221 static void cs421x_fixup_sense_b(struct hda_codec *codec, 222 const struct hda_fixup *fix, int action) 223 { 224 struct cs_spec *spec = codec->spec; 225 226 if (action == HDA_FIXUP_ACT_PRE_PROBE) 227 spec->sense_b = 1; 228 } 229 230 static const struct hda_fixup cs421x_fixups[] = { 231 [CS421X_CDB4210] = { 232 .type = HDA_FIXUP_PINS, 233 .v.pins = cdb4210_pincfgs, 234 .chained = true, 235 .chain_id = CS421X_SENSE_B, 236 }, 237 [CS421X_SENSE_B] = { 238 .type = HDA_FIXUP_FUNC, 239 .v.func = cs421x_fixup_sense_b, 240 }, 241 [CS421X_STUMPY] = { 242 .type = HDA_FIXUP_PINS, 243 .v.pins = stumpy_pincfgs, 244 }, 245 }; 246 247 static const struct hda_verb cs421x_coef_init_verbs[] = { 248 {0x0B, AC_VERB_SET_PROC_STATE, 1}, 249 {0x0B, AC_VERB_SET_COEF_INDEX, CS421X_IDX_DEV_CFG}, 250 /* 251 * Disable Coefficient Index Auto-Increment(DAI)=1, 252 * PDREF=0 253 */ 254 {0x0B, AC_VERB_SET_PROC_COEF, 0x0001 }, 255 256 {0x0B, AC_VERB_SET_COEF_INDEX, CS421X_IDX_ADC_CFG}, 257 /* ADC SZCMode = Digital Soft Ramp */ 258 {0x0B, AC_VERB_SET_PROC_COEF, 0x0002 }, 259 260 {0x0B, AC_VERB_SET_COEF_INDEX, CS421X_IDX_DAC_CFG}, 261 {0x0B, AC_VERB_SET_PROC_COEF, 262 (0x0002 /* DAC SZCMode = Digital Soft Ramp */ 263 | 0x0004 /* Mute DAC on FIFO error */ 264 | 0x0008 /* Enable DAC High Pass Filter */ 265 )}, 266 {} /* terminator */ 267 }; 268 269 /* Errata: CS4210 rev A1 Silicon 270 * 271 * http://www.cirrus.com/en/pubs/errata/ 272 * 273 * Description: 274 * 1. Performance degredation is present in the ADC. 275 * 2. Speaker output is not completely muted upon HP detect. 276 * 3. Noise is present when clipping occurs on the amplified 277 * speaker outputs. 278 * 279 * Workaround: 280 * The following verb sequence written to the registers during 281 * initialization will correct the issues listed above. 282 */ 283 284 static const struct hda_verb cs421x_coef_init_verbs_A1_silicon_fixes[] = { 285 {0x0B, AC_VERB_SET_PROC_STATE, 0x01}, /* VPW: processing on */ 286 287 {0x0B, AC_VERB_SET_COEF_INDEX, 0x0006}, 288 {0x0B, AC_VERB_SET_PROC_COEF, 0x9999}, /* Test mode: on */ 289 290 {0x0B, AC_VERB_SET_COEF_INDEX, 0x000A}, 291 {0x0B, AC_VERB_SET_PROC_COEF, 0x14CB}, /* Chop double */ 292 293 {0x0B, AC_VERB_SET_COEF_INDEX, 0x0011}, 294 {0x0B, AC_VERB_SET_PROC_COEF, 0xA2D0}, /* Increase ADC current */ 295 296 {0x0B, AC_VERB_SET_COEF_INDEX, 0x001A}, 297 {0x0B, AC_VERB_SET_PROC_COEF, 0x02A9}, /* Mute speaker */ 298 299 {0x0B, AC_VERB_SET_COEF_INDEX, 0x001B}, 300 {0x0B, AC_VERB_SET_PROC_COEF, 0X1006}, /* Remove noise */ 301 302 {} /* terminator */ 303 }; 304 305 /* Speaker Amp Gain is controlled by the vendor widget's coef 4 */ 306 static const DECLARE_TLV_DB_SCALE(cs421x_speaker_boost_db_scale, 900, 300, 0); 307 308 static int cs421x_boost_vol_info(struct snd_kcontrol *kcontrol, 309 struct snd_ctl_elem_info *uinfo) 310 { 311 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 312 uinfo->count = 1; 313 uinfo->value.integer.min = 0; 314 uinfo->value.integer.max = 3; 315 return 0; 316 } 317 318 static int cs421x_boost_vol_get(struct snd_kcontrol *kcontrol, 319 struct snd_ctl_elem_value *ucontrol) 320 { 321 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 322 323 ucontrol->value.integer.value[0] = 324 cs_vendor_coef_get(codec, CS421X_IDX_SPK_CTL) & 0x0003; 325 return 0; 326 } 327 328 static int cs421x_boost_vol_put(struct snd_kcontrol *kcontrol, 329 struct snd_ctl_elem_value *ucontrol) 330 { 331 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 332 333 unsigned int vol = ucontrol->value.integer.value[0]; 334 unsigned int coef = 335 cs_vendor_coef_get(codec, CS421X_IDX_SPK_CTL); 336 unsigned int original_coef = coef; 337 338 coef &= ~0x0003; 339 coef |= (vol & 0x0003); 340 if (original_coef != coef) { 341 cs_vendor_coef_set(codec, CS421X_IDX_SPK_CTL, coef); 342 return 1; 343 } 344 345 return 0; 346 } 347 348 static const struct snd_kcontrol_new cs421x_speaker_boost_ctl = { 349 350 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 351 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | 352 SNDRV_CTL_ELEM_ACCESS_TLV_READ), 353 .name = "Speaker Boost Playback Volume", 354 .info = cs421x_boost_vol_info, 355 .get = cs421x_boost_vol_get, 356 .put = cs421x_boost_vol_put, 357 .tlv = { .p = cs421x_speaker_boost_db_scale }, 358 }; 359 360 static void cs4210_pinmux_init(struct hda_codec *codec) 361 { 362 struct cs_spec *spec = codec->spec; 363 unsigned int def_conf, coef; 364 365 /* GPIO, DMIC_SCL, DMIC_SDA and SENSE_B are multiplexed */ 366 coef = cs_vendor_coef_get(codec, CS421X_IDX_DEV_CFG); 367 368 if (spec->gpio_mask) 369 coef |= 0x0008; /* B1,B2 are GPIOs */ 370 else 371 coef &= ~0x0008; 372 373 if (spec->sense_b) 374 coef |= 0x0010; /* B2 is SENSE_B, not inverted */ 375 else 376 coef &= ~0x0010; 377 378 cs_vendor_coef_set(codec, CS421X_IDX_DEV_CFG, coef); 379 380 if ((spec->gpio_mask || spec->sense_b) && 381 is_active_pin(codec, CS421X_DMIC_PIN_NID)) { 382 383 /* 384 * GPIO or SENSE_B forced - disconnect the DMIC pin. 385 */ 386 def_conf = snd_hda_codec_get_pincfg(codec, CS421X_DMIC_PIN_NID); 387 def_conf &= ~AC_DEFCFG_PORT_CONN; 388 def_conf |= (AC_JACK_PORT_NONE << AC_DEFCFG_PORT_CONN_SHIFT); 389 snd_hda_codec_set_pincfg(codec, CS421X_DMIC_PIN_NID, def_conf); 390 } 391 } 392 393 static void cs4210_spdif_automute(struct hda_codec *codec, 394 struct hda_jack_callback *tbl) 395 { 396 struct cs_spec *spec = codec->spec; 397 bool spdif_present = false; 398 hda_nid_t spdif_pin = spec->gen.autocfg.dig_out_pins[0]; 399 400 /* detect on spdif is specific to CS4210 */ 401 if (!spec->spdif_detect || 402 spec->vendor_nid != CS4210_VENDOR_NID) 403 return; 404 405 spdif_present = snd_hda_jack_detect(codec, spdif_pin); 406 if (spdif_present == spec->spdif_present) 407 return; 408 409 spec->spdif_present = spdif_present; 410 /* SPDIF TX on/off */ 411 snd_hda_set_pin_ctl(codec, spdif_pin, spdif_present ? PIN_OUT : 0); 412 413 cs_automute(codec); 414 } 415 416 static void parse_cs421x_digital(struct hda_codec *codec) 417 { 418 struct cs_spec *spec = codec->spec; 419 struct auto_pin_cfg *cfg = &spec->gen.autocfg; 420 int i; 421 422 for (i = 0; i < cfg->dig_outs; i++) { 423 hda_nid_t nid = cfg->dig_out_pins[i]; 424 425 if (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP) { 426 spec->spdif_detect = 1; 427 snd_hda_jack_detect_enable_callback(codec, nid, 428 cs4210_spdif_automute); 429 } 430 } 431 } 432 433 static int cs421x_init(struct hda_codec *codec) 434 { 435 struct cs_spec *spec = codec->spec; 436 437 if (spec->vendor_nid == CS4210_VENDOR_NID) { 438 snd_hda_sequence_write(codec, cs421x_coef_init_verbs); 439 snd_hda_sequence_write(codec, cs421x_coef_init_verbs_A1_silicon_fixes); 440 cs4210_pinmux_init(codec); 441 } 442 443 snd_hda_gen_init(codec); 444 445 if (spec->gpio_mask) { 446 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_MASK, 447 spec->gpio_mask); 448 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DIRECTION, 449 spec->gpio_dir); 450 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 451 spec->gpio_data); 452 } 453 454 cs4210_spdif_automute(codec, NULL); 455 456 return 0; 457 } 458 459 static void fix_volume_caps(struct hda_codec *codec, hda_nid_t dac) 460 { 461 unsigned int caps; 462 463 /* set the upper-limit for mixer amp to 0dB */ 464 caps = query_amp_caps(codec, dac, HDA_OUTPUT); 465 caps &= ~(0x7f << AC_AMPCAP_NUM_STEPS_SHIFT); 466 caps |= ((caps >> AC_AMPCAP_OFFSET_SHIFT) & 0x7f) 467 << AC_AMPCAP_NUM_STEPS_SHIFT; 468 snd_hda_override_amp_caps(codec, dac, HDA_OUTPUT, caps); 469 } 470 471 static int cs421x_parse_auto_config(struct hda_codec *codec) 472 { 473 struct cs_spec *spec = codec->spec; 474 hda_nid_t dac = CS4210_DAC_NID; 475 int err; 476 477 fix_volume_caps(codec, dac); 478 479 err = snd_hda_parse_pin_defcfg(codec, &spec->gen.autocfg, NULL, 0); 480 if (err < 0) 481 return err; 482 483 err = snd_hda_gen_parse_auto_config(codec, &spec->gen.autocfg); 484 if (err < 0) 485 return err; 486 487 parse_cs421x_digital(codec); 488 489 if (spec->gen.autocfg.speaker_outs && 490 spec->vendor_nid == CS4210_VENDOR_NID) { 491 if (!snd_hda_gen_add_kctl(&spec->gen, NULL, 492 &cs421x_speaker_boost_ctl)) 493 return -ENOMEM; 494 } 495 496 return 0; 497 } 498 499 /* 500 * Manage PDREF, when transitioning to D3hot 501 * (DAC,ADC) -> D3, PDREF=1, AFG->D3 502 */ 503 static int cs421x_suspend(struct hda_codec *codec) 504 { 505 struct cs_spec *spec = codec->spec; 506 unsigned int coef; 507 508 snd_hda_shutup_pins(codec); 509 510 snd_hda_codec_write(codec, CS4210_DAC_NID, 0, 511 AC_VERB_SET_POWER_STATE, AC_PWRST_D3); 512 snd_hda_codec_write(codec, CS4210_ADC_NID, 0, 513 AC_VERB_SET_POWER_STATE, AC_PWRST_D3); 514 515 if (spec->vendor_nid == CS4210_VENDOR_NID) { 516 coef = cs_vendor_coef_get(codec, CS421X_IDX_DEV_CFG); 517 coef |= 0x0004; /* PDREF */ 518 cs_vendor_coef_set(codec, CS421X_IDX_DEV_CFG, coef); 519 } 520 521 return 0; 522 } 523 524 static int cs421x_probe(struct hda_codec *codec, const struct hda_device_id *id) 525 { 526 struct cs_spec *spec; 527 int err; 528 529 spec = cs_alloc_spec(codec, id->driver_data); 530 if (!spec) 531 return -ENOMEM; 532 533 spec->gen.automute_hook = cs_automute; 534 535 if (spec->vendor_nid == CS4210_VENDOR_NID) { 536 snd_hda_pick_fixup(codec, cs421x_models, cs421x_fixup_tbl, 537 cs421x_fixups); 538 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); 539 540 /* 541 * Update the GPIO/DMIC/SENSE_B pinmux before the configuration 542 * is auto-parsed. If GPIO or SENSE_B is forced, DMIC input 543 * is disabled. 544 */ 545 cs4210_pinmux_init(codec); 546 } 547 548 err = cs421x_parse_auto_config(codec); 549 if (err < 0) 550 goto error; 551 552 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); 553 554 return 0; 555 556 error: 557 snd_hda_gen_remove(codec); 558 return err; 559 } 560 561 static const struct hda_codec_ops cs421x_codec_ops = { 562 .probe = cs421x_probe, 563 .remove = snd_hda_gen_remove, 564 .build_controls = snd_hda_gen_build_controls, 565 .build_pcms = snd_hda_gen_build_pcms, 566 .init = cs421x_init, 567 .unsol_event = snd_hda_jack_unsol_event, 568 .suspend = cs421x_suspend, 569 .stream_pm = snd_hda_gen_stream_pm, 570 }; 571 572 /* 573 * driver entries 574 */ 575 static const struct hda_device_id snd_hda_id_cs421x[] = { 576 HDA_CODEC_ID_MODEL(0x10134210, "CS4210", CS4210_VENDOR_NID), 577 HDA_CODEC_ID_MODEL(0x10134213, "CS4213", CS4213_VENDOR_NID), 578 {} /* terminator */ 579 }; 580 MODULE_DEVICE_TABLE(hdaudio, snd_hda_id_cs421x); 581 582 MODULE_LICENSE("GPL"); 583 MODULE_DESCRIPTION("Cirrus Logic CS421x HD-audio codec"); 584 585 static struct hda_codec_driver cs421x_driver = { 586 .id = snd_hda_id_cs421x, 587 .ops = &cs421x_codec_ops, 588 }; 589 590 module_hda_codec_driver(cs421x_driver); 591