diff --git a/drivers/iio/adc/qcom-vadc-common.c b/drivers/iio/adc/qcom-vadc-common.c index 9052b5b2d215..e0c7ed818ac0 100644 --- a/drivers/iio/adc/qcom-vadc-common.c +++ b/drivers/iio/adc/qcom-vadc-common.c @@ -552,6 +552,10 @@ static int qcom_vadc_scale_hw_smb1398_temp( const struct vadc_prescale_ratio *prescale, const struct adc5_data *data, u16 adc_code, int *result_mdec); +static int qcom_vadc_scale_hw_pm2250_s3_die_temp( + const struct vadc_prescale_ratio *prescale, + const struct adc5_data *data, + u16 adc_code, int *result_mdec); static int qcom_vadc_scale_hw_chg5_temp( const struct vadc_prescale_ratio *prescale, const struct adc5_data *data, @@ -589,6 +593,7 @@ static struct qcom_adc5_scale_type scale_adc5_fn[] = { [SCALE_HW_CALIB_PM5_CHG_TEMP] = {qcom_vadc_scale_hw_chg5_temp}, [SCALE_HW_CALIB_PM5_SMB_TEMP] = {qcom_vadc_scale_hw_smb_temp}, [SCALE_HW_CALIB_PM5_SMB1398_TEMP] = {qcom_vadc_scale_hw_smb1398_temp}, + [SCALE_HW_CALIB_PM2250_S3_DIE_TEMP] = {qcom_vadc_scale_hw_pm2250_s3_die_temp}, [SCALE_HW_CALIB_PM7_SMB_TEMP] = {qcom_vadc_scale_hw_pm7_smb_temp}, [SCALE_HW_CALIB_PM7_CHG_TEMP] = {qcom_vadc_scale_hw_pm7_chg_temp}, }; @@ -1032,6 +1037,35 @@ static int qcom_vadc_scale_hw_smb1398_temp( return 0; } +static int qcom_vadc_scale_hw_pm2250_s3_die_temp( + const struct vadc_prescale_ratio *prescale, + const struct adc5_data *data, + u16 adc_code, int *result_mdec) +{ + s64 voltage = 0, adc_vdd_ref_mv = 1875; + + 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) { + voltage *= prescale->den; + voltage = div64_s64(voltage, prescale->num); + } else { + voltage = 0; + } + + voltage = PMIC5_PM2250_S3_DIE_TEMP_CONSTANT - voltage; + voltage *= 100000; + voltage = div64_s64(voltage, PMIC5_PM2250_S3_DIE_TEMP_SCALE_FACTOR); + + *result_mdec = voltage; + + return 0; +} + static int qcom_vadc_scale_hw_chg5_temp( const struct vadc_prescale_ratio *prescale, const struct adc5_data *data, diff --git a/drivers/iio/adc/qcom-vadc-common.h b/drivers/iio/adc/qcom-vadc-common.h index 612a9b07cfd0..5151b47c46fd 100644 --- a/drivers/iio/adc/qcom-vadc-common.h +++ b/drivers/iio/adc/qcom-vadc-common.h @@ -45,6 +45,9 @@ #define PMIC5_SMB1398_TEMP_SCALE_FACTOR 340 #define PMIC5_SMB1398_TEMP_CONSTANT 268235 +#define PMIC5_PM2250_S3_DIE_TEMP_SCALE_FACTOR 187263 +#define PMIC5_PM2250_S3_DIE_TEMP_CONSTANT 720100 + #define PMI_CHG_SCALE_1 -138890 #define PMI_CHG_SCALE_2 391750000000LL @@ -150,6 +153,8 @@ struct vadc_prescale_ratio { * charger temperature. * SCALE_HW_CALIB_CUR_RAW: Returns result in microamperes for PMIC7 channels * that uses raw ADC code. + * SCALE_HW_CALIB_PM2250_S3_DIE_TEMP: Returns result in millidegrees for + * S3 die temperature channel on PM2250. */ enum vadc_scale_fn_type { SCALE_DEFAULT = 0, @@ -173,6 +178,7 @@ enum vadc_scale_fn_type { SCALE_HW_CALIB_PM7_SMB_TEMP, SCALE_HW_CALIB_PM7_CHG_TEMP, SCALE_HW_CALIB_CUR_RAW, + SCALE_HW_CALIB_PM2250_S3_DIE_TEMP, SCALE_HW_CALIB_INVALID, };