Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ASoC: cs42l43: Correct handling of 3-pole jack load detection

The load detection process for 3-pole jacks requires slightly
updated reference values to ensure an accurate result. Update
the code to apply different tunings for the 3-pole and 4-pole
cases. This also updates the thresholds overall so update the
relevant comments to match.

Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com>
Link: https://patch.msgid.link/20260130150927.2964664-1-ckeepax@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

Charles Keepax and committed by
Mark Brown
e77a4081 6b641122

+31 -6
+31 -6
sound/soc/codecs/cs42l43-jack.c
··· 496 496 pm_runtime_put_autosuspend(priv->dev); 497 497 } 498 498 499 - static void cs42l43_start_load_detect(struct cs42l43_codec *priv) 499 + static const struct reg_sequence cs42l43_3pole_patch[] = { 500 + { 0x4000, 0x00000055 }, 501 + { 0x4000, 0x000000AA }, 502 + { 0x17420, 0x8500F300 }, 503 + { 0x17424, 0x36003E00 }, 504 + { 0x4000, 0x00000000 }, 505 + }; 506 + 507 + static const struct reg_sequence cs42l43_4pole_patch[] = { 508 + { 0x4000, 0x00000055 }, 509 + { 0x4000, 0x000000AA }, 510 + { 0x17420, 0x7800E600 }, 511 + { 0x17424, 0x36003800 }, 512 + { 0x4000, 0x00000000 }, 513 + }; 514 + 515 + static void cs42l43_start_load_detect(struct cs42l43_codec *priv, bool mic) 500 516 { 501 517 struct cs42l43 *cs42l43 = priv->core; 502 518 ··· 535 519 if (!time_left) 536 520 dev_err(priv->dev, "Load detect HP power down timed out\n"); 537 521 } 522 + 523 + if (mic) 524 + regmap_multi_reg_write_bypassed(cs42l43->regmap, 525 + cs42l43_4pole_patch, 526 + ARRAY_SIZE(cs42l43_4pole_patch)); 527 + else 528 + regmap_multi_reg_write_bypassed(cs42l43->regmap, 529 + cs42l43_3pole_patch, 530 + ARRAY_SIZE(cs42l43_3pole_patch)); 538 531 539 532 regmap_update_bits(cs42l43->regmap, CS42L43_BLOCK_EN3, 540 533 CS42L43_ADC1_EN_MASK | CS42L43_ADC2_EN_MASK, 0); ··· 623 598 624 599 reinit_completion(&priv->load_detect); 625 600 626 - cs42l43_start_load_detect(priv); 601 + cs42l43_start_load_detect(priv, mic); 627 602 time_left = wait_for_completion_timeout(&priv->load_detect, 628 603 msecs_to_jiffies(CS42L43_LOAD_TIMEOUT_MS)); 629 604 cs42l43_stop_load_detect(priv); ··· 647 622 } 648 623 649 624 switch (val & CS42L43_AMP3_RES_DET_MASK) { 650 - case 0x0: // low impedance 651 - case 0x1: // high impedance 625 + case 0x0: // < 22 Ohm impedance 626 + case 0x1: // < 150 Ohm impedance 627 + case 0x2: // < 1000 Ohm impedance 652 628 return CS42L43_JACK_HEADPHONE; 653 - case 0x2: // lineout 654 - case 0x3: // Open circuit 629 + case 0x3: // > 1000 Ohm impedance 655 630 return CS42L43_JACK_LINEOUT; 656 631 default: 657 632 return -EINVAL;