]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
thermal/drivers/qcom/tsens-v0_1: Add mdm9607 correction offsets
authorStephan Gerhold <stephan.gerhold@kernkonzept.com>
Wed, 7 Jun 2023 10:47:46 +0000 (12:47 +0200)
committerDaniel Lezcano <daniel.lezcano@linaro.org>
Mon, 26 Jun 2023 10:03:13 +0000 (12:03 +0200)
According to the msm-3.18 vendor kernel from Qualcomm, mdm9607 needs
"correction factors" to adjust for additional offsets observed after the
factory calibration values in the fuses [1, 2].

The fixed offsets should be applied unless there is a special
calibration mode value that indicates that no offsets are needed [3].

Note that the new calibration mode values are called differently in this
patch compared to the vendor kernel:
  - TSENS_TWO_POINT_CALIB_N_WA        -> ONE_PT_CALIB2_NO_OFFSET
  - TSENS_TWO_POINT_CALIB_N_OFFSET_WA -> TWO_PT_CALIB_NO_OFFSET
This is because close inspection of the calibration function [3] reveals
that TSENS_TWO_POINT_CALIB_N_WA is actually a "one point" calibration
because the if statements skip all "point2" related code for it.

[1]: https://git.codelinaro.org/clo/la/kernel/msm-3.18/-/commit/d9d2db1b82bf3f72f5de0803d55e6849eb5b671e
[2]: https://git.codelinaro.org/clo/la/kernel/msm-3.18/-/commit/d75aef53a760e8ff7bac54049d00c8b2ee1b193e
[3]: https://git.codelinaro.org/clo/la/kernel/msm-3.18/-/blob/LE.UM.4.3.2.r1-04200-9x07/drivers/thermal/msm-tsens.c#L2987-3136

Fixes: a2149ab815fc ("thermal/drivers/qcom/tsens-v0_1: Add support for MDM9607")
Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Signed-off-by: Stephan Gerhold <stephan.gerhold@kernkonzept.com>
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Link: https://lore.kernel.org/r/20230508-msm8909-tsens-v5-3-5eb632235ba7@kernkonzept.com
drivers/thermal/qcom/tsens-v0_1.c
drivers/thermal/qcom/tsens.c
drivers/thermal/qcom/tsens.h

index 9802ae1d4fcf89802e1375aad04602d14c2e5ae2..4a55a8ea00438ac0decfc7d2e95bad4c43276987 100644 (file)
@@ -241,6 +241,17 @@ static int __init init_9607(struct tsens_priv *priv)
        for (i = 0; i < priv->num_sensors; ++i)
                priv->sensor[i].slope = 3000;
 
+       priv->sensor[0].p1_calib_offset = 1;
+       priv->sensor[0].p2_calib_offset = 1;
+       priv->sensor[1].p1_calib_offset = -4;
+       priv->sensor[1].p2_calib_offset = -2;
+       priv->sensor[2].p1_calib_offset = 4;
+       priv->sensor[2].p2_calib_offset = 8;
+       priv->sensor[3].p1_calib_offset = -3;
+       priv->sensor[3].p2_calib_offset = -5;
+       priv->sensor[4].p1_calib_offset = -4;
+       priv->sensor[4].p2_calib_offset = -4;
+
        return init_common(priv);
 }
 
index 1c457b55efb392b150ed12d84d858af36779025d..9dd5e4b709117e2f899fe17d90abcf2bf1af92ee 100644 (file)
@@ -134,10 +134,12 @@ int tsens_read_calibration(struct tsens_priv *priv, int shift, u32 *p1, u32 *p2,
                        p1[i] = p1[i] + (base1 << shift);
                break;
        case TWO_PT_CALIB:
+       case TWO_PT_CALIB_NO_OFFSET:
                for (i = 0; i < priv->num_sensors; i++)
                        p2[i] = (p2[i] + base2) << shift;
                fallthrough;
        case ONE_PT_CALIB2:
+       case ONE_PT_CALIB2_NO_OFFSET:
                for (i = 0; i < priv->num_sensors; i++)
                        p1[i] = (p1[i] + base1) << shift;
                break;
@@ -149,6 +151,18 @@ int tsens_read_calibration(struct tsens_priv *priv, int shift, u32 *p1, u32 *p2,
                }
        }
 
+       /* Apply calibration offset workaround except for _NO_OFFSET modes */
+       switch (mode) {
+       case TWO_PT_CALIB:
+               for (i = 0; i < priv->num_sensors; i++)
+                       p2[i] += priv->sensor[i].p2_calib_offset;
+               fallthrough;
+       case ONE_PT_CALIB2:
+               for (i = 0; i < priv->num_sensors; i++)
+                       p1[i] += priv->sensor[i].p1_calib_offset;
+               break;
+       }
+
        return mode;
 }
 
@@ -254,7 +268,7 @@ void compute_intercept_slope(struct tsens_priv *priv, u32 *p1,
 
                if (!priv->sensor[i].slope)
                        priv->sensor[i].slope = SLOPE_DEFAULT;
-               if (mode == TWO_PT_CALIB) {
+               if (mode == TWO_PT_CALIB || mode == TWO_PT_CALIB_NO_OFFSET) {
                        /*
                         * slope (m) = adc_code2 - adc_code1 (y2 - y1)/
                         *      temp_120_degc - temp_30_degc (x2 - x1)
index 433eba370998cf0a37b56d13557cdcb40a6898f7..1cd8f4fe0971ffcebe1433514bd69b83098b7c4a 100644 (file)
@@ -10,6 +10,8 @@
 #define ONE_PT_CALIB           0x1
 #define ONE_PT_CALIB2          0x2
 #define TWO_PT_CALIB           0x3
+#define ONE_PT_CALIB2_NO_OFFSET        0x6
+#define TWO_PT_CALIB_NO_OFFSET 0x7
 #define CAL_DEGC_PT1           30
 #define CAL_DEGC_PT2           120
 #define SLOPE_FACTOR           1000
@@ -57,6 +59,8 @@ struct tsens_sensor {
        unsigned int                    hw_id;
        int                             slope;
        u32                             status;
+       int                             p1_calib_offset;
+       int                             p2_calib_offset;
 };
 
 /**