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