diff --git a/drivers/iio/adc/qcom-spmi-adc5.c b/drivers/iio/adc/qcom-spmi-adc5.c index c94a56057f0f..7941d6804b7f 100644 --- a/drivers/iio/adc/qcom-spmi-adc5.c +++ b/drivers/iio/adc/qcom-spmi-adc5.c @@ -602,8 +602,8 @@ static const struct adc5_channels adc5_chans_pmic[ADC5_MAX_CHANNEL] = { SCALE_HW_CALIB_THERM_100K_PULLUP) [ADC5_AMUX_THM2] = ADC5_CHAN_TEMP("amux_thm2", 0, SCALE_HW_CALIB_PM5_SMB_TEMP) - [ADC5_PARALLEL_ISENSE] = ADC5_CHAN_VOLT("parallel_isense", 1, - SCALE_HW_CALIB_CUR) + [ADC5_PARALLEL_ISENSE] = ADC5_CHAN_VOLT("parallel_isense", 0, + SCALE_HW_CALIB_PM5_CUR) [ADC5_GPIO1_100K_PU] = ADC5_CHAN_TEMP("gpio1_100k_pu", 0, SCALE_HW_CALIB_THERM_100K_PULLUP) [ADC5_GPIO2_100K_PU] = ADC5_CHAN_TEMP("gpio2_100k_pu", 0, diff --git a/drivers/iio/adc/qcom-vadc-common.c b/drivers/iio/adc/qcom-vadc-common.c index ed5d91cf9134..41e587cad3bd 100644 --- a/drivers/iio/adc/qcom-vadc-common.c +++ b/drivers/iio/adc/qcom-vadc-common.c @@ -542,14 +542,21 @@ static int qcom_vadc_scale_hw_calib_volt( const struct u32_fract *prescale, const struct adc5_data *data, u16 adc_code, int *result_uv); +/* Current scaling for PMIC7 */ static int qcom_vadc_scale_hw_calib_current( const struct u32_fract *prescale, const struct adc5_data *data, u16 adc_code, int *result_ua); +/* Raw current for PMIC7 */ static int qcom_vadc_scale_hw_calib_current_raw( const struct u32_fract *prescale, const struct adc5_data *data, u16 adc_code, int *result_ua); +/* Current scaling for PMIC5 */ +static int qcom_vadc5_scale_hw_calib_current( + const struct u32_fract *prescale, + const struct adc5_data *data, + u16 adc_code, int *result_ua); static int qcom_vadc_scale_hw_calib_therm( const struct u32_fract *prescale, const struct adc5_data *data, @@ -607,6 +614,7 @@ static struct qcom_adc5_scale_type scale_adc5_fn[] = { [SCALE_HW_CALIB_DEFAULT] = {qcom_vadc_scale_hw_calib_volt}, [SCALE_HW_CALIB_CUR] = {qcom_vadc_scale_hw_calib_current}, [SCALE_HW_CALIB_CUR_RAW] = {qcom_vadc_scale_hw_calib_current_raw}, + [SCALE_HW_CALIB_PM5_CUR] = {qcom_vadc5_scale_hw_calib_current}, [SCALE_HW_CALIB_THERM_100K_PULLUP] = {qcom_vadc_scale_hw_calib_therm}, [SCALE_HW_CALIB_BATT_THERM_100K] = { qcom_vadc_scale_hw_calib_batt_therm_100}, @@ -880,6 +888,30 @@ static int qcom_vadc_scale_hw_calib_current( return 0; } +static int qcom_vadc5_scale_hw_calib_current( + const struct u32_fract *prescale, + const struct adc5_data *data, + u16 adc_code, int *result_ua) +{ + s64 voltage = 0, result = 0; + bool positive = true; + + if (adc_code & ADC5_USR_DATA_CHECK) { + adc_code = ~adc_code + 1; + positive = false; + } + + voltage = (s64)(s16) adc_code * data->full_scale_code_cur * 1000; + voltage = div64_s64(voltage, VADC5_MAX_CODE); + result = div64_s64(voltage * prescale->denominator, prescale->numerator); + *result_ua = result; + + if (!positive) + *result_ua = -result; + + return 0; +} + static int qcom_vadc_scale_hw_calib_volt( const struct u32_fract *prescale, const struct adc5_data *data, diff --git a/include/linux/iio/adc/qcom-vadc-common.h b/include/linux/iio/adc/qcom-vadc-common.h index 6d90caa91b45..55a17d81a83c 100644 --- a/include/linux/iio/adc/qcom-vadc-common.h +++ b/include/linux/iio/adc/qcom-vadc-common.h @@ -131,6 +131,8 @@ struct vadc_linear_graph { * that use raw ADC code. * SCALE_HW_CALIB_PM2250_S3_DIE_TEMP: Returns result in millidegrees for * S3 die temperature channel on PM2250. + * SCALE_HW_CALIB_PM5_CUR: Returns result in microamperes for PMIC5 channels + * that use voltage scaling. */ enum vadc_scale_fn_type { SCALE_DEFAULT = 0, @@ -155,6 +157,7 @@ enum vadc_scale_fn_type { SCALE_HW_CALIB_CUR, SCALE_HW_CALIB_CUR_RAW, SCALE_HW_CALIB_PM2250_S3_DIE_TEMP, + SCALE_HW_CALIB_PM5_CUR, SCALE_HW_CALIB_INVALID, };