iio: spmi-adc5: Add option to specify scale-fun-type in devicetree

There are chances that some signals would share the same ADC channel
but have different scale functions, such as SMB1398 TEMP signal would
use the same ADC channel that SMB1390 TEMP signal is using but it has
different voltage to temperature calcuation. Add an option to specify
scale-fun-type in devicetree to handle such kind of requirement.

Change-Id: I3cbf042e13a7c1b6473911154282d455231ea608
Signed-off-by: Fenglin Wu <fenglinw@codeaurora.org>
tirimbino
Fenglin Wu 6 years ago committed by Ashish Chavan
parent 77a389280c
commit a6007bd4a5
  1. 11
      drivers/iio/adc/qcom-spmi-adc5.c
  2. 32
      drivers/iio/adc/qcom-vadc-common.c
  3. 4
      drivers/iio/adc/qcom-vadc-common.h
  4. 18
      include/dt-bindings/iio/qcom,spmi-vadc.h

@ -852,6 +852,11 @@ static int adc_get_dt_channel_data(struct device *dev,
prop->avg_samples = VADC_DEF_AVG_SAMPLES;
}
prop->scale_fn_type = -EINVAL;
ret = of_property_read_u32(node, "qcom,scale-fn-type", &value);
if (!ret && value < SCALE_HW_CALIB_MAX)
prop->scale_fn_type = value;
prop->lut_index = VADC_DEF_LUT_INDEX;
ret = of_property_read_u32(node, "qcom,lut-index", &value);
@ -945,8 +950,10 @@ static int adc_get_dt_data(struct adc_chip *adc, struct device_node *node)
return ret;
}
prop.scale_fn_type =
data->adc_chans[prop.channel].scale_fn_type;
if (prop.scale_fn_type == -EINVAL)
prop.scale_fn_type =
data->adc_chans[prop.channel].scale_fn_type;
adc->chan_props[index] = prop;
adc_chan = &data->adc_chans[prop.channel];

@ -925,6 +925,35 @@ static int qcom_vadc_scale_hw_smb_temp(
return 0;
}
static int qcom_vadc_scale_hw_smb1398_temp(
const struct vadc_prescale_ratio *prescale,
const struct adc_data *data,
u16 adc_code, int *result_mdec)
{
s64 voltage = 0, adc_vdd_ref_mv = 1875;
u64 temp;
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 = div64_s64(voltage, data->full_scale_code_volt);
if (voltage > 0) {
temp = voltage * prescale->den;
temp *= 100;
do_div(temp, prescale->num * PMIC5_SMB1398_TEMP_SCALE_FACTOR);
voltage = temp;
} else {
voltage = 0;
}
voltage = voltage - PMIC5_SMB1398_TEMP_CONSTANT;
*result_mdec = voltage;
return 0;
}
static int qcom_vadc_scale_hw_chg5_temp(
const struct vadc_prescale_ratio *prescale,
const struct adc_data *data,
@ -1043,6 +1072,9 @@ int qcom_vadc_hw_scale(enum vadc_scale_fn_type scaletype,
case SCALE_HW_CALIB_PM5_SMB_TEMP:
return qcom_vadc_scale_hw_smb_temp(prescale, data,
adc_code, result);
case SCALE_HW_CALIB_PM5_SMB1398_TEMP:
return qcom_vadc_scale_hw_smb1398_temp(prescale, data,
adc_code, result);
default:
return -EINVAL;
}

@ -44,6 +44,8 @@
#define PMIC5_CHG_TEMP_SCALE_FACTOR 377500
#define PMIC5_SMB_TEMP_CONSTANT 419400
#define PMIC5_SMB_TEMP_SCALE_FACTOR 356
#define PMIC5_SMB1398_TEMP_SCALE_FACTOR 340
#define PMIC5_SMB1398_TEMP_CONSTANT 268235
#define PMI_CHG_SCALE_1 -138890
#define PMI_CHG_SCALE_2 391750000000LL
@ -147,6 +149,8 @@ enum vadc_scale_fn_type {
SCALE_HW_CALIB_BATT_THERM_100K,
SCALE_HW_CALIB_BATT_THERM_30K,
SCALE_HW_CALIB_BATT_THERM_400K,
SCALE_HW_CALIB_PM5_SMB1398_TEMP,
SCALE_HW_CALIB_MAX,
};
struct adc_data {

@ -229,4 +229,22 @@
#define ADC_MAX_CHANNEL 0xc0
/* VADC scale function index */
#define ADC_SCALE_DEFAULT 0x0
#define ADC_SCALE_THERM_100K_PULLUP 0x1
#define ADC_SCALE_PMIC_THERM 0x2
#define ADC_SCALE_XOTHERM 0x3
#define ADC_SCALE_PMI_CHG_TEMP 0x4
#define ADC_SCALE_HW_CALIB_DEFAULT 0x5
#define ADC_SCALE_HW_CALIB_THERM_100K_PULLUP 0x6
#define ADC_SCALE_HW_CALIB_XOTHERM 0x7
#define ADC_SCALE_HW_CALIB_PMIC_THERM 0x8
#define ADC_SCALE_HW_CALIB_CUR 0x9
#define ADC_SCALE_HW_CALIB_PM5_CHG_TEMP 0xA
#define ADC_SCALE_HW_CALIB_PM5_SMB_TEMP 0xB
#define ADC_SCALE_HW_CALIB_BATT_THERM_100K 0xC
#define ADC_SCALE_HW_CALIB_BATT_THERM_30K 0xD
#define ADC_SCALE_HW_CALIB_BATT_THERM_400K 0xE
#define ADC_SCALE_HW_CALIB_PM5_SMB1398_TEMP 0xF
#endif /* _DT_BINDINGS_QCOM_SPMI_VADC_H */

Loading…
Cancel
Save