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

Commit bd4a40b5 authored by Karl Komierowski's avatar Karl Komierowski Committed by Samuel Ortiz
Browse files

mfd: Refactor ab8500 GPADC API, add raw access



Refactor the GPADC interface to avoid bugs in calling code:

- ab8500_gpadc_[convert|read_raw|ad_to_voltage] clarifies
  each functions use case, *convert wraps *read_raw, and we
  can access raw ADC values properly.
- Renamed gpadc function arguments from "input" to "channel" to
  clarify use, so we don't get confused again.

Signed-off-by: default avatarKalle Komierowski <kalle.komierowski@stericsson.com>
Reviewed-by: default avatarMattias Wallin <mattias.wallin@stericsson.com>
Reviewed-by: default avatarJohn Beckett <john.beckett@stericsson.com>
Signed-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
Signed-off-by: default avatarSamuel Ortiz <sameo@linux.intel.com>
parent 981c65a9
Loading
Loading
Loading
Loading
+43 −13
Original line number Diff line number Diff line
@@ -143,12 +143,15 @@ struct ab8500_gpadc *ab8500_gpadc_get(char *name)
}
EXPORT_SYMBOL(ab8500_gpadc_get);

static int ab8500_gpadc_ad_to_voltage(struct ab8500_gpadc *gpadc, u8 input,
/**
 * ab8500_gpadc_ad_to_voltage() - Convert a raw ADC value to a voltage
 */
int ab8500_gpadc_ad_to_voltage(struct ab8500_gpadc *gpadc, u8 channel,
	int ad_value)
{
	int res;

	switch (input) {
	switch (channel) {
	case MAIN_CHARGER_V:
		/* For some reason we don't have calibrated data */
		if (!gpadc->cal_data[ADC_INPUT_VMAIN].gain) {
@@ -232,18 +235,46 @@ static int ab8500_gpadc_ad_to_voltage(struct ab8500_gpadc *gpadc, u8 input,
	}
	return res;
}
EXPORT_SYMBOL(ab8500_gpadc_ad_to_voltage);

/**
 * ab8500_gpadc_convert() - gpadc conversion
 * @input:	analog input to be converted to digital data
 * @channel:	analog channel to be converted to digital data
 *
 * This function converts the selected analog i/p to digital
 * data.
 */
int ab8500_gpadc_convert(struct ab8500_gpadc *gpadc, u8 input)
int ab8500_gpadc_convert(struct ab8500_gpadc *gpadc, u8 channel)
{
	int ad_value;
	int voltage;

	ad_value = ab8500_gpadc_read_raw(gpadc, channel);
	if (ad_value < 0) {
		dev_err(gpadc->dev, "GPADC raw value failed ch: %d\n", channel);
		return ad_value;
	}

	voltage = ab8500_gpadc_ad_to_voltage(gpadc, channel, ad_value);

	if (voltage < 0)
		dev_err(gpadc->dev, "GPADC to voltage conversion failed ch:"
			" %d AD: 0x%x\n", channel, ad_value);

	return voltage;
}
EXPORT_SYMBOL(ab8500_gpadc_convert);

/**
 * ab8500_gpadc_read_raw() - gpadc read
 * @channel:	analog channel to be read
 *
 * This function obtains the raw ADC value, this then needs
 * to be converted by calling ab8500_gpadc_ad_to_voltage()
 */
int ab8500_gpadc_read_raw(struct ab8500_gpadc *gpadc, u8 channel)
{
	int ret;
	u16 data = 0;
	int looplimit = 0;
	u8 val, low_data, high_data;

@@ -278,9 +309,9 @@ int ab8500_gpadc_convert(struct ab8500_gpadc *gpadc, u8 input)
		goto out;
	}

	/* Select the input source and set average samples to 16 */
	/* Select the channel source and set average samples to 16 */
	ret = abx500_set_register_interruptible(gpadc->dev, AB8500_GPADC,
		AB8500_GPADC_CTRL2_REG, (input | SW_AVG_16));
		AB8500_GPADC_CTRL2_REG, (channel | SW_AVG_16));
	if (ret < 0) {
		dev_err(gpadc->dev,
			"gpadc_conversion: set avg samples failed\n");
@@ -292,7 +323,7 @@ int ab8500_gpadc_convert(struct ab8500_gpadc *gpadc, u8 input)
	 * charging current sense if it needed, ABB 3.0 needs some special
	 * treatment too.
	 */
	switch (input) {
	switch (channel) {
	case MAIN_CHARGER_C:
	case USB_CHARGER_C:
		ret = abx500_mask_and_set_register_interruptible(gpadc->dev,
@@ -359,7 +390,6 @@ int ab8500_gpadc_convert(struct ab8500_gpadc *gpadc, u8 input)
		goto out;
	}

	data = (high_data << 8) | low_data;
	/* Disable GPADC */
	ret = abx500_set_register_interruptible(gpadc->dev, AB8500_GPADC,
		AB8500_GPADC_CTRL1_REG, DIS_GPADC);
@@ -370,8 +400,8 @@ int ab8500_gpadc_convert(struct ab8500_gpadc *gpadc, u8 input)
	/* Disable VTVout LDO this is required for GPADC */
	regulator_disable(gpadc->regu);
	mutex_unlock(&gpadc->ab8500_gpadc_lock);
	ret = ab8500_gpadc_ad_to_voltage(gpadc, input, data);
	return ret;

	return (high_data << 8) | low_data;

out:
	/*
@@ -385,10 +415,10 @@ out:
	regulator_disable(gpadc->regu);
	mutex_unlock(&gpadc->ab8500_gpadc_lock);
	dev_err(gpadc->dev,
		"gpadc_conversion: Failed to AD convert channel %d\n", input);
		"gpadc_conversion: Failed to AD convert channel %d\n", channel);
	return ret;
}
EXPORT_SYMBOL(ab8500_gpadc_convert);
EXPORT_SYMBOL(ab8500_gpadc_read_raw);

/**
 * ab8500_bm_gpswadcconvend_handler() - isr for s/w gpadc conversion completion
+4 −1
Original line number Diff line number Diff line
@@ -27,6 +27,9 @@
struct ab8500_gpadc;

struct ab8500_gpadc *ab8500_gpadc_get(char *name);
int ab8500_gpadc_convert(struct ab8500_gpadc *gpadc, u8 input);
int ab8500_gpadc_convert(struct ab8500_gpadc *gpadc, u8 channel);
int ab8500_gpadc_read_raw(struct ab8500_gpadc *gpadc, u8 channel);
int ab8500_gpadc_ad_to_voltage(struct ab8500_gpadc *gpadc,
    u8 channel, int ad_value);

#endif /* _AB8500_GPADC_H */