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

Commit 3a94c5d2 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "thermal: adc_tm: Update threshold cross notification to thermal client"

parents 24eda1e6 869d0b0c
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
+107 −38
Original line number Diff line number Diff line
/*
 * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
 * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -20,42 +20,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)
{
	bool descending = true;
	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)
{
@@ -101,10 +141,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(
@@ -114,7 +171,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(
@@ -124,7 +187,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
@@ -262,6 +262,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);

+22 −2
Original line number Diff line number Diff line
/*
 * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
 * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -65,6 +65,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},
@@ -880,6 +884,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 &&
@@ -895,6 +901,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);
@@ -929,7 +946,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,