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

Commit 81a58950 authored by Siddartha Mohanadoss's avatar Siddartha Mohanadoss Committed by Jeevan Shriram
Browse files

thermal: qpnp-adc-tm: Support refreshed BTM driver



The BTM (Battery temperature module) peripheral driver
on the PMIC (Power management IC) supports threshold
monitoring and notifies clients when thresholds are crossed.
PMCOBALT supports refreshed BTM peripheral register interface
and the driver uses compatible property qpnp-adc-tm-hc to
distinguish using the refreshed peripheral. The external
client interface with the driver remains the same. Updates
include handling the interrupt when the thresholds are
crossed,programming the threholds and configuring
the hardware based on the refreshed design.

BTM peripheral needs the VADC_HC peripheral to compute the
gain/offset that are used to reverse compute the threhold
values to ADC code. Some of the reverse computation API's
such as calculating thermistor thresholds require the
gain and offset values before computing the ADC code to
be programmed. This requires modification to the existing
calibration API in the VADC_HC driver to calculate
the reference calibration points and store these values
for clients to use in the reverse computation

Change-Id: I989cfa4f40e7f1671f04dfa9d4c3fe2ccbbc44ab
Signed-off-by: default avatarSiddartha Mohanadoss <smohanad@codeaurora.org>
parent be6417fe
Loading
Loading
Loading
Loading
+72 −2
Original line number Diff line number Diff line
@@ -12,14 +12,41 @@ VADC_TM node

Required properties:
- compatible : should be "qcom,qpnp-adc-tm" for thermal ADC driver.
	     : should be "qcom,qpnp-adc-tm-hc" for thermal ADC driver using
	       refreshed BTM peripheral.
- reg : offset and length of the PMIC Aribter register map.
- address-cells : Must be one.
- size-cells : Must be zero.
- interrupts : The thermal ADC bank peripheral interrupts for eoc, high and low interrupts.
- interrupt-names : Should be "eoc-int-en-set", "high-thr-en-set" and "low-thr-en-set".
- interrupt-names : Should be "eoc-int-en-set", "high-thr-en-set" and "low-thr-en-set"
		    for qcom,qpnp-adc-tm type.
		  : Should be "eoc-int-en-set" for qcom,qpnp-adc-tm-hc type.
- qcom,adc-bit-resolution : Bit resolution of the ADC.
- qcom,adc-vdd-reference : Voltage reference used by the ADC.

The following properties are required in the main node for qcom,qpnp-adc-tm-hc peripheral.
- qcom,decimation : Should be present for qcom,qpnp-adc-tm-hc peripheral as its common setting
		    across all the channels. Sampling rate to use for all the channel measurements.
		    Select from the following unsigned int.
		    0 : 512
		    1 : 1K
		    2 : 2K
		    3 : 4K
- qcom,fast-avg-setup : Should be present for qcom,qpnp-adc-tm-hc peripheral as its common setting
		    across all the channels. Average number of samples to be used for measurement.
		    Fast averaging provides the option to obtain a single measurement from the ADC
		    that is an average of multiple samples. The value selected is 2^(value)
		    Select from the following unsigned int.
			0 : 1
			1 : 2
			2 : 4
			3 : 8
			4 : 16
			5 : 32
			6 : 64
			7 : 128
			8 : 256

Optional properties:
- qcom,thermal-node : If present a thermal node is created and the channel is registered as
		part of the thermal sysfs which allows clients to use the thermal framework
@@ -54,6 +81,8 @@ Required properties:
		    1 : 1K
		    2 : 2K
		    3 : 4K
		    Note: This property is not required in the channel node in qcom,qpnp-adc-tm-hc
		    peripheral.
- qcom,pre-div-channel-scaling : Pre-div used for the channel before the signal is being measured.
				 Select from the following unsigned int for the corresponding
				 numerator/denominator pre-div ratio.
@@ -114,6 +143,8 @@ Required properties:
			6 : 64
			7 : 128
			8 : 256
			Note: This property is not required in the channel node in
			qcom,qpnp-adc-tm-hc peripheral.
- qcom,btm-channel-number : Depending on the PMIC version, a max of upto 8 BTM channels.
			    The BTM channel numbers are statically allocated to the
			    corresponding channel node.
@@ -125,7 +156,7 @@ client_node {
	qcom,client-adc_tm = <&pm8941_adc_tm>;
};

Example:
Example for "qcom,qpnp-adc-tm" device:
	/* Main Node */
	qcom,vadc@3400 {
                        compatible = "qcom,qpnp-adc-tm";
@@ -169,3 +200,42 @@ Example:
				qcom,btm-channel-number = <0x78>;
			};
	};

Example for "qcom,qpnp-adc-tm-hc" device:
	/* Main Node */
	pmcobalt_adc_tm: vadc@3400 {
			compatible = "qcom,qpnp-adc-tm-hc";
			reg = <0x3400 0x100>;
			#address-cells = <1>;
			#size-cells = <0>;
			interrupts = <0x0 0x34 0x0 IRQ_TYPE_EDGE_RISING>;
			interrupt-names = "eoc-int-en-set";
			qcom,adc-bit-resolution = <15>;
			qcom,adc-vdd-reference = <1875>;
			qcom,adc_tm-vadc = <&pmcobalt_vadc>;
			qcom,decimation = <0>;
			qcom,fast-avg-setup = <0>;

			/* Channel Node to be registered as part of thermal sysfs */
                        chan@b5 {
                                label = "pa_therm1";
				reg = <0xb5>;
                                qcom,pre-div-channel-scaling = <0>;
                                qcom,calibration-type = "absolute";
                                qcom,scale-function = <2>;
                                qcom,hw-settle-time = <0>;
				qcom,btm-channel-number = <0x70>;
				qcom,thermal-node;
                        };

			/* Channel Node */
			chan@6 {
				label = "vbat_sns";
				reg = <6>;
				qcom,pre-div-channel-scaling = <1>;
				qcom,calibration-type = "absolute";
				qcom,scale-function = <3>;
				qcom,hw-settle-time = <0>;
				qcom,btm-channel-number = <0x78>;
			};
	};
+76 −18
Original line number Diff line number Diff line
@@ -1074,6 +1074,7 @@ int32_t qpnp_adc_scale_therm_pu2(struct qpnp_vadc_chip *chip,
EXPORT_SYMBOL(qpnp_adc_scale_therm_pu2);

int32_t qpnp_adc_tm_scale_voltage_therm_pu2(struct qpnp_vadc_chip *chip,
		const struct qpnp_adc_properties *adc_properties,
					uint32_t reg, int64_t *result)
{
	int64_t adc_voltage = 0;
@@ -1090,9 +1091,15 @@ int32_t qpnp_adc_tm_scale_voltage_therm_pu2(struct qpnp_vadc_chip *chip,

	do_div(adc_voltage, param1.dy);

	if (adc_properties->adc_hc)
		qpnp_adc_map_voltage_temp(adcmap_100k_104ef_104fb_1875_vref,
			ARRAY_SIZE(adcmap_100k_104ef_104fb_1875_vref),
			adc_voltage, result);
	else
		qpnp_adc_map_voltage_temp(adcmap_100k_104ef_104fb,
			ARRAY_SIZE(adcmap_100k_104ef_104fb),
			adc_voltage, result);

	if (negative_offset)
		adc_voltage = -adc_voltage;

@@ -1101,6 +1108,7 @@ int32_t qpnp_adc_tm_scale_voltage_therm_pu2(struct qpnp_vadc_chip *chip,
EXPORT_SYMBOL(qpnp_adc_tm_scale_voltage_therm_pu2);

int32_t qpnp_adc_tm_scale_therm_voltage_pu2(struct qpnp_vadc_chip *chip,
			const struct qpnp_adc_properties *adc_properties,
				struct qpnp_adc_tm_config *param)
{
	struct qpnp_vadc_linear_graph param1;
@@ -1108,11 +1116,20 @@ int32_t qpnp_adc_tm_scale_therm_voltage_pu2(struct qpnp_vadc_chip *chip,

	qpnp_get_vadc_gain_and_offset(chip, &param1, CALIB_RATIOMETRIC);

	if (adc_properties->adc_hc) {
		rc = qpnp_adc_map_temp_voltage(
			adcmap_100k_104ef_104fb_1875_vref,
			ARRAY_SIZE(adcmap_100k_104ef_104fb_1875_vref),
			param->low_thr_temp, &param->low_thr_voltage);
		if (rc)
			return rc;
	} else {
		rc = qpnp_adc_map_temp_voltage(adcmap_100k_104ef_104fb,
			ARRAY_SIZE(adcmap_100k_104ef_104fb),
			param->low_thr_temp, &param->low_thr_voltage);
		if (rc)
			return rc;
	}

	param->low_thr_voltage *= param1.dy;
	do_div(param->low_thr_voltage, param1.adc_vref);
@@ -1772,6 +1789,7 @@ int32_t qpnp_adc_get_devicetree_data(struct platform_device *pdev,
	struct qpnp_adc_properties *adc_prop;
	struct qpnp_adc_amux_properties *amux_prop;
	int count_adc_channel_list = 0, decimation, rc = 0, i = 0;
	int decimation_tm_hc = 0, fast_avg_setup_tm_hc = 0;
	bool adc_hc;

	if (!node)
@@ -1812,6 +1830,27 @@ int32_t qpnp_adc_get_devicetree_data(struct platform_device *pdev,
	adc_hc = adc_qpnp->adc_hc;
	adc_prop->adc_hc = adc_hc;

	if (of_device_is_compatible(node, "qcom,qpnp-adc-tm-hc")) {
		rc = of_property_read_u32(node, "qcom,decimation",
						&decimation_tm_hc);
		if (rc) {
			pr_err("Invalid decimation property\n");
			return -EINVAL;
		}

		rc = of_property_read_u32(node,
			"qcom,fast-avg-setup", &fast_avg_setup_tm_hc);
		if (rc) {
			pr_err("Invalid fast average setup with %d\n", rc);
			return -EINVAL;
		}

		if ((fast_avg_setup_tm_hc) > ADC_FAST_AVG_SAMPLE_16) {
			pr_err("Max average support is 2^16\n");
			return -EINVAL;
		}
	}

	for_each_child_of_node(node, child) {
		int channel_num, scaling, post_scaling, hw_settle_time;
		int fast_avg_setup, calib_type = 0, rc;
@@ -1829,12 +1868,7 @@ int32_t qpnp_adc_get_devicetree_data(struct platform_device *pdev,
			pr_err("Invalid channel num\n");
			return -EINVAL;
		}
		rc = of_property_read_u32(child, "qcom,decimation",
								&decimation);
		if (rc) {
			pr_err("Invalid channel decimation property\n");
			return -EINVAL;
		}

		if (!of_device_is_compatible(node, "qcom,qpnp-iadc")) {
			rc = of_property_read_u32(child,
				"qcom,hw-settle-time", &hw_settle_time);
@@ -1860,6 +1894,23 @@ int32_t qpnp_adc_get_devicetree_data(struct platform_device *pdev,
				pr_err("Invalid calibration type\n");
				return -EINVAL;
			}

			/*
			 * ADC_TM_HC decimation setting is common across
			 * channels.
			 */
			if (!of_device_is_compatible(node,
						"qcom,qpnp-adc-tm-hc")) {
				rc = of_property_read_u32(child,
					"qcom,decimation", &decimation);
				if (rc) {
					pr_err("Invalid decimation\n");
					return -EINVAL;
				}
			} else {
				decimation = decimation_tm_hc;
			}

			if (!strcmp(calibration_param, "absolute")) {
				if (adc_hc)
					calib_type = ADC_HC_ABS_CAL;
@@ -1884,12 +1935,19 @@ int32_t qpnp_adc_get_devicetree_data(struct platform_device *pdev,
				return -EINVAL;
			}
		}

		/* ADC_TM_HC fast avg setting is common across channels */
		if (!of_device_is_compatible(node, "qcom,qpnp-adc-tm-hc")) {
			rc = of_property_read_u32(child,
				"qcom,fast-avg-setup", &fast_avg_setup);
			if (rc) {
				pr_err("Invalid channel fast average setup\n");
				return -EINVAL;
			}
		} else {
			fast_avg_setup = fast_avg_setup_tm_hc;
		}

		/* Individual channel properties */
		adc_channel_list[i].name = (char *)channel_name;
		adc_channel_list[i].channel_num = channel_num;
+384 −300

File changed.

Preview size limit exceeded, changes collapsed.

+899 −287

File changed.

Preview size limit exceeded, changes collapsed.

+17 −3
Original line number Diff line number Diff line
/*
 * Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
 * Copyright (c) 2012-2016, 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
@@ -1062,7 +1062,7 @@ struct qpnp_vadc_chan_properties {
	enum qpnp_adc_tm_channel_select		tm_channel_select;
	enum qpnp_state_request			state_request;
	enum qpnp_adc_calib_type		calib_type;
	struct qpnp_vadc_linear_graph	adc_graph[2];
	struct qpnp_vadc_linear_graph	adc_graph[ADC_HC_CAL_SEL_NONE];
};

/**
@@ -1243,6 +1243,10 @@ struct qpnp_adc_drv {
 * @fast_avg_setup - Ability to provide single result from the ADC
 *			that is an average of multiple measurements.
 * @trigger_channel - HW trigger channel for conversion sequencer.
 * @calib_type - Used to store the calibration type for the channel
 *		 absolute/ratiometric.
 * @cal_val - Used to determine if fresh calibration value or timer
 *	      updated calibration value is to be used.
 * @chan_prop - Represent the channel properties of the ADC.
 */
struct qpnp_adc_amux_properties {
@@ -1252,6 +1256,8 @@ struct qpnp_adc_amux_properties {
	uint32_t				hw_settle_time;
	uint32_t				fast_avg_setup;
	enum qpnp_vadc_trigger			trigger_channel;
	enum qpnp_adc_calib_type		calib_type;
	enum qpnp_adc_cal_val			cal_val;
	struct qpnp_vadc_chan_properties	chan_prop[0];
};

@@ -1683,19 +1689,25 @@ int32_t qpnp_adc_qrd_skut1_btm_scaler(struct qpnp_vadc_chip *dev,
 *		and convert given temperature to voltage on supported
 *		thermistor channels using 100k pull-up.
 * @dev:	Structure device for qpnp vadc
 * @adc_prop:	adc properties of the qpnp adc such as bit resolution,
 *		reference voltage.
 * @param:	The input temperature values.
 */
int32_t qpnp_adc_tm_scale_therm_voltage_pu2(struct qpnp_vadc_chip *dev,
		const struct qpnp_adc_properties *adc_properties,
				struct qpnp_adc_tm_config *param);
/**
 * qpnp_adc_tm_scale_therm_voltage_pu2() - Performs reverse calibration
 *		and converts the given ADC code to temperature for
 *		thermistor channels using 100k pull-up.
 * @dev:	Structure device for qpnp vadc
 * @adc_prop:	adc properties of the qpnp adc such as bit resolution,
 *		reference voltage.
 * @reg:	The input ADC code.
 * @result:	The physical measurement temperature on the thermistor.
 */
int32_t qpnp_adc_tm_scale_voltage_therm_pu2(struct qpnp_vadc_chip *dev,
			const struct qpnp_adc_properties *adc_prop,
				uint32_t reg, int64_t *result);
/**
 * qpnp_adc_usb_scaler() - Performs reverse calibration on the low/high
@@ -2017,10 +2029,12 @@ static inline int32_t qpnp_adc_scale_millidegc_pmic_voltage_thr(
{ return -ENXIO; }
static inline int32_t qpnp_adc_tm_scale_therm_voltage_pu2(
				struct qpnp_vadc_chip *dev,
			const struct qpnp_adc_properties *adc_properties,
				struct qpnp_adc_tm_config *param)
{ return -ENXIO; }
static inline int32_t qpnp_adc_tm_scale_voltage_therm_pu2(
				struct qpnp_vadc_chip *dev,
			const struct qpnp_adc_properties *adc_prop,
			uint32_t reg, int64_t *result)
{ return -ENXIO; }
static inline int32_t qpnp_adc_smb_btm_rscaler(struct qpnp_vadc_chip *dev,