blob: 30a1cddd541c39f859a2c880479f512f90ea00c7 [file] [log] [blame]
xjb04a4022021-11-25 15:01:52 +08001// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (c) 2020 MediaTek Inc.
4 */
5
6#include <linux/completion.h>
7#include <linux/delay.h>
8#include <linux/err.h>
9#include <linux/iio/iio.h>
10#include <linux/interrupt.h>
11#include <linux/kernel.h>
12#include <linux/mfd/mt6330/registers.h>
13#include <linux/mfd/mt6358/registers.h>
14#include <linux/mfd/mt6359/registers.h>
15#include <linux/mfd/mt6397/core.h>
16#include <linux/module.h>
17#include <linux/of.h>
18#include <linux/of_device.h>
19#include <linux/platform_device.h>
20#include <linux/regmap.h>
21
22#include <dt-bindings/iio/mt635x-auxadc.h>
23
24#define AUXADC_RDY_BIT BIT(15)
25
26#define AUXADC_DEF_R_RATIO 1
27#define AUXADC_DEF_AVG_NUM 8
28
29#define AUXADC_AVG_TIME_US 10
30#define AUXADC_POLL_DELAY_US 100
31#define AUXADC_TIMEOUT_US 32000
32#define VOLT_FULL 1800
33#define IMP_STOP_DELAY_US 150
34
35#define AUXADC_ATTR_BASIC 0
36#define AUXADC_ATTR_BURST16 1
37
38struct mt635x_auxadc_device {
39 unsigned int chip_id;
40 struct regmap *regmap;
41 struct device *dev;
42 unsigned int nchannels;
43 struct iio_chan_spec *iio_chans;
44 struct mutex lock;
45 const struct auxadc_info *info;
46 int imp_vbat;
47 struct completion imp_done;
48 int imix_r;
49};
50
51/*
52 * @ch_name: HW channel name
53 * @ch_num: HW channel number
54 * @res: ADC resolution
55 * @r_ratio: resistance ratio, represented by r_ratio[0] / r_ratio[1]
56 * @avg_num: sampling times of AUXADC measurments then average it
57 * @regs: request and data output registers for this channel
58 * @has_regs: determine if this channel has request and data output registers
59 */
60struct auxadc_channels {
61 enum iio_chan_type type;
62 long info_mask;
63 /* AUXADC channel attribute */
64 const char *ch_name;
65 unsigned char ch_num;
66 unsigned char res;
67 unsigned char r_ratio[2];
68 unsigned short avg_num;
69 const struct auxadc_regs *regs;
70 bool has_regs;
71};
72
73#define MT635x_AUXADC_CHANNEL(_ch_name, _ch_num, _res, _has_regs) \
74 [AUXADC_##_ch_name] = { \
75 .type = IIO_VOLTAGE, \
76 .info_mask = BIT(IIO_CHAN_INFO_RAW) | \
77 BIT(IIO_CHAN_INFO_PROCESSED), \
78 .ch_name = __stringify(_ch_name), \
79 .ch_num = _ch_num, \
80 .res = _res, \
81 .has_regs = _has_regs, \
82 }
83
84#define regmap_bulk_read_poll_timeout(map, addr, val, cond, sleep_us, timeout_us) \
85({ \
86 u64 __timeout_us = (timeout_us); \
87 unsigned long __sleep_us = (sleep_us); \
88 ktime_t __timeout = ktime_add_us(ktime_get(), __timeout_us); \
89 int __ret; \
90 might_sleep_if(__sleep_us); \
91 for (;;) { \
92 __ret = regmap_bulk_read((map), (addr), &(val), 2); \
93 if (__ret) \
94 break; \
95 if (cond) \
96 break; \
97 if ((__timeout_us) && \
98 ktime_compare(ktime_get(), __timeout) > 0) { \
99 __ret = regmap_bulk_read((map), (addr), &(val), 2); \
100 break; \
101 } \
102 if (__sleep_us) \
103 usleep_range((__sleep_us >> 2) + 1, __sleep_us); \
104 } \
105 __ret ?: ((cond) ? 0 : -ETIMEDOUT); \
106})
107
108/*
109 * The array represents all possible AUXADC channels found
110 * in the supported PMICs.
111 */
112static struct auxadc_channels auxadc_chans[] = {
113 MT635x_AUXADC_CHANNEL(BATADC, 0, 15, true),
114 MT635x_AUXADC_CHANNEL(ISENSE, 0, 15, true),
115 MT635x_AUXADC_CHANNEL(VCDT, 2, 12, true),
116 MT635x_AUXADC_CHANNEL(BAT_TEMP, 3, 12, true),
117 MT635x_AUXADC_CHANNEL(BATID, 3, 12, true),
118 MT635x_AUXADC_CHANNEL(CHIP_TEMP, 4, 12, true),
119 MT635x_AUXADC_CHANNEL(VCORE_TEMP, 4, 12, true),
120 MT635x_AUXADC_CHANNEL(VPROC_TEMP, 4, 12, true),
121 MT635x_AUXADC_CHANNEL(VGPU_TEMP, 4, 12, true),
122 MT635x_AUXADC_CHANNEL(ACCDET, 5, 12, true),
123 MT635x_AUXADC_CHANNEL(VDCXO, 6, 12, true),
124 MT635x_AUXADC_CHANNEL(TSX_TEMP, 7, 15, true),
125 MT635x_AUXADC_CHANNEL(HPOFS_CAL, 9, 15, true),
126 MT635x_AUXADC_CHANNEL(DCXO_TEMP, 10, 15, true),
127 MT635x_AUXADC_CHANNEL(VBIF, 11, 12, true),
128 MT635x_AUXADC_CHANNEL(IMP, 0, 15, false),
129 [AUXADC_IMIX_R] = {
130 .type = IIO_RESISTANCE,
131 .info_mask = BIT(IIO_CHAN_INFO_RAW),
132 .ch_name = "IMIX_R",
133 .has_regs = false,
134 },
xj112b9672022-01-25 16:13:48 +0800135 MT635x_AUXADC_CHANNEL(TYPEL, 13, 15, true),
136 MT635x_AUXADC_CHANNEL(DRDI, 13, 15, true),
xjb04a4022021-11-25 15:01:52 +0800137};
138
139struct auxadc_regs {
140 unsigned int rqst_reg;
141 unsigned int rqst_shift;
142 unsigned int out_reg;
143};
144
145#define MT635x_AUXADC_REG(_ch_name, _chip, _rqst_reg, _rqst_shift, _out_reg) \
146 [AUXADC_##_ch_name] = { \
147 .rqst_reg = _chip##_##_rqst_reg, \
148 .rqst_shift = _rqst_shift, \
149 .out_reg = _chip##_##_out_reg, \
150 } \
151
152static const struct auxadc_regs mt6330_auxadc_regs_tbl[] = {
153 MT635x_AUXADC_REG(BATADC, MT6330, AUXADC_RQST0, 0, AUXADC_ADC22_L),
154 MT635x_AUXADC_REG(VCDT, MT6330, AUXADC_RQST0, 2, AUXADC_ADC2_L),
155 MT635x_AUXADC_REG(CHIP_TEMP, MT6330, AUXADC_RQST0, 4, AUXADC_ADC4_L),
156 MT635x_AUXADC_REG(VCORE_TEMP, MT6330, AUXADC_RQST3, 0, AUXADC_ADC38_L),
157 MT635x_AUXADC_REG(VPROC_TEMP, MT6330, AUXADC_RQST3, 1, AUXADC_ADC39_L),
158 MT635x_AUXADC_REG(VGPU_TEMP, MT6330, AUXADC_RQST3, 2, AUXADC_ADC40_L),
159 MT635x_AUXADC_REG(TSX_TEMP, MT6330, AUXADC_RQST2, 4, AUXADC_ADC15_L),
160 MT635x_AUXADC_REG(DCXO_TEMP, MT6330, AUXADC_RQST2, 6, AUXADC_ADC32_L),
161 MT635x_AUXADC_REG(TYPEL, MT6330, AUXADC_RQST4, 4, AUXADC_ADC_EXT0_L),
162 MT635x_AUXADC_REG(DRDI, MT6330, AUXADC_RQST4, 5, AUXADC_ADC_EXT1_L),
163};
164
165static const struct auxadc_regs mt6358_auxadc_regs_tbl[] = {
166 MT635x_AUXADC_REG(BATADC, MT6358, AUXADC_RQST0, 0, AUXADC_ADC0),
167 MT635x_AUXADC_REG(VCDT, MT6358, AUXADC_RQST0, 2, AUXADC_ADC2),
168 MT635x_AUXADC_REG(BAT_TEMP, MT6358, AUXADC_RQST0, 3, AUXADC_ADC3),
169 MT635x_AUXADC_REG(CHIP_TEMP, MT6358, AUXADC_RQST0, 4, AUXADC_ADC4),
170 MT635x_AUXADC_REG(VCORE_TEMP, MT6358, AUXADC_RQST1, 8, AUXADC_ADC38),
171 MT635x_AUXADC_REG(VPROC_TEMP, MT6358, AUXADC_RQST1, 9, AUXADC_ADC39),
172 MT635x_AUXADC_REG(VGPU_TEMP, MT6358, AUXADC_RQST1, 10, AUXADC_ADC40),
173 MT635x_AUXADC_REG(ACCDET, MT6358, AUXADC_RQST0, 5, AUXADC_ADC5),
174 MT635x_AUXADC_REG(VDCXO, MT6358, AUXADC_RQST0, 6, AUXADC_ADC6),
175 MT635x_AUXADC_REG(TSX_TEMP, MT6358, AUXADC_RQST0, 7, AUXADC_ADC7),
176 MT635x_AUXADC_REG(HPOFS_CAL, MT6358, AUXADC_RQST0, 9, AUXADC_ADC9),
177 MT635x_AUXADC_REG(DCXO_TEMP, MT6358, AUXADC_RQST0, 10, AUXADC_ADC10),
178 MT635x_AUXADC_REG(VBIF, MT6358, AUXADC_RQST0, 11, AUXADC_ADC11),
179};
180
181static const struct auxadc_regs mt6359_auxadc_regs_tbl[] = {
182 MT635x_AUXADC_REG(BATADC, MT6359, AUXADC_RQST0, 0, AUXADC_ADC0),
183 MT635x_AUXADC_REG(BAT_TEMP, MT6359, AUXADC_RQST0, 3, AUXADC_ADC3),
184 MT635x_AUXADC_REG(CHIP_TEMP, MT6359, AUXADC_RQST0, 4, AUXADC_ADC4),
185 MT635x_AUXADC_REG(VCORE_TEMP, MT6359, AUXADC_RQST1, 8, AUXADC_ADC38),
186 MT635x_AUXADC_REG(VPROC_TEMP, MT6359, AUXADC_RQST1, 9, AUXADC_ADC39),
187 MT635x_AUXADC_REG(VGPU_TEMP, MT6359, AUXADC_RQST1, 10, AUXADC_ADC40),
188 MT635x_AUXADC_REG(ACCDET, MT6359, AUXADC_RQST0, 5, AUXADC_ADC5),
189 MT635x_AUXADC_REG(VDCXO, MT6359, AUXADC_RQST0, 6, AUXADC_ADC6),
190 MT635x_AUXADC_REG(TSX_TEMP, MT6359, AUXADC_RQST0, 7, AUXADC_ADC7),
191 MT635x_AUXADC_REG(HPOFS_CAL, MT6359, AUXADC_RQST0, 9, AUXADC_ADC9),
192 MT635x_AUXADC_REG(DCXO_TEMP, MT6359, AUXADC_RQST0, 10, AUXADC_ADC10),
193 MT635x_AUXADC_REG(VBIF, MT6359, AUXADC_RQST0, 11, AUXADC_ADC11),
194};
195
196static const unsigned int mt6330_rst_setting[][3] = {
197 {
198 MT6330_HK_TOP_WKEY_L, 0xFF, 0x30,
199 }, {
200 MT6330_HK_TOP_WKEY_H, 0xFF, 0x63,
201 }, {
202 MT6330_HK_TOP_STRUP_CON1, 0xa, 0x8,
203 }, {
204 MT6330_HK_TOP_STRUP_CON1, 0x2, 2,
205 }, {
206 MT6330_HK_TOP_STRUP_CON1, 0x8, 0,
207 }, {
208 MT6330_HK_TOP_WKEY_L, 0xFF, 0,
209 }, {
210 MT6330_HK_TOP_WKEY_H, 0xFF, 0,
211 }
212};
213
214static const unsigned int mt6358_rst_setting[][3] = {
215 {
216 MT6358_HK_TOP_RST_CON0, 0x9, 0x9,
217 }, {
218 MT6358_HK_TOP_RST_CON0, 0x9, 0,
219 }, {
220 MT6358_AUXADC_RQST0, 0x80, 0x80,
221 }, {
222 MT6358_AUXADC_RQST1, 0x40, 0x40,
223 }
224};
225
226static const unsigned int mt6359_rst_setting[][3] = {
227 {
228 MT6359_HK_TOP_WKEY, 0xFFFF, 0x6359,
229 }, {
230 MT6359_HK_TOP_RST_CON0, 0x9, 0x9,
231 }, {
232 MT6359_HK_TOP_RST_CON0, 0x9, 0,
233 }, {
234 MT6359_HK_TOP_WKEY, 0xFFFF, 0,
235 }, {
236 MT6359_AUXADC_RQST0, 0x80, 0x80,
237 }, {
238 MT6359_AUXADC_RQST1, 0x40, 0x40,
239 }
240};
241
242struct auxadc_info {
243 const struct auxadc_regs *regs_tbl;
244 const unsigned int (*rst_setting)[3];
245 unsigned int num_rst_setting;
246 unsigned int attr;
247 int (*imp_conv)(struct mt635x_auxadc_device *adc_dev,
248 int *vbat, int *ibat);
249 void (*imp_stop)(struct mt635x_auxadc_device *adc_dev);
250};
251
252#define MT6358_IMP_CK_SW_MASK (BIT(1) | BIT(0))
253#define MT6358_IMP_AUTORPT_EN_MASK BIT(15)
254#define MT6358_IMP_CLR_MASK (BIT(14) | BIT(7))
255
256static int mt6358_imp_conv(struct mt635x_auxadc_device *adc_dev,
257 int *vbat, int *ibat)
258{
259 int ret;
260
261 reinit_completion(&adc_dev->imp_done);
262 /* start conversion */
263 regmap_update_bits(adc_dev->regmap, MT6358_AUXADC_DCM_CON,
264 MT6358_IMP_CK_SW_MASK, MT6358_IMP_CK_SW_MASK);
265 regmap_update_bits(adc_dev->regmap, MT6358_AUXADC_IMP1,
266 MT6358_IMP_AUTORPT_EN_MASK,
267 MT6358_IMP_AUTORPT_EN_MASK);
268 ret = wait_for_completion_timeout(&adc_dev->imp_done,
269 usecs_to_jiffies(AUXADC_TIMEOUT_US));
270 if (!ret) {
271 adc_dev->info->imp_stop(adc_dev);
272 dev_err(adc_dev->dev, "IMP Time out!\n");
273 ret = -ETIMEDOUT;
274 }
275 *vbat = adc_dev->imp_vbat;
276 regmap_read(adc_dev->regmap, MT6358_FGADC_R_CON0, ibat);
277
278 return ret;
279}
280
281static void mt6358_imp_stop(struct mt635x_auxadc_device *adc_dev)
282{
283 regmap_read(adc_dev->regmap, MT6358_AUXADC_ADC28, &adc_dev->imp_vbat);
284 adc_dev->imp_vbat &= BIT(auxadc_chans[AUXADC_IMP].res) - 1;
285 /* stop conversion after read VBAT */
286 regmap_update_bits(adc_dev->regmap, MT6358_AUXADC_IMP0,
287 MT6358_IMP_CLR_MASK, MT6358_IMP_CLR_MASK);
288 regmap_update_bits(adc_dev->regmap, MT6358_AUXADC_IMP0,
289 MT6358_IMP_CLR_MASK, 0);
290 regmap_update_bits(adc_dev->regmap, MT6358_AUXADC_IMP1,
291 MT6358_IMP_AUTORPT_EN_MASK, 0);
292 regmap_update_bits(adc_dev->regmap, MT6358_AUXADC_DCM_CON,
293 MT6358_IMP_CK_SW_MASK, 0);
294}
295
296static int mt6359_imp_conv(struct mt635x_auxadc_device *adc_dev,
297 int *vbat, int *ibat)
298{
299 int ret;
300
301 reinit_completion(&adc_dev->imp_done);
302 /* start conversion */
303 regmap_write(adc_dev->regmap, MT6359_AUXADC_IMP0, 1);
304 ret = wait_for_completion_timeout(&adc_dev->imp_done,
305 usecs_to_jiffies(AUXADC_TIMEOUT_US));
306 if (!ret) {
307 adc_dev->info->imp_stop(adc_dev);
308 dev_err(adc_dev->dev, "IMP Time out!\n");
309 ret = -ETIMEDOUT;
310 }
311 *vbat = adc_dev->imp_vbat;
312 regmap_read(adc_dev->regmap, MT6359_FGADC_R_CON0, ibat);
313
314 return ret;
315}
316
317static void mt6359_imp_stop(struct mt635x_auxadc_device *adc_dev)
318{
319 /* stop conversio */
320 regmap_write(adc_dev->regmap, MT6359_AUXADC_IMP0, 0);
321 udelay(IMP_STOP_DELAY_US);
322 regmap_read(adc_dev->regmap, MT6359_AUXADC_IMP3, &adc_dev->imp_vbat);
323 adc_dev->imp_vbat &= BIT(auxadc_chans[AUXADC_IMP].res) - 1;
324}
325
326static const struct auxadc_info mt6330_info = {
327 .regs_tbl = mt6330_auxadc_regs_tbl,
328 .rst_setting = mt6330_rst_setting,
329 .num_rst_setting = ARRAY_SIZE(mt6330_rst_setting),
330 .attr = (AUXADC_ATTR_BASIC | AUXADC_ATTR_BURST16),
331};
332
333static const struct auxadc_info mt6358_info = {
334 .regs_tbl = mt6358_auxadc_regs_tbl,
335 .rst_setting = mt6358_rst_setting,
336 .num_rst_setting = ARRAY_SIZE(mt6358_rst_setting),
337 .attr = AUXADC_ATTR_BASIC,
338 .imp_conv = mt6358_imp_conv,
339 .imp_stop = mt6358_imp_stop,
340};
341
342static const struct auxadc_info mt6359_info = {
343 .regs_tbl = mt6359_auxadc_regs_tbl,
344 .rst_setting = mt6359_rst_setting,
345 .num_rst_setting = ARRAY_SIZE(mt6359_rst_setting),
346 .attr = AUXADC_ATTR_BASIC,
347 .imp_conv = mt6359_imp_conv,
348 .imp_stop = mt6359_imp_stop,
349};
350
351static irqreturn_t imp_isr(int irq, void *dev_id)
352{
353 struct mt635x_auxadc_device *adc_dev = dev_id;
354
355 adc_dev->info->imp_stop(adc_dev);
356 complete(&adc_dev->imp_done);
357 return IRQ_HANDLED;
358}
359
360static void auxadc_reset(struct mt635x_auxadc_device *adc_dev)
361{
362 int i;
363
364 for (i = 0; i < adc_dev->info->num_rst_setting; i++) {
365 regmap_update_bits(adc_dev->regmap,
366 adc_dev->info->rst_setting[i][0],
367 adc_dev->info->rst_setting[i][1],
368 adc_dev->info->rst_setting[i][2]);
369 }
370 dev_info(adc_dev->dev, "reset AUXADC done\n");
371}
372
373/*
374 * @adc_dev: pointer to the struct mt635x_auxadc_device
375 * @auxadc_chan: pointer to the struct auxadc_channels, it represents specific
376 auxadc channel
377 * @val: pointer to output value
378 */
379static int get_auxadc_out(struct mt635x_auxadc_device *adc_dev,
380 const struct auxadc_channels *auxadc_chan, int *val)
381{
382 int ret;
383
384 regmap_write(adc_dev->regmap,
385 auxadc_chan->regs->rqst_reg,
386 BIT(auxadc_chan->regs->rqst_shift));
387 usleep_range(auxadc_chan->avg_num * AUXADC_AVG_TIME_US,
388 (auxadc_chan->avg_num + 1) * AUXADC_AVG_TIME_US);
389
390 if (adc_dev->info->attr & AUXADC_ATTR_BURST16)
391 ret = regmap_bulk_read_poll_timeout(adc_dev->regmap,
392 auxadc_chan->regs->out_reg,
393 *val,
394 (*val & AUXADC_RDY_BIT),
395 AUXADC_POLL_DELAY_US,
396 AUXADC_TIMEOUT_US);
397 else
398 ret = regmap_read_poll_timeout(adc_dev->regmap,
399 auxadc_chan->regs->out_reg,
400 *val,
401 (*val & AUXADC_RDY_BIT),
402 AUXADC_POLL_DELAY_US,
403 AUXADC_TIMEOUT_US);
404
405 *val &= BIT(auxadc_chan->res) - 1;
406 if (ret == -ETIMEDOUT)
407 dev_err(adc_dev->dev, "(%d)Time out!\n", auxadc_chan->ch_num);
408
409 return ret;
410}
411
412static int mt635x_auxadc_read_raw(struct iio_dev *indio_dev,
413 struct iio_chan_spec const *chan,
414 int *val,
415 int *val2,
416 long mask)
417{
418 struct mt635x_auxadc_device *adc_dev = iio_priv(indio_dev);
419 const struct auxadc_channels *auxadc_chan;
420 int auxadc_out = 0;
421 int ret;
422
423 mutex_lock(&adc_dev->lock);
424 pm_stay_awake(adc_dev->dev);
425
426 auxadc_chan = &auxadc_chans[chan->channel];
427 switch (chan->channel) {
428 case AUXADC_IMP:
429 if (adc_dev->info->imp_conv)
430 ret = adc_dev->info->imp_conv(adc_dev,
431 &auxadc_out, val2);
432 else
433 ret = -EINVAL;
434 break;
435 case AUXADC_IMIX_R:
436 auxadc_out = adc_dev->imix_r;
437 ret = 0;
438 break;
439 default:
440 if (auxadc_chan->regs)
441 ret = get_auxadc_out(adc_dev, auxadc_chan,
442 &auxadc_out);
443 else
444 ret = -EINVAL;
445 break;
446 }
447
448 pm_relax(adc_dev->dev);
449 mutex_unlock(&adc_dev->lock);
450 if (ret != -ETIMEDOUT && ret < 0)
451 goto err;
452
453 switch (mask) {
454 case IIO_CHAN_INFO_PROCESSED:
455 *val = auxadc_out * auxadc_chan->r_ratio[0] * VOLT_FULL;
456 *val = (*val / auxadc_chan->r_ratio[1]) >> auxadc_chan->res;
457 ret = IIO_VAL_INT;
458 break;
459 case IIO_CHAN_INFO_RAW:
460 *val = auxadc_out;
461 ret = IIO_VAL_INT;
462 break;
463 default:
464 return -EINVAL;
465 }
466 if (chan->channel == AUXADC_IMP)
467 ret = IIO_VAL_INT_MULTIPLE;
468err:
469 return ret;
470}
471
472static int mt635x_auxadc_of_xlate(struct iio_dev *indio_dev,
473 const struct of_phandle_args *iiospec)
474{
475 int i;
476
477 for (i = 0; i < indio_dev->num_channels; i++) {
478 if (indio_dev->channels[i].channel == iiospec->args[0])
479 return i;
480 }
481
482 return -EINVAL;
483}
484
485static const struct iio_info mt635x_auxadc_info = {
486 .read_raw = &mt635x_auxadc_read_raw,
487 .of_xlate = &mt635x_auxadc_of_xlate,
488};
489
490static int auxadc_init_imix_r(struct mt635x_auxadc_device *adc_dev,
491 struct device_node *imix_r_node)
492{
493 unsigned int val = 0;
494 int ret;
495
496 if (adc_dev->imix_r)
497 return 0;
498 ret = of_property_read_u32(imix_r_node, "val", &val);
499 if (ret)
500 dev_notice(adc_dev->dev, "no imix_r, ret=%d\n", ret);
501 adc_dev->imix_r = (int)val;
502 return 0;
503}
504
505static int auxadc_get_data_from_dt(struct mt635x_auxadc_device *adc_dev,
506 unsigned int *channel,
507 struct device_node *node)
508{
509 int ret;
510 struct auxadc_channels *auxadc_chan;
511 unsigned int value = 0;
512 unsigned int val_arr[2] = {0};
513
514 ret = of_property_read_u32(node, "channel", channel);
515 if (ret) {
516 dev_notice(adc_dev->dev,
517 "invalid channel in node:%s\n", node->name);
518 return ret;
519 }
520 if (*channel < AUXADC_CHAN_MIN || *channel > AUXADC_CHAN_MAX) {
521 dev_notice(adc_dev->dev,
522 "invalid channel number %d in node:%s\n",
523 *channel, node->name);
524 return ret;
525 }
526 if (*channel == AUXADC_IMIX_R)
527 return auxadc_init_imix_r(adc_dev, node);
528 auxadc_chan = &auxadc_chans[*channel];
529
530 ret = of_property_read_u32_array(node, "resistance-ratio", val_arr, 2);
531 if (!ret) {
532 auxadc_chan->r_ratio[0] = val_arr[0];
533 auxadc_chan->r_ratio[1] = val_arr[1];
534 } else {
535 auxadc_chan->r_ratio[0] = AUXADC_DEF_R_RATIO;
536 auxadc_chan->r_ratio[1] = 1;
537 }
538
539 ret = of_property_read_u32(node, "avg-num", &value);
540 if (!ret)
541 auxadc_chan->avg_num = value;
542 else
543 auxadc_chan->avg_num = AUXADC_DEF_AVG_NUM;
544
545 return 0;
546}
547
548static int auxadc_parse_dt(struct mt635x_auxadc_device *adc_dev,
549 struct device_node *node)
550{
551 struct iio_chan_spec *iio_chan;
552 struct device_node *child;
553 unsigned int channel = 0, index = 0;
554 int ret;
555
556 adc_dev->nchannels = of_get_available_child_count(node);
557 if (!adc_dev->nchannels)
558 return -EINVAL;
559
560 adc_dev->iio_chans = devm_kcalloc(adc_dev->dev, adc_dev->nchannels,
561 sizeof(*adc_dev->iio_chans), GFP_KERNEL);
562 if (!adc_dev->iio_chans)
563 return -ENOMEM;
564 iio_chan = adc_dev->iio_chans;
565
566 for_each_available_child_of_node(node, child) {
567 ret = auxadc_get_data_from_dt(adc_dev, &channel, child);
568 if (ret) {
569 of_node_put(child);
570 return ret;
571 }
572 if (auxadc_chans[channel].has_regs) {
573 auxadc_chans[channel].regs =
574 &adc_dev->info->regs_tbl[channel];
575 }
576
577 iio_chan->channel = channel;
578 iio_chan->datasheet_name = auxadc_chans[channel].ch_name;
579 iio_chan->extend_name = auxadc_chans[channel].ch_name;
580 iio_chan->info_mask_separate = auxadc_chans[channel].info_mask;
581 iio_chan->type = auxadc_chans[channel].type;
582 iio_chan->indexed = 1;
583 iio_chan->address = index++;
584
585 iio_chan++;
586 }
587
588 return 0;
589}
590
591static int mt635x_auxadc_probe(struct platform_device *pdev)
592{
593 struct device_node *node = pdev->dev.of_node;
594 struct mt635x_auxadc_device *adc_dev;
595 struct iio_dev *indio_dev;
596 struct mt6397_chip *chip;
597 int ret, imp_irq;
598
599 chip = dev_get_drvdata(pdev->dev.parent);
600 indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*adc_dev));
601 if (!indio_dev)
602 return -ENOMEM;
603
604 adc_dev = iio_priv(indio_dev);
605 adc_dev->regmap = chip->regmap;
606 adc_dev->dev = &pdev->dev;
607 mutex_init(&adc_dev->lock);
608 init_completion(&adc_dev->imp_done);
609 device_init_wakeup(&pdev->dev, true);
610 adc_dev->info = of_device_get_match_data(&pdev->dev);
611 if (adc_dev->info->imp_conv) {
612 imp_irq = platform_get_irq_byname(pdev, "imp");
613 if (imp_irq < 0) {
614 dev_notice(&pdev->dev, "failed to get IMP irq, ret=%d\n",
615 imp_irq);
616 return imp_irq;
617 }
618 ret = devm_request_threaded_irq(&pdev->dev, imp_irq, NULL, imp_isr,
619 IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
620 "auxadc_imp", adc_dev);
621 if (ret) {
622 dev_notice(&pdev->dev,
623 "failed to request IMP irq, ret=%d\n", ret);
624 return ret;
625 }
626 }
627
628 ret = auxadc_parse_dt(adc_dev, node);
629 if (ret < 0) {
630 dev_notice(&pdev->dev, "auxadc_parse_dt fail, ret=%d\n", ret);
631 return ret;
632 }
633 auxadc_reset(adc_dev);
634
635 indio_dev->dev.parent = &pdev->dev;
636 indio_dev->name = dev_name(&pdev->dev);
637 indio_dev->info = &mt635x_auxadc_info;
638 indio_dev->modes = INDIO_DIRECT_MODE;
639 indio_dev->channels = adc_dev->iio_chans;
640 indio_dev->num_channels = adc_dev->nchannels;
641
642 ret = devm_iio_device_register(&pdev->dev, indio_dev);
643 if (ret < 0) {
644 dev_notice(&pdev->dev, "failed to register iio device!\n");
645 return ret;
646 }
647 dev_info(&pdev->dev, "%s done\n", __func__);
648
649 return 0;
650}
651
652static const struct of_device_id mt635x_auxadc_of_match[] = {
653 {
654 .compatible = "mediatek,mt6330-auxadc",
655 .data = &mt6330_info,
656 }, {
657 .compatible = "mediatek,mt6358-auxadc",
658 .data = &mt6358_info,
659 }, {
660 .compatible = "mediatek,mt6359-auxadc",
661 .data = &mt6359_info,
662 }, {
663 /* sentinel */
664 }
665};
666MODULE_DEVICE_TABLE(of, mt635x_auxadc_of_match);
667
668static struct platform_driver mt635x_auxadc_driver = {
669 .driver = {
670 .name = "mt635x-auxadc",
671 .of_match_table = mt635x_auxadc_of_match,
672 },
673 .probe = mt635x_auxadc_probe,
674};
675module_platform_driver(mt635x_auxadc_driver);
676
677MODULE_LICENSE("GPL v2");
678MODULE_AUTHOR("Jeter Chen <Jeter.Chen@mediatek.com>");
679MODULE_DESCRIPTION("MediaTek PMIC AUXADC Driver for MT635x PMIC");