Message ID | 20220910124701.4060321-3-dmitry.baryshkov@linaro.org |
---|---|
State | New |
Headers | show |
Series | thermal/drivers/tsens: specify nvmem cells in DT rather than parsing them manually | expand |
Hi Dmitry, I like this clean up. On Sat, Sep 10, 2022 at 6:17 PM Dmitry Baryshkov <dmitry.baryshkov@linaro.org> wrote: > > Add a unified function using nvmem cells for parsing the calibration > data rather than parsing the calibration blob manually. > > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> > --- > drivers/thermal/qcom/tsens-v0_1.c | 15 ++++++++ > drivers/thermal/qcom/tsens-v1.c | 6 ++- > drivers/thermal/qcom/tsens.c | 62 +++++++++++++++++++++++++++++++ > drivers/thermal/qcom/tsens.h | 4 ++ > 4 files changed, 86 insertions(+), 1 deletion(-) > > diff --git a/drivers/thermal/qcom/tsens-v0_1.c b/drivers/thermal/qcom/tsens-v0_1.c > index f136cb350238..2974eea578f4 100644 > --- a/drivers/thermal/qcom/tsens-v0_1.c > +++ b/drivers/thermal/qcom/tsens-v0_1.c > @@ -229,6 +229,11 @@ static int calibrate_8916(struct tsens_priv *priv) > u32 p1[5], p2[5]; > int mode = 0; > u32 *qfprom_cdata, *qfprom_csel; > + int ret; > + > + ret = tsens_calibrate_nvmem(priv, 3); > + if (!ret) > + return 0; > > qfprom_cdata = (u32 *)qfprom_read(priv->dev, "calib"); > if (IS_ERR(qfprom_cdata)) > @@ -286,6 +291,11 @@ static int calibrate_8939(struct tsens_priv *priv) > int mode = 0; > u32 *qfprom_cdata; > u32 cdata[6]; > + int ret; > + > + ret = tsens_calibrate_nvmem(priv, 2); > + if (!ret) > + return 0; > > qfprom_cdata = (u32 *)qfprom_read(priv->dev, "calib"); > if (IS_ERR(qfprom_cdata)) > @@ -491,6 +501,11 @@ static int calibrate_9607(struct tsens_priv *priv) > u32 p1[5], p2[5]; > int mode = 0; > u32 *qfprom_cdata; > + int ret; > + > + ret = tsens_calibrate_nvmem(priv, 2); > + if (!ret) > + return 0; > > qfprom_cdata = (u32 *)qfprom_read(priv->dev, "calib"); > if (IS_ERR(qfprom_cdata)) > diff --git a/drivers/thermal/qcom/tsens-v1.c b/drivers/thermal/qcom/tsens-v1.c > index 573e261ccca7..868d7b4c9e36 100644 > --- a/drivers/thermal/qcom/tsens-v1.c > +++ b/drivers/thermal/qcom/tsens-v1.c > @@ -172,7 +172,11 @@ static int calibrate_v1(struct tsens_priv *priv) > u32 p1[10], p2[10]; > u32 mode = 0, lsb = 0, msb = 0; > u32 *qfprom_cdata; > - int i; > + int i, ret; > + > + ret = tsens_calibrate_nvmem(priv, 2); > + if (!ret) > + return 0; > > qfprom_cdata = (u32 *)qfprom_read(priv->dev, "calib"); > if (IS_ERR(qfprom_cdata)) > diff --git a/drivers/thermal/qcom/tsens.c b/drivers/thermal/qcom/tsens.c > index e49f58e83513..8331b924325a 100644 > --- a/drivers/thermal/qcom/tsens.c > +++ b/drivers/thermal/qcom/tsens.c > @@ -70,6 +70,68 @@ char *qfprom_read(struct device *dev, const char *cname) > return ret; > } > > +int tsens_calibrate_nvmem(struct tsens_priv *priv, int shift) > +{ > + u32 mode; > + u32 base1, base2; > + u32 p1[MAX_SENSORS], p2[MAX_SENSORS]; > + char name[] = "sX_pY"; > + int i, ret; > + > + if (priv->num_sensors > MAX_SENSORS) > + return -EINVAL; > + > + ret = nvmem_cell_read_variable_le_u32(priv->dev, "mode", &mode); > + if (ret == -ENOENT) > + dev_warn(priv->dev, "Please migrate to sepate nvmem cells for calibration data\n"); typo: separate > + if (ret < 0) > + return ret; > + > + dev_dbg(priv->dev, "calibration mode is %d\n", mode); > + > + ret = nvmem_cell_read_variable_le_u32(priv->dev, "base1", &base1); > + if (ret < 0) > + return ret; > + > + ret = nvmem_cell_read_variable_le_u32(priv->dev, "base2", &base2); > + if (ret < 0) > + return ret; > + > + for (i = 0; i < priv->num_sensors; i++) { > + ret = snprintf(name, sizeof(name), "s%d_p1", i); > + if (ret < 0) > + return ret; > + > + ret = nvmem_cell_read_variable_le_u32(priv->dev, name, &p1[i]); > + if (ret) > + return ret; > + > + p1[i] = (base1 + p1[i]) << shift; > + > + ret = snprintf(name, sizeof(name), "s%d_p2", i); > + if (ret < 0) > + return ret; > + > + ret = nvmem_cell_read_variable_le_u32(priv->dev, name, &p2[i]); > + if (ret) > + return ret; > + > + p2[i] = (base2 + p2[i]) << shift; Have you verified that the p1 and p2 arrays end up with identical values before and after this conversion? > + } > + > + if (mode == NO_PT_CALIB) { > + dev_dbg(priv->dev, "calibrationless mode\n"); > + for (i = 0; i < priv->num_sensors; i++) { > + p1[i] = 500; > + p2[i] = 780; > + } > + } > + > + compute_intercept_slope(priv, p1, p2, mode); > + > + return 0; > +} > + > /*
On 13 September 2022 22:18:48 GMT+03:00, Amit Kucheria <amitk@kernel.org> wrote: >Hi Dmitry, > >I like this clean up. > >On Sat, Sep 10, 2022 at 6:17 PM Dmitry Baryshkov ><dmitry.baryshkov@linaro.org> wrote: >> >> Add a unified function using nvmem cells for parsing the calibration >> data rather than parsing the calibration blob manually. >> >> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> >> --- >> drivers/thermal/qcom/tsens-v0_1.c | 15 ++++++++ >> drivers/thermal/qcom/tsens-v1.c | 6 ++- >> drivers/thermal/qcom/tsens.c | 62 +++++++++++++++++++++++++++++++ >> drivers/thermal/qcom/tsens.h | 4 ++ >> 4 files changed, 86 insertions(+), 1 deletion(-) >> >> diff --git a/drivers/thermal/qcom/tsens-v0_1.c b/drivers/thermal/qcom/tsens-v0_1.c >> index f136cb350238..2974eea578f4 100644 >> --- a/drivers/thermal/qcom/tsens-v0_1.c >> +++ b/drivers/thermal/qcom/tsens-v0_1.c >> @@ -229,6 +229,11 @@ static int calibrate_8916(struct tsens_priv *priv) >> u32 p1[5], p2[5]; >> int mode = 0; >> u32 *qfprom_cdata, *qfprom_csel; >> + int ret; >> + >> + ret = tsens_calibrate_nvmem(priv, 3); >> + if (!ret) >> + return 0; >> >> qfprom_cdata = (u32 *)qfprom_read(priv->dev, "calib"); >> if (IS_ERR(qfprom_cdata)) >> @@ -286,6 +291,11 @@ static int calibrate_8939(struct tsens_priv *priv) >> int mode = 0; >> u32 *qfprom_cdata; >> u32 cdata[6]; >> + int ret; >> + >> + ret = tsens_calibrate_nvmem(priv, 2); >> + if (!ret) >> + return 0; >> >> qfprom_cdata = (u32 *)qfprom_read(priv->dev, "calib"); >> if (IS_ERR(qfprom_cdata)) >> @@ -491,6 +501,11 @@ static int calibrate_9607(struct tsens_priv *priv) >> u32 p1[5], p2[5]; >> int mode = 0; >> u32 *qfprom_cdata; >> + int ret; >> + >> + ret = tsens_calibrate_nvmem(priv, 2); >> + if (!ret) >> + return 0; >> >> qfprom_cdata = (u32 *)qfprom_read(priv->dev, "calib"); >> if (IS_ERR(qfprom_cdata)) >> diff --git a/drivers/thermal/qcom/tsens-v1.c b/drivers/thermal/qcom/tsens-v1.c >> index 573e261ccca7..868d7b4c9e36 100644 >> --- a/drivers/thermal/qcom/tsens-v1.c >> +++ b/drivers/thermal/qcom/tsens-v1.c >> @@ -172,7 +172,11 @@ static int calibrate_v1(struct tsens_priv *priv) >> u32 p1[10], p2[10]; >> u32 mode = 0, lsb = 0, msb = 0; >> u32 *qfprom_cdata; >> - int i; >> + int i, ret; >> + >> + ret = tsens_calibrate_nvmem(priv, 2); >> + if (!ret) >> + return 0; >> >> qfprom_cdata = (u32 *)qfprom_read(priv->dev, "calib"); >> if (IS_ERR(qfprom_cdata)) >> diff --git a/drivers/thermal/qcom/tsens.c b/drivers/thermal/qcom/tsens.c >> index e49f58e83513..8331b924325a 100644 >> --- a/drivers/thermal/qcom/tsens.c >> +++ b/drivers/thermal/qcom/tsens.c >> @@ -70,6 +70,68 @@ char *qfprom_read(struct device *dev, const char *cname) >> return ret; >> } >> >> +int tsens_calibrate_nvmem(struct tsens_priv *priv, int shift) >> +{ >> + u32 mode; >> + u32 base1, base2; >> + u32 p1[MAX_SENSORS], p2[MAX_SENSORS]; >> + char name[] = "sX_pY"; >> + int i, ret; >> + >> + if (priv->num_sensors > MAX_SENSORS) >> + return -EINVAL; >> + >> + ret = nvmem_cell_read_variable_le_u32(priv->dev, "mode", &mode); >> + if (ret == -ENOENT) >> + dev_warn(priv->dev, "Please migrate to sepate nvmem cells for calibration data\n"); > >typo: separate Ack. > >> + if (ret < 0) >> + return ret; >> + >> + dev_dbg(priv->dev, "calibration mode is %d\n", mode); >> + >> + ret = nvmem_cell_read_variable_le_u32(priv->dev, "base1", &base1); >> + if (ret < 0) >> + return ret; >> + >> + ret = nvmem_cell_read_variable_le_u32(priv->dev, "base2", &base2); >> + if (ret < 0) >> + return ret; >> + >> + for (i = 0; i < priv->num_sensors; i++) { >> + ret = snprintf(name, sizeof(name), "s%d_p1", i); >> + if (ret < 0) >> + return ret; >> + >> + ret = nvmem_cell_read_variable_le_u32(priv->dev, name, &p1[i]); >> + if (ret) >> + return ret; >> + >> + p1[i] = (base1 + p1[i]) << shift; >> + >> + ret = snprintf(name, sizeof(name), "s%d_p2", i); >> + if (ret < 0) >> + return ret; >> + >> + ret = nvmem_cell_read_variable_le_u32(priv->dev, name, &p2[i]); >> + if (ret) >> + return ret; >> + >> + p2[i] = (base2 + p2[i]) << shift; > >Have you verified that the p1 and p2 arrays end up with identical >values before and after this conversion? Yes. I have verified that the calibration values are unchanged on db410c(apq8016, v0_1) and qcs404-evb (v1). > > >> + } >> + >> + if (mode == NO_PT_CALIB) { >> + dev_dbg(priv->dev, "calibrationless mode\n"); >> + for (i = 0; i < priv->num_sensors; i++) { >> + p1[i] = 500; >> + p2[i] = 780; >> + } >> + } >> + >> + compute_intercept_slope(priv, p1, p2, mode); >> + >> + return 0; >> +} >> + >> /*
diff --git a/drivers/thermal/qcom/tsens-v0_1.c b/drivers/thermal/qcom/tsens-v0_1.c index f136cb350238..2974eea578f4 100644 --- a/drivers/thermal/qcom/tsens-v0_1.c +++ b/drivers/thermal/qcom/tsens-v0_1.c @@ -229,6 +229,11 @@ static int calibrate_8916(struct tsens_priv *priv) u32 p1[5], p2[5]; int mode = 0; u32 *qfprom_cdata, *qfprom_csel; + int ret; + + ret = tsens_calibrate_nvmem(priv, 3); + if (!ret) + return 0; qfprom_cdata = (u32 *)qfprom_read(priv->dev, "calib"); if (IS_ERR(qfprom_cdata)) @@ -286,6 +291,11 @@ static int calibrate_8939(struct tsens_priv *priv) int mode = 0; u32 *qfprom_cdata; u32 cdata[6]; + int ret; + + ret = tsens_calibrate_nvmem(priv, 2); + if (!ret) + return 0; qfprom_cdata = (u32 *)qfprom_read(priv->dev, "calib"); if (IS_ERR(qfprom_cdata)) @@ -491,6 +501,11 @@ static int calibrate_9607(struct tsens_priv *priv) u32 p1[5], p2[5]; int mode = 0; u32 *qfprom_cdata; + int ret; + + ret = tsens_calibrate_nvmem(priv, 2); + if (!ret) + return 0; qfprom_cdata = (u32 *)qfprom_read(priv->dev, "calib"); if (IS_ERR(qfprom_cdata)) diff --git a/drivers/thermal/qcom/tsens-v1.c b/drivers/thermal/qcom/tsens-v1.c index 573e261ccca7..868d7b4c9e36 100644 --- a/drivers/thermal/qcom/tsens-v1.c +++ b/drivers/thermal/qcom/tsens-v1.c @@ -172,7 +172,11 @@ static int calibrate_v1(struct tsens_priv *priv) u32 p1[10], p2[10]; u32 mode = 0, lsb = 0, msb = 0; u32 *qfprom_cdata; - int i; + int i, ret; + + ret = tsens_calibrate_nvmem(priv, 2); + if (!ret) + return 0; qfprom_cdata = (u32 *)qfprom_read(priv->dev, "calib"); if (IS_ERR(qfprom_cdata)) diff --git a/drivers/thermal/qcom/tsens.c b/drivers/thermal/qcom/tsens.c index e49f58e83513..8331b924325a 100644 --- a/drivers/thermal/qcom/tsens.c +++ b/drivers/thermal/qcom/tsens.c @@ -70,6 +70,68 @@ char *qfprom_read(struct device *dev, const char *cname) return ret; } +int tsens_calibrate_nvmem(struct tsens_priv *priv, int shift) +{ + u32 mode; + u32 base1, base2; + u32 p1[MAX_SENSORS], p2[MAX_SENSORS]; + char name[] = "sX_pY"; + int i, ret; + + if (priv->num_sensors > MAX_SENSORS) + return -EINVAL; + + ret = nvmem_cell_read_variable_le_u32(priv->dev, "mode", &mode); + if (ret == -ENOENT) + dev_warn(priv->dev, "Please migrate to sepate nvmem cells for calibration data\n"); + if (ret < 0) + return ret; + + dev_dbg(priv->dev, "calibration mode is %d\n", mode); + + ret = nvmem_cell_read_variable_le_u32(priv->dev, "base1", &base1); + if (ret < 0) + return ret; + + ret = nvmem_cell_read_variable_le_u32(priv->dev, "base2", &base2); + if (ret < 0) + return ret; + + for (i = 0; i < priv->num_sensors; i++) { + ret = snprintf(name, sizeof(name), "s%d_p1", i); + if (ret < 0) + return ret; + + ret = nvmem_cell_read_variable_le_u32(priv->dev, name, &p1[i]); + if (ret) + return ret; + + p1[i] = (base1 + p1[i]) << shift; + + ret = snprintf(name, sizeof(name), "s%d_p2", i); + if (ret < 0) + return ret; + + ret = nvmem_cell_read_variable_le_u32(priv->dev, name, &p2[i]); + if (ret) + return ret; + + p2[i] = (base2 + p2[i]) << shift; + } + + if (mode == NO_PT_CALIB) { + dev_dbg(priv->dev, "calibrationless mode\n"); + for (i = 0; i < priv->num_sensors; i++) { + p1[i] = 500; + p2[i] = 780; + } + } + + compute_intercept_slope(priv, p1, p2, mode); + + return 0; +} + /* * Use this function on devices where slope and offset calculations * depend on calibration data read from qfprom. On others the slope diff --git a/drivers/thermal/qcom/tsens.h b/drivers/thermal/qcom/tsens.h index ba05c8233356..504ed3394a79 100644 --- a/drivers/thermal/qcom/tsens.h +++ b/drivers/thermal/qcom/tsens.h @@ -6,6 +6,7 @@ #ifndef __QCOM_TSENS_H__ #define __QCOM_TSENS_H__ +#define NO_PT_CALIB 0x0 #define ONE_PT_CALIB 0x1 #define ONE_PT_CALIB2 0x2 #define TWO_PT_CALIB 0x3 @@ -17,6 +18,8 @@ #define THRESHOLD_MAX_ADC_CODE 0x3ff #define THRESHOLD_MIN_ADC_CODE 0x0 +#define MAX_SENSORS 16 + #include <linux/interrupt.h> #include <linux/thermal.h> #include <linux/regmap.h> @@ -576,6 +579,7 @@ struct tsens_priv { }; char *qfprom_read(struct device *dev, const char *cname); +int tsens_calibrate_nvmem(struct tsens_priv *priv, int shift); void compute_intercept_slope(struct tsens_priv *priv, u32 *pt1, u32 *pt2, u32 mode); int init_common(struct tsens_priv *priv); int get_temp_tsens_valid(const struct tsens_sensor *s, int *temp);
Add a unified function using nvmem cells for parsing the calibration data rather than parsing the calibration blob manually. Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> --- drivers/thermal/qcom/tsens-v0_1.c | 15 ++++++++ drivers/thermal/qcom/tsens-v1.c | 6 ++- drivers/thermal/qcom/tsens.c | 62 +++++++++++++++++++++++++++++++ drivers/thermal/qcom/tsens.h | 4 ++ 4 files changed, 86 insertions(+), 1 deletion(-)