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

Commit 44dc73c3 authored by Jishnu Prakash's avatar Jishnu Prakash
Browse files

thermal: adc_tm: Update threshold cross notification to thermal client



Increased resolution of mapping between raw adc code and temperature
for thermistors. Adjust thresholds written to ensure interrupts get
triggered correctly for temperatures read.
In addition, measure temperature causing threshold violation and
provide it directly to thermal framework instead of waiting for thermal
framework to read it.

Change-Id: I4330c659a91021ef44fa17c9c79e379105aa8fc3
Signed-off-by: default avatarJishnu Prakash <jprakash@codeaurora.org>
parent 71ba584c
Loading
Loading
Loading
Loading
+36 −36
Original line number Diff line number Diff line
@@ -52,40 +52,40 @@ static const struct vadc_map_pt adcmap_100k_104ef_104fb[] = {
 * 1.875V reference.
 */
static const struct vadc_map_pt adcmap_100k_104ef_104fb_1875_vref[] = {
	{ 1831,	-40000 },
	{ 1814,	-35000 },
	{ 1791,	-30000 },
	{ 1761,	-25000 },
	{ 1723,	-20000 },
	{ 1675,	-15000 },
	{ 1616,	-10000 },
	{ 1545,	-5000 },
	{ 1463,	0 },
	{ 1370,	5000 },
	{ 1268,	10000 },
	{ 1160,	15000 },
	{ 1049,	20000 },
	{ 937,	25000 },
	{ 828,	30000 },
	{ 726,	35000 },
	{ 630,	40000 },
	{ 544,	45000 },
	{ 467,	50000 },
	{ 399,	55000 },
	{ 340,	60000 },
	{ 290,	65000 },
	{ 247,	70000 },
	{ 209,	75000 },
	{ 179,	80000 },
	{ 153,	85000 },
	{ 130,	90000 },
	{ 112,	95000 },
	{ 96,	100000 },
	{ 82,	105000 },
	{ 71,	110000 },
	{ 62,	115000 },
	{ 53,	120000 },
	{ 46,	125000 },
	{ 1831000,	-40000 },
	{ 1814000,	-35000 },
	{ 1791000,	-30000 },
	{ 1761000,	-25000 },
	{ 1723000,	-20000 },
	{ 1675000,	-15000 },
	{ 1616000,	-10000 },
	{ 1545000,	-5000 },
	{ 1463000,	0 },
	{ 1370000,	5000 },
	{ 1268000,	10000 },
	{ 1160000,	15000 },
	{ 1049000,	20000 },
	{ 937000,	25000 },
	{ 828000,	30000 },
	{ 726000,	35000 },
	{ 630000,	40000 },
	{ 544000,	45000 },
	{ 467000,	50000 },
	{ 399000,	55000 },
	{ 340000,	60000 },
	{ 290000,	65000 },
	{ 247000,	70000 },
	{ 209000,	75000 },
	{ 179000,	80000 },
	{ 153000,	85000 },
	{ 130000,	90000 },
	{ 112000,	95000 },
	{ 96000,	100000 },
	{ 82000,	105000 },
	{ 71000,	110000 },
	{ 62000,	115000 },
	{ 53000,	120000 },
	{ 46000,	125000 },
};

/*
@@ -739,14 +739,14 @@ static int qcom_vadc_scale_hw_calib_therm(
				const struct adc_data *data,
				u16 adc_code, int *result_mdec)
{
	s64 voltage = 0, result = 0, adc_vdd_ref_mv = 1875;
	s64 voltage = 0, result = 0;
	int ret;

	if (adc_code > VADC5_MAX_CODE)
		adc_code = 0;

	/* (ADC code * vref_vadc (1.875V)) / full_scale_code */
	voltage = (s64) adc_code * adc_vdd_ref_mv * 1000;
	voltage = (s64) adc_code * ADC_HC_VDD_REF * 1000;
	voltage = div64_s64(voltage, (data->full_scale_code_volt
								* 1000));
	ret = qcom_vadc_map_voltage_temp(adcmap_100k_104ef_104fb_1875_vref,
+1 −0
Original line number Diff line number Diff line
@@ -51,6 +51,7 @@
#define VADC5_MAX_CODE				0x7fff
#define VADC5_FULL_SCALE_CODE			0x70e4
#define ADC_USR_DATA_CHECK			0x8000
#define ADC_HC_VDD_REF			1875000

/**
 * struct vadc_map_pt - Map the graph representation for ADC channel
+106 −37
Original line number Diff line number Diff line
@@ -11,42 +11,82 @@
 * 1.875V reference and 100k pull-up.
 */
static const struct adc_tm_map_pt adcmap_100k_104ef_104fb_1875_vref[] = {
	{ 1831,	-40000 },
	{ 1814,	-35000 },
	{ 1791,	-30000 },
	{ 1761,	-25000 },
	{ 1723,	-20000 },
	{ 1675,	-15000 },
	{ 1616,	-10000 },
	{ 1545,	-5000 },
	{ 1463,	0 },
	{ 1370,	5000 },
	{ 1268,	10000 },
	{ 1160,	15000 },
	{ 1049,	20000 },
	{ 937,	25000 },
	{ 828,	30000 },
	{ 726,	35000 },
	{ 630,	40000 },
	{ 544,	45000 },
	{ 467,	50000 },
	{ 399,	55000 },
	{ 340,	60000 },
	{ 290,	65000 },
	{ 247,	70000 },
	{ 209,	75000 },
	{ 179,	80000 },
	{ 153,	85000 },
	{ 130,	90000 },
	{ 112,	95000 },
	{ 96,	100000 },
	{ 82,	105000 },
	{ 71,	110000 },
	{ 62,	115000 },
	{ 53,	120000 },
	{ 46,	125000 },
	{ 1831000,	-40000 },
	{ 1814000,	-35000 },
	{ 1791000,	-30000 },
	{ 1761000,	-25000 },
	{ 1723000,	-20000 },
	{ 1675000,	-15000 },
	{ 1616000,	-10000 },
	{ 1545000,	-5000 },
	{ 1463000,	0 },
	{ 1370000,	5000 },
	{ 1268000,	10000 },
	{ 1160000,	15000 },
	{ 1049000,	20000 },
	{ 937000,	25000 },
	{ 828000,	30000 },
	{ 726000,	35000 },
	{ 630000,	40000 },
	{ 544000,	45000 },
	{ 467000,	50000 },
	{ 399000,	55000 },
	{ 340000,	60000 },
	{ 290000,	65000 },
	{ 247000,	70000 },
	{ 209000,	75000 },
	{ 179000,	80000 },
	{ 153000,	85000 },
	{ 130000,	90000 },
	{ 112000,	95000 },
	{ 96000,	100000 },
	{ 82000,	105000 },
	{ 71000,	110000 },
	{ 62000,	115000 },
	{ 53000,	120000 },
	{ 46000,	125000 },
};

static void adc_tm_map_voltage_temp(const struct adc_tm_map_pt *pts,
				      size_t tablesize, int input, int *output)
{
	unsigned int descending = 1;
	u32 i = 0;

	/* Check if table is descending or ascending */
	if (tablesize > 1) {
		if (pts[0].x < pts[1].x)
			descending = 0;
	}

	while (i < tablesize) {
		if ((descending) && (pts[i].x < input)) {
			/* table entry is less than measured*/
			 /* value and table is descending, stop */
			break;
		} else if ((!descending) &&
				(pts[i].x > input)) {
			/* table entry is greater than measured*/
			/*value and table is ascending, stop */
			break;
		}
		i++;
	}

	if (i == 0) {
		*output = pts[0].y;
	} else if (i == tablesize) {
		*output = pts[tablesize - 1].y;
	} else {
		/* result is between search_index and search_index-1 */
		/* interpolate linearly */
		*output = (((int32_t)((pts[i].y - pts[i - 1].y) *
			(input - pts[i - 1].x)) /
			(pts[i].x - pts[i - 1].x)) +
			pts[i - 1].y);
	}
}

static void adc_tm_map_temp_voltage(const struct adc_tm_map_pt *pts,
		size_t tablesize, int input, int64_t *output)
{
@@ -91,10 +131,27 @@ static void adc_tm_map_temp_voltage(const struct adc_tm_map_pt *pts,
	}
}

int therm_fwd_scale(int64_t code, uint32_t adc_hc_vdd_ref_mv,
			const struct adc_tm_data *data)
{
	int64_t volt = 0;
	int result = 0;

	volt = (s64) code * adc_hc_vdd_ref_mv;
	volt = div64_s64(volt, (data->full_scale_code_volt));

	adc_tm_map_voltage_temp(adcmap_100k_104ef_104fb_1875_vref,
				 ARRAY_SIZE(adcmap_100k_104ef_104fb_1875_vref),
				 (int) volt, &result);

	return result;
}
EXPORT_SYMBOL(therm_fwd_scale);

void adc_tm_scale_therm_voltage_100k(struct adc_tm_config *param,
				const struct adc_tm_data *data)
{
	uint32_t adc_hc_vdd_ref_mv = 1875;
	int temp;

	/* High temperature maps to lower threshold voltage */
	adc_tm_map_temp_voltage(
@@ -104,7 +161,13 @@ void adc_tm_scale_therm_voltage_100k(struct adc_tm_config *param,

	param->low_thr_voltage *= data->full_scale_code_volt;
	param->low_thr_voltage = div64_s64(param->low_thr_voltage,
						adc_hc_vdd_ref_mv);
						ADC_HC_VDD_REF);

	temp = therm_fwd_scale(param->low_thr_voltage,
				ADC_HC_VDD_REF, data);

	if (temp < param->high_thr_temp)
		param->low_thr_voltage--;

	/* Low temperature maps to higher threshold voltage */
	adc_tm_map_temp_voltage(
@@ -114,7 +177,13 @@ void adc_tm_scale_therm_voltage_100k(struct adc_tm_config *param,

	param->high_thr_voltage *= data->full_scale_code_volt;
	param->high_thr_voltage = div64_s64(param->high_thr_voltage,
						adc_hc_vdd_ref_mv);
						ADC_HC_VDD_REF);

	temp = therm_fwd_scale(param->high_thr_voltage,
				ADC_HC_VDD_REF, data);

	if (temp > param->low_thr_temp)
		param->high_thr_voltage++;

}
EXPORT_SYMBOL(adc_tm_scale_therm_voltage_100k);
+3 −0
Original line number Diff line number Diff line
@@ -256,6 +256,9 @@ struct adc_tm_linear_graph {
	s32 gnd;
};

int therm_fwd_scale(int64_t code, uint32_t adc_hc_vdd_ref_mv,
				const struct adc_tm_data *data);

void adc_tm_scale_therm_voltage_100k(struct adc_tm_config *param,
				const struct adc_tm_data *data);

+21 −1
Original line number Diff line number Diff line
@@ -56,6 +56,10 @@
#define ADC_TM_LOWER_MASK(n)			((n) & 0x000000ff)
#define ADC_TM_UPPER_MASK(n)			(((n) & 0xffffff00) >> 8)

#define ADC_TM_Mn_DATA0(n)			((n * 2) + 0xa0)
#define ADC_TM_Mn_DATA1(n)			((n * 2) + 0xa1)
#define ADC_TM_DATA_SHIFT			8

static struct adc_tm_trip_reg_type adc_tm_ch_data[] = {
	[ADC_TM_CHAN0] = {ADC_TM_M0_ADC_CH_SEL_CTL},
	[ADC_TM_CHAN1] = {ADC_TM_M1_ADC_CH_SEL_CTL},
@@ -871,6 +875,8 @@ static irqreturn_t adc_tm5_handler(int irq, void *data)

	while (i < chip->dt_channels) {
		bool upper_set = false, lower_set = false;
		u8 data_low = 0, data_high = 0;
		u16 code = 0;
		int temp;

		if (!chip->sensor[i].non_thermal &&
@@ -886,6 +892,17 @@ static irqreturn_t adc_tm5_handler(int irq, void *data)
				i++;
				continue;
			}
			ret = adc_tm5_read_reg(chip, ADC_TM_Mn_DATA0(i),
						&data_low, 1);
			if (ret)
				pr_err("adc_tm data_low read failed with %d\n",
							ret);
			ret = adc_tm5_read_reg(chip, ADC_TM_Mn_DATA1(i),
						&data_high, 1);
			if (ret)
				pr_err("adc_tm data_high read failed with %d\n",
							ret);
			code = ((data_high << ADC_TM_DATA_SHIFT) | data_low);
		}

		spin_lock_irqsave(&chip->adc_tm_lock, flags);
@@ -920,7 +937,10 @@ static irqreturn_t adc_tm5_handler(int irq, void *data)
			 * the appropriate trips.
			 */
			pr_debug("notifying of_thermal\n");
			of_thermal_handle_trip(chip->sensor[i].tzd);
			temp = therm_fwd_scale((int64_t)code,
						ADC_HC_VDD_REF, chip->data);
			of_thermal_handle_trip_temp(chip->sensor[i].tzd,
						temp);
		} else {
			if (lower_set) {
				ret = adc_tm5_reg_update(chip,