1 // SPDX-License-Identifier: GPL-2.0 2 // 3 // CS42L43 CODEC driver jack handling 4 // 5 // Copyright (C) 2022-2023 Cirrus Logic, Inc. and 6 // Cirrus Logic International Semiconductor Ltd. 7 8 #include <linux/build_bug.h> 9 #include <linux/completion.h> 10 #include <linux/delay.h> 11 #include <linux/errno.h> 12 #include <linux/irq.h> 13 #include <linux/jiffies.h> 14 #include <linux/mfd/cs42l43.h> 15 #include <linux/mfd/cs42l43-regs.h> 16 #include <linux/mutex.h> 17 #include <linux/pm_runtime.h> 18 #include <linux/property.h> 19 #include <linux/regmap.h> 20 #include <linux/time.h> 21 #include <linux/workqueue.h> 22 #include <sound/control.h> 23 #include <sound/jack.h> 24 #include <sound/pcm.h> 25 #include <sound/pcm_params.h> 26 #include <sound/soc-component.h> 27 #include <sound/soc-jack.h> 28 #include <sound/soc.h> 29 30 #include "cs42l43.h" 31 32 static const unsigned int cs42l43_accdet_us[] = { 33 20, 100, 1000, 10000, 50000, 75000, 100000, 200000, 34 }; 35 36 static const unsigned int cs42l43_accdet_db_ms[] = { 37 0, 125, 250, 500, 750, 1000, 1250, 1500, 38 }; 39 40 static const unsigned int cs42l43_accdet_ramp_ms[] = { 10, 40, 90, 170 }; 41 42 static const unsigned int cs42l43_accdet_bias_sense[] = { 43 14, 24, 43, 52, 61, 71, 90, 99, 0, 44 }; 45 46 static int cs42l43_find_index(struct cs42l43_codec *priv, const char * const prop, 47 unsigned int defval, unsigned int *val, 48 const unsigned int *values, const int nvalues) 49 { 50 struct cs42l43 *cs42l43 = priv->core; 51 int i, ret; 52 53 ret = device_property_read_u32(cs42l43->dev, prop, &defval); 54 if (ret != -EINVAL && ret < 0) { 55 dev_err(priv->dev, "Property %s malformed: %d\n", prop, ret); 56 return ret; 57 } 58 59 if (val) 60 *val = defval; 61 62 for (i = 0; i < nvalues; i++) 63 if (defval == values[i]) 64 return i; 65 66 dev_err(priv->dev, "Invalid value for property %s: %d\n", prop, defval); 67 return -EINVAL; 68 } 69 70 int cs42l43_set_jack(struct snd_soc_component *component, 71 struct snd_soc_jack *jack, void *d) 72 { 73 struct cs42l43_codec *priv = snd_soc_component_get_drvdata(component); 74 struct cs42l43 *cs42l43 = priv->core; 75 /* This tip sense invert is always set, HW wants an inverted signal */ 76 unsigned int tip_deb = CS42L43_TIPSENSE_INV_MASK; 77 unsigned int hs2 = 0x2 << CS42L43_HSDET_MODE_SHIFT; 78 unsigned int autocontrol = 0, pdncntl = 0; 79 int ret; 80 81 dev_dbg(priv->dev, "Configure accessory detect\n"); 82 83 ret = pm_runtime_resume_and_get(priv->dev); 84 if (ret) { 85 dev_err(priv->dev, "Failed to resume for jack config: %d\n", ret); 86 return ret; 87 } 88 89 mutex_lock(&priv->jack_lock); 90 91 priv->jack_hp = jack; 92 93 if (!jack) 94 goto done; 95 96 ret = device_property_count_u32(cs42l43->dev, "cirrus,buttons-ohms"); 97 if (ret != -EINVAL) { 98 if (ret < 0) { 99 dev_err(priv->dev, "Property cirrus,buttons-ohms malformed: %d\n", 100 ret); 101 goto error; 102 } 103 104 if (ret > CS42L43_N_BUTTONS) { 105 ret = -EINVAL; 106 dev_err(priv->dev, "Property cirrus,buttons-ohms too many entries\n"); 107 goto error; 108 } 109 110 ret = device_property_read_u32_array(cs42l43->dev, "cirrus,buttons-ohms", 111 priv->buttons, ret); 112 if (ret < 0) { 113 dev_err(priv->dev, "Property cirrus,button-ohms malformed: %d\n", 114 ret); 115 goto error; 116 } 117 } else { 118 priv->buttons[0] = 70; 119 priv->buttons[1] = 185; 120 priv->buttons[2] = 355; 121 priv->buttons[3] = 735; 122 } 123 124 ret = cs42l43_find_index(priv, "cirrus,detect-us", 50000, &priv->detect_us, 125 cs42l43_accdet_us, ARRAY_SIZE(cs42l43_accdet_us)); 126 if (ret < 0) 127 goto error; 128 129 hs2 |= ret << CS42L43_AUTO_HSDET_TIME_SHIFT; 130 131 priv->bias_low = device_property_read_bool(cs42l43->dev, "cirrus,bias-low"); 132 133 ret = cs42l43_find_index(priv, "cirrus,bias-ramp-ms", 170, 134 &priv->bias_ramp_ms, cs42l43_accdet_ramp_ms, 135 ARRAY_SIZE(cs42l43_accdet_ramp_ms)); 136 if (ret < 0) 137 goto error; 138 139 hs2 |= ret << CS42L43_HSBIAS_RAMP_SHIFT; 140 141 ret = cs42l43_find_index(priv, "cirrus,bias-sense-microamp", 14, 142 &priv->bias_sense_ua, cs42l43_accdet_bias_sense, 143 ARRAY_SIZE(cs42l43_accdet_bias_sense)); 144 if (ret < 0) 145 goto error; 146 147 if (priv->bias_sense_ua) 148 autocontrol |= ret << CS42L43_HSBIAS_SENSE_TRIP_SHIFT; 149 150 if (!device_property_read_bool(cs42l43->dev, "cirrus,button-automute")) 151 autocontrol |= CS42L43_S0_AUTO_ADCMUTE_DISABLE_MASK; 152 153 ret = device_property_read_u32(cs42l43->dev, "cirrus,tip-debounce-ms", 154 &priv->tip_debounce_ms); 155 if (ret < 0 && ret != -EINVAL) { 156 dev_err(priv->dev, "Property cirrus,tip-debounce-ms malformed: %d\n", ret); 157 goto error; 158 } 159 160 /* This tip sense invert is set normally, as TIPSENSE_INV already inverted */ 161 if (device_property_read_bool(cs42l43->dev, "cirrus,tip-invert")) 162 autocontrol |= 0x1 << CS42L43_JACKDET_INV_SHIFT; 163 164 if (device_property_read_bool(cs42l43->dev, "cirrus,tip-disable-pullup")) 165 autocontrol |= 0x1 << CS42L43_JACKDET_MODE_SHIFT; 166 else 167 autocontrol |= 0x3 << CS42L43_JACKDET_MODE_SHIFT; 168 169 ret = cs42l43_find_index(priv, "cirrus,tip-fall-db-ms", 500, 170 NULL, cs42l43_accdet_db_ms, 171 ARRAY_SIZE(cs42l43_accdet_db_ms)); 172 if (ret < 0) 173 goto error; 174 175 tip_deb |= ret << CS42L43_TIPSENSE_FALLING_DB_TIME_SHIFT; 176 177 ret = cs42l43_find_index(priv, "cirrus,tip-rise-db-ms", 500, 178 NULL, cs42l43_accdet_db_ms, 179 ARRAY_SIZE(cs42l43_accdet_db_ms)); 180 if (ret < 0) 181 goto error; 182 183 tip_deb |= ret << CS42L43_TIPSENSE_RISING_DB_TIME_SHIFT; 184 185 if (device_property_read_bool(cs42l43->dev, "cirrus,use-ring-sense")) { 186 unsigned int ring_deb = 0; 187 188 priv->use_ring_sense = true; 189 190 /* HW wants an inverted signal, so invert the invert */ 191 if (!device_property_read_bool(cs42l43->dev, "cirrus,ring-invert")) 192 ring_deb |= CS42L43_RINGSENSE_INV_MASK; 193 194 if (!device_property_read_bool(cs42l43->dev, 195 "cirrus,ring-disable-pullup")) 196 ring_deb |= CS42L43_RINGSENSE_PULLUP_PDNB_MASK; 197 198 ret = cs42l43_find_index(priv, "cirrus,ring-fall-db-ms", 500, 199 NULL, cs42l43_accdet_db_ms, 200 ARRAY_SIZE(cs42l43_accdet_db_ms)); 201 if (ret < 0) 202 goto error; 203 204 ring_deb |= ret << CS42L43_RINGSENSE_FALLING_DB_TIME_SHIFT; 205 206 ret = cs42l43_find_index(priv, "cirrus,ring-rise-db-ms", 500, 207 NULL, cs42l43_accdet_db_ms, 208 ARRAY_SIZE(cs42l43_accdet_db_ms)); 209 if (ret < 0) 210 goto error; 211 212 ring_deb |= ret << CS42L43_RINGSENSE_RISING_DB_TIME_SHIFT; 213 pdncntl |= CS42L43_RING_SENSE_EN_MASK; 214 215 regmap_update_bits(cs42l43->regmap, CS42L43_RINGSENSE_DEB_CTRL, 216 CS42L43_RINGSENSE_INV_MASK | 217 CS42L43_RINGSENSE_PULLUP_PDNB_MASK | 218 CS42L43_RINGSENSE_FALLING_DB_TIME_MASK | 219 CS42L43_RINGSENSE_RISING_DB_TIME_MASK, 220 ring_deb); 221 } 222 223 regmap_update_bits(cs42l43->regmap, CS42L43_TIPSENSE_DEB_CTRL, 224 CS42L43_TIPSENSE_INV_MASK | 225 CS42L43_TIPSENSE_FALLING_DB_TIME_MASK | 226 CS42L43_TIPSENSE_RISING_DB_TIME_MASK, tip_deb); 227 regmap_update_bits(cs42l43->regmap, CS42L43_HS2, 228 CS42L43_HSBIAS_RAMP_MASK | CS42L43_HSDET_MODE_MASK | 229 CS42L43_AUTO_HSDET_TIME_MASK, hs2); 230 231 done: 232 ret = 0; 233 234 regmap_update_bits(cs42l43->regmap, CS42L43_HS_BIAS_SENSE_AND_CLAMP_AUTOCONTROL, 235 CS42L43_JACKDET_MODE_MASK | CS42L43_S0_AUTO_ADCMUTE_DISABLE_MASK | 236 CS42L43_HSBIAS_SENSE_TRIP_MASK, autocontrol); 237 regmap_update_bits(cs42l43->regmap, CS42L43_PDNCNTL, 238 CS42L43_RING_SENSE_EN_MASK, pdncntl); 239 240 dev_dbg(priv->dev, "Successfully configured accessory detect\n"); 241 242 error: 243 mutex_unlock(&priv->jack_lock); 244 245 pm_runtime_mark_last_busy(priv->dev); 246 pm_runtime_put_autosuspend(priv->dev); 247 248 return ret; 249 } 250 251 static void cs42l43_start_hs_bias(struct cs42l43_codec *priv, bool type_detect) 252 { 253 struct cs42l43 *cs42l43 = priv->core; 254 unsigned int val = 0x3 << CS42L43_HSBIAS_MODE_SHIFT; 255 256 dev_dbg(priv->dev, "Start headset bias\n"); 257 258 regmap_update_bits(cs42l43->regmap, CS42L43_HS2, 259 CS42L43_HS_CLAMP_DISABLE_MASK, CS42L43_HS_CLAMP_DISABLE_MASK); 260 261 if (!type_detect) { 262 if (priv->bias_low) 263 val = 0x2 << CS42L43_HSBIAS_MODE_SHIFT; 264 265 if (priv->bias_sense_ua) 266 regmap_update_bits(cs42l43->regmap, 267 CS42L43_HS_BIAS_SENSE_AND_CLAMP_AUTOCONTROL, 268 CS42L43_HSBIAS_SENSE_EN_MASK | 269 CS42L43_AUTO_HSBIAS_CLAMP_EN_MASK, 270 CS42L43_HSBIAS_SENSE_EN_MASK | 271 CS42L43_AUTO_HSBIAS_CLAMP_EN_MASK); 272 } 273 274 regmap_update_bits(cs42l43->regmap, CS42L43_MIC_DETECT_CONTROL_1, 275 CS42L43_HSBIAS_MODE_MASK, val); 276 277 msleep(priv->bias_ramp_ms); 278 } 279 280 static void cs42l43_stop_hs_bias(struct cs42l43_codec *priv) 281 { 282 struct cs42l43 *cs42l43 = priv->core; 283 284 dev_dbg(priv->dev, "Stop headset bias\n"); 285 286 regmap_update_bits(cs42l43->regmap, CS42L43_MIC_DETECT_CONTROL_1, 287 CS42L43_HSBIAS_MODE_MASK, 0x1 << CS42L43_HSBIAS_MODE_SHIFT); 288 289 regmap_update_bits(cs42l43->regmap, CS42L43_HS2, 290 CS42L43_HS_CLAMP_DISABLE_MASK, 0); 291 292 if (priv->bias_sense_ua) { 293 regmap_update_bits(cs42l43->regmap, 294 CS42L43_HS_BIAS_SENSE_AND_CLAMP_AUTOCONTROL, 295 CS42L43_HSBIAS_SENSE_EN_MASK | 296 CS42L43_AUTO_HSBIAS_CLAMP_EN_MASK, 0); 297 } 298 } 299 300 irqreturn_t cs42l43_bias_detect_clamp(int irq, void *data) 301 { 302 struct cs42l43_codec *priv = data; 303 304 queue_delayed_work(system_wq, &priv->bias_sense_timeout, 305 msecs_to_jiffies(1000)); 306 307 return IRQ_HANDLED; 308 } 309 310 #define CS42L43_JACK_PRESENT 0x3 311 #define CS42L43_JACK_ABSENT 0x0 312 313 #define CS42L43_JACK_OPTICAL (SND_JACK_MECHANICAL | SND_JACK_AVOUT) 314 #define CS42L43_JACK_HEADPHONE (SND_JACK_MECHANICAL | SND_JACK_HEADPHONE) 315 #define CS42L43_JACK_HEADSET (SND_JACK_MECHANICAL | SND_JACK_HEADSET) 316 #define CS42L43_JACK_LINEOUT (SND_JACK_MECHANICAL | SND_JACK_LINEOUT) 317 #define CS42L43_JACK_LINEIN (SND_JACK_MECHANICAL | SND_JACK_LINEIN) 318 #define CS42L43_JACK_EXTENSION (SND_JACK_MECHANICAL) 319 #define CS42L43_JACK_BUTTONS (SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2 | \ 320 SND_JACK_BTN_3 | SND_JACK_BTN_4 | SND_JACK_BTN_5) 321 322 static inline bool cs42l43_jack_present(struct cs42l43_codec *priv) 323 { 324 struct cs42l43 *cs42l43 = priv->core; 325 unsigned int sts = 0; 326 327 regmap_read(cs42l43->regmap, CS42L43_TIP_RING_SENSE_INTERRUPT_STATUS, &sts); 328 329 sts = (sts >> CS42L43_TIPSENSE_PLUG_DB_STS_SHIFT) & CS42L43_JACK_PRESENT; 330 331 return sts == CS42L43_JACK_PRESENT; 332 } 333 334 static void cs42l43_start_button_detect(struct cs42l43_codec *priv) 335 { 336 struct cs42l43 *cs42l43 = priv->core; 337 unsigned int val = 0x3 << CS42L43_BUTTON_DETECT_MODE_SHIFT; 338 339 dev_dbg(priv->dev, "Start button detect\n"); 340 341 priv->button_detect_running = true; 342 343 if (priv->bias_low) 344 val = 0x1 << CS42L43_BUTTON_DETECT_MODE_SHIFT; 345 346 regmap_update_bits(cs42l43->regmap, CS42L43_MIC_DETECT_CONTROL_1, 347 CS42L43_BUTTON_DETECT_MODE_MASK | 348 CS42L43_MIC_LVL_DET_DISABLE_MASK, val); 349 } 350 351 static void cs42l43_stop_button_detect(struct cs42l43_codec *priv) 352 { 353 struct cs42l43 *cs42l43 = priv->core; 354 355 dev_dbg(priv->dev, "Stop button detect\n"); 356 357 regmap_update_bits(cs42l43->regmap, CS42L43_MIC_DETECT_CONTROL_1, 358 CS42L43_BUTTON_DETECT_MODE_MASK | 359 CS42L43_MIC_LVL_DET_DISABLE_MASK, 360 CS42L43_MIC_LVL_DET_DISABLE_MASK); 361 362 priv->button_detect_running = false; 363 } 364 365 #define CS42L43_BUTTON_COMB_MAX 512 366 #define CS42L43_BUTTON_ROUT 2210 367 368 void cs42l43_button_press_work(struct work_struct *work) 369 { 370 struct cs42l43_codec *priv = container_of(work, struct cs42l43_codec, 371 button_press_work.work); 372 struct cs42l43 *cs42l43 = priv->core; 373 unsigned int buttons = 0; 374 unsigned int val = 0; 375 int i, ret; 376 377 ret = pm_runtime_resume_and_get(priv->dev); 378 if (ret) { 379 dev_err(priv->dev, "Failed to resume for button press: %d\n", ret); 380 return; 381 } 382 383 mutex_lock(&priv->jack_lock); 384 385 if (!priv->button_detect_running) { 386 dev_dbg(priv->dev, "Spurious button press IRQ\n"); 387 goto error; 388 } 389 390 regmap_read(cs42l43->regmap, CS42L43_DETECT_STATUS_1, &val); 391 392 /* Bail if jack removed, the button is irrelevant and likely invalid */ 393 if (!cs42l43_jack_present(priv)) { 394 dev_dbg(priv->dev, "Button ignored due to removal\n"); 395 goto error; 396 } 397 398 if (val & CS42L43_HSBIAS_CLAMP_STS_MASK) { 399 dev_dbg(priv->dev, "Button ignored due to bias sense\n"); 400 goto error; 401 } 402 403 val = (val & CS42L43_HSDET_DC_STS_MASK) >> CS42L43_HSDET_DC_STS_SHIFT; 404 val = ((CS42L43_BUTTON_COMB_MAX << 20) / (val + 1)) - (1 << 20); 405 if (val) 406 val = (CS42L43_BUTTON_ROUT << 20) / val; 407 else 408 val = UINT_MAX; 409 410 for (i = 0; i < CS42L43_N_BUTTONS; i++) { 411 if (val < priv->buttons[i]) { 412 buttons = SND_JACK_BTN_0 >> i; 413 dev_dbg(priv->dev, "Detected button %d at %d Ohms\n", i, val); 414 break; 415 } 416 } 417 418 if (!buttons) 419 dev_dbg(priv->dev, "Unrecognised button: %d Ohms\n", val); 420 421 snd_soc_jack_report(priv->jack_hp, buttons, CS42L43_JACK_BUTTONS); 422 423 error: 424 mutex_unlock(&priv->jack_lock); 425 426 pm_runtime_mark_last_busy(priv->dev); 427 pm_runtime_put_autosuspend(priv->dev); 428 } 429 430 irqreturn_t cs42l43_button_press(int irq, void *data) 431 { 432 struct cs42l43_codec *priv = data; 433 434 // Wait for 2 full cycles of comb filter to ensure good reading 435 queue_delayed_work(system_wq, &priv->button_press_work, 436 msecs_to_jiffies(20)); 437 438 return IRQ_HANDLED; 439 } 440 441 void cs42l43_button_release_work(struct work_struct *work) 442 { 443 struct cs42l43_codec *priv = container_of(work, struct cs42l43_codec, 444 button_release_work); 445 int ret; 446 447 ret = pm_runtime_resume_and_get(priv->dev); 448 if (ret) { 449 dev_err(priv->dev, "Failed to resume for button release: %d\n", ret); 450 return; 451 } 452 453 mutex_lock(&priv->jack_lock); 454 455 if (priv->button_detect_running) { 456 dev_dbg(priv->dev, "Button release IRQ\n"); 457 458 snd_soc_jack_report(priv->jack_hp, 0, CS42L43_JACK_BUTTONS); 459 } else { 460 dev_dbg(priv->dev, "Spurious button release IRQ\n"); 461 } 462 463 mutex_unlock(&priv->jack_lock); 464 465 pm_runtime_mark_last_busy(priv->dev); 466 pm_runtime_put_autosuspend(priv->dev); 467 } 468 469 irqreturn_t cs42l43_button_release(int irq, void *data) 470 { 471 struct cs42l43_codec *priv = data; 472 473 queue_work(system_wq, &priv->button_release_work); 474 475 return IRQ_HANDLED; 476 } 477 478 void cs42l43_bias_sense_timeout(struct work_struct *work) 479 { 480 struct cs42l43_codec *priv = container_of(work, struct cs42l43_codec, 481 bias_sense_timeout.work); 482 struct cs42l43 *cs42l43 = priv->core; 483 int ret; 484 485 ret = pm_runtime_resume_and_get(priv->dev); 486 if (ret) { 487 dev_err(priv->dev, "Failed to resume for bias sense: %d\n", ret); 488 return; 489 } 490 491 mutex_lock(&priv->jack_lock); 492 493 if (cs42l43_jack_present(priv) && priv->button_detect_running) { 494 dev_dbg(priv->dev, "Bias sense timeout out, restore bias\n"); 495 496 regmap_update_bits(cs42l43->regmap, 497 CS42L43_HS_BIAS_SENSE_AND_CLAMP_AUTOCONTROL, 498 CS42L43_AUTO_HSBIAS_CLAMP_EN_MASK, 0); 499 regmap_update_bits(cs42l43->regmap, 500 CS42L43_HS_BIAS_SENSE_AND_CLAMP_AUTOCONTROL, 501 CS42L43_AUTO_HSBIAS_CLAMP_EN_MASK, 502 CS42L43_AUTO_HSBIAS_CLAMP_EN_MASK); 503 } 504 505 mutex_unlock(&priv->jack_lock); 506 507 pm_runtime_mark_last_busy(priv->dev); 508 pm_runtime_put_autosuspend(priv->dev); 509 } 510 511 static void cs42l43_start_load_detect(struct cs42l43_codec *priv) 512 { 513 struct cs42l43 *cs42l43 = priv->core; 514 515 dev_dbg(priv->dev, "Start load detect\n"); 516 517 snd_soc_dapm_mutex_lock(snd_soc_component_get_dapm(priv->component)); 518 519 priv->load_detect_running = true; 520 521 if (priv->hp_ena && !priv->hp_ilimited) { 522 unsigned long time_left; 523 524 reinit_completion(&priv->hp_shutdown); 525 526 regmap_update_bits(cs42l43->regmap, CS42L43_BLOCK_EN8, 527 CS42L43_HP_EN_MASK, 0); 528 529 time_left = wait_for_completion_timeout(&priv->hp_shutdown, 530 msecs_to_jiffies(CS42L43_HP_TIMEOUT_MS)); 531 if (!time_left) 532 dev_err(priv->dev, "Load detect HP power down timed out\n"); 533 } 534 535 regmap_update_bits(cs42l43->regmap, CS42L43_BLOCK_EN3, 536 CS42L43_ADC1_EN_MASK | CS42L43_ADC2_EN_MASK, 0); 537 regmap_update_bits(cs42l43->regmap, CS42L43_DACCNFG2, CS42L43_HP_HPF_EN_MASK, 0); 538 regmap_update_bits(cs42l43->regmap, CS42L43_MIC_DETECT_CONTROL_1, 539 CS42L43_HSBIAS_MODE_MASK, 0); 540 regmap_update_bits(cs42l43->regmap, CS42L43_CTRL, 541 CS42L43_ADPTPWR_MODE_MASK, 0x4 << CS42L43_ADPTPWR_MODE_SHIFT); 542 regmap_update_bits(cs42l43->regmap, CS42L43_PGAVOL, 543 CS42L43_HP_DIG_VOL_RAMP_MASK | CS42L43_HP_ANA_VOL_RAMP_MASK, 0x6); 544 regmap_update_bits(cs42l43->regmap, CS42L43_DACCNFG1, 545 CS42L43_HP_MSTR_VOL_CTRL_EN_MASK, 0); 546 547 regmap_update_bits(cs42l43->regmap, CS42L43_HS2, 548 CS42L43_HS_CLAMP_DISABLE_MASK, CS42L43_HS_CLAMP_DISABLE_MASK); 549 550 regmap_update_bits(cs42l43->regmap, CS42L43_LOADDETENA, 551 CS42L43_HPLOAD_DET_EN_MASK, 552 CS42L43_HPLOAD_DET_EN_MASK); 553 554 snd_soc_dapm_mutex_unlock(snd_soc_component_get_dapm(priv->component)); 555 } 556 557 static void cs42l43_stop_load_detect(struct cs42l43_codec *priv) 558 { 559 struct cs42l43 *cs42l43 = priv->core; 560 561 dev_dbg(priv->dev, "Stop load detect\n"); 562 563 snd_soc_dapm_mutex_lock(snd_soc_component_get_dapm(priv->component)); 564 565 regmap_update_bits(cs42l43->regmap, CS42L43_LOADDETENA, 566 CS42L43_HPLOAD_DET_EN_MASK, 0); 567 regmap_update_bits(cs42l43->regmap, CS42L43_HS2, 568 CS42L43_HS_CLAMP_DISABLE_MASK, 0); 569 regmap_update_bits(cs42l43->regmap, CS42L43_DACCNFG1, 570 CS42L43_HP_MSTR_VOL_CTRL_EN_MASK, 571 CS42L43_HP_MSTR_VOL_CTRL_EN_MASK); 572 regmap_update_bits(cs42l43->regmap, CS42L43_PGAVOL, 573 CS42L43_HP_DIG_VOL_RAMP_MASK | CS42L43_HP_ANA_VOL_RAMP_MASK, 574 0x4 << CS42L43_HP_DIG_VOL_RAMP_SHIFT); 575 regmap_update_bits(cs42l43->regmap, CS42L43_CTRL, 576 CS42L43_ADPTPWR_MODE_MASK, 0x7 << CS42L43_ADPTPWR_MODE_SHIFT); 577 regmap_update_bits(cs42l43->regmap, CS42L43_MIC_DETECT_CONTROL_1, 578 CS42L43_HSBIAS_MODE_MASK, 0x1 << CS42L43_HSBIAS_MODE_SHIFT); 579 regmap_update_bits(cs42l43->regmap, CS42L43_DACCNFG2, 580 CS42L43_HP_HPF_EN_MASK, CS42L43_HP_HPF_EN_MASK); 581 582 regmap_update_bits(cs42l43->regmap, CS42L43_BLOCK_EN3, 583 CS42L43_ADC1_EN_MASK | CS42L43_ADC2_EN_MASK, 584 priv->adc_ena); 585 586 if (priv->hp_ena && !priv->hp_ilimited) { 587 unsigned long time_left; 588 589 reinit_completion(&priv->hp_startup); 590 591 regmap_update_bits(cs42l43->regmap, CS42L43_BLOCK_EN8, 592 CS42L43_HP_EN_MASK, priv->hp_ena); 593 594 time_left = wait_for_completion_timeout(&priv->hp_startup, 595 msecs_to_jiffies(CS42L43_HP_TIMEOUT_MS)); 596 if (!time_left) 597 dev_err(priv->dev, "Load detect HP restore timed out\n"); 598 } 599 600 priv->load_detect_running = false; 601 602 snd_soc_dapm_mutex_unlock(snd_soc_component_get_dapm(priv->component)); 603 } 604 605 static int cs42l43_run_load_detect(struct cs42l43_codec *priv, bool mic) 606 { 607 struct cs42l43 *cs42l43 = priv->core; 608 unsigned int val = 0; 609 unsigned long time_left; 610 611 reinit_completion(&priv->load_detect); 612 613 cs42l43_start_load_detect(priv); 614 time_left = wait_for_completion_timeout(&priv->load_detect, 615 msecs_to_jiffies(CS42L43_LOAD_TIMEOUT_MS)); 616 cs42l43_stop_load_detect(priv); 617 618 if (!time_left) 619 return -ETIMEDOUT; 620 621 regmap_read(cs42l43->regmap, CS42L43_LOADDETRESULTS, &val); 622 623 dev_dbg(priv->dev, "Headphone load detect: 0x%x\n", val); 624 625 /* Bail if jack removed, the load is irrelevant and likely invalid */ 626 if (!cs42l43_jack_present(priv)) 627 return -ENODEV; 628 629 if (mic) { 630 cs42l43_start_hs_bias(priv, false); 631 cs42l43_start_button_detect(priv); 632 633 return CS42L43_JACK_HEADSET; 634 } 635 636 switch (val & CS42L43_AMP3_RES_DET_MASK) { 637 case 0x0: // low impedance 638 case 0x1: // high impedance 639 return CS42L43_JACK_HEADPHONE; 640 case 0x2: // lineout 641 case 0x3: // Open circuit 642 return CS42L43_JACK_LINEOUT; 643 default: 644 return -EINVAL; 645 } 646 } 647 648 static int cs42l43_run_type_detect(struct cs42l43_codec *priv) 649 { 650 struct cs42l43 *cs42l43 = priv->core; 651 int timeout_ms = ((2 * priv->detect_us) / USEC_PER_MSEC) + 200; 652 unsigned int type = 0xff; 653 unsigned long time_left; 654 655 reinit_completion(&priv->type_detect); 656 657 cs42l43_start_hs_bias(priv, true); 658 regmap_update_bits(cs42l43->regmap, CS42L43_HS2, 659 CS42L43_HSDET_MODE_MASK, 0x3 << CS42L43_HSDET_MODE_SHIFT); 660 661 time_left = wait_for_completion_timeout(&priv->type_detect, 662 msecs_to_jiffies(timeout_ms)); 663 664 regmap_update_bits(cs42l43->regmap, CS42L43_HS2, 665 CS42L43_HSDET_MODE_MASK, 0x2 << CS42L43_HSDET_MODE_SHIFT); 666 cs42l43_stop_hs_bias(priv); 667 668 if (!time_left) 669 return -ETIMEDOUT; 670 671 regmap_read(cs42l43->regmap, CS42L43_HS_STAT, &type); 672 673 dev_dbg(priv->dev, "Type detect: 0x%x\n", type); 674 675 /* Bail if jack removed, the type is irrelevant and likely invalid */ 676 if (!cs42l43_jack_present(priv)) 677 return -ENODEV; 678 679 switch (type & CS42L43_HSDET_TYPE_STS_MASK) { 680 case 0x0: // CTIA 681 case 0x1: // OMTP 682 return cs42l43_run_load_detect(priv, true); 683 case 0x2: // 3-pole 684 return cs42l43_run_load_detect(priv, false); 685 case 0x3: // Open-circuit 686 return CS42L43_JACK_EXTENSION; 687 default: 688 return -EINVAL; 689 } 690 } 691 692 static void cs42l43_clear_jack(struct cs42l43_codec *priv) 693 { 694 struct cs42l43 *cs42l43 = priv->core; 695 696 cs42l43_stop_button_detect(priv); 697 cs42l43_stop_hs_bias(priv); 698 699 regmap_update_bits(cs42l43->regmap, CS42L43_ADC_B_CTRL1, 700 CS42L43_PGA_WIDESWING_MODE_EN_MASK, 0); 701 regmap_update_bits(cs42l43->regmap, CS42L43_ADC_B_CTRL2, 702 CS42L43_PGA_WIDESWING_MODE_EN_MASK, 0); 703 regmap_update_bits(cs42l43->regmap, CS42L43_STEREO_MIC_CTRL, 704 CS42L43_JACK_STEREO_CONFIG_MASK, 0); 705 regmap_update_bits(cs42l43->regmap, CS42L43_HS2, 706 CS42L43_HSDET_MODE_MASK | CS42L43_HSDET_MANUAL_MODE_MASK, 707 0x2 << CS42L43_HSDET_MODE_SHIFT); 708 709 snd_soc_jack_report(priv->jack_hp, 0, 0xFFFF); 710 } 711 712 void cs42l43_tip_sense_work(struct work_struct *work) 713 { 714 struct cs42l43_codec *priv = container_of(work, struct cs42l43_codec, 715 tip_sense_work.work); 716 struct cs42l43 *cs42l43 = priv->core; 717 unsigned int sts = 0; 718 unsigned int tip, ring; 719 int ret, report; 720 721 ret = pm_runtime_resume_and_get(priv->dev); 722 if (ret) { 723 dev_err(priv->dev, "Failed to resume for tip work: %d\n", ret); 724 return; 725 } 726 727 mutex_lock(&priv->jack_lock); 728 729 regmap_read(cs42l43->regmap, CS42L43_TIP_RING_SENSE_INTERRUPT_STATUS, &sts); 730 731 dev_dbg(priv->dev, "Tip sense: 0x%x\n", sts); 732 733 tip = (sts >> CS42L43_TIPSENSE_PLUG_DB_STS_SHIFT) & CS42L43_JACK_PRESENT; 734 ring = (sts >> CS42L43_RINGSENSE_PLUG_DB_STS_SHIFT) & CS42L43_JACK_PRESENT; 735 736 if (tip == CS42L43_JACK_PRESENT) { 737 if (cs42l43->sdw && !priv->jack_present) { 738 priv->jack_present = true; 739 pm_runtime_get(priv->dev); 740 } 741 742 if (priv->use_ring_sense && ring == CS42L43_JACK_ABSENT) { 743 report = CS42L43_JACK_OPTICAL; 744 } else { 745 report = cs42l43_run_type_detect(priv); 746 if (report < 0) { 747 dev_err(priv->dev, "Jack detect failed: %d\n", report); 748 goto error; 749 } 750 } 751 752 snd_soc_jack_report(priv->jack_hp, report, report); 753 } else { 754 priv->jack_override = 0; 755 756 cs42l43_clear_jack(priv); 757 758 if (cs42l43->sdw && priv->jack_present) { 759 pm_runtime_put(priv->dev); 760 priv->jack_present = false; 761 } 762 } 763 764 error: 765 mutex_unlock(&priv->jack_lock); 766 767 pm_runtime_mark_last_busy(priv->dev); 768 pm_runtime_put_autosuspend(priv->dev); 769 } 770 771 irqreturn_t cs42l43_tip_sense(int irq, void *data) 772 { 773 struct cs42l43_codec *priv = data; 774 775 cancel_delayed_work(&priv->bias_sense_timeout); 776 cancel_delayed_work(&priv->tip_sense_work); 777 cancel_delayed_work(&priv->button_press_work); 778 cancel_work(&priv->button_release_work); 779 780 queue_delayed_work(system_long_wq, &priv->tip_sense_work, 781 msecs_to_jiffies(priv->tip_debounce_ms)); 782 783 return IRQ_HANDLED; 784 } 785 786 enum cs42l43_raw_jack { 787 CS42L43_JACK_RAW_CTIA = 0, 788 CS42L43_JACK_RAW_OMTP, 789 CS42L43_JACK_RAW_HEADPHONE, 790 CS42L43_JACK_RAW_LINE_OUT, 791 CS42L43_JACK_RAW_LINE_IN, 792 CS42L43_JACK_RAW_MICROPHONE, 793 CS42L43_JACK_RAW_OPTICAL, 794 }; 795 796 #define CS42L43_JACK_3_POLE_SWITCHES ((0x2 << CS42L43_HSDET_MANUAL_MODE_SHIFT) | \ 797 CS42L43_AMP3_4_GNDREF_HS3_SEL_MASK | \ 798 CS42L43_AMP3_4_GNDREF_HS4_SEL_MASK | \ 799 CS42L43_HSBIAS_GNDREF_HS3_SEL_MASK | \ 800 CS42L43_HSBIAS_GNDREF_HS4_SEL_MASK | \ 801 CS42L43_HSGND_HS3_SEL_MASK | \ 802 CS42L43_HSGND_HS4_SEL_MASK) 803 804 static const struct cs42l43_jack_override_mode { 805 unsigned int hsdet_mode; 806 unsigned int mic_ctrl; 807 unsigned int clamp_ctrl; 808 int report; 809 } cs42l43_jack_override_modes[] = { 810 [CS42L43_JACK_RAW_CTIA] = { 811 .hsdet_mode = CS42L43_AMP3_4_GNDREF_HS3_SEL_MASK | 812 CS42L43_HSBIAS_GNDREF_HS3_SEL_MASK | 813 CS42L43_HSBIAS_OUT_HS4_SEL_MASK | 814 CS42L43_HSGND_HS3_SEL_MASK, 815 .clamp_ctrl = CS42L43_SMIC_HPAMP_CLAMP_DIS_FRC_MASK, 816 .report = CS42L43_JACK_HEADSET, 817 }, 818 [CS42L43_JACK_RAW_OMTP] = { 819 .hsdet_mode = (0x1 << CS42L43_HSDET_MANUAL_MODE_SHIFT) | 820 CS42L43_AMP3_4_GNDREF_HS4_SEL_MASK | 821 CS42L43_HSBIAS_GNDREF_HS4_SEL_MASK | 822 CS42L43_HSBIAS_OUT_HS3_SEL_MASK | 823 CS42L43_HSGND_HS4_SEL_MASK, 824 .clamp_ctrl = CS42L43_SMIC_HPAMP_CLAMP_DIS_FRC_MASK, 825 .report = CS42L43_JACK_HEADSET, 826 }, 827 [CS42L43_JACK_RAW_HEADPHONE] = { 828 .hsdet_mode = CS42L43_JACK_3_POLE_SWITCHES, 829 .clamp_ctrl = CS42L43_SMIC_HPAMP_CLAMP_DIS_FRC_MASK, 830 .report = CS42L43_JACK_HEADPHONE, 831 }, 832 [CS42L43_JACK_RAW_LINE_OUT] = { 833 .hsdet_mode = CS42L43_JACK_3_POLE_SWITCHES, 834 .clamp_ctrl = CS42L43_SMIC_HPAMP_CLAMP_DIS_FRC_MASK, 835 .report = CS42L43_JACK_LINEOUT, 836 }, 837 [CS42L43_JACK_RAW_LINE_IN] = { 838 .hsdet_mode = CS42L43_JACK_3_POLE_SWITCHES, 839 .mic_ctrl = 0x2 << CS42L43_JACK_STEREO_CONFIG_SHIFT, 840 .report = CS42L43_JACK_LINEIN, 841 }, 842 [CS42L43_JACK_RAW_MICROPHONE] = { 843 .hsdet_mode = CS42L43_JACK_3_POLE_SWITCHES, 844 .mic_ctrl = (0x3 << CS42L43_JACK_STEREO_CONFIG_SHIFT) | 845 CS42L43_HS1_BIAS_EN_MASK | CS42L43_HS2_BIAS_EN_MASK, 846 .report = CS42L43_JACK_LINEIN, 847 }, 848 [CS42L43_JACK_RAW_OPTICAL] = { 849 .hsdet_mode = CS42L43_JACK_3_POLE_SWITCHES, 850 .clamp_ctrl = CS42L43_SMIC_HPAMP_CLAMP_DIS_FRC_MASK, 851 .report = CS42L43_JACK_OPTICAL, 852 }, 853 }; 854 855 static const char * const cs42l43_jack_text[] = { 856 "None", "CTIA", "OMTP", "Headphone", "Line-Out", 857 "Line-In", "Microphone", "Optical", 858 }; 859 860 static_assert(ARRAY_SIZE(cs42l43_jack_override_modes) == 861 ARRAY_SIZE(cs42l43_jack_text) - 1); 862 863 SOC_ENUM_SINGLE_VIRT_DECL(cs42l43_jack_enum, cs42l43_jack_text); 864 865 int cs42l43_jack_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 866 { 867 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); 868 struct cs42l43_codec *priv = snd_soc_component_get_drvdata(component); 869 870 mutex_lock(&priv->jack_lock); 871 ucontrol->value.integer.value[0] = priv->jack_override; 872 mutex_unlock(&priv->jack_lock); 873 874 return 0; 875 } 876 877 int cs42l43_jack_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 878 { 879 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); 880 struct cs42l43_codec *priv = snd_soc_component_get_drvdata(component); 881 struct cs42l43 *cs42l43 = priv->core; 882 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 883 unsigned int override = ucontrol->value.integer.value[0]; 884 885 if (override >= e->items) 886 return -EINVAL; 887 888 mutex_lock(&priv->jack_lock); 889 890 if (!cs42l43_jack_present(priv)) { 891 mutex_unlock(&priv->jack_lock); 892 return -EBUSY; 893 } 894 895 if (override == priv->jack_override) { 896 mutex_unlock(&priv->jack_lock); 897 return 0; 898 } 899 900 priv->jack_override = override; 901 902 cs42l43_clear_jack(priv); 903 904 if (!override) { 905 queue_delayed_work(system_long_wq, &priv->tip_sense_work, 0); 906 } else { 907 override--; 908 909 regmap_update_bits(cs42l43->regmap, CS42L43_HS2, 910 CS42L43_HSDET_MODE_MASK | 911 CS42L43_HSDET_MANUAL_MODE_MASK | 912 CS42L43_AMP3_4_GNDREF_HS3_SEL_MASK | 913 CS42L43_AMP3_4_GNDREF_HS4_SEL_MASK | 914 CS42L43_HSBIAS_GNDREF_HS3_SEL_MASK | 915 CS42L43_HSBIAS_GNDREF_HS4_SEL_MASK | 916 CS42L43_HSBIAS_OUT_HS3_SEL_MASK | 917 CS42L43_HSBIAS_OUT_HS4_SEL_MASK | 918 CS42L43_HSGND_HS3_SEL_MASK | 919 CS42L43_HSGND_HS4_SEL_MASK, 920 cs42l43_jack_override_modes[override].hsdet_mode); 921 regmap_update_bits(cs42l43->regmap, CS42L43_STEREO_MIC_CTRL, 922 CS42L43_HS2_BIAS_EN_MASK | CS42L43_HS1_BIAS_EN_MASK | 923 CS42L43_JACK_STEREO_CONFIG_MASK, 924 cs42l43_jack_override_modes[override].mic_ctrl); 925 regmap_update_bits(cs42l43->regmap, CS42L43_STEREO_MIC_CLAMP_CTRL, 926 CS42L43_SMIC_HPAMP_CLAMP_DIS_FRC_MASK, 927 cs42l43_jack_override_modes[override].clamp_ctrl); 928 929 switch (override) { 930 case CS42L43_JACK_RAW_CTIA: 931 case CS42L43_JACK_RAW_OMTP: 932 cs42l43_start_hs_bias(priv, false); 933 cs42l43_start_button_detect(priv); 934 break; 935 case CS42L43_JACK_RAW_LINE_IN: 936 regmap_update_bits(cs42l43->regmap, CS42L43_ADC_B_CTRL1, 937 CS42L43_PGA_WIDESWING_MODE_EN_MASK, 938 CS42L43_PGA_WIDESWING_MODE_EN_MASK); 939 regmap_update_bits(cs42l43->regmap, CS42L43_ADC_B_CTRL2, 940 CS42L43_PGA_WIDESWING_MODE_EN_MASK, 941 CS42L43_PGA_WIDESWING_MODE_EN_MASK); 942 break; 943 case CS42L43_JACK_RAW_MICROPHONE: 944 cs42l43_start_hs_bias(priv, false); 945 break; 946 default: 947 break; 948 } 949 950 snd_soc_jack_report(priv->jack_hp, 951 cs42l43_jack_override_modes[override].report, 952 cs42l43_jack_override_modes[override].report); 953 } 954 955 mutex_unlock(&priv->jack_lock); 956 957 return 1; 958 } 959
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.