Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 79f5ff3a authored by Siva Kumar Akkireddi's avatar Siva Kumar Akkireddi
Browse files

thermal: tsens: Add calibration support for qcs405



Add efuse reads to compute slope and offset used to convert final
temperature readings. Add all efuse related TSENS reads for 1xxx
controller across different targets in a common file for calibration.

Change-Id: I95ed119377767e518f0fa38720e73a5ce3561b41
Signed-off-by: default avatarSiva Kumar Akkireddi <sivaa@codeaurora.org>
parent d732694b
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ Required properties:
	       should be "qcom,sdm845-tsens" for SDM845 TSENS driver.
	       should be "qcom,tsens24xx" for 2.4 TSENS controller.
	       should be "qcom,msm8937-tsens" for 8937 TSENS driver.
	       should be "qcom,qcs405-tsens" for QCS405 TSENS driver.
	       The compatible property is used to identify the respective controller to use
	       for the corresponding SoC.
- reg : offset and length of the TSENS registers with associated property in reg-names
+1 −1
Original line number Diff line number Diff line
@@ -62,4 +62,4 @@ obj-$(CONFIG_MTK_THERMAL) += mtk_thermal.o
obj-$(CONFIG_GENERIC_ADC_THERMAL)	+= thermal-generic-adc.o
obj-$(CONFIG_ZX2967_THERMAL)	+= zx2967_thermal.o
obj-$(CONFIG_UNIPHIER_THERMAL)	+= uniphier_thermal.o
obj-$(CONFIG_THERMAL_TSENS)	+= msm-tsens.o tsens2xxx.o tsens-dbg.o tsens-mtc.o tsens1xxx.o
obj-$(CONFIG_THERMAL_TSENS)	+= msm-tsens.o tsens2xxx.o tsens-dbg.o tsens-mtc.o tsens1xxx.o tsens_calib.o
+3 −0
Original line number Diff line number Diff line
@@ -89,6 +89,9 @@ static const struct of_device_id tsens_table[] = {
	{	.compatible = "qcom,msm8937-tsens",
		.data = &data_tsens14xx,
	},
	{	.compatible = "qcom,qcs405-tsens",
		.data = &data_tsens14xx_405,
	},
	{}
};
MODULE_DEVICE_TABLE(of, tsens_table);
+10 −3
Original line number Diff line number Diff line
@@ -23,7 +23,8 @@

#define DEBUG_SIZE					10
#define TSENS_MAX_SENSORS			16
#define TSENS_1x_MAX_SENSORS			11
#define TSENS_NUM_SENSORS_8937		11
#define TSENS_NUM_SENSORS_405		10
#define TSENS_CONTROLLER_ID(n)			(n)
#define TSENS_CTRL_ADDR(n)			(n)
#define TSENS_TM_SN_STATUS(n)			((n) + 0xa0)
@@ -32,6 +33,9 @@
#define ONE_PT_CALIB2		0x2
#define TWO_PT_CALIB		0x3

#define SLOPE_FACTOR		1000
#define SLOPE_DEFAULT		3200

enum tsens_dbg_type {
	TSENS_DBG_POLL,
	TSENS_DBG_LOG_TEMP_READS,
@@ -156,7 +160,10 @@ struct tsens_device {
};

extern const struct tsens_data data_tsens2xxx, data_tsens23xx, data_tsens24xx;
extern const struct tsens_data data_tsens14xx;
extern const struct tsens_data data_tsens14xx, data_tsens14xx_405;
extern struct list_head tsens_device_list;

extern int calibrate_8937(struct tsens_device *tmdev);
extern int calibrate_405(struct tsens_device *tmdev);

#endif /* __QCOM_TSENS_H__ */
+27 −172
Original line number Diff line number Diff line
@@ -55,102 +55,6 @@
#define TSENS_THRESHOLD_MIN_CODE	0x0
#define TSENS_SCALE_MILLIDEG		1000

/* eeprom layout data for 8937 */
#define BASE0_MASK	0x000000ff
#define BASE1_MASK	0xff000000
#define BASE1_SHIFT	24

#define S0_P1_MASK		0x000001f8
#define S1_P1_MASK		0x001f8000
#define S2_P1_MASK_0_4		0xf8000000
#define S2_P1_MASK_5		0x00000001
#define S3_P1_MASK		0x00001f80
#define S4_P1_MASK		0x01f80000
#define S5_P1_MASK		0x00003f00
#define S6_P1_MASK		0x03f00000
#define S7_P1_MASK		0x0000003f
#define S8_P1_MASK		0x0003f000
#define S9_P1_MASK		0x0000003f
#define S10_P1_MASK		0x0003f000

#define S0_P2_MASK		0x00007e00
#define S1_P2_MASK		0x07e00000
#define S2_P2_MASK		0x0000007e
#define S3_P2_MASK		0x0007e000
#define S4_P2_MASK		0x7e000000
#define S5_P2_MASK		0x000fc000
#define S6_P2_MASK		0xfc000000
#define S7_P2_MASK		0x00000fc0
#define S8_P2_MASK		0x00fc0000
#define S9_P2_MASK		0x00000fc0
#define S10_P2_MASK		0x00fc0000

#define S0_P1_SHIFT     3
#define S1_P1_SHIFT     15
#define S2_P1_SHIFT_0_4 27
#define S2_P1_SHIFT_5   5
#define S3_P1_SHIFT     7
#define S4_P1_SHIFT     19
#define S5_P1_SHIFT     8
#define S6_P1_SHIFT     20
#define S8_P1_SHIFT     12
#define S10_P1_SHIFT    12

#define S0_P2_SHIFT     9
#define S1_P2_SHIFT     21
#define S2_P2_SHIFT     1
#define S3_P2_SHIFT     13
#define S4_P2_SHIFT     25
#define S5_P2_SHIFT     14
#define S6_P2_SHIFT     26
#define S7_P2_SHIFT     6
#define S8_P2_SHIFT     18
#define S9_P2_SHIFT     6
#define S10_P2_SHIFT    18

#define CAL_SEL_MASK	0x00000007

#define CAL_DEGC_PT1		30
#define CAL_DEGC_PT2		120
#define SLOPE_FACTOR		1000
#define SLOPE_DEFAULT		3200

/*
 * Use this function on devices where slope and offset calculations
 * depend on calibration data read from qfprom. On others the slope
 * and offset values are derived from tz->tzp->slope and tz->tzp->offset
 * resp.
 */
static void compute_intercept_slope(struct tsens_device *tmdev, u32 *p1,
			     u32 *p2, u32 mode)
{
	int i;
	int num, den;

	for (i = 0; i < TSENS_1x_MAX_SENSORS; i++) {
		pr_debug(
			"sensor%d - data_point1:%#x data_point2:%#x\n",
			i, p1[i], p2[i]);

		tmdev->sensor[i].slope = SLOPE_DEFAULT;
		if (mode == TWO_PT_CALIB) {
			/*
			 * slope (m) = adc_code2 - adc_code1 (y2 - y1)/
			 *	temp_120_degc - temp_30_degc (x2 - x1)
			 */
			num = p2[i] - p1[i];
			num *= SLOPE_FACTOR;
			den = CAL_DEGC_PT2 - CAL_DEGC_PT1;
			tmdev->sensor[i].slope = num / den;
		}

		tmdev->sensor[i].offset = (p1[i] * SLOPE_FACTOR) -
				(CAL_DEGC_PT1 *
				tmdev->sensor[i].slope);
		pr_debug("offset:%d\n", tmdev->sensor[i].offset);
	}
}

static int code_to_degc(u32 adc_code, const struct tsens_sensor *sensor)
{
	int degc, num, den;
@@ -184,72 +88,6 @@ static int degc_to_code(int degc, const struct tsens_sensor *sensor)
	return code;
}

static int calibrate_8937(struct tsens_device *tmdev)
{
	int base0 = 0, base1 = 0, i;
	u32 p1[TSENS_1x_MAX_SENSORS], p2[TSENS_1x_MAX_SENSORS];
	int mode = 0, tmp = 0;
	u32 qfprom_cdata[5] = {0, 0, 0, 0, 0};

	qfprom_cdata[0] = readl_relaxed(tmdev->tsens_calib_addr + 0x1D8);
	qfprom_cdata[1] = readl_relaxed(tmdev->tsens_calib_addr + 0x1DC);
	qfprom_cdata[2] = readl_relaxed(tmdev->tsens_calib_addr + 0x210);
	qfprom_cdata[3] = readl_relaxed(tmdev->tsens_calib_addr + 0x214);
	qfprom_cdata[4] = readl_relaxed(tmdev->tsens_calib_addr + 0x230);

	mode = (qfprom_cdata[2] & CAL_SEL_MASK);
	pr_debug("calibration mode is %d\n", mode);

	switch (mode) {
	case TWO_PT_CALIB:
		base1 = (qfprom_cdata[1] & BASE1_MASK) >> BASE1_SHIFT;
		p2[0] = (qfprom_cdata[2] & S0_P2_MASK) >> S0_P2_SHIFT;
		p2[1] = (qfprom_cdata[2] & S1_P2_MASK) >> S1_P2_SHIFT;
		p2[2] = (qfprom_cdata[3] & S2_P2_MASK) >> S2_P2_SHIFT;
		p2[3] = (qfprom_cdata[3] & S3_P2_MASK) >> S3_P2_SHIFT;
		p2[4] = (qfprom_cdata[3] & S4_P2_MASK) >> S4_P2_SHIFT;
		p2[5] = (qfprom_cdata[0] & S5_P2_MASK) >> S5_P2_SHIFT;
		p2[6] = (qfprom_cdata[0] & S6_P2_MASK) >> S6_P2_SHIFT;
		p2[7] = (qfprom_cdata[1] & S7_P2_MASK) >> S7_P2_SHIFT;
		p2[8] = (qfprom_cdata[1] & S8_P2_MASK) >> S8_P2_SHIFT;
		p2[9] = (qfprom_cdata[4] & S9_P2_MASK) >> S9_P2_SHIFT;
		p2[10] = (qfprom_cdata[4] & S10_P2_MASK) >> S10_P2_SHIFT;

		for (i = 0; i < TSENS_1x_MAX_SENSORS; i++)
			p2[i] = ((base1 + p2[i]) << 2);
		/* Fall through */
	case ONE_PT_CALIB2:
		base0 = (qfprom_cdata[0] & BASE0_MASK);
		p1[0] = (qfprom_cdata[2] & S0_P1_MASK) >> S0_P1_SHIFT;
		p1[1] = (qfprom_cdata[2] & S1_P1_MASK) >> S1_P1_SHIFT;
		p1[2] = (qfprom_cdata[2] & S2_P1_MASK_0_4) >> S2_P1_SHIFT_0_4;
		tmp = (qfprom_cdata[3] & S2_P1_MASK_5) << S2_P1_SHIFT_5;
		p1[2] |= tmp;
		p1[3] = (qfprom_cdata[3] & S3_P1_MASK) >> S3_P1_SHIFT;
		p1[4] = (qfprom_cdata[3] & S4_P1_MASK) >> S4_P1_SHIFT;
		p1[5] = (qfprom_cdata[0] & S5_P1_MASK) >> S5_P1_SHIFT;
		p1[6] = (qfprom_cdata[0] & S6_P1_MASK) >> S6_P1_SHIFT;
		p1[7] = (qfprom_cdata[1] & S7_P1_MASK);
		p1[8] = (qfprom_cdata[1] & S8_P1_MASK) >> S8_P1_SHIFT;
		p1[9] = (qfprom_cdata[4] & S9_P1_MASK);
		p1[10] = (qfprom_cdata[4] & S10_P1_MASK) >> S10_P1_SHIFT;

		for (i = 0; i < TSENS_1x_MAX_SENSORS; i++)
			p1[i] = (((base0) + p1[i]) << 2);
		break;
	default:
		for (i = 0; i < TSENS_1x_MAX_SENSORS; i++) {
			p1[i] = 500;
			p2[i] = 780;
		}
		break;
	}

	compute_intercept_slope(tmdev, p1, p2, mode);

	return 0;
}

static int tsens1xxx_get_temp(struct tsens_sensor *sensor, int *temp)
{
	struct tsens_device *tmdev = NULL;
@@ -486,7 +324,7 @@ static irqreturn_t tsens_irq_thread(int irq, void *data)
	sensor_status_ctrl_addr =
		TSENS_S0_UPPER_LOWER_STATUS_CTRL_ADDR(tm->tsens_tm_addr);

	for (i = 0; i < TSENS_1x_MAX_SENSORS; i++) {
	for (i = 0; i < tm->ctrl_data->num_sensors; i++) {
		bool upper_thr = false, lower_thr = false;

		if (IS_ERR(tm->sensor[i].tzd))
@@ -651,7 +489,24 @@ static const struct tsens_ops ops_tsens1xxx = {
};

const struct tsens_data data_tsens14xx = {
	.num_sensors = TSENS_NUM_SENSORS_8937,
	.ops = &ops_tsens1xxx,
	.valid_status_check = true,
	.mtc = true,
};

static const struct tsens_ops ops_tsens1xxx_405 = {
	.hw_init = tsens1xxx_hw_init,
	.get_temp = tsens1xxx_get_temp,
	.set_trips = tsens1xxx_set_trip_temp,
	.interrupts_reg = tsens1xxx_register_interrupts,
	.sensor_en = tsens1xxx_hw_sensor_en,
	.calibrate = calibrate_405,
};

const struct tsens_data data_tsens14xx_405 = {
	.num_sensors = TSENS_NUM_SENSORS_405,
	.ops = &ops_tsens1xxx_405,
	.valid_status_check = true,
	.mtc = true,
};
Loading