]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
ASoC: cs42l43: Correct handling of 3-pole jack load detection
authorCharles Keepax <ckeepax@opensource.cirrus.com>
Fri, 30 Jan 2026 15:09:27 +0000 (15:09 +0000)
committerMark Brown <broonie@kernel.org>
Mon, 2 Feb 2026 12:09:26 +0000 (12:09 +0000)
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>
sound/soc/codecs/cs42l43-jack.c

index b719d62635a0eb1a2995a95f14ef0d917add2be8..b83bc4de1301d16ad9eb9ccbddec870a58334607 100644 (file)
@@ -496,7 +496,23 @@ void cs42l43_bias_sense_timeout(struct work_struct *work)
        pm_runtime_put_autosuspend(priv->dev);
 }
 
-static void cs42l43_start_load_detect(struct cs42l43_codec *priv)
+static const struct reg_sequence cs42l43_3pole_patch[] = {
+       { 0x4000,       0x00000055 },
+       { 0x4000,       0x000000AA },
+       { 0x17420,      0x8500F300 },
+       { 0x17424,      0x36003E00 },
+       { 0x4000,       0x00000000 },
+};
+
+static const struct reg_sequence cs42l43_4pole_patch[] = {
+       { 0x4000,       0x00000055 },
+       { 0x4000,       0x000000AA },
+       { 0x17420,      0x7800E600 },
+       { 0x17424,      0x36003800 },
+       { 0x4000,       0x00000000 },
+};
+
+static void cs42l43_start_load_detect(struct cs42l43_codec *priv, bool mic)
 {
        struct cs42l43 *cs42l43 = priv->core;
 
@@ -520,6 +536,15 @@ static void cs42l43_start_load_detect(struct cs42l43_codec *priv)
                        dev_err(priv->dev, "Load detect HP power down timed out\n");
        }
 
+       if (mic)
+               regmap_multi_reg_write_bypassed(cs42l43->regmap,
+                                               cs42l43_4pole_patch,
+                                               ARRAY_SIZE(cs42l43_4pole_patch));
+       else
+               regmap_multi_reg_write_bypassed(cs42l43->regmap,
+                                               cs42l43_3pole_patch,
+                                               ARRAY_SIZE(cs42l43_3pole_patch));
+
        regmap_update_bits(cs42l43->regmap, CS42L43_BLOCK_EN3,
                           CS42L43_ADC1_EN_MASK | CS42L43_ADC2_EN_MASK, 0);
        regmap_update_bits(cs42l43->regmap, CS42L43_DACCNFG2, CS42L43_HP_HPF_EN_MASK, 0);
@@ -598,7 +623,7 @@ static int cs42l43_run_load_detect(struct cs42l43_codec *priv, bool mic)
 
        reinit_completion(&priv->load_detect);
 
-       cs42l43_start_load_detect(priv);
+       cs42l43_start_load_detect(priv, mic);
        time_left = wait_for_completion_timeout(&priv->load_detect,
                                                msecs_to_jiffies(CS42L43_LOAD_TIMEOUT_MS));
        cs42l43_stop_load_detect(priv);
@@ -622,11 +647,11 @@ static int cs42l43_run_load_detect(struct cs42l43_codec *priv, bool mic)
        }
 
        switch (val & CS42L43_AMP3_RES_DET_MASK) {
-       case 0x0: // low impedance
-       case 0x1: // high impedance
+       case 0x0: // < 22 Ohm impedance
+       case 0x1: // < 150 Ohm impedance
+       case 0x2: // < 1000 Ohm impedance
                return CS42L43_JACK_HEADPHONE;
-       case 0x2: // lineout
-       case 0x3: // Open circuit
+       case 0x3: // > 1000 Ohm impedance
                return CS42L43_JACK_LINEOUT;
        default:
                return -EINVAL;