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

Commit ae731133 authored by Siddartha Mohanadoss's avatar Siddartha Mohanadoss
Browse files

hwmon: qpnp-adc: Add reverse scaling API



Add separate VADC reverse scaling function to consider
the channel properties that include the pre-div scaling
for the reverse calibration on VADC channels to support
recurring channel measurement mode.

Change-Id: Ifd863c3c3fd0c3c7f93b80fac8cf186f10c69e38
Signed-off-by: default avatarSiddartha Mohanadoss <smohanad@codeaurora.org>
parent 1c267e4a
Loading
Loading
Loading
Loading
+50 −0
Original line number Diff line number Diff line
@@ -1216,6 +1216,56 @@ int32_t qpnp_adc_absolute_rthr(struct qpnp_vadc_chip *chip,
}
EXPORT_SYMBOL(qpnp_adc_absolute_rthr);

int32_t qpnp_vadc_absolute_rthr(struct qpnp_vadc_chip *chip,
		const struct qpnp_vadc_chan_properties *chan_prop,
		struct qpnp_adc_tm_btm_param *param,
		uint32_t *low_threshold, uint32_t *high_threshold)
{
	struct qpnp_vadc_linear_graph vbatt_param;
	int rc = 0, sign = 0;
	int64_t low_thr = 0, high_thr = 0;

	if (!chan_prop || !chan_prop->offset_gain_numerator ||
		!chan_prop->offset_gain_denominator)
		return -EINVAL;

	rc = qpnp_get_vadc_gain_and_offset(chip, &vbatt_param, CALIB_ABSOLUTE);
	if (rc < 0)
		return rc;

	low_thr = (((param->low_thr)/chan_prop->offset_gain_denominator
					- QPNP_ADC_625_UV) * vbatt_param.dy);
	if (low_thr < 0) {
		sign = 1;
		low_thr = -low_thr;
	}
	low_thr = low_thr * chan_prop->offset_gain_numerator;
	do_div(low_thr, QPNP_ADC_625_UV);
	if (sign)
		low_thr = -low_thr;
	*low_threshold = low_thr + vbatt_param.adc_gnd;

	sign = 0;
	high_thr = (((param->high_thr)/chan_prop->offset_gain_denominator
					- QPNP_ADC_625_UV) * vbatt_param.dy);
	if (high_thr < 0) {
		sign = 1;
		high_thr = -high_thr;
	}
	high_thr = high_thr * chan_prop->offset_gain_numerator;
	do_div(high_thr, QPNP_ADC_625_UV);
	if (sign)
		high_thr = -high_thr;
	*high_threshold = high_thr + vbatt_param.adc_gnd;

	pr_debug("high_volt:%d, low_volt:%d\n", param->high_thr,
				param->low_thr);
	pr_debug("adc_code_high:%x, adc_code_low:%x\n", *high_threshold,
				*low_threshold);
	return 0;
}
EXPORT_SYMBOL(qpnp_vadc_absolute_rthr);

int32_t qpnp_adc_btm_scaler(struct qpnp_vadc_chip *chip,
		struct qpnp_adc_tm_btm_param *param,
		uint32_t *low_threshold, uint32_t *high_threshold)
+21 −8
Original line number Diff line number Diff line
@@ -159,9 +159,8 @@ static struct qpnp_vadc_scale_fn vadc_scale_fn[] = {
	[SCALE_NCP_03WF683_THERM] = {qpnp_adc_scale_therm_ncp03},
};

static struct qpnp_adc_tm_reverse_scale_fn adc_vadc_rscale_fn[] = {
	[SCALE_RVADC_ABSOLUTE] = {qpnp_adc_absolute_rthr},
	[SCALE_RVADC_PMIC_THERM] = {qpnp_adc_scale_millidegc_pmic_voltage_thr},
static struct qpnp_vadc_rscale_fn adc_vadc_rscale_fn[] = {
	[SCALE_RVADC_ABSOLUTE] = {qpnp_vadc_absolute_rthr},
};

static int32_t qpnp_vadc_read_reg(struct qpnp_vadc_chip *vadc, int16_t reg,
@@ -1843,7 +1842,7 @@ int32_t qpnp_vadc_channel_monitor(struct qpnp_vadc_chip *chip,
{
	uint32_t channel, scale_type = 0;
	uint32_t low_thr = 0, high_thr = 0;
	int rc = 0, idx = 0;
	int rc = 0, idx = 0, amux_prescaling = 0;
	struct qpnp_vadc_chip *vadc = dev_get_drvdata(chip->dev);

	if (qpnp_vadc_is_valid(vadc))
@@ -1876,13 +1875,26 @@ int32_t qpnp_vadc_channel_monitor(struct qpnp_vadc_chip *chip,
	}

	scale_type = vadc->adc->adc_channels[idx].adc_scale_fn;
	if ((scale_type >= SCALE_RVADC_SCALE_NONE) ||
		((scale_type != SCALE_RVADC_ABSOLUTE) &&
		(scale_type != SCALE_RVADC_PMIC_THERM))) {
	if (scale_type >= SCALE_RVADC_SCALE_NONE) {
		rc = -EBADF;
		goto fail_unlock;
	}

	amux_prescaling =
		vadc->adc->adc_channels[idx].chan_path_prescaling;

	if (amux_prescaling >= PATH_SCALING_NONE) {
		rc = -EINVAL;
		goto fail_unlock;
	}

	vadc->adc->amux_prop->chan_prop->offset_gain_numerator =
		qpnp_vadc_amux_scaling_ratio[amux_prescaling].num;
	vadc->adc->amux_prop->chan_prop->offset_gain_denominator =
		 qpnp_vadc_amux_scaling_ratio[amux_prescaling].den;
	vadc->adc->amux_prop->chan_prop->calib_type =
		vadc->adc->adc_channels[idx].calib_type;

	pr_debug("channel:%d, scale_type:%d, dt_idx:%d",
					channel, scale_type, idx);
	vadc->adc->amux_prop->amux_channel = channel;
@@ -1893,7 +1905,8 @@ int32_t qpnp_vadc_channel_monitor(struct qpnp_vadc_chip *chip,
	vadc->adc->amux_prop->fast_avg_setup =
			vadc->adc->adc_channels[idx].fast_avg_setup;
	vadc->adc->amux_prop->mode_sel = ADC_OP_MEASUREMENT_INTERVAL;
	adc_vadc_rscale_fn[scale_type].chan(vadc, param,
	adc_vadc_rscale_fn[scale_type].chan(vadc,
			vadc->adc->amux_prop->chan_prop, param,
			&low_thr, &high_thr);

	if (param->timer_interval >= ADC_MEAS1_INTERVAL_NONE) {
+37 −1
Original line number Diff line number Diff line
@@ -301,7 +301,6 @@ enum qpnp_adc_tm_rscale_fn_type {
 */
enum qpnp_vadc_rscale_fn_type {
	SCALE_RVADC_ABSOLUTE = 0,
	SCALE_RVADC_PMIC_THERM = 3,
	SCALE_RVADC_SCALE_NONE,
};

@@ -974,6 +973,19 @@ struct qpnp_adc_tm_reverse_scale_fn {
		uint32_t *, uint32_t *);
};

/**
 * struct qpnp_vadc_rscale_fn - Scaling function prototype
 * @chan: Function pointer to one of the scaling functions
 *	which takes the adc properties, channel properties,
 *	and returns the physical result
 */
struct qpnp_vadc_rscale_fn {
	int32_t (*chan) (struct qpnp_vadc_chip *,
		const struct qpnp_vadc_chan_properties *,
		struct qpnp_adc_tm_btm_param *,
		uint32_t *, uint32_t *);
};

/**
 * struct qpnp_iadc_calib - IADC channel calibration structure.
 * @channel - Channel for which the historical offset and gain is
@@ -1476,6 +1488,25 @@ int32_t qpnp_adc_usb_scaler(struct qpnp_vadc_chip *dev,
int32_t qpnp_adc_vbatt_rscaler(struct qpnp_vadc_chip *dev,
		struct qpnp_adc_tm_btm_param *param,
		uint32_t *low_threshold, uint32_t *high_threshold);
/**
 * qpnp_vadc_absolute_rthr() - Performs reverse calibration on the low/high
 *		voltage threshold values passed by the client.
 *		The function applies absolute calibration on the
 *		voltage values.
 * @dev:	Structure device for qpnp vadc
 * @chan_prop:	Individual channel properties to compensate the i/p scaling,
 *		slope and offset.
 * @param:	The input parameters that contain the low/high voltage
 *		threshold values.
 * @low_threshold: The low threshold value that needs to be updated with
 *		the above calibrated voltage value.
 * @high_threshold: The low threshold value that needs to be updated with
 *		the above calibrated voltage value.
 */
int32_t qpnp_vadc_absolute_rthr(struct qpnp_vadc_chip *dev,
		const struct qpnp_vadc_chan_properties *chan_prop,
		struct qpnp_adc_tm_btm_param *param,
		uint32_t *low_threshold, uint32_t *high_threshold);
/**
 * qpnp_adc_absolute_rthr() - Performs reverse calibration on the low/high
 *		voltage threshold values passed by the client.
@@ -1682,6 +1713,11 @@ static inline int32_t qpnp_adc_vbatt_rscaler(struct qpnp_vadc_chip *dev,
		struct qpnp_adc_tm_btm_param *param,
		uint32_t *low_threshold, uint32_t *high_threshold)
{ return -ENXIO; }
static inline int32_t qpnp_vadc_absolute_rthr(struct qpnp_vadc_chip *dev,
		const struct qpnp_vadc_chan_properties *chan_prop,
		struct qpnp_adc_tm_btm_param *param,
		uint32_t *low_threshold, uint32_t *high_threshold)
{ return -ENXIO; }
static inline int32_t qpnp_adc_absolute_rthr(struct qpnp_vadc_chip *dev,
		struct qpnp_adc_tm_btm_param *param,
		uint32_t *low_threshold, uint32_t *high_threshold)