xref: /OK3568_Linux_fs/kernel/drivers/iio/adc/sc27xx_adc.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun // Copyright (C) 2018 Spreadtrum Communications Inc.
3*4882a593Smuzhiyun 
4*4882a593Smuzhiyun #include <linux/hwspinlock.h>
5*4882a593Smuzhiyun #include <linux/iio/iio.h>
6*4882a593Smuzhiyun #include <linux/module.h>
7*4882a593Smuzhiyun #include <linux/nvmem-consumer.h>
8*4882a593Smuzhiyun #include <linux/of.h>
9*4882a593Smuzhiyun #include <linux/of_device.h>
10*4882a593Smuzhiyun #include <linux/platform_device.h>
11*4882a593Smuzhiyun #include <linux/regmap.h>
12*4882a593Smuzhiyun #include <linux/slab.h>
13*4882a593Smuzhiyun 
14*4882a593Smuzhiyun /* PMIC global registers definition */
15*4882a593Smuzhiyun #define SC27XX_MODULE_EN		0xc08
16*4882a593Smuzhiyun #define SC27XX_MODULE_ADC_EN		BIT(5)
17*4882a593Smuzhiyun #define SC27XX_ARM_CLK_EN		0xc10
18*4882a593Smuzhiyun #define SC27XX_CLK_ADC_EN		BIT(5)
19*4882a593Smuzhiyun #define SC27XX_CLK_ADC_CLK_EN		BIT(6)
20*4882a593Smuzhiyun 
21*4882a593Smuzhiyun /* ADC controller registers definition */
22*4882a593Smuzhiyun #define SC27XX_ADC_CTL			0x0
23*4882a593Smuzhiyun #define SC27XX_ADC_CH_CFG		0x4
24*4882a593Smuzhiyun #define SC27XX_ADC_DATA			0x4c
25*4882a593Smuzhiyun #define SC27XX_ADC_INT_EN		0x50
26*4882a593Smuzhiyun #define SC27XX_ADC_INT_CLR		0x54
27*4882a593Smuzhiyun #define SC27XX_ADC_INT_STS		0x58
28*4882a593Smuzhiyun #define SC27XX_ADC_INT_RAW		0x5c
29*4882a593Smuzhiyun 
30*4882a593Smuzhiyun /* Bits and mask definition for SC27XX_ADC_CTL register */
31*4882a593Smuzhiyun #define SC27XX_ADC_EN			BIT(0)
32*4882a593Smuzhiyun #define SC27XX_ADC_CHN_RUN		BIT(1)
33*4882a593Smuzhiyun #define SC27XX_ADC_12BIT_MODE		BIT(2)
34*4882a593Smuzhiyun #define SC27XX_ADC_RUN_NUM_MASK		GENMASK(7, 4)
35*4882a593Smuzhiyun #define SC27XX_ADC_RUN_NUM_SHIFT	4
36*4882a593Smuzhiyun 
37*4882a593Smuzhiyun /* Bits and mask definition for SC27XX_ADC_CH_CFG register */
38*4882a593Smuzhiyun #define SC27XX_ADC_CHN_ID_MASK		GENMASK(4, 0)
39*4882a593Smuzhiyun #define SC27XX_ADC_SCALE_MASK		GENMASK(10, 9)
40*4882a593Smuzhiyun #define SC27XX_ADC_SCALE_SHIFT		9
41*4882a593Smuzhiyun 
42*4882a593Smuzhiyun /* Bits definitions for SC27XX_ADC_INT_EN registers */
43*4882a593Smuzhiyun #define SC27XX_ADC_IRQ_EN		BIT(0)
44*4882a593Smuzhiyun 
45*4882a593Smuzhiyun /* Bits definitions for SC27XX_ADC_INT_CLR registers */
46*4882a593Smuzhiyun #define SC27XX_ADC_IRQ_CLR		BIT(0)
47*4882a593Smuzhiyun 
48*4882a593Smuzhiyun /* Bits definitions for SC27XX_ADC_INT_RAW registers */
49*4882a593Smuzhiyun #define SC27XX_ADC_IRQ_RAW		BIT(0)
50*4882a593Smuzhiyun 
51*4882a593Smuzhiyun /* Mask definition for SC27XX_ADC_DATA register */
52*4882a593Smuzhiyun #define SC27XX_ADC_DATA_MASK		GENMASK(11, 0)
53*4882a593Smuzhiyun 
54*4882a593Smuzhiyun /* Timeout (ms) for the trylock of hardware spinlocks */
55*4882a593Smuzhiyun #define SC27XX_ADC_HWLOCK_TIMEOUT	5000
56*4882a593Smuzhiyun 
57*4882a593Smuzhiyun /* Timeout (us) for ADC data conversion according to ADC datasheet */
58*4882a593Smuzhiyun #define SC27XX_ADC_RDY_TIMEOUT		1000000
59*4882a593Smuzhiyun #define SC27XX_ADC_POLL_RAW_STATUS	500
60*4882a593Smuzhiyun 
61*4882a593Smuzhiyun /* Maximum ADC channel number */
62*4882a593Smuzhiyun #define SC27XX_ADC_CHANNEL_MAX		32
63*4882a593Smuzhiyun 
64*4882a593Smuzhiyun /* ADC voltage ratio definition */
65*4882a593Smuzhiyun #define SC27XX_VOLT_RATIO(n, d)		\
66*4882a593Smuzhiyun 	(((n) << SC27XX_RATIO_NUMERATOR_OFFSET) | (d))
67*4882a593Smuzhiyun #define SC27XX_RATIO_NUMERATOR_OFFSET	16
68*4882a593Smuzhiyun #define SC27XX_RATIO_DENOMINATOR_MASK	GENMASK(15, 0)
69*4882a593Smuzhiyun 
70*4882a593Smuzhiyun struct sc27xx_adc_data {
71*4882a593Smuzhiyun 	struct device *dev;
72*4882a593Smuzhiyun 	struct regmap *regmap;
73*4882a593Smuzhiyun 	/*
74*4882a593Smuzhiyun 	 * One hardware spinlock to synchronize between the multiple
75*4882a593Smuzhiyun 	 * subsystems which will access the unique ADC controller.
76*4882a593Smuzhiyun 	 */
77*4882a593Smuzhiyun 	struct hwspinlock *hwlock;
78*4882a593Smuzhiyun 	int channel_scale[SC27XX_ADC_CHANNEL_MAX];
79*4882a593Smuzhiyun 	u32 base;
80*4882a593Smuzhiyun 	int irq;
81*4882a593Smuzhiyun };
82*4882a593Smuzhiyun 
83*4882a593Smuzhiyun struct sc27xx_adc_linear_graph {
84*4882a593Smuzhiyun 	int volt0;
85*4882a593Smuzhiyun 	int adc0;
86*4882a593Smuzhiyun 	int volt1;
87*4882a593Smuzhiyun 	int adc1;
88*4882a593Smuzhiyun };
89*4882a593Smuzhiyun 
90*4882a593Smuzhiyun /*
91*4882a593Smuzhiyun  * According to the datasheet, we can convert one ADC value to one voltage value
92*4882a593Smuzhiyun  * through 2 points in the linear graph. If the voltage is less than 1.2v, we
93*4882a593Smuzhiyun  * should use the small-scale graph, and if more than 1.2v, we should use the
94*4882a593Smuzhiyun  * big-scale graph.
95*4882a593Smuzhiyun  */
96*4882a593Smuzhiyun static struct sc27xx_adc_linear_graph big_scale_graph = {
97*4882a593Smuzhiyun 	4200, 3310,
98*4882a593Smuzhiyun 	3600, 2832,
99*4882a593Smuzhiyun };
100*4882a593Smuzhiyun 
101*4882a593Smuzhiyun static struct sc27xx_adc_linear_graph small_scale_graph = {
102*4882a593Smuzhiyun 	1000, 3413,
103*4882a593Smuzhiyun 	100, 341,
104*4882a593Smuzhiyun };
105*4882a593Smuzhiyun 
106*4882a593Smuzhiyun static const struct sc27xx_adc_linear_graph sc2731_big_scale_graph_calib = {
107*4882a593Smuzhiyun 	4200, 850,
108*4882a593Smuzhiyun 	3600, 728,
109*4882a593Smuzhiyun };
110*4882a593Smuzhiyun 
111*4882a593Smuzhiyun static const struct sc27xx_adc_linear_graph sc2731_small_scale_graph_calib = {
112*4882a593Smuzhiyun 	1000, 838,
113*4882a593Smuzhiyun 	100, 84,
114*4882a593Smuzhiyun };
115*4882a593Smuzhiyun 
sc27xx_adc_get_calib_data(u32 calib_data,int calib_adc)116*4882a593Smuzhiyun static int sc27xx_adc_get_calib_data(u32 calib_data, int calib_adc)
117*4882a593Smuzhiyun {
118*4882a593Smuzhiyun 	return ((calib_data & 0xff) + calib_adc - 128) * 4;
119*4882a593Smuzhiyun }
120*4882a593Smuzhiyun 
sc27xx_adc_scale_calibration(struct sc27xx_adc_data * data,bool big_scale)121*4882a593Smuzhiyun static int sc27xx_adc_scale_calibration(struct sc27xx_adc_data *data,
122*4882a593Smuzhiyun 					bool big_scale)
123*4882a593Smuzhiyun {
124*4882a593Smuzhiyun 	const struct sc27xx_adc_linear_graph *calib_graph;
125*4882a593Smuzhiyun 	struct sc27xx_adc_linear_graph *graph;
126*4882a593Smuzhiyun 	struct nvmem_cell *cell;
127*4882a593Smuzhiyun 	const char *cell_name;
128*4882a593Smuzhiyun 	u32 calib_data = 0;
129*4882a593Smuzhiyun 	void *buf;
130*4882a593Smuzhiyun 	size_t len;
131*4882a593Smuzhiyun 
132*4882a593Smuzhiyun 	if (big_scale) {
133*4882a593Smuzhiyun 		calib_graph = &sc2731_big_scale_graph_calib;
134*4882a593Smuzhiyun 		graph = &big_scale_graph;
135*4882a593Smuzhiyun 		cell_name = "big_scale_calib";
136*4882a593Smuzhiyun 	} else {
137*4882a593Smuzhiyun 		calib_graph = &sc2731_small_scale_graph_calib;
138*4882a593Smuzhiyun 		graph = &small_scale_graph;
139*4882a593Smuzhiyun 		cell_name = "small_scale_calib";
140*4882a593Smuzhiyun 	}
141*4882a593Smuzhiyun 
142*4882a593Smuzhiyun 	cell = nvmem_cell_get(data->dev, cell_name);
143*4882a593Smuzhiyun 	if (IS_ERR(cell))
144*4882a593Smuzhiyun 		return PTR_ERR(cell);
145*4882a593Smuzhiyun 
146*4882a593Smuzhiyun 	buf = nvmem_cell_read(cell, &len);
147*4882a593Smuzhiyun 	nvmem_cell_put(cell);
148*4882a593Smuzhiyun 
149*4882a593Smuzhiyun 	if (IS_ERR(buf))
150*4882a593Smuzhiyun 		return PTR_ERR(buf);
151*4882a593Smuzhiyun 
152*4882a593Smuzhiyun 	memcpy(&calib_data, buf, min(len, sizeof(u32)));
153*4882a593Smuzhiyun 
154*4882a593Smuzhiyun 	/* Only need to calibrate the adc values in the linear graph. */
155*4882a593Smuzhiyun 	graph->adc0 = sc27xx_adc_get_calib_data(calib_data, calib_graph->adc0);
156*4882a593Smuzhiyun 	graph->adc1 = sc27xx_adc_get_calib_data(calib_data >> 8,
157*4882a593Smuzhiyun 						calib_graph->adc1);
158*4882a593Smuzhiyun 
159*4882a593Smuzhiyun 	kfree(buf);
160*4882a593Smuzhiyun 	return 0;
161*4882a593Smuzhiyun }
162*4882a593Smuzhiyun 
sc27xx_adc_get_ratio(int channel,int scale)163*4882a593Smuzhiyun static int sc27xx_adc_get_ratio(int channel, int scale)
164*4882a593Smuzhiyun {
165*4882a593Smuzhiyun 	switch (channel) {
166*4882a593Smuzhiyun 	case 1:
167*4882a593Smuzhiyun 	case 2:
168*4882a593Smuzhiyun 	case 3:
169*4882a593Smuzhiyun 	case 4:
170*4882a593Smuzhiyun 		return scale ? SC27XX_VOLT_RATIO(400, 1025) :
171*4882a593Smuzhiyun 			SC27XX_VOLT_RATIO(1, 1);
172*4882a593Smuzhiyun 	case 5:
173*4882a593Smuzhiyun 		return SC27XX_VOLT_RATIO(7, 29);
174*4882a593Smuzhiyun 	case 6:
175*4882a593Smuzhiyun 		return SC27XX_VOLT_RATIO(375, 9000);
176*4882a593Smuzhiyun 	case 7:
177*4882a593Smuzhiyun 	case 8:
178*4882a593Smuzhiyun 		return scale ? SC27XX_VOLT_RATIO(100, 125) :
179*4882a593Smuzhiyun 			SC27XX_VOLT_RATIO(1, 1);
180*4882a593Smuzhiyun 	case 19:
181*4882a593Smuzhiyun 		return SC27XX_VOLT_RATIO(1, 3);
182*4882a593Smuzhiyun 	default:
183*4882a593Smuzhiyun 		return SC27XX_VOLT_RATIO(1, 1);
184*4882a593Smuzhiyun 	}
185*4882a593Smuzhiyun 	return SC27XX_VOLT_RATIO(1, 1);
186*4882a593Smuzhiyun }
187*4882a593Smuzhiyun 
sc27xx_adc_read(struct sc27xx_adc_data * data,int channel,int scale,int * val)188*4882a593Smuzhiyun static int sc27xx_adc_read(struct sc27xx_adc_data *data, int channel,
189*4882a593Smuzhiyun 			   int scale, int *val)
190*4882a593Smuzhiyun {
191*4882a593Smuzhiyun 	int ret;
192*4882a593Smuzhiyun 	u32 tmp, value, status;
193*4882a593Smuzhiyun 
194*4882a593Smuzhiyun 	ret = hwspin_lock_timeout_raw(data->hwlock, SC27XX_ADC_HWLOCK_TIMEOUT);
195*4882a593Smuzhiyun 	if (ret) {
196*4882a593Smuzhiyun 		dev_err(data->dev, "timeout to get the hwspinlock\n");
197*4882a593Smuzhiyun 		return ret;
198*4882a593Smuzhiyun 	}
199*4882a593Smuzhiyun 
200*4882a593Smuzhiyun 	ret = regmap_update_bits(data->regmap, data->base + SC27XX_ADC_CTL,
201*4882a593Smuzhiyun 				 SC27XX_ADC_EN, SC27XX_ADC_EN);
202*4882a593Smuzhiyun 	if (ret)
203*4882a593Smuzhiyun 		goto unlock_adc;
204*4882a593Smuzhiyun 
205*4882a593Smuzhiyun 	ret = regmap_update_bits(data->regmap, data->base + SC27XX_ADC_INT_CLR,
206*4882a593Smuzhiyun 				 SC27XX_ADC_IRQ_CLR, SC27XX_ADC_IRQ_CLR);
207*4882a593Smuzhiyun 	if (ret)
208*4882a593Smuzhiyun 		goto disable_adc;
209*4882a593Smuzhiyun 
210*4882a593Smuzhiyun 	/* Configure the channel id and scale */
211*4882a593Smuzhiyun 	tmp = (scale << SC27XX_ADC_SCALE_SHIFT) & SC27XX_ADC_SCALE_MASK;
212*4882a593Smuzhiyun 	tmp |= channel & SC27XX_ADC_CHN_ID_MASK;
213*4882a593Smuzhiyun 	ret = regmap_update_bits(data->regmap, data->base + SC27XX_ADC_CH_CFG,
214*4882a593Smuzhiyun 				 SC27XX_ADC_CHN_ID_MASK | SC27XX_ADC_SCALE_MASK,
215*4882a593Smuzhiyun 				 tmp);
216*4882a593Smuzhiyun 	if (ret)
217*4882a593Smuzhiyun 		goto disable_adc;
218*4882a593Smuzhiyun 
219*4882a593Smuzhiyun 	/* Select 12bit conversion mode, and only sample 1 time */
220*4882a593Smuzhiyun 	tmp = SC27XX_ADC_12BIT_MODE;
221*4882a593Smuzhiyun 	tmp |= (0 << SC27XX_ADC_RUN_NUM_SHIFT) & SC27XX_ADC_RUN_NUM_MASK;
222*4882a593Smuzhiyun 	ret = regmap_update_bits(data->regmap, data->base + SC27XX_ADC_CTL,
223*4882a593Smuzhiyun 				 SC27XX_ADC_RUN_NUM_MASK | SC27XX_ADC_12BIT_MODE,
224*4882a593Smuzhiyun 				 tmp);
225*4882a593Smuzhiyun 	if (ret)
226*4882a593Smuzhiyun 		goto disable_adc;
227*4882a593Smuzhiyun 
228*4882a593Smuzhiyun 	ret = regmap_update_bits(data->regmap, data->base + SC27XX_ADC_CTL,
229*4882a593Smuzhiyun 				 SC27XX_ADC_CHN_RUN, SC27XX_ADC_CHN_RUN);
230*4882a593Smuzhiyun 	if (ret)
231*4882a593Smuzhiyun 		goto disable_adc;
232*4882a593Smuzhiyun 
233*4882a593Smuzhiyun 	ret = regmap_read_poll_timeout(data->regmap,
234*4882a593Smuzhiyun 				       data->base + SC27XX_ADC_INT_RAW,
235*4882a593Smuzhiyun 				       status, (status & SC27XX_ADC_IRQ_RAW),
236*4882a593Smuzhiyun 				       SC27XX_ADC_POLL_RAW_STATUS,
237*4882a593Smuzhiyun 				       SC27XX_ADC_RDY_TIMEOUT);
238*4882a593Smuzhiyun 	if (ret) {
239*4882a593Smuzhiyun 		dev_err(data->dev, "read adc timeout, status = 0x%x\n", status);
240*4882a593Smuzhiyun 		goto disable_adc;
241*4882a593Smuzhiyun 	}
242*4882a593Smuzhiyun 
243*4882a593Smuzhiyun 	ret = regmap_read(data->regmap, data->base + SC27XX_ADC_DATA, &value);
244*4882a593Smuzhiyun 	if (ret)
245*4882a593Smuzhiyun 		goto disable_adc;
246*4882a593Smuzhiyun 
247*4882a593Smuzhiyun 	value &= SC27XX_ADC_DATA_MASK;
248*4882a593Smuzhiyun 
249*4882a593Smuzhiyun disable_adc:
250*4882a593Smuzhiyun 	regmap_update_bits(data->regmap, data->base + SC27XX_ADC_CTL,
251*4882a593Smuzhiyun 			   SC27XX_ADC_EN, 0);
252*4882a593Smuzhiyun unlock_adc:
253*4882a593Smuzhiyun 	hwspin_unlock_raw(data->hwlock);
254*4882a593Smuzhiyun 
255*4882a593Smuzhiyun 	if (!ret)
256*4882a593Smuzhiyun 		*val = value;
257*4882a593Smuzhiyun 
258*4882a593Smuzhiyun 	return ret;
259*4882a593Smuzhiyun }
260*4882a593Smuzhiyun 
sc27xx_adc_volt_ratio(struct sc27xx_adc_data * data,int channel,int scale,u32 * div_numerator,u32 * div_denominator)261*4882a593Smuzhiyun static void sc27xx_adc_volt_ratio(struct sc27xx_adc_data *data,
262*4882a593Smuzhiyun 				  int channel, int scale,
263*4882a593Smuzhiyun 				  u32 *div_numerator, u32 *div_denominator)
264*4882a593Smuzhiyun {
265*4882a593Smuzhiyun 	u32 ratio = sc27xx_adc_get_ratio(channel, scale);
266*4882a593Smuzhiyun 
267*4882a593Smuzhiyun 	*div_numerator = ratio >> SC27XX_RATIO_NUMERATOR_OFFSET;
268*4882a593Smuzhiyun 	*div_denominator = ratio & SC27XX_RATIO_DENOMINATOR_MASK;
269*4882a593Smuzhiyun }
270*4882a593Smuzhiyun 
sc27xx_adc_to_volt(struct sc27xx_adc_linear_graph * graph,int raw_adc)271*4882a593Smuzhiyun static int sc27xx_adc_to_volt(struct sc27xx_adc_linear_graph *graph,
272*4882a593Smuzhiyun 			      int raw_adc)
273*4882a593Smuzhiyun {
274*4882a593Smuzhiyun 	int tmp;
275*4882a593Smuzhiyun 
276*4882a593Smuzhiyun 	tmp = (graph->volt0 - graph->volt1) * (raw_adc - graph->adc1);
277*4882a593Smuzhiyun 	tmp /= (graph->adc0 - graph->adc1);
278*4882a593Smuzhiyun 	tmp += graph->volt1;
279*4882a593Smuzhiyun 
280*4882a593Smuzhiyun 	return tmp < 0 ? 0 : tmp;
281*4882a593Smuzhiyun }
282*4882a593Smuzhiyun 
sc27xx_adc_convert_volt(struct sc27xx_adc_data * data,int channel,int scale,int raw_adc)283*4882a593Smuzhiyun static int sc27xx_adc_convert_volt(struct sc27xx_adc_data *data, int channel,
284*4882a593Smuzhiyun 				   int scale, int raw_adc)
285*4882a593Smuzhiyun {
286*4882a593Smuzhiyun 	u32 numerator, denominator;
287*4882a593Smuzhiyun 	u32 volt;
288*4882a593Smuzhiyun 
289*4882a593Smuzhiyun 	/*
290*4882a593Smuzhiyun 	 * Convert ADC values to voltage values according to the linear graph,
291*4882a593Smuzhiyun 	 * and channel 5 and channel 1 has been calibrated, so we can just
292*4882a593Smuzhiyun 	 * return the voltage values calculated by the linear graph. But other
293*4882a593Smuzhiyun 	 * channels need be calculated to the real voltage values with the
294*4882a593Smuzhiyun 	 * voltage ratio.
295*4882a593Smuzhiyun 	 */
296*4882a593Smuzhiyun 	switch (channel) {
297*4882a593Smuzhiyun 	case 5:
298*4882a593Smuzhiyun 		return sc27xx_adc_to_volt(&big_scale_graph, raw_adc);
299*4882a593Smuzhiyun 
300*4882a593Smuzhiyun 	case 1:
301*4882a593Smuzhiyun 		return sc27xx_adc_to_volt(&small_scale_graph, raw_adc);
302*4882a593Smuzhiyun 
303*4882a593Smuzhiyun 	default:
304*4882a593Smuzhiyun 		volt = sc27xx_adc_to_volt(&small_scale_graph, raw_adc);
305*4882a593Smuzhiyun 		break;
306*4882a593Smuzhiyun 	}
307*4882a593Smuzhiyun 
308*4882a593Smuzhiyun 	sc27xx_adc_volt_ratio(data, channel, scale, &numerator, &denominator);
309*4882a593Smuzhiyun 
310*4882a593Smuzhiyun 	return (volt * denominator + numerator / 2) / numerator;
311*4882a593Smuzhiyun }
312*4882a593Smuzhiyun 
sc27xx_adc_read_processed(struct sc27xx_adc_data * data,int channel,int scale,int * val)313*4882a593Smuzhiyun static int sc27xx_adc_read_processed(struct sc27xx_adc_data *data,
314*4882a593Smuzhiyun 				     int channel, int scale, int *val)
315*4882a593Smuzhiyun {
316*4882a593Smuzhiyun 	int ret, raw_adc;
317*4882a593Smuzhiyun 
318*4882a593Smuzhiyun 	ret = sc27xx_adc_read(data, channel, scale, &raw_adc);
319*4882a593Smuzhiyun 	if (ret)
320*4882a593Smuzhiyun 		return ret;
321*4882a593Smuzhiyun 
322*4882a593Smuzhiyun 	*val = sc27xx_adc_convert_volt(data, channel, scale, raw_adc);
323*4882a593Smuzhiyun 	return 0;
324*4882a593Smuzhiyun }
325*4882a593Smuzhiyun 
sc27xx_adc_read_raw(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,int * val,int * val2,long mask)326*4882a593Smuzhiyun static int sc27xx_adc_read_raw(struct iio_dev *indio_dev,
327*4882a593Smuzhiyun 			       struct iio_chan_spec const *chan,
328*4882a593Smuzhiyun 			       int *val, int *val2, long mask)
329*4882a593Smuzhiyun {
330*4882a593Smuzhiyun 	struct sc27xx_adc_data *data = iio_priv(indio_dev);
331*4882a593Smuzhiyun 	int scale = data->channel_scale[chan->channel];
332*4882a593Smuzhiyun 	int ret, tmp;
333*4882a593Smuzhiyun 
334*4882a593Smuzhiyun 	switch (mask) {
335*4882a593Smuzhiyun 	case IIO_CHAN_INFO_RAW:
336*4882a593Smuzhiyun 		mutex_lock(&indio_dev->mlock);
337*4882a593Smuzhiyun 		ret = sc27xx_adc_read(data, chan->channel, scale, &tmp);
338*4882a593Smuzhiyun 		mutex_unlock(&indio_dev->mlock);
339*4882a593Smuzhiyun 
340*4882a593Smuzhiyun 		if (ret)
341*4882a593Smuzhiyun 			return ret;
342*4882a593Smuzhiyun 
343*4882a593Smuzhiyun 		*val = tmp;
344*4882a593Smuzhiyun 		return IIO_VAL_INT;
345*4882a593Smuzhiyun 
346*4882a593Smuzhiyun 	case IIO_CHAN_INFO_PROCESSED:
347*4882a593Smuzhiyun 		mutex_lock(&indio_dev->mlock);
348*4882a593Smuzhiyun 		ret = sc27xx_adc_read_processed(data, chan->channel, scale,
349*4882a593Smuzhiyun 						&tmp);
350*4882a593Smuzhiyun 		mutex_unlock(&indio_dev->mlock);
351*4882a593Smuzhiyun 
352*4882a593Smuzhiyun 		if (ret)
353*4882a593Smuzhiyun 			return ret;
354*4882a593Smuzhiyun 
355*4882a593Smuzhiyun 		*val = tmp;
356*4882a593Smuzhiyun 		return IIO_VAL_INT;
357*4882a593Smuzhiyun 
358*4882a593Smuzhiyun 	case IIO_CHAN_INFO_SCALE:
359*4882a593Smuzhiyun 		*val = scale;
360*4882a593Smuzhiyun 		return IIO_VAL_INT;
361*4882a593Smuzhiyun 
362*4882a593Smuzhiyun 	default:
363*4882a593Smuzhiyun 		return -EINVAL;
364*4882a593Smuzhiyun 	}
365*4882a593Smuzhiyun }
366*4882a593Smuzhiyun 
sc27xx_adc_write_raw(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,int val,int val2,long mask)367*4882a593Smuzhiyun static int sc27xx_adc_write_raw(struct iio_dev *indio_dev,
368*4882a593Smuzhiyun 				struct iio_chan_spec const *chan,
369*4882a593Smuzhiyun 				int val, int val2, long mask)
370*4882a593Smuzhiyun {
371*4882a593Smuzhiyun 	struct sc27xx_adc_data *data = iio_priv(indio_dev);
372*4882a593Smuzhiyun 
373*4882a593Smuzhiyun 	switch (mask) {
374*4882a593Smuzhiyun 	case IIO_CHAN_INFO_SCALE:
375*4882a593Smuzhiyun 		data->channel_scale[chan->channel] = val;
376*4882a593Smuzhiyun 		return IIO_VAL_INT;
377*4882a593Smuzhiyun 
378*4882a593Smuzhiyun 	default:
379*4882a593Smuzhiyun 		return -EINVAL;
380*4882a593Smuzhiyun 	}
381*4882a593Smuzhiyun }
382*4882a593Smuzhiyun 
383*4882a593Smuzhiyun static const struct iio_info sc27xx_info = {
384*4882a593Smuzhiyun 	.read_raw = &sc27xx_adc_read_raw,
385*4882a593Smuzhiyun 	.write_raw = &sc27xx_adc_write_raw,
386*4882a593Smuzhiyun };
387*4882a593Smuzhiyun 
388*4882a593Smuzhiyun #define SC27XX_ADC_CHANNEL(index, mask) {			\
389*4882a593Smuzhiyun 	.type = IIO_VOLTAGE,					\
390*4882a593Smuzhiyun 	.channel = index,					\
391*4882a593Smuzhiyun 	.info_mask_separate = mask | BIT(IIO_CHAN_INFO_SCALE),	\
392*4882a593Smuzhiyun 	.datasheet_name = "CH##index",				\
393*4882a593Smuzhiyun 	.indexed = 1,						\
394*4882a593Smuzhiyun }
395*4882a593Smuzhiyun 
396*4882a593Smuzhiyun static const struct iio_chan_spec sc27xx_channels[] = {
397*4882a593Smuzhiyun 	SC27XX_ADC_CHANNEL(0, BIT(IIO_CHAN_INFO_PROCESSED)),
398*4882a593Smuzhiyun 	SC27XX_ADC_CHANNEL(1, BIT(IIO_CHAN_INFO_PROCESSED)),
399*4882a593Smuzhiyun 	SC27XX_ADC_CHANNEL(2, BIT(IIO_CHAN_INFO_PROCESSED)),
400*4882a593Smuzhiyun 	SC27XX_ADC_CHANNEL(3, BIT(IIO_CHAN_INFO_PROCESSED)),
401*4882a593Smuzhiyun 	SC27XX_ADC_CHANNEL(4, BIT(IIO_CHAN_INFO_PROCESSED)),
402*4882a593Smuzhiyun 	SC27XX_ADC_CHANNEL(5, BIT(IIO_CHAN_INFO_PROCESSED)),
403*4882a593Smuzhiyun 	SC27XX_ADC_CHANNEL(6, BIT(IIO_CHAN_INFO_PROCESSED)),
404*4882a593Smuzhiyun 	SC27XX_ADC_CHANNEL(7, BIT(IIO_CHAN_INFO_PROCESSED)),
405*4882a593Smuzhiyun 	SC27XX_ADC_CHANNEL(8, BIT(IIO_CHAN_INFO_PROCESSED)),
406*4882a593Smuzhiyun 	SC27XX_ADC_CHANNEL(9, BIT(IIO_CHAN_INFO_PROCESSED)),
407*4882a593Smuzhiyun 	SC27XX_ADC_CHANNEL(10, BIT(IIO_CHAN_INFO_PROCESSED)),
408*4882a593Smuzhiyun 	SC27XX_ADC_CHANNEL(11, BIT(IIO_CHAN_INFO_PROCESSED)),
409*4882a593Smuzhiyun 	SC27XX_ADC_CHANNEL(12, BIT(IIO_CHAN_INFO_PROCESSED)),
410*4882a593Smuzhiyun 	SC27XX_ADC_CHANNEL(13, BIT(IIO_CHAN_INFO_PROCESSED)),
411*4882a593Smuzhiyun 	SC27XX_ADC_CHANNEL(14, BIT(IIO_CHAN_INFO_PROCESSED)),
412*4882a593Smuzhiyun 	SC27XX_ADC_CHANNEL(15, BIT(IIO_CHAN_INFO_PROCESSED)),
413*4882a593Smuzhiyun 	SC27XX_ADC_CHANNEL(16, BIT(IIO_CHAN_INFO_PROCESSED)),
414*4882a593Smuzhiyun 	SC27XX_ADC_CHANNEL(17, BIT(IIO_CHAN_INFO_PROCESSED)),
415*4882a593Smuzhiyun 	SC27XX_ADC_CHANNEL(18, BIT(IIO_CHAN_INFO_PROCESSED)),
416*4882a593Smuzhiyun 	SC27XX_ADC_CHANNEL(19, BIT(IIO_CHAN_INFO_PROCESSED)),
417*4882a593Smuzhiyun 	SC27XX_ADC_CHANNEL(20, BIT(IIO_CHAN_INFO_RAW)),
418*4882a593Smuzhiyun 	SC27XX_ADC_CHANNEL(21, BIT(IIO_CHAN_INFO_PROCESSED)),
419*4882a593Smuzhiyun 	SC27XX_ADC_CHANNEL(22, BIT(IIO_CHAN_INFO_PROCESSED)),
420*4882a593Smuzhiyun 	SC27XX_ADC_CHANNEL(23, BIT(IIO_CHAN_INFO_PROCESSED)),
421*4882a593Smuzhiyun 	SC27XX_ADC_CHANNEL(24, BIT(IIO_CHAN_INFO_PROCESSED)),
422*4882a593Smuzhiyun 	SC27XX_ADC_CHANNEL(25, BIT(IIO_CHAN_INFO_PROCESSED)),
423*4882a593Smuzhiyun 	SC27XX_ADC_CHANNEL(26, BIT(IIO_CHAN_INFO_PROCESSED)),
424*4882a593Smuzhiyun 	SC27XX_ADC_CHANNEL(27, BIT(IIO_CHAN_INFO_PROCESSED)),
425*4882a593Smuzhiyun 	SC27XX_ADC_CHANNEL(28, BIT(IIO_CHAN_INFO_PROCESSED)),
426*4882a593Smuzhiyun 	SC27XX_ADC_CHANNEL(29, BIT(IIO_CHAN_INFO_PROCESSED)),
427*4882a593Smuzhiyun 	SC27XX_ADC_CHANNEL(30, BIT(IIO_CHAN_INFO_PROCESSED)),
428*4882a593Smuzhiyun 	SC27XX_ADC_CHANNEL(31, BIT(IIO_CHAN_INFO_PROCESSED)),
429*4882a593Smuzhiyun };
430*4882a593Smuzhiyun 
sc27xx_adc_enable(struct sc27xx_adc_data * data)431*4882a593Smuzhiyun static int sc27xx_adc_enable(struct sc27xx_adc_data *data)
432*4882a593Smuzhiyun {
433*4882a593Smuzhiyun 	int ret;
434*4882a593Smuzhiyun 
435*4882a593Smuzhiyun 	ret = regmap_update_bits(data->regmap, SC27XX_MODULE_EN,
436*4882a593Smuzhiyun 				 SC27XX_MODULE_ADC_EN, SC27XX_MODULE_ADC_EN);
437*4882a593Smuzhiyun 	if (ret)
438*4882a593Smuzhiyun 		return ret;
439*4882a593Smuzhiyun 
440*4882a593Smuzhiyun 	/* Enable ADC work clock and controller clock */
441*4882a593Smuzhiyun 	ret = regmap_update_bits(data->regmap, SC27XX_ARM_CLK_EN,
442*4882a593Smuzhiyun 				 SC27XX_CLK_ADC_EN | SC27XX_CLK_ADC_CLK_EN,
443*4882a593Smuzhiyun 				 SC27XX_CLK_ADC_EN | SC27XX_CLK_ADC_CLK_EN);
444*4882a593Smuzhiyun 	if (ret)
445*4882a593Smuzhiyun 		goto disable_adc;
446*4882a593Smuzhiyun 
447*4882a593Smuzhiyun 	/* ADC channel scales' calibration from nvmem device */
448*4882a593Smuzhiyun 	ret = sc27xx_adc_scale_calibration(data, true);
449*4882a593Smuzhiyun 	if (ret)
450*4882a593Smuzhiyun 		goto disable_clk;
451*4882a593Smuzhiyun 
452*4882a593Smuzhiyun 	ret = sc27xx_adc_scale_calibration(data, false);
453*4882a593Smuzhiyun 	if (ret)
454*4882a593Smuzhiyun 		goto disable_clk;
455*4882a593Smuzhiyun 
456*4882a593Smuzhiyun 	return 0;
457*4882a593Smuzhiyun 
458*4882a593Smuzhiyun disable_clk:
459*4882a593Smuzhiyun 	regmap_update_bits(data->regmap, SC27XX_ARM_CLK_EN,
460*4882a593Smuzhiyun 			   SC27XX_CLK_ADC_EN | SC27XX_CLK_ADC_CLK_EN, 0);
461*4882a593Smuzhiyun disable_adc:
462*4882a593Smuzhiyun 	regmap_update_bits(data->regmap, SC27XX_MODULE_EN,
463*4882a593Smuzhiyun 			   SC27XX_MODULE_ADC_EN, 0);
464*4882a593Smuzhiyun 
465*4882a593Smuzhiyun 	return ret;
466*4882a593Smuzhiyun }
467*4882a593Smuzhiyun 
sc27xx_adc_disable(void * _data)468*4882a593Smuzhiyun static void sc27xx_adc_disable(void *_data)
469*4882a593Smuzhiyun {
470*4882a593Smuzhiyun 	struct sc27xx_adc_data *data = _data;
471*4882a593Smuzhiyun 
472*4882a593Smuzhiyun 	/* Disable ADC work clock and controller clock */
473*4882a593Smuzhiyun 	regmap_update_bits(data->regmap, SC27XX_ARM_CLK_EN,
474*4882a593Smuzhiyun 			   SC27XX_CLK_ADC_EN | SC27XX_CLK_ADC_CLK_EN, 0);
475*4882a593Smuzhiyun 
476*4882a593Smuzhiyun 	regmap_update_bits(data->regmap, SC27XX_MODULE_EN,
477*4882a593Smuzhiyun 			   SC27XX_MODULE_ADC_EN, 0);
478*4882a593Smuzhiyun }
479*4882a593Smuzhiyun 
sc27xx_adc_probe(struct platform_device * pdev)480*4882a593Smuzhiyun static int sc27xx_adc_probe(struct platform_device *pdev)
481*4882a593Smuzhiyun {
482*4882a593Smuzhiyun 	struct device *dev = &pdev->dev;
483*4882a593Smuzhiyun 	struct device_node *np = dev->of_node;
484*4882a593Smuzhiyun 	struct sc27xx_adc_data *sc27xx_data;
485*4882a593Smuzhiyun 	struct iio_dev *indio_dev;
486*4882a593Smuzhiyun 	int ret;
487*4882a593Smuzhiyun 
488*4882a593Smuzhiyun 	indio_dev = devm_iio_device_alloc(dev, sizeof(*sc27xx_data));
489*4882a593Smuzhiyun 	if (!indio_dev)
490*4882a593Smuzhiyun 		return -ENOMEM;
491*4882a593Smuzhiyun 
492*4882a593Smuzhiyun 	sc27xx_data = iio_priv(indio_dev);
493*4882a593Smuzhiyun 
494*4882a593Smuzhiyun 	sc27xx_data->regmap = dev_get_regmap(dev->parent, NULL);
495*4882a593Smuzhiyun 	if (!sc27xx_data->regmap) {
496*4882a593Smuzhiyun 		dev_err(dev, "failed to get ADC regmap\n");
497*4882a593Smuzhiyun 		return -ENODEV;
498*4882a593Smuzhiyun 	}
499*4882a593Smuzhiyun 
500*4882a593Smuzhiyun 	ret = of_property_read_u32(np, "reg", &sc27xx_data->base);
501*4882a593Smuzhiyun 	if (ret) {
502*4882a593Smuzhiyun 		dev_err(dev, "failed to get ADC base address\n");
503*4882a593Smuzhiyun 		return ret;
504*4882a593Smuzhiyun 	}
505*4882a593Smuzhiyun 
506*4882a593Smuzhiyun 	sc27xx_data->irq = platform_get_irq(pdev, 0);
507*4882a593Smuzhiyun 	if (sc27xx_data->irq < 0)
508*4882a593Smuzhiyun 		return sc27xx_data->irq;
509*4882a593Smuzhiyun 
510*4882a593Smuzhiyun 	ret = of_hwspin_lock_get_id(np, 0);
511*4882a593Smuzhiyun 	if (ret < 0) {
512*4882a593Smuzhiyun 		dev_err(dev, "failed to get hwspinlock id\n");
513*4882a593Smuzhiyun 		return ret;
514*4882a593Smuzhiyun 	}
515*4882a593Smuzhiyun 
516*4882a593Smuzhiyun 	sc27xx_data->hwlock = devm_hwspin_lock_request_specific(dev, ret);
517*4882a593Smuzhiyun 	if (!sc27xx_data->hwlock) {
518*4882a593Smuzhiyun 		dev_err(dev, "failed to request hwspinlock\n");
519*4882a593Smuzhiyun 		return -ENXIO;
520*4882a593Smuzhiyun 	}
521*4882a593Smuzhiyun 
522*4882a593Smuzhiyun 	sc27xx_data->dev = dev;
523*4882a593Smuzhiyun 
524*4882a593Smuzhiyun 	ret = sc27xx_adc_enable(sc27xx_data);
525*4882a593Smuzhiyun 	if (ret) {
526*4882a593Smuzhiyun 		dev_err(dev, "failed to enable ADC module\n");
527*4882a593Smuzhiyun 		return ret;
528*4882a593Smuzhiyun 	}
529*4882a593Smuzhiyun 
530*4882a593Smuzhiyun 	ret = devm_add_action_or_reset(dev, sc27xx_adc_disable, sc27xx_data);
531*4882a593Smuzhiyun 	if (ret) {
532*4882a593Smuzhiyun 		dev_err(dev, "failed to add ADC disable action\n");
533*4882a593Smuzhiyun 		return ret;
534*4882a593Smuzhiyun 	}
535*4882a593Smuzhiyun 
536*4882a593Smuzhiyun 	indio_dev->name = dev_name(dev);
537*4882a593Smuzhiyun 	indio_dev->modes = INDIO_DIRECT_MODE;
538*4882a593Smuzhiyun 	indio_dev->info = &sc27xx_info;
539*4882a593Smuzhiyun 	indio_dev->channels = sc27xx_channels;
540*4882a593Smuzhiyun 	indio_dev->num_channels = ARRAY_SIZE(sc27xx_channels);
541*4882a593Smuzhiyun 	ret = devm_iio_device_register(dev, indio_dev);
542*4882a593Smuzhiyun 	if (ret)
543*4882a593Smuzhiyun 		dev_err(dev, "could not register iio (ADC)");
544*4882a593Smuzhiyun 
545*4882a593Smuzhiyun 	return ret;
546*4882a593Smuzhiyun }
547*4882a593Smuzhiyun 
548*4882a593Smuzhiyun static const struct of_device_id sc27xx_adc_of_match[] = {
549*4882a593Smuzhiyun 	{ .compatible = "sprd,sc2731-adc", },
550*4882a593Smuzhiyun 	{ }
551*4882a593Smuzhiyun };
552*4882a593Smuzhiyun 
553*4882a593Smuzhiyun static struct platform_driver sc27xx_adc_driver = {
554*4882a593Smuzhiyun 	.probe = sc27xx_adc_probe,
555*4882a593Smuzhiyun 	.driver = {
556*4882a593Smuzhiyun 		.name = "sc27xx-adc",
557*4882a593Smuzhiyun 		.of_match_table = sc27xx_adc_of_match,
558*4882a593Smuzhiyun 	},
559*4882a593Smuzhiyun };
560*4882a593Smuzhiyun 
561*4882a593Smuzhiyun module_platform_driver(sc27xx_adc_driver);
562*4882a593Smuzhiyun 
563*4882a593Smuzhiyun MODULE_AUTHOR("Freeman Liu <freeman.liu@spreadtrum.com>");
564*4882a593Smuzhiyun MODULE_DESCRIPTION("Spreadtrum SC27XX ADC Driver");
565*4882a593Smuzhiyun MODULE_LICENSE("GPL v2");
566