1*72c7df85SCaleb Connolly // SPDX-License-Identifier: GPL-2.0-only 2*72c7df85SCaleb Connolly /* 3*72c7df85SCaleb Connolly * Copyright (c) 2016-2017, 2019, The Linux Foundation. All rights reserved. 4*72c7df85SCaleb Connolly * Copyright (c) 2022 Linaro Limited. 5*72c7df85SCaleb Connolly * Author: Caleb Connolly <caleb.connolly@linaro.org> 6*72c7df85SCaleb Connolly * 7*72c7df85SCaleb Connolly * This driver is for the Round Robin ADC found in the pmi8998 and pm660 PMICs. 8*72c7df85SCaleb Connolly */ 9*72c7df85SCaleb Connolly 10*72c7df85SCaleb Connolly #include <linux/bitfield.h> 11*72c7df85SCaleb Connolly #include <linux/delay.h> 12*72c7df85SCaleb Connolly #include <linux/kernel.h> 13*72c7df85SCaleb Connolly #include <linux/math64.h> 14*72c7df85SCaleb Connolly #include <linux/module.h> 15*72c7df85SCaleb Connolly #include <linux/mod_devicetable.h> 16*72c7df85SCaleb Connolly #include <linux/platform_device.h> 17*72c7df85SCaleb Connolly #include <linux/property.h> 18*72c7df85SCaleb Connolly #include <linux/regmap.h> 19*72c7df85SCaleb Connolly #include <linux/spmi.h> 20*72c7df85SCaleb Connolly #include <linux/types.h> 21*72c7df85SCaleb Connolly #include <linux/units.h> 22*72c7df85SCaleb Connolly 23*72c7df85SCaleb Connolly #include <asm/unaligned.h> 24*72c7df85SCaleb Connolly 25*72c7df85SCaleb Connolly #include <linux/iio/iio.h> 26*72c7df85SCaleb Connolly #include <linux/iio/types.h> 27*72c7df85SCaleb Connolly 28*72c7df85SCaleb Connolly #include <soc/qcom/qcom-spmi-pmic.h> 29*72c7df85SCaleb Connolly 30*72c7df85SCaleb Connolly #define DRIVER_NAME "qcom-spmi-rradc" 31*72c7df85SCaleb Connolly 32*72c7df85SCaleb Connolly #define RR_ADC_EN_CTL 0x46 33*72c7df85SCaleb Connolly #define RR_ADC_SKIN_TEMP_LSB 0x50 34*72c7df85SCaleb Connolly #define RR_ADC_SKIN_TEMP_MSB 0x51 35*72c7df85SCaleb Connolly #define RR_ADC_CTL 0x52 36*72c7df85SCaleb Connolly #define RR_ADC_CTL_CONTINUOUS_SEL BIT(3) 37*72c7df85SCaleb Connolly #define RR_ADC_LOG 0x53 38*72c7df85SCaleb Connolly #define RR_ADC_LOG_CLR_CTRL BIT(0) 39*72c7df85SCaleb Connolly 40*72c7df85SCaleb Connolly #define RR_ADC_FAKE_BATT_LOW_LSB 0x58 41*72c7df85SCaleb Connolly #define RR_ADC_FAKE_BATT_LOW_MSB 0x59 42*72c7df85SCaleb Connolly #define RR_ADC_FAKE_BATT_HIGH_LSB 0x5A 43*72c7df85SCaleb Connolly #define RR_ADC_FAKE_BATT_HIGH_MSB 0x5B 44*72c7df85SCaleb Connolly 45*72c7df85SCaleb Connolly #define RR_ADC_BATT_ID_CTRL 0x60 46*72c7df85SCaleb Connolly #define RR_ADC_BATT_ID_CTRL_CHANNEL_CONV BIT(0) 47*72c7df85SCaleb Connolly #define RR_ADC_BATT_ID_TRIGGER 0x61 48*72c7df85SCaleb Connolly #define RR_ADC_BATT_ID_STS 0x62 49*72c7df85SCaleb Connolly #define RR_ADC_BATT_ID_CFG 0x63 50*72c7df85SCaleb Connolly #define BATT_ID_SETTLE_MASK GENMASK(7, 5) 51*72c7df85SCaleb Connolly #define RR_ADC_BATT_ID_5_LSB 0x66 52*72c7df85SCaleb Connolly #define RR_ADC_BATT_ID_5_MSB 0x67 53*72c7df85SCaleb Connolly #define RR_ADC_BATT_ID_15_LSB 0x68 54*72c7df85SCaleb Connolly #define RR_ADC_BATT_ID_15_MSB 0x69 55*72c7df85SCaleb Connolly #define RR_ADC_BATT_ID_150_LSB 0x6A 56*72c7df85SCaleb Connolly #define RR_ADC_BATT_ID_150_MSB 0x6B 57*72c7df85SCaleb Connolly 58*72c7df85SCaleb Connolly #define RR_ADC_BATT_THERM_CTRL 0x70 59*72c7df85SCaleb Connolly #define RR_ADC_BATT_THERM_TRIGGER 0x71 60*72c7df85SCaleb Connolly #define RR_ADC_BATT_THERM_STS 0x72 61*72c7df85SCaleb Connolly #define RR_ADC_BATT_THERM_CFG 0x73 62*72c7df85SCaleb Connolly #define RR_ADC_BATT_THERM_LSB 0x74 63*72c7df85SCaleb Connolly #define RR_ADC_BATT_THERM_MSB 0x75 64*72c7df85SCaleb Connolly #define RR_ADC_BATT_THERM_FREQ 0x76 65*72c7df85SCaleb Connolly 66*72c7df85SCaleb Connolly #define RR_ADC_AUX_THERM_CTRL 0x80 67*72c7df85SCaleb Connolly #define RR_ADC_AUX_THERM_TRIGGER 0x81 68*72c7df85SCaleb Connolly #define RR_ADC_AUX_THERM_STS 0x82 69*72c7df85SCaleb Connolly #define RR_ADC_AUX_THERM_CFG 0x83 70*72c7df85SCaleb Connolly #define RR_ADC_AUX_THERM_LSB 0x84 71*72c7df85SCaleb Connolly #define RR_ADC_AUX_THERM_MSB 0x85 72*72c7df85SCaleb Connolly 73*72c7df85SCaleb Connolly #define RR_ADC_SKIN_HOT 0x86 74*72c7df85SCaleb Connolly #define RR_ADC_SKIN_TOO_HOT 0x87 75*72c7df85SCaleb Connolly 76*72c7df85SCaleb Connolly #define RR_ADC_AUX_THERM_C1 0x88 77*72c7df85SCaleb Connolly #define RR_ADC_AUX_THERM_C2 0x89 78*72c7df85SCaleb Connolly #define RR_ADC_AUX_THERM_C3 0x8A 79*72c7df85SCaleb Connolly #define RR_ADC_AUX_THERM_HALF_RANGE 0x8B 80*72c7df85SCaleb Connolly 81*72c7df85SCaleb Connolly #define RR_ADC_USB_IN_V_CTRL 0x90 82*72c7df85SCaleb Connolly #define RR_ADC_USB_IN_V_TRIGGER 0x91 83*72c7df85SCaleb Connolly #define RR_ADC_USB_IN_V_STS 0x92 84*72c7df85SCaleb Connolly #define RR_ADC_USB_IN_V_LSB 0x94 85*72c7df85SCaleb Connolly #define RR_ADC_USB_IN_V_MSB 0x95 86*72c7df85SCaleb Connolly #define RR_ADC_USB_IN_I_CTRL 0x98 87*72c7df85SCaleb Connolly #define RR_ADC_USB_IN_I_TRIGGER 0x99 88*72c7df85SCaleb Connolly #define RR_ADC_USB_IN_I_STS 0x9A 89*72c7df85SCaleb Connolly #define RR_ADC_USB_IN_I_LSB 0x9C 90*72c7df85SCaleb Connolly #define RR_ADC_USB_IN_I_MSB 0x9D 91*72c7df85SCaleb Connolly 92*72c7df85SCaleb Connolly #define RR_ADC_DC_IN_V_CTRL 0xA0 93*72c7df85SCaleb Connolly #define RR_ADC_DC_IN_V_TRIGGER 0xA1 94*72c7df85SCaleb Connolly #define RR_ADC_DC_IN_V_STS 0xA2 95*72c7df85SCaleb Connolly #define RR_ADC_DC_IN_V_LSB 0xA4 96*72c7df85SCaleb Connolly #define RR_ADC_DC_IN_V_MSB 0xA5 97*72c7df85SCaleb Connolly #define RR_ADC_DC_IN_I_CTRL 0xA8 98*72c7df85SCaleb Connolly #define RR_ADC_DC_IN_I_TRIGGER 0xA9 99*72c7df85SCaleb Connolly #define RR_ADC_DC_IN_I_STS 0xAA 100*72c7df85SCaleb Connolly #define RR_ADC_DC_IN_I_LSB 0xAC 101*72c7df85SCaleb Connolly #define RR_ADC_DC_IN_I_MSB 0xAD 102*72c7df85SCaleb Connolly 103*72c7df85SCaleb Connolly #define RR_ADC_PMI_DIE_TEMP_CTRL 0xB0 104*72c7df85SCaleb Connolly #define RR_ADC_PMI_DIE_TEMP_TRIGGER 0xB1 105*72c7df85SCaleb Connolly #define RR_ADC_PMI_DIE_TEMP_STS 0xB2 106*72c7df85SCaleb Connolly #define RR_ADC_PMI_DIE_TEMP_CFG 0xB3 107*72c7df85SCaleb Connolly #define RR_ADC_PMI_DIE_TEMP_LSB 0xB4 108*72c7df85SCaleb Connolly #define RR_ADC_PMI_DIE_TEMP_MSB 0xB5 109*72c7df85SCaleb Connolly 110*72c7df85SCaleb Connolly #define RR_ADC_CHARGER_TEMP_CTRL 0xB8 111*72c7df85SCaleb Connolly #define RR_ADC_CHARGER_TEMP_TRIGGER 0xB9 112*72c7df85SCaleb Connolly #define RR_ADC_CHARGER_TEMP_STS 0xBA 113*72c7df85SCaleb Connolly #define RR_ADC_CHARGER_TEMP_CFG 0xBB 114*72c7df85SCaleb Connolly #define RR_ADC_CHARGER_TEMP_LSB 0xBC 115*72c7df85SCaleb Connolly #define RR_ADC_CHARGER_TEMP_MSB 0xBD 116*72c7df85SCaleb Connolly #define RR_ADC_CHARGER_HOT 0xBE 117*72c7df85SCaleb Connolly #define RR_ADC_CHARGER_TOO_HOT 0xBF 118*72c7df85SCaleb Connolly 119*72c7df85SCaleb Connolly #define RR_ADC_GPIO_CTRL 0xC0 120*72c7df85SCaleb Connolly #define RR_ADC_GPIO_TRIGGER 0xC1 121*72c7df85SCaleb Connolly #define RR_ADC_GPIO_STS 0xC2 122*72c7df85SCaleb Connolly #define RR_ADC_GPIO_LSB 0xC4 123*72c7df85SCaleb Connolly #define RR_ADC_GPIO_MSB 0xC5 124*72c7df85SCaleb Connolly 125*72c7df85SCaleb Connolly #define RR_ADC_ATEST_CTRL 0xC8 126*72c7df85SCaleb Connolly #define RR_ADC_ATEST_TRIGGER 0xC9 127*72c7df85SCaleb Connolly #define RR_ADC_ATEST_STS 0xCA 128*72c7df85SCaleb Connolly #define RR_ADC_ATEST_LSB 0xCC 129*72c7df85SCaleb Connolly #define RR_ADC_ATEST_MSB 0xCD 130*72c7df85SCaleb Connolly #define RR_ADC_SEC_ACCESS 0xD0 131*72c7df85SCaleb Connolly 132*72c7df85SCaleb Connolly #define RR_ADC_PERPH_RESET_CTL2 0xD9 133*72c7df85SCaleb Connolly #define RR_ADC_PERPH_RESET_CTL3 0xDA 134*72c7df85SCaleb Connolly #define RR_ADC_PERPH_RESET_CTL4 0xDB 135*72c7df85SCaleb Connolly #define RR_ADC_INT_TEST1 0xE0 136*72c7df85SCaleb Connolly #define RR_ADC_INT_TEST_VAL 0xE1 137*72c7df85SCaleb Connolly 138*72c7df85SCaleb Connolly #define RR_ADC_TM_TRIGGER_CTRLS 0xE2 139*72c7df85SCaleb Connolly #define RR_ADC_TM_ADC_CTRLS 0xE3 140*72c7df85SCaleb Connolly #define RR_ADC_TM_CNL_CTRL 0xE4 141*72c7df85SCaleb Connolly #define RR_ADC_TM_BATT_ID_CTRL 0xE5 142*72c7df85SCaleb Connolly #define RR_ADC_TM_THERM_CTRL 0xE6 143*72c7df85SCaleb Connolly #define RR_ADC_TM_CONV_STS 0xE7 144*72c7df85SCaleb Connolly #define RR_ADC_TM_ADC_READ_LSB 0xE8 145*72c7df85SCaleb Connolly #define RR_ADC_TM_ADC_READ_MSB 0xE9 146*72c7df85SCaleb Connolly #define RR_ADC_TM_ATEST_MUX_1 0xEA 147*72c7df85SCaleb Connolly #define RR_ADC_TM_ATEST_MUX_2 0xEB 148*72c7df85SCaleb Connolly #define RR_ADC_TM_REFERENCES 0xED 149*72c7df85SCaleb Connolly #define RR_ADC_TM_MISC_CTL 0xEE 150*72c7df85SCaleb Connolly #define RR_ADC_TM_RR_CTRL 0xEF 151*72c7df85SCaleb Connolly 152*72c7df85SCaleb Connolly #define RR_ADC_TRIGGER_EVERY_CYCLE BIT(7) 153*72c7df85SCaleb Connolly #define RR_ADC_TRIGGER_CTL BIT(0) 154*72c7df85SCaleb Connolly 155*72c7df85SCaleb Connolly #define RR_ADC_BATT_ID_RANGE 820 156*72c7df85SCaleb Connolly 157*72c7df85SCaleb Connolly #define RR_ADC_BITS 10 158*72c7df85SCaleb Connolly #define RR_ADC_CHAN_MSB (1 << RR_ADC_BITS) 159*72c7df85SCaleb Connolly #define RR_ADC_FS_VOLTAGE_MV 2500 160*72c7df85SCaleb Connolly 161*72c7df85SCaleb Connolly /* BATT_THERM 0.25K/LSB */ 162*72c7df85SCaleb Connolly #define RR_ADC_BATT_THERM_LSB_K 4 163*72c7df85SCaleb Connolly 164*72c7df85SCaleb Connolly #define RR_ADC_TEMP_FS_VOLTAGE_NUM 5000000 165*72c7df85SCaleb Connolly #define RR_ADC_TEMP_FS_VOLTAGE_DEN 3 166*72c7df85SCaleb Connolly #define RR_ADC_DIE_TEMP_OFFSET 601400 167*72c7df85SCaleb Connolly #define RR_ADC_DIE_TEMP_SLOPE 2 168*72c7df85SCaleb Connolly #define RR_ADC_DIE_TEMP_OFFSET_MILLI_DEGC 25000 169*72c7df85SCaleb Connolly 170*72c7df85SCaleb Connolly #define RR_ADC_CHG_TEMP_GF_OFFSET_UV 1303168 171*72c7df85SCaleb Connolly #define RR_ADC_CHG_TEMP_GF_SLOPE_UV_PER_C 3784 172*72c7df85SCaleb Connolly #define RR_ADC_CHG_TEMP_SMIC_OFFSET_UV 1338433 173*72c7df85SCaleb Connolly #define RR_ADC_CHG_TEMP_SMIC_SLOPE_UV_PER_C 3655 174*72c7df85SCaleb Connolly #define RR_ADC_CHG_TEMP_660_GF_OFFSET_UV 1309001 175*72c7df85SCaleb Connolly #define RR_ADC_CHG_TEMP_660_GF_SLOPE_UV_PER_C 3403 176*72c7df85SCaleb Connolly #define RR_ADC_CHG_TEMP_660_SMIC_OFFSET_UV 1295898 177*72c7df85SCaleb Connolly #define RR_ADC_CHG_TEMP_660_SMIC_SLOPE_UV_PER_C 3596 178*72c7df85SCaleb Connolly #define RR_ADC_CHG_TEMP_660_MGNA_OFFSET_UV 1314779 179*72c7df85SCaleb Connolly #define RR_ADC_CHG_TEMP_660_MGNA_SLOPE_UV_PER_C 3496 180*72c7df85SCaleb Connolly #define RR_ADC_CHG_TEMP_OFFSET_MILLI_DEGC 25000 181*72c7df85SCaleb Connolly #define RR_ADC_CHG_THRESHOLD_SCALE 4 182*72c7df85SCaleb Connolly 183*72c7df85SCaleb Connolly #define RR_ADC_VOLT_INPUT_FACTOR 8 184*72c7df85SCaleb Connolly #define RR_ADC_CURR_INPUT_FACTOR 2000 185*72c7df85SCaleb Connolly #define RR_ADC_CURR_USBIN_INPUT_FACTOR_MIL 1886 186*72c7df85SCaleb Connolly #define RR_ADC_CURR_USBIN_660_FACTOR_MIL 9 187*72c7df85SCaleb Connolly #define RR_ADC_CURR_USBIN_660_UV_VAL 579500 188*72c7df85SCaleb Connolly 189*72c7df85SCaleb Connolly #define RR_ADC_GPIO_FS_RANGE 5000 190*72c7df85SCaleb Connolly #define RR_ADC_COHERENT_CHECK_RETRY 5 191*72c7df85SCaleb Connolly #define RR_ADC_CHAN_MAX_CONTINUOUS_BUFFER_LEN 16 192*72c7df85SCaleb Connolly 193*72c7df85SCaleb Connolly #define RR_ADC_STS_CHANNEL_READING_MASK GENMASK(1, 0) 194*72c7df85SCaleb Connolly #define RR_ADC_STS_CHANNEL_STS BIT(1) 195*72c7df85SCaleb Connolly 196*72c7df85SCaleb Connolly #define RR_ADC_TP_REV_VERSION1 21 197*72c7df85SCaleb Connolly #define RR_ADC_TP_REV_VERSION2 29 198*72c7df85SCaleb Connolly #define RR_ADC_TP_REV_VERSION3 32 199*72c7df85SCaleb Connolly 200*72c7df85SCaleb Connolly #define RRADC_BATT_ID_DELAY_MAX 8 201*72c7df85SCaleb Connolly 202*72c7df85SCaleb Connolly enum rradc_channel_id { 203*72c7df85SCaleb Connolly RR_ADC_BATT_ID = 0, 204*72c7df85SCaleb Connolly RR_ADC_BATT_THERM, 205*72c7df85SCaleb Connolly RR_ADC_SKIN_TEMP, 206*72c7df85SCaleb Connolly RR_ADC_USBIN_I, 207*72c7df85SCaleb Connolly RR_ADC_USBIN_V, 208*72c7df85SCaleb Connolly RR_ADC_DCIN_I, 209*72c7df85SCaleb Connolly RR_ADC_DCIN_V, 210*72c7df85SCaleb Connolly RR_ADC_DIE_TEMP, 211*72c7df85SCaleb Connolly RR_ADC_CHG_TEMP, 212*72c7df85SCaleb Connolly RR_ADC_GPIO, 213*72c7df85SCaleb Connolly RR_ADC_CHAN_MAX 214*72c7df85SCaleb Connolly }; 215*72c7df85SCaleb Connolly 216*72c7df85SCaleb Connolly struct rradc_chip; 217*72c7df85SCaleb Connolly 218*72c7df85SCaleb Connolly /** 219*72c7df85SCaleb Connolly * struct rradc_channel - rradc channel data 220*72c7df85SCaleb Connolly * @label: channel label 221*72c7df85SCaleb Connolly * @lsb: Channel least significant byte 222*72c7df85SCaleb Connolly * @status: Channel status address 223*72c7df85SCaleb Connolly * @size: number of bytes to read 224*72c7df85SCaleb Connolly * @trigger_addr: Trigger address, trigger is only used on some channels 225*72c7df85SCaleb Connolly * @trigger_mask: Trigger mask 226*72c7df85SCaleb Connolly * @scale_fn: Post process callback for channels which can't be exposed 227*72c7df85SCaleb Connolly * as offset + scale. 228*72c7df85SCaleb Connolly */ 229*72c7df85SCaleb Connolly struct rradc_channel { 230*72c7df85SCaleb Connolly const char *label; 231*72c7df85SCaleb Connolly u8 lsb; 232*72c7df85SCaleb Connolly u8 status; 233*72c7df85SCaleb Connolly int size; 234*72c7df85SCaleb Connolly int trigger_addr; 235*72c7df85SCaleb Connolly int trigger_mask; 236*72c7df85SCaleb Connolly int (*scale_fn)(struct rradc_chip *chip, u16 adc_code, int *result); 237*72c7df85SCaleb Connolly }; 238*72c7df85SCaleb Connolly 239*72c7df85SCaleb Connolly struct rradc_chip { 240*72c7df85SCaleb Connolly struct device *dev; 241*72c7df85SCaleb Connolly const struct qcom_spmi_pmic *pmic; 242*72c7df85SCaleb Connolly /* 243*72c7df85SCaleb Connolly * Lock held while doing channel conversion 244*72c7df85SCaleb Connolly * involving multiple register read/writes 245*72c7df85SCaleb Connolly */ 246*72c7df85SCaleb Connolly struct mutex conversion_lock; 247*72c7df85SCaleb Connolly struct regmap *regmap; 248*72c7df85SCaleb Connolly u32 base; 249*72c7df85SCaleb Connolly int batt_id_delay; 250*72c7df85SCaleb Connolly u16 batt_id_data; 251*72c7df85SCaleb Connolly }; 252*72c7df85SCaleb Connolly 253*72c7df85SCaleb Connolly static const int batt_id_delays[] = { 0, 1, 4, 12, 20, 40, 60, 80 }; 254*72c7df85SCaleb Connolly static const struct rradc_channel rradc_chans[RR_ADC_CHAN_MAX]; 255*72c7df85SCaleb Connolly static const struct iio_chan_spec rradc_iio_chans[RR_ADC_CHAN_MAX]; 256*72c7df85SCaleb Connolly 257*72c7df85SCaleb Connolly static int rradc_read(struct rradc_chip *chip, u16 addr, __le16 *buf, int len) 258*72c7df85SCaleb Connolly { 259*72c7df85SCaleb Connolly int ret, retry_cnt = 0; 260*72c7df85SCaleb Connolly __le16 data_check[RR_ADC_CHAN_MAX_CONTINUOUS_BUFFER_LEN / 2]; 261*72c7df85SCaleb Connolly 262*72c7df85SCaleb Connolly if (len > RR_ADC_CHAN_MAX_CONTINUOUS_BUFFER_LEN) { 263*72c7df85SCaleb Connolly dev_err(chip->dev, 264*72c7df85SCaleb Connolly "Can't read more than %d bytes, but asked to read %d bytes.\n", 265*72c7df85SCaleb Connolly RR_ADC_CHAN_MAX_CONTINUOUS_BUFFER_LEN, len); 266*72c7df85SCaleb Connolly return -EINVAL; 267*72c7df85SCaleb Connolly } 268*72c7df85SCaleb Connolly 269*72c7df85SCaleb Connolly while (retry_cnt < RR_ADC_COHERENT_CHECK_RETRY) { 270*72c7df85SCaleb Connolly ret = regmap_bulk_read(chip->regmap, chip->base + addr, buf, 271*72c7df85SCaleb Connolly len); 272*72c7df85SCaleb Connolly if (ret < 0) { 273*72c7df85SCaleb Connolly dev_err(chip->dev, "rr_adc reg 0x%x failed :%d\n", addr, 274*72c7df85SCaleb Connolly ret); 275*72c7df85SCaleb Connolly return ret; 276*72c7df85SCaleb Connolly } 277*72c7df85SCaleb Connolly 278*72c7df85SCaleb Connolly ret = regmap_bulk_read(chip->regmap, chip->base + addr, 279*72c7df85SCaleb Connolly data_check, len); 280*72c7df85SCaleb Connolly if (ret < 0) { 281*72c7df85SCaleb Connolly dev_err(chip->dev, "rr_adc reg 0x%x failed :%d\n", addr, 282*72c7df85SCaleb Connolly ret); 283*72c7df85SCaleb Connolly return ret; 284*72c7df85SCaleb Connolly } 285*72c7df85SCaleb Connolly 286*72c7df85SCaleb Connolly if (memcmp(buf, data_check, len) != 0) { 287*72c7df85SCaleb Connolly retry_cnt++; 288*72c7df85SCaleb Connolly dev_dbg(chip->dev, 289*72c7df85SCaleb Connolly "coherent read error, retry_cnt:%d\n", 290*72c7df85SCaleb Connolly retry_cnt); 291*72c7df85SCaleb Connolly continue; 292*72c7df85SCaleb Connolly } 293*72c7df85SCaleb Connolly 294*72c7df85SCaleb Connolly break; 295*72c7df85SCaleb Connolly } 296*72c7df85SCaleb Connolly 297*72c7df85SCaleb Connolly if (retry_cnt == RR_ADC_COHERENT_CHECK_RETRY) 298*72c7df85SCaleb Connolly dev_err(chip->dev, "Retry exceeded for coherrency check\n"); 299*72c7df85SCaleb Connolly 300*72c7df85SCaleb Connolly return ret; 301*72c7df85SCaleb Connolly } 302*72c7df85SCaleb Connolly 303*72c7df85SCaleb Connolly static int rradc_get_fab_coeff(struct rradc_chip *chip, int64_t *offset, 304*72c7df85SCaleb Connolly int64_t *slope) 305*72c7df85SCaleb Connolly { 306*72c7df85SCaleb Connolly if (chip->pmic->subtype == PM660_SUBTYPE) { 307*72c7df85SCaleb Connolly switch (chip->pmic->fab_id) { 308*72c7df85SCaleb Connolly case PM660_FAB_ID_GF: 309*72c7df85SCaleb Connolly *offset = RR_ADC_CHG_TEMP_660_GF_OFFSET_UV; 310*72c7df85SCaleb Connolly *slope = RR_ADC_CHG_TEMP_660_GF_SLOPE_UV_PER_C; 311*72c7df85SCaleb Connolly return 0; 312*72c7df85SCaleb Connolly case PM660_FAB_ID_TSMC: 313*72c7df85SCaleb Connolly *offset = RR_ADC_CHG_TEMP_660_SMIC_OFFSET_UV; 314*72c7df85SCaleb Connolly *slope = RR_ADC_CHG_TEMP_660_SMIC_SLOPE_UV_PER_C; 315*72c7df85SCaleb Connolly return 0; 316*72c7df85SCaleb Connolly default: 317*72c7df85SCaleb Connolly *offset = RR_ADC_CHG_TEMP_660_MGNA_OFFSET_UV; 318*72c7df85SCaleb Connolly *slope = RR_ADC_CHG_TEMP_660_MGNA_SLOPE_UV_PER_C; 319*72c7df85SCaleb Connolly } 320*72c7df85SCaleb Connolly } else if (chip->pmic->subtype == PMI8998_SUBTYPE) { 321*72c7df85SCaleb Connolly switch (chip->pmic->fab_id) { 322*72c7df85SCaleb Connolly case PMI8998_FAB_ID_GF: 323*72c7df85SCaleb Connolly *offset = RR_ADC_CHG_TEMP_GF_OFFSET_UV; 324*72c7df85SCaleb Connolly *slope = RR_ADC_CHG_TEMP_GF_SLOPE_UV_PER_C; 325*72c7df85SCaleb Connolly return 0; 326*72c7df85SCaleb Connolly case PMI8998_FAB_ID_SMIC: 327*72c7df85SCaleb Connolly *offset = RR_ADC_CHG_TEMP_SMIC_OFFSET_UV; 328*72c7df85SCaleb Connolly *slope = RR_ADC_CHG_TEMP_SMIC_SLOPE_UV_PER_C; 329*72c7df85SCaleb Connolly return 0; 330*72c7df85SCaleb Connolly default: 331*72c7df85SCaleb Connolly return -EINVAL; 332*72c7df85SCaleb Connolly } 333*72c7df85SCaleb Connolly } 334*72c7df85SCaleb Connolly 335*72c7df85SCaleb Connolly return -EINVAL; 336*72c7df85SCaleb Connolly } 337*72c7df85SCaleb Connolly 338*72c7df85SCaleb Connolly /* 339*72c7df85SCaleb Connolly * These functions explicitly cast int64_t to int. 340*72c7df85SCaleb Connolly * They will never overflow, as the values are small enough. 341*72c7df85SCaleb Connolly */ 342*72c7df85SCaleb Connolly static int rradc_post_process_batt_id(struct rradc_chip *chip, u16 adc_code, 343*72c7df85SCaleb Connolly int *result_ohms) 344*72c7df85SCaleb Connolly { 345*72c7df85SCaleb Connolly uint32_t current_value; 346*72c7df85SCaleb Connolly int64_t r_id; 347*72c7df85SCaleb Connolly 348*72c7df85SCaleb Connolly current_value = chip->batt_id_data; 349*72c7df85SCaleb Connolly r_id = ((int64_t)adc_code * RR_ADC_FS_VOLTAGE_MV); 350*72c7df85SCaleb Connolly r_id = div64_s64(r_id, (RR_ADC_CHAN_MSB * current_value)); 351*72c7df85SCaleb Connolly *result_ohms = (int)(r_id * MILLI); 352*72c7df85SCaleb Connolly 353*72c7df85SCaleb Connolly return 0; 354*72c7df85SCaleb Connolly } 355*72c7df85SCaleb Connolly 356*72c7df85SCaleb Connolly static int rradc_enable_continuous_mode(struct rradc_chip *chip) 357*72c7df85SCaleb Connolly { 358*72c7df85SCaleb Connolly int ret; 359*72c7df85SCaleb Connolly 360*72c7df85SCaleb Connolly /* Clear channel log */ 361*72c7df85SCaleb Connolly ret = regmap_update_bits(chip->regmap, chip->base + RR_ADC_LOG, 362*72c7df85SCaleb Connolly RR_ADC_LOG_CLR_CTRL, RR_ADC_LOG_CLR_CTRL); 363*72c7df85SCaleb Connolly if (ret < 0) { 364*72c7df85SCaleb Connolly dev_err(chip->dev, "log ctrl update to clear failed:%d\n", ret); 365*72c7df85SCaleb Connolly return ret; 366*72c7df85SCaleb Connolly } 367*72c7df85SCaleb Connolly 368*72c7df85SCaleb Connolly ret = regmap_update_bits(chip->regmap, chip->base + RR_ADC_LOG, 369*72c7df85SCaleb Connolly RR_ADC_LOG_CLR_CTRL, 0); 370*72c7df85SCaleb Connolly if (ret < 0) { 371*72c7df85SCaleb Connolly dev_err(chip->dev, "log ctrl update to not clear failed:%d\n", 372*72c7df85SCaleb Connolly ret); 373*72c7df85SCaleb Connolly return ret; 374*72c7df85SCaleb Connolly } 375*72c7df85SCaleb Connolly 376*72c7df85SCaleb Connolly /* Switch to continuous mode */ 377*72c7df85SCaleb Connolly ret = regmap_update_bits(chip->regmap, chip->base + RR_ADC_CTL, 378*72c7df85SCaleb Connolly RR_ADC_CTL_CONTINUOUS_SEL, 379*72c7df85SCaleb Connolly RR_ADC_CTL_CONTINUOUS_SEL); 380*72c7df85SCaleb Connolly if (ret < 0) 381*72c7df85SCaleb Connolly dev_err(chip->dev, "Update to continuous mode failed:%d\n", 382*72c7df85SCaleb Connolly ret); 383*72c7df85SCaleb Connolly 384*72c7df85SCaleb Connolly return ret; 385*72c7df85SCaleb Connolly } 386*72c7df85SCaleb Connolly 387*72c7df85SCaleb Connolly static int rradc_disable_continuous_mode(struct rradc_chip *chip) 388*72c7df85SCaleb Connolly { 389*72c7df85SCaleb Connolly int ret; 390*72c7df85SCaleb Connolly 391*72c7df85SCaleb Connolly /* Switch to non continuous mode */ 392*72c7df85SCaleb Connolly ret = regmap_update_bits(chip->regmap, chip->base + RR_ADC_CTL, 393*72c7df85SCaleb Connolly RR_ADC_CTL_CONTINUOUS_SEL, 0); 394*72c7df85SCaleb Connolly if (ret < 0) 395*72c7df85SCaleb Connolly dev_err(chip->dev, "Update to non-continuous mode failed:%d\n", 396*72c7df85SCaleb Connolly ret); 397*72c7df85SCaleb Connolly 398*72c7df85SCaleb Connolly return ret; 399*72c7df85SCaleb Connolly } 400*72c7df85SCaleb Connolly 401*72c7df85SCaleb Connolly static bool rradc_is_ready(struct rradc_chip *chip, 402*72c7df85SCaleb Connolly enum rradc_channel_id chan_address) 403*72c7df85SCaleb Connolly { 404*72c7df85SCaleb Connolly const struct rradc_channel *chan = &rradc_chans[chan_address]; 405*72c7df85SCaleb Connolly int ret; 406*72c7df85SCaleb Connolly unsigned int status, mask; 407*72c7df85SCaleb Connolly 408*72c7df85SCaleb Connolly /* BATT_ID STS bit does not get set initially */ 409*72c7df85SCaleb Connolly switch (chan_address) { 410*72c7df85SCaleb Connolly case RR_ADC_BATT_ID: 411*72c7df85SCaleb Connolly mask = RR_ADC_STS_CHANNEL_STS; 412*72c7df85SCaleb Connolly break; 413*72c7df85SCaleb Connolly default: 414*72c7df85SCaleb Connolly mask = RR_ADC_STS_CHANNEL_READING_MASK; 415*72c7df85SCaleb Connolly break; 416*72c7df85SCaleb Connolly } 417*72c7df85SCaleb Connolly 418*72c7df85SCaleb Connolly ret = regmap_read(chip->regmap, chip->base + chan->status, &status); 419*72c7df85SCaleb Connolly if (ret < 0 || !(status & mask)) 420*72c7df85SCaleb Connolly return false; 421*72c7df85SCaleb Connolly 422*72c7df85SCaleb Connolly return true; 423*72c7df85SCaleb Connolly } 424*72c7df85SCaleb Connolly 425*72c7df85SCaleb Connolly static int rradc_read_status_in_cont_mode(struct rradc_chip *chip, 426*72c7df85SCaleb Connolly enum rradc_channel_id chan_address) 427*72c7df85SCaleb Connolly { 428*72c7df85SCaleb Connolly const struct rradc_channel *chan = &rradc_chans[chan_address]; 429*72c7df85SCaleb Connolly const struct iio_chan_spec *iio_chan = &rradc_iio_chans[chan_address]; 430*72c7df85SCaleb Connolly int ret, i; 431*72c7df85SCaleb Connolly 432*72c7df85SCaleb Connolly if (chan->trigger_mask == 0) { 433*72c7df85SCaleb Connolly dev_err(chip->dev, "Channel doesn't have a trigger mask\n"); 434*72c7df85SCaleb Connolly return -EINVAL; 435*72c7df85SCaleb Connolly } 436*72c7df85SCaleb Connolly 437*72c7df85SCaleb Connolly ret = regmap_update_bits(chip->regmap, chip->base + chan->trigger_addr, 438*72c7df85SCaleb Connolly chan->trigger_mask, chan->trigger_mask); 439*72c7df85SCaleb Connolly if (ret < 0) { 440*72c7df85SCaleb Connolly dev_err(chip->dev, 441*72c7df85SCaleb Connolly "Failed to apply trigger for channel '%s' ret=%d\n", 442*72c7df85SCaleb Connolly iio_chan->extend_name, ret); 443*72c7df85SCaleb Connolly return ret; 444*72c7df85SCaleb Connolly } 445*72c7df85SCaleb Connolly 446*72c7df85SCaleb Connolly ret = rradc_enable_continuous_mode(chip); 447*72c7df85SCaleb Connolly if (ret < 0) { 448*72c7df85SCaleb Connolly dev_err(chip->dev, "Failed to switch to continuous mode\n"); 449*72c7df85SCaleb Connolly goto disable_trigger; 450*72c7df85SCaleb Connolly } 451*72c7df85SCaleb Connolly 452*72c7df85SCaleb Connolly /* 453*72c7df85SCaleb Connolly * The wait/sleep values were found through trial and error, 454*72c7df85SCaleb Connolly * this is mostly for the battery ID channel which takes some 455*72c7df85SCaleb Connolly * time to settle. 456*72c7df85SCaleb Connolly */ 457*72c7df85SCaleb Connolly for (i = 0; i < 5; i++) { 458*72c7df85SCaleb Connolly if (rradc_is_ready(chip, chan_address)) 459*72c7df85SCaleb Connolly break; 460*72c7df85SCaleb Connolly usleep_range(50000, 50000 + 500); 461*72c7df85SCaleb Connolly } 462*72c7df85SCaleb Connolly 463*72c7df85SCaleb Connolly if (i == 5) { 464*72c7df85SCaleb Connolly dev_err(chip->dev, "Channel '%s' is not ready\n", 465*72c7df85SCaleb Connolly iio_chan->extend_name); 466*72c7df85SCaleb Connolly ret = -ETIMEDOUT; 467*72c7df85SCaleb Connolly } 468*72c7df85SCaleb Connolly 469*72c7df85SCaleb Connolly rradc_disable_continuous_mode(chip); 470*72c7df85SCaleb Connolly 471*72c7df85SCaleb Connolly disable_trigger: 472*72c7df85SCaleb Connolly regmap_update_bits(chip->regmap, chip->base + chan->trigger_addr, 473*72c7df85SCaleb Connolly chan->trigger_mask, 0); 474*72c7df85SCaleb Connolly 475*72c7df85SCaleb Connolly return ret; 476*72c7df85SCaleb Connolly } 477*72c7df85SCaleb Connolly 478*72c7df85SCaleb Connolly static int rradc_prepare_batt_id_conversion(struct rradc_chip *chip, 479*72c7df85SCaleb Connolly enum rradc_channel_id chan_address, 480*72c7df85SCaleb Connolly u16 *data) 481*72c7df85SCaleb Connolly { 482*72c7df85SCaleb Connolly int ret; 483*72c7df85SCaleb Connolly 484*72c7df85SCaleb Connolly ret = regmap_update_bits(chip->regmap, chip->base + RR_ADC_BATT_ID_CTRL, 485*72c7df85SCaleb Connolly RR_ADC_BATT_ID_CTRL_CHANNEL_CONV, 486*72c7df85SCaleb Connolly RR_ADC_BATT_ID_CTRL_CHANNEL_CONV); 487*72c7df85SCaleb Connolly if (ret < 0) { 488*72c7df85SCaleb Connolly dev_err(chip->dev, "Enabling BATT ID channel failed:%d\n", ret); 489*72c7df85SCaleb Connolly return ret; 490*72c7df85SCaleb Connolly } 491*72c7df85SCaleb Connolly 492*72c7df85SCaleb Connolly ret = regmap_update_bits(chip->regmap, 493*72c7df85SCaleb Connolly chip->base + RR_ADC_BATT_ID_TRIGGER, 494*72c7df85SCaleb Connolly RR_ADC_TRIGGER_CTL, RR_ADC_TRIGGER_CTL); 495*72c7df85SCaleb Connolly if (ret < 0) { 496*72c7df85SCaleb Connolly dev_err(chip->dev, "BATT_ID trigger set failed:%d\n", ret); 497*72c7df85SCaleb Connolly goto out_disable_batt_id; 498*72c7df85SCaleb Connolly } 499*72c7df85SCaleb Connolly 500*72c7df85SCaleb Connolly ret = rradc_read_status_in_cont_mode(chip, chan_address); 501*72c7df85SCaleb Connolly 502*72c7df85SCaleb Connolly /* Reset registers back to default values */ 503*72c7df85SCaleb Connolly regmap_update_bits(chip->regmap, chip->base + RR_ADC_BATT_ID_TRIGGER, 504*72c7df85SCaleb Connolly RR_ADC_TRIGGER_CTL, 0); 505*72c7df85SCaleb Connolly 506*72c7df85SCaleb Connolly out_disable_batt_id: 507*72c7df85SCaleb Connolly regmap_update_bits(chip->regmap, chip->base + RR_ADC_BATT_ID_CTRL, 508*72c7df85SCaleb Connolly RR_ADC_BATT_ID_CTRL_CHANNEL_CONV, 0); 509*72c7df85SCaleb Connolly 510*72c7df85SCaleb Connolly return ret; 511*72c7df85SCaleb Connolly } 512*72c7df85SCaleb Connolly 513*72c7df85SCaleb Connolly static int rradc_do_conversion(struct rradc_chip *chip, 514*72c7df85SCaleb Connolly enum rradc_channel_id chan_address, u16 *data) 515*72c7df85SCaleb Connolly { 516*72c7df85SCaleb Connolly const struct rradc_channel *chan = &rradc_chans[chan_address]; 517*72c7df85SCaleb Connolly const struct iio_chan_spec *iio_chan = &rradc_iio_chans[chan_address]; 518*72c7df85SCaleb Connolly int ret; 519*72c7df85SCaleb Connolly __le16 buf[3]; 520*72c7df85SCaleb Connolly 521*72c7df85SCaleb Connolly mutex_lock(&chip->conversion_lock); 522*72c7df85SCaleb Connolly 523*72c7df85SCaleb Connolly switch (chan_address) { 524*72c7df85SCaleb Connolly case RR_ADC_BATT_ID: 525*72c7df85SCaleb Connolly ret = rradc_prepare_batt_id_conversion(chip, chan_address, data); 526*72c7df85SCaleb Connolly if (ret < 0) { 527*72c7df85SCaleb Connolly dev_err(chip->dev, "Battery ID conversion failed:%d\n", 528*72c7df85SCaleb Connolly ret); 529*72c7df85SCaleb Connolly goto unlock_out; 530*72c7df85SCaleb Connolly } 531*72c7df85SCaleb Connolly break; 532*72c7df85SCaleb Connolly 533*72c7df85SCaleb Connolly case RR_ADC_USBIN_V: 534*72c7df85SCaleb Connolly case RR_ADC_DIE_TEMP: 535*72c7df85SCaleb Connolly ret = rradc_read_status_in_cont_mode(chip, chan_address); 536*72c7df85SCaleb Connolly if (ret < 0) { 537*72c7df85SCaleb Connolly dev_err(chip->dev, 538*72c7df85SCaleb Connolly "Error reading in continuous mode:%d\n", ret); 539*72c7df85SCaleb Connolly goto unlock_out; 540*72c7df85SCaleb Connolly } 541*72c7df85SCaleb Connolly break; 542*72c7df85SCaleb Connolly default: 543*72c7df85SCaleb Connolly if (!rradc_is_ready(chip, chan_address)) { 544*72c7df85SCaleb Connolly /* 545*72c7df85SCaleb Connolly * Usually this means the channel isn't attached, for example 546*72c7df85SCaleb Connolly * the in_voltage_usbin_v_input channel will not be ready if 547*72c7df85SCaleb Connolly * no USB cable is attached 548*72c7df85SCaleb Connolly */ 549*72c7df85SCaleb Connolly dev_dbg(chip->dev, "channel '%s' is not ready\n", 550*72c7df85SCaleb Connolly iio_chan->extend_name); 551*72c7df85SCaleb Connolly ret = -ENODATA; 552*72c7df85SCaleb Connolly goto unlock_out; 553*72c7df85SCaleb Connolly } 554*72c7df85SCaleb Connolly break; 555*72c7df85SCaleb Connolly } 556*72c7df85SCaleb Connolly 557*72c7df85SCaleb Connolly ret = rradc_read(chip, chan->lsb, buf, chan->size); 558*72c7df85SCaleb Connolly if (ret) { 559*72c7df85SCaleb Connolly dev_err(chip->dev, "read data failed\n"); 560*72c7df85SCaleb Connolly goto unlock_out; 561*72c7df85SCaleb Connolly } 562*72c7df85SCaleb Connolly 563*72c7df85SCaleb Connolly /* 564*72c7df85SCaleb Connolly * For the battery ID we read the register for every ID ADC and then 565*72c7df85SCaleb Connolly * see which one is actually connected. 566*72c7df85SCaleb Connolly */ 567*72c7df85SCaleb Connolly if (chan_address == RR_ADC_BATT_ID) { 568*72c7df85SCaleb Connolly u16 batt_id_150 = le16_to_cpu(buf[2]); 569*72c7df85SCaleb Connolly u16 batt_id_15 = le16_to_cpu(buf[1]); 570*72c7df85SCaleb Connolly u16 batt_id_5 = le16_to_cpu(buf[0]); 571*72c7df85SCaleb Connolly 572*72c7df85SCaleb Connolly if (!batt_id_150 && !batt_id_15 && !batt_id_5) { 573*72c7df85SCaleb Connolly dev_err(chip->dev, 574*72c7df85SCaleb Connolly "Invalid batt_id values with all zeros\n"); 575*72c7df85SCaleb Connolly ret = -EINVAL; 576*72c7df85SCaleb Connolly goto unlock_out; 577*72c7df85SCaleb Connolly } 578*72c7df85SCaleb Connolly 579*72c7df85SCaleb Connolly if (batt_id_150 <= RR_ADC_BATT_ID_RANGE) { 580*72c7df85SCaleb Connolly *data = batt_id_150; 581*72c7df85SCaleb Connolly chip->batt_id_data = 150; 582*72c7df85SCaleb Connolly } else if (batt_id_15 <= RR_ADC_BATT_ID_RANGE) { 583*72c7df85SCaleb Connolly *data = batt_id_15; 584*72c7df85SCaleb Connolly chip->batt_id_data = 15; 585*72c7df85SCaleb Connolly } else { 586*72c7df85SCaleb Connolly *data = batt_id_5; 587*72c7df85SCaleb Connolly chip->batt_id_data = 5; 588*72c7df85SCaleb Connolly } 589*72c7df85SCaleb Connolly } else { 590*72c7df85SCaleb Connolly /* 591*72c7df85SCaleb Connolly * All of the other channels are either 1 or 2 bytes. 592*72c7df85SCaleb Connolly * We can rely on the second byte being 0 for 1-byte channels. 593*72c7df85SCaleb Connolly */ 594*72c7df85SCaleb Connolly *data = le16_to_cpu(buf[0]); 595*72c7df85SCaleb Connolly } 596*72c7df85SCaleb Connolly 597*72c7df85SCaleb Connolly unlock_out: 598*72c7df85SCaleb Connolly mutex_unlock(&chip->conversion_lock); 599*72c7df85SCaleb Connolly 600*72c7df85SCaleb Connolly return ret; 601*72c7df85SCaleb Connolly } 602*72c7df85SCaleb Connolly 603*72c7df85SCaleb Connolly static int rradc_read_scale(struct rradc_chip *chip, int chan_address, int *val, 604*72c7df85SCaleb Connolly int *val2) 605*72c7df85SCaleb Connolly { 606*72c7df85SCaleb Connolly int64_t fab_offset, fab_slope; 607*72c7df85SCaleb Connolly int ret; 608*72c7df85SCaleb Connolly 609*72c7df85SCaleb Connolly ret = rradc_get_fab_coeff(chip, &fab_offset, &fab_slope); 610*72c7df85SCaleb Connolly if (ret < 0) { 611*72c7df85SCaleb Connolly dev_err(chip->dev, "Unable to get fab id coefficients\n"); 612*72c7df85SCaleb Connolly return -EINVAL; 613*72c7df85SCaleb Connolly } 614*72c7df85SCaleb Connolly 615*72c7df85SCaleb Connolly switch (chan_address) { 616*72c7df85SCaleb Connolly case RR_ADC_SKIN_TEMP: 617*72c7df85SCaleb Connolly *val = MILLI; 618*72c7df85SCaleb Connolly *val2 = RR_ADC_BATT_THERM_LSB_K; 619*72c7df85SCaleb Connolly return IIO_VAL_FRACTIONAL; 620*72c7df85SCaleb Connolly case RR_ADC_USBIN_I: 621*72c7df85SCaleb Connolly *val = RR_ADC_CURR_USBIN_INPUT_FACTOR_MIL * 622*72c7df85SCaleb Connolly RR_ADC_FS_VOLTAGE_MV; 623*72c7df85SCaleb Connolly *val2 = RR_ADC_CHAN_MSB; 624*72c7df85SCaleb Connolly return IIO_VAL_FRACTIONAL; 625*72c7df85SCaleb Connolly case RR_ADC_DCIN_I: 626*72c7df85SCaleb Connolly *val = RR_ADC_CURR_INPUT_FACTOR * RR_ADC_FS_VOLTAGE_MV; 627*72c7df85SCaleb Connolly *val2 = RR_ADC_CHAN_MSB; 628*72c7df85SCaleb Connolly return IIO_VAL_FRACTIONAL; 629*72c7df85SCaleb Connolly case RR_ADC_USBIN_V: 630*72c7df85SCaleb Connolly case RR_ADC_DCIN_V: 631*72c7df85SCaleb Connolly *val = RR_ADC_VOLT_INPUT_FACTOR * RR_ADC_FS_VOLTAGE_MV * MILLI; 632*72c7df85SCaleb Connolly *val2 = RR_ADC_CHAN_MSB; 633*72c7df85SCaleb Connolly return IIO_VAL_FRACTIONAL; 634*72c7df85SCaleb Connolly case RR_ADC_GPIO: 635*72c7df85SCaleb Connolly *val = RR_ADC_GPIO_FS_RANGE; 636*72c7df85SCaleb Connolly *val2 = RR_ADC_CHAN_MSB; 637*72c7df85SCaleb Connolly return IIO_VAL_FRACTIONAL; 638*72c7df85SCaleb Connolly case RR_ADC_CHG_TEMP: 639*72c7df85SCaleb Connolly /* 640*72c7df85SCaleb Connolly * We divide val2 by MILLI instead of multiplying val 641*72c7df85SCaleb Connolly * to avoid an integer overflow. 642*72c7df85SCaleb Connolly */ 643*72c7df85SCaleb Connolly *val = -RR_ADC_TEMP_FS_VOLTAGE_NUM; 644*72c7df85SCaleb Connolly *val2 = div64_s64(RR_ADC_TEMP_FS_VOLTAGE_DEN * RR_ADC_CHAN_MSB * 645*72c7df85SCaleb Connolly fab_slope, 646*72c7df85SCaleb Connolly MILLI); 647*72c7df85SCaleb Connolly 648*72c7df85SCaleb Connolly return IIO_VAL_FRACTIONAL; 649*72c7df85SCaleb Connolly case RR_ADC_DIE_TEMP: 650*72c7df85SCaleb Connolly *val = RR_ADC_TEMP_FS_VOLTAGE_NUM; 651*72c7df85SCaleb Connolly *val2 = RR_ADC_TEMP_FS_VOLTAGE_DEN * RR_ADC_CHAN_MSB * 652*72c7df85SCaleb Connolly RR_ADC_DIE_TEMP_SLOPE; 653*72c7df85SCaleb Connolly 654*72c7df85SCaleb Connolly return IIO_VAL_FRACTIONAL; 655*72c7df85SCaleb Connolly default: 656*72c7df85SCaleb Connolly return -EINVAL; 657*72c7df85SCaleb Connolly } 658*72c7df85SCaleb Connolly } 659*72c7df85SCaleb Connolly 660*72c7df85SCaleb Connolly static int rradc_read_offset(struct rradc_chip *chip, int chan_address, int *val) 661*72c7df85SCaleb Connolly { 662*72c7df85SCaleb Connolly int64_t fab_offset, fab_slope; 663*72c7df85SCaleb Connolly int64_t offset1, offset2; 664*72c7df85SCaleb Connolly int ret; 665*72c7df85SCaleb Connolly 666*72c7df85SCaleb Connolly switch (chan_address) { 667*72c7df85SCaleb Connolly case RR_ADC_SKIN_TEMP: 668*72c7df85SCaleb Connolly /* 669*72c7df85SCaleb Connolly * Offset from kelvin to degC, divided by the 670*72c7df85SCaleb Connolly * scale factor (250). We lose some precision here. 671*72c7df85SCaleb Connolly * 273150 / 250 = 1092.6 672*72c7df85SCaleb Connolly */ 673*72c7df85SCaleb Connolly *val = div64_s64(ABSOLUTE_ZERO_MILLICELSIUS, 674*72c7df85SCaleb Connolly (MILLI / RR_ADC_BATT_THERM_LSB_K)); 675*72c7df85SCaleb Connolly return IIO_VAL_INT; 676*72c7df85SCaleb Connolly case RR_ADC_CHG_TEMP: 677*72c7df85SCaleb Connolly ret = rradc_get_fab_coeff(chip, &fab_offset, &fab_slope); 678*72c7df85SCaleb Connolly if (ret < 0) { 679*72c7df85SCaleb Connolly dev_err(chip->dev, 680*72c7df85SCaleb Connolly "Unable to get fab id coefficients\n"); 681*72c7df85SCaleb Connolly return -EINVAL; 682*72c7df85SCaleb Connolly } 683*72c7df85SCaleb Connolly offset1 = -(fab_offset * RR_ADC_TEMP_FS_VOLTAGE_DEN * 684*72c7df85SCaleb Connolly RR_ADC_CHAN_MSB); 685*72c7df85SCaleb Connolly offset1 += (int64_t)RR_ADC_TEMP_FS_VOLTAGE_NUM / 2ULL; 686*72c7df85SCaleb Connolly offset1 = div64_s64(offset1, 687*72c7df85SCaleb Connolly (int64_t)(RR_ADC_TEMP_FS_VOLTAGE_NUM)); 688*72c7df85SCaleb Connolly 689*72c7df85SCaleb Connolly offset2 = (int64_t)RR_ADC_CHG_TEMP_OFFSET_MILLI_DEGC * 690*72c7df85SCaleb Connolly RR_ADC_TEMP_FS_VOLTAGE_DEN * RR_ADC_CHAN_MSB * 691*72c7df85SCaleb Connolly (int64_t)fab_slope; 692*72c7df85SCaleb Connolly offset2 += ((int64_t)MILLI * RR_ADC_TEMP_FS_VOLTAGE_NUM) / 2; 693*72c7df85SCaleb Connolly offset2 = div64_s64( 694*72c7df85SCaleb Connolly offset2, ((int64_t)MILLI * RR_ADC_TEMP_FS_VOLTAGE_NUM)); 695*72c7df85SCaleb Connolly 696*72c7df85SCaleb Connolly /* 697*72c7df85SCaleb Connolly * The -1 is to compensate for lost precision. 698*72c7df85SCaleb Connolly * It should actually be -0.7906976744186046. 699*72c7df85SCaleb Connolly * This works out to every value being off 700*72c7df85SCaleb Connolly * by about +0.091 degrees C after applying offset and scale. 701*72c7df85SCaleb Connolly */ 702*72c7df85SCaleb Connolly *val = (int)(offset1 - offset2 - 1); 703*72c7df85SCaleb Connolly return IIO_VAL_INT; 704*72c7df85SCaleb Connolly case RR_ADC_DIE_TEMP: 705*72c7df85SCaleb Connolly offset1 = -RR_ADC_DIE_TEMP_OFFSET * 706*72c7df85SCaleb Connolly (int64_t)RR_ADC_TEMP_FS_VOLTAGE_DEN * 707*72c7df85SCaleb Connolly (int64_t)RR_ADC_CHAN_MSB; 708*72c7df85SCaleb Connolly offset1 = div64_s64(offset1, RR_ADC_TEMP_FS_VOLTAGE_NUM); 709*72c7df85SCaleb Connolly 710*72c7df85SCaleb Connolly offset2 = -(int64_t)RR_ADC_CHG_TEMP_OFFSET_MILLI_DEGC * 711*72c7df85SCaleb Connolly RR_ADC_TEMP_FS_VOLTAGE_DEN * RR_ADC_CHAN_MSB * 712*72c7df85SCaleb Connolly RR_ADC_DIE_TEMP_SLOPE; 713*72c7df85SCaleb Connolly offset2 = div64_s64(offset2, 714*72c7df85SCaleb Connolly ((int64_t)RR_ADC_TEMP_FS_VOLTAGE_NUM)); 715*72c7df85SCaleb Connolly 716*72c7df85SCaleb Connolly /* 717*72c7df85SCaleb Connolly * The result is -339, it should be -338.69789, this results 718*72c7df85SCaleb Connolly * in the calculated die temp being off by 719*72c7df85SCaleb Connolly * -0.004 - -0.0175 degrees C 720*72c7df85SCaleb Connolly */ 721*72c7df85SCaleb Connolly *val = (int)(offset1 - offset2); 722*72c7df85SCaleb Connolly return IIO_VAL_INT; 723*72c7df85SCaleb Connolly default: 724*72c7df85SCaleb Connolly break; 725*72c7df85SCaleb Connolly } 726*72c7df85SCaleb Connolly return -EINVAL; 727*72c7df85SCaleb Connolly } 728*72c7df85SCaleb Connolly 729*72c7df85SCaleb Connolly static int rradc_read_raw(struct iio_dev *indio_dev, 730*72c7df85SCaleb Connolly struct iio_chan_spec const *chan_spec, int *val, 731*72c7df85SCaleb Connolly int *val2, long mask) 732*72c7df85SCaleb Connolly { 733*72c7df85SCaleb Connolly struct rradc_chip *chip = iio_priv(indio_dev); 734*72c7df85SCaleb Connolly const struct rradc_channel *chan; 735*72c7df85SCaleb Connolly int ret; 736*72c7df85SCaleb Connolly u16 adc_code; 737*72c7df85SCaleb Connolly 738*72c7df85SCaleb Connolly if (chan_spec->address >= RR_ADC_CHAN_MAX) { 739*72c7df85SCaleb Connolly dev_err(chip->dev, "Invalid channel index:%lu\n", 740*72c7df85SCaleb Connolly chan_spec->address); 741*72c7df85SCaleb Connolly return -EINVAL; 742*72c7df85SCaleb Connolly } 743*72c7df85SCaleb Connolly 744*72c7df85SCaleb Connolly switch (mask) { 745*72c7df85SCaleb Connolly case IIO_CHAN_INFO_SCALE: 746*72c7df85SCaleb Connolly return rradc_read_scale(chip, chan_spec->address, val, val2); 747*72c7df85SCaleb Connolly case IIO_CHAN_INFO_OFFSET: 748*72c7df85SCaleb Connolly return rradc_read_offset(chip, chan_spec->address, val); 749*72c7df85SCaleb Connolly case IIO_CHAN_INFO_RAW: 750*72c7df85SCaleb Connolly ret = rradc_do_conversion(chip, chan_spec->address, &adc_code); 751*72c7df85SCaleb Connolly if (ret < 0) 752*72c7df85SCaleb Connolly return ret; 753*72c7df85SCaleb Connolly 754*72c7df85SCaleb Connolly *val = adc_code; 755*72c7df85SCaleb Connolly return IIO_VAL_INT; 756*72c7df85SCaleb Connolly case IIO_CHAN_INFO_PROCESSED: 757*72c7df85SCaleb Connolly chan = &rradc_chans[chan_spec->address]; 758*72c7df85SCaleb Connolly if (!chan->scale_fn) 759*72c7df85SCaleb Connolly return -EINVAL; 760*72c7df85SCaleb Connolly ret = rradc_do_conversion(chip, chan_spec->address, &adc_code); 761*72c7df85SCaleb Connolly if (ret < 0) 762*72c7df85SCaleb Connolly return ret; 763*72c7df85SCaleb Connolly 764*72c7df85SCaleb Connolly *val = chan->scale_fn(chip, adc_code, val); 765*72c7df85SCaleb Connolly return IIO_VAL_INT; 766*72c7df85SCaleb Connolly default: 767*72c7df85SCaleb Connolly return -EINVAL; 768*72c7df85SCaleb Connolly } 769*72c7df85SCaleb Connolly } 770*72c7df85SCaleb Connolly 771*72c7df85SCaleb Connolly static int rradc_read_label(struct iio_dev *indio_dev, 772*72c7df85SCaleb Connolly struct iio_chan_spec const *chan, char *label) 773*72c7df85SCaleb Connolly { 774*72c7df85SCaleb Connolly return snprintf(label, PAGE_SIZE, "%s\n", 775*72c7df85SCaleb Connolly rradc_chans[chan->address].label); 776*72c7df85SCaleb Connolly } 777*72c7df85SCaleb Connolly 778*72c7df85SCaleb Connolly static const struct iio_info rradc_info = { 779*72c7df85SCaleb Connolly .read_raw = rradc_read_raw, 780*72c7df85SCaleb Connolly .read_label = rradc_read_label, 781*72c7df85SCaleb Connolly }; 782*72c7df85SCaleb Connolly 783*72c7df85SCaleb Connolly static const struct rradc_channel rradc_chans[RR_ADC_CHAN_MAX] = { 784*72c7df85SCaleb Connolly { 785*72c7df85SCaleb Connolly .label = "batt_id", 786*72c7df85SCaleb Connolly .scale_fn = rradc_post_process_batt_id, 787*72c7df85SCaleb Connolly .lsb = RR_ADC_BATT_ID_5_LSB, 788*72c7df85SCaleb Connolly .status = RR_ADC_BATT_ID_STS, 789*72c7df85SCaleb Connolly .size = 6, 790*72c7df85SCaleb Connolly .trigger_addr = RR_ADC_BATT_ID_TRIGGER, 791*72c7df85SCaleb Connolly .trigger_mask = BIT(0), 792*72c7df85SCaleb Connolly }, { 793*72c7df85SCaleb Connolly .label = "batt", 794*72c7df85SCaleb Connolly .lsb = RR_ADC_BATT_THERM_LSB, 795*72c7df85SCaleb Connolly .status = RR_ADC_BATT_THERM_STS, 796*72c7df85SCaleb Connolly .size = 2, 797*72c7df85SCaleb Connolly .trigger_addr = RR_ADC_BATT_THERM_TRIGGER, 798*72c7df85SCaleb Connolly }, { 799*72c7df85SCaleb Connolly .label = "pmi8998_skin", 800*72c7df85SCaleb Connolly .lsb = RR_ADC_SKIN_TEMP_LSB, 801*72c7df85SCaleb Connolly .status = RR_ADC_AUX_THERM_STS, 802*72c7df85SCaleb Connolly .size = 2, 803*72c7df85SCaleb Connolly .trigger_addr = RR_ADC_AUX_THERM_TRIGGER, 804*72c7df85SCaleb Connolly }, { 805*72c7df85SCaleb Connolly .label = "usbin_i", 806*72c7df85SCaleb Connolly .lsb = RR_ADC_USB_IN_I_LSB, 807*72c7df85SCaleb Connolly .status = RR_ADC_USB_IN_I_STS, 808*72c7df85SCaleb Connolly .size = 2, 809*72c7df85SCaleb Connolly .trigger_addr = RR_ADC_USB_IN_I_TRIGGER, 810*72c7df85SCaleb Connolly }, { 811*72c7df85SCaleb Connolly .label = "usbin_v", 812*72c7df85SCaleb Connolly .lsb = RR_ADC_USB_IN_V_LSB, 813*72c7df85SCaleb Connolly .status = RR_ADC_USB_IN_V_STS, 814*72c7df85SCaleb Connolly .size = 2, 815*72c7df85SCaleb Connolly .trigger_addr = RR_ADC_USB_IN_V_TRIGGER, 816*72c7df85SCaleb Connolly .trigger_mask = BIT(7), 817*72c7df85SCaleb Connolly }, { 818*72c7df85SCaleb Connolly .label = "dcin_i", 819*72c7df85SCaleb Connolly .lsb = RR_ADC_DC_IN_I_LSB, 820*72c7df85SCaleb Connolly .status = RR_ADC_DC_IN_I_STS, 821*72c7df85SCaleb Connolly .size = 2, 822*72c7df85SCaleb Connolly .trigger_addr = RR_ADC_DC_IN_I_TRIGGER, 823*72c7df85SCaleb Connolly }, { 824*72c7df85SCaleb Connolly .label = "dcin_v", 825*72c7df85SCaleb Connolly .lsb = RR_ADC_DC_IN_V_LSB, 826*72c7df85SCaleb Connolly .status = RR_ADC_DC_IN_V_STS, 827*72c7df85SCaleb Connolly .size = 2, 828*72c7df85SCaleb Connolly .trigger_addr = RR_ADC_DC_IN_V_TRIGGER, 829*72c7df85SCaleb Connolly }, { 830*72c7df85SCaleb Connolly .label = "pmi8998_die", 831*72c7df85SCaleb Connolly .lsb = RR_ADC_PMI_DIE_TEMP_LSB, 832*72c7df85SCaleb Connolly .status = RR_ADC_PMI_DIE_TEMP_STS, 833*72c7df85SCaleb Connolly .size = 2, 834*72c7df85SCaleb Connolly .trigger_addr = RR_ADC_PMI_DIE_TEMP_TRIGGER, 835*72c7df85SCaleb Connolly .trigger_mask = RR_ADC_TRIGGER_EVERY_CYCLE, 836*72c7df85SCaleb Connolly }, { 837*72c7df85SCaleb Connolly .label = "chg", 838*72c7df85SCaleb Connolly .lsb = RR_ADC_CHARGER_TEMP_LSB, 839*72c7df85SCaleb Connolly .status = RR_ADC_CHARGER_TEMP_STS, 840*72c7df85SCaleb Connolly .size = 2, 841*72c7df85SCaleb Connolly .trigger_addr = RR_ADC_CHARGER_TEMP_TRIGGER, 842*72c7df85SCaleb Connolly }, { 843*72c7df85SCaleb Connolly .label = "gpio", 844*72c7df85SCaleb Connolly .lsb = RR_ADC_GPIO_LSB, 845*72c7df85SCaleb Connolly .status = RR_ADC_GPIO_STS, 846*72c7df85SCaleb Connolly .size = 2, 847*72c7df85SCaleb Connolly .trigger_addr = RR_ADC_GPIO_TRIGGER, 848*72c7df85SCaleb Connolly }, 849*72c7df85SCaleb Connolly }; 850*72c7df85SCaleb Connolly 851*72c7df85SCaleb Connolly static const struct iio_chan_spec rradc_iio_chans[RR_ADC_CHAN_MAX] = { 852*72c7df85SCaleb Connolly { 853*72c7df85SCaleb Connolly .type = IIO_RESISTANCE, 854*72c7df85SCaleb Connolly .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), 855*72c7df85SCaleb Connolly .address = RR_ADC_BATT_ID, 856*72c7df85SCaleb Connolly .channel = 0, 857*72c7df85SCaleb Connolly .indexed = 1, 858*72c7df85SCaleb Connolly }, { 859*72c7df85SCaleb Connolly .type = IIO_TEMP, 860*72c7df85SCaleb Connolly .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), 861*72c7df85SCaleb Connolly .address = RR_ADC_BATT_THERM, 862*72c7df85SCaleb Connolly .channel = 0, 863*72c7df85SCaleb Connolly .indexed = 1, 864*72c7df85SCaleb Connolly }, { 865*72c7df85SCaleb Connolly .type = IIO_TEMP, 866*72c7df85SCaleb Connolly .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | 867*72c7df85SCaleb Connolly BIT(IIO_CHAN_INFO_SCALE) | 868*72c7df85SCaleb Connolly BIT(IIO_CHAN_INFO_OFFSET), 869*72c7df85SCaleb Connolly .address = RR_ADC_SKIN_TEMP, 870*72c7df85SCaleb Connolly .channel = 1, 871*72c7df85SCaleb Connolly .indexed = 1, 872*72c7df85SCaleb Connolly }, { 873*72c7df85SCaleb Connolly .type = IIO_CURRENT, 874*72c7df85SCaleb Connolly .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | 875*72c7df85SCaleb Connolly BIT(IIO_CHAN_INFO_SCALE), 876*72c7df85SCaleb Connolly .address = RR_ADC_USBIN_I, 877*72c7df85SCaleb Connolly .channel = 0, 878*72c7df85SCaleb Connolly .indexed = 1, 879*72c7df85SCaleb Connolly }, { 880*72c7df85SCaleb Connolly .type = IIO_VOLTAGE, 881*72c7df85SCaleb Connolly .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | 882*72c7df85SCaleb Connolly BIT(IIO_CHAN_INFO_SCALE), 883*72c7df85SCaleb Connolly .address = RR_ADC_USBIN_V, 884*72c7df85SCaleb Connolly .channel = 0, 885*72c7df85SCaleb Connolly .indexed = 1, 886*72c7df85SCaleb Connolly }, { 887*72c7df85SCaleb Connolly .type = IIO_CURRENT, 888*72c7df85SCaleb Connolly .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | 889*72c7df85SCaleb Connolly BIT(IIO_CHAN_INFO_SCALE), 890*72c7df85SCaleb Connolly .address = RR_ADC_DCIN_I, 891*72c7df85SCaleb Connolly .channel = 1, 892*72c7df85SCaleb Connolly .indexed = 1, 893*72c7df85SCaleb Connolly }, { 894*72c7df85SCaleb Connolly .type = IIO_VOLTAGE, 895*72c7df85SCaleb Connolly .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | 896*72c7df85SCaleb Connolly BIT(IIO_CHAN_INFO_SCALE), 897*72c7df85SCaleb Connolly .address = RR_ADC_DCIN_V, 898*72c7df85SCaleb Connolly .channel = 1, 899*72c7df85SCaleb Connolly .indexed = 1, 900*72c7df85SCaleb Connolly }, { 901*72c7df85SCaleb Connolly .type = IIO_TEMP, 902*72c7df85SCaleb Connolly .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | 903*72c7df85SCaleb Connolly BIT(IIO_CHAN_INFO_SCALE) | 904*72c7df85SCaleb Connolly BIT(IIO_CHAN_INFO_OFFSET), 905*72c7df85SCaleb Connolly .address = RR_ADC_DIE_TEMP, 906*72c7df85SCaleb Connolly .channel = 2, 907*72c7df85SCaleb Connolly .indexed = 1, 908*72c7df85SCaleb Connolly }, { 909*72c7df85SCaleb Connolly .type = IIO_TEMP, 910*72c7df85SCaleb Connolly .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | 911*72c7df85SCaleb Connolly BIT(IIO_CHAN_INFO_OFFSET) | 912*72c7df85SCaleb Connolly BIT(IIO_CHAN_INFO_SCALE), 913*72c7df85SCaleb Connolly .address = RR_ADC_CHG_TEMP, 914*72c7df85SCaleb Connolly .channel = 3, 915*72c7df85SCaleb Connolly .indexed = 1, 916*72c7df85SCaleb Connolly }, { 917*72c7df85SCaleb Connolly .type = IIO_VOLTAGE, 918*72c7df85SCaleb Connolly .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) | 919*72c7df85SCaleb Connolly BIT(IIO_CHAN_INFO_SCALE), 920*72c7df85SCaleb Connolly .address = RR_ADC_GPIO, 921*72c7df85SCaleb Connolly .channel = 2, 922*72c7df85SCaleb Connolly .indexed = 1, 923*72c7df85SCaleb Connolly }, 924*72c7df85SCaleb Connolly }; 925*72c7df85SCaleb Connolly 926*72c7df85SCaleb Connolly static int rradc_probe(struct platform_device *pdev) 927*72c7df85SCaleb Connolly { 928*72c7df85SCaleb Connolly struct device *dev = &pdev->dev; 929*72c7df85SCaleb Connolly struct iio_dev *indio_dev; 930*72c7df85SCaleb Connolly struct rradc_chip *chip; 931*72c7df85SCaleb Connolly int ret, i, batt_id_delay; 932*72c7df85SCaleb Connolly 933*72c7df85SCaleb Connolly indio_dev = devm_iio_device_alloc(dev, sizeof(*chip)); 934*72c7df85SCaleb Connolly if (!indio_dev) 935*72c7df85SCaleb Connolly return -ENOMEM; 936*72c7df85SCaleb Connolly 937*72c7df85SCaleb Connolly chip = iio_priv(indio_dev); 938*72c7df85SCaleb Connolly chip->regmap = dev_get_regmap(pdev->dev.parent, NULL); 939*72c7df85SCaleb Connolly if (!chip->regmap) { 940*72c7df85SCaleb Connolly dev_err(dev, "Couldn't get parent's regmap\n"); 941*72c7df85SCaleb Connolly return -EINVAL; 942*72c7df85SCaleb Connolly } 943*72c7df85SCaleb Connolly 944*72c7df85SCaleb Connolly chip->dev = dev; 945*72c7df85SCaleb Connolly mutex_init(&chip->conversion_lock); 946*72c7df85SCaleb Connolly 947*72c7df85SCaleb Connolly ret = device_property_read_u32(dev, "reg", &chip->base); 948*72c7df85SCaleb Connolly if (ret < 0) { 949*72c7df85SCaleb Connolly dev_err(chip->dev, "Couldn't find reg address, ret = %d\n", 950*72c7df85SCaleb Connolly ret); 951*72c7df85SCaleb Connolly return ret; 952*72c7df85SCaleb Connolly } 953*72c7df85SCaleb Connolly 954*72c7df85SCaleb Connolly batt_id_delay = -1; 955*72c7df85SCaleb Connolly ret = device_property_read_u32(dev, "qcom,batt-id-delay-ms", 956*72c7df85SCaleb Connolly &batt_id_delay); 957*72c7df85SCaleb Connolly if (!ret) { 958*72c7df85SCaleb Connolly for (i = 0; i < RRADC_BATT_ID_DELAY_MAX; i++) { 959*72c7df85SCaleb Connolly if (batt_id_delay == batt_id_delays[i]) 960*72c7df85SCaleb Connolly break; 961*72c7df85SCaleb Connolly } 962*72c7df85SCaleb Connolly if (i == RRADC_BATT_ID_DELAY_MAX) 963*72c7df85SCaleb Connolly batt_id_delay = -1; 964*72c7df85SCaleb Connolly } 965*72c7df85SCaleb Connolly 966*72c7df85SCaleb Connolly if (batt_id_delay >= 0) { 967*72c7df85SCaleb Connolly batt_id_delay = FIELD_PREP(BATT_ID_SETTLE_MASK, batt_id_delay); 968*72c7df85SCaleb Connolly ret = regmap_update_bits(chip->regmap, 969*72c7df85SCaleb Connolly chip->base + RR_ADC_BATT_ID_CFG, 970*72c7df85SCaleb Connolly batt_id_delay, batt_id_delay); 971*72c7df85SCaleb Connolly if (ret < 0) { 972*72c7df85SCaleb Connolly dev_err(chip->dev, 973*72c7df85SCaleb Connolly "BATT_ID settling time config failed:%d\n", 974*72c7df85SCaleb Connolly ret); 975*72c7df85SCaleb Connolly } 976*72c7df85SCaleb Connolly } 977*72c7df85SCaleb Connolly 978*72c7df85SCaleb Connolly /* Get the PMIC revision, we need it to handle some varying coefficients */ 979*72c7df85SCaleb Connolly chip->pmic = qcom_pmic_get(chip->dev); 980*72c7df85SCaleb Connolly if (IS_ERR(chip->pmic)) { 981*72c7df85SCaleb Connolly dev_err(chip->dev, "Unable to get reference to PMIC device\n"); 982*72c7df85SCaleb Connolly return PTR_ERR(chip->pmic); 983*72c7df85SCaleb Connolly } 984*72c7df85SCaleb Connolly 985*72c7df85SCaleb Connolly switch (chip->pmic->subtype) { 986*72c7df85SCaleb Connolly case PMI8998_SUBTYPE: 987*72c7df85SCaleb Connolly indio_dev->name = "pmi8998-rradc"; 988*72c7df85SCaleb Connolly break; 989*72c7df85SCaleb Connolly case PM660_SUBTYPE: 990*72c7df85SCaleb Connolly indio_dev->name = "pm660-rradc"; 991*72c7df85SCaleb Connolly break; 992*72c7df85SCaleb Connolly default: 993*72c7df85SCaleb Connolly indio_dev->name = DRIVER_NAME; 994*72c7df85SCaleb Connolly break; 995*72c7df85SCaleb Connolly } 996*72c7df85SCaleb Connolly indio_dev->modes = INDIO_DIRECT_MODE; 997*72c7df85SCaleb Connolly indio_dev->info = &rradc_info; 998*72c7df85SCaleb Connolly indio_dev->channels = rradc_iio_chans; 999*72c7df85SCaleb Connolly indio_dev->num_channels = ARRAY_SIZE(rradc_iio_chans); 1000*72c7df85SCaleb Connolly 1001*72c7df85SCaleb Connolly return devm_iio_device_register(dev, indio_dev); 1002*72c7df85SCaleb Connolly } 1003*72c7df85SCaleb Connolly 1004*72c7df85SCaleb Connolly static const struct of_device_id rradc_match_table[] = { 1005*72c7df85SCaleb Connolly { .compatible = "qcom,pm660-rradc" }, 1006*72c7df85SCaleb Connolly { .compatible = "qcom,pmi8998-rradc" }, 1007*72c7df85SCaleb Connolly {} 1008*72c7df85SCaleb Connolly }; 1009*72c7df85SCaleb Connolly MODULE_DEVICE_TABLE(of, rradc_match_table); 1010*72c7df85SCaleb Connolly 1011*72c7df85SCaleb Connolly static struct platform_driver rradc_driver = { 1012*72c7df85SCaleb Connolly .driver = { 1013*72c7df85SCaleb Connolly .name = DRIVER_NAME, 1014*72c7df85SCaleb Connolly .of_match_table = rradc_match_table, 1015*72c7df85SCaleb Connolly }, 1016*72c7df85SCaleb Connolly .probe = rradc_probe, 1017*72c7df85SCaleb Connolly }; 1018*72c7df85SCaleb Connolly module_platform_driver(rradc_driver); 1019*72c7df85SCaleb Connolly 1020*72c7df85SCaleb Connolly MODULE_DESCRIPTION("QCOM SPMI PMIC RR ADC driver"); 1021*72c7df85SCaleb Connolly MODULE_AUTHOR("Caleb Connolly <caleb.connolly@linaro.org>"); 1022*72c7df85SCaleb Connolly MODULE_LICENSE("GPL"); 1023