aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/iio/adc/twl6030-gpadc.c
diff options
context:
space:
mode:
authorOleksandr Kozaruk <oleksandr.kozaruk@ti.com>2013-07-25 09:26:00 -0400
committerJonathan Cameron <jic23@kernel.org>2013-08-17 10:50:57 -0400
commit1696f36482e7063051a1dad86a54be83fd847f4f (patch)
treea5ddf64d53e83ced8e050d4f650beb92905264d4 /drivers/iio/adc/twl6030-gpadc.c
parent1eb70a97452cacbe7aae752879b782e1e97a3484 (diff)
iio: twl6030-gpadc: TWL6030, TWL6032 GPADC driver
The GPADC is general purpose ADC found on TWL6030, and TWL6032 PMIC, known also as Phoenix and PhoenixLite. The TWL6030 and TWL6032 have GPADC with 17 and 19 channels respectively. Some channels have current source and are used for measuring voltage drop on resistive load for detecting battery ID resistance, or measuring voltage drop on NTC resistors for external temperature measurements. Some channels measure voltage, (i.e. battery voltage), and have voltage dividers, thus, capable to scale voltage. Some channels are dedicated for measuring die temperature. Some channels are calibrated in 2 points, having offsets from ideal values kept in trim registers. This is used to correct measurements. The differences between GPADC in TWL6030 and TWL6032: - 10 bit vs 12 bit ADC; - 17 vs 19 channels; - channels have different purpose(i.e. battery voltage channel 8 vs channel 18); - trim values are interpreted differently. Based on the driver patched from Balaji TK, Graeme Gregory, Ambresh K, Girish S Ghongdemath. Signed-off-by: Balaji T K <balajitk@ti.com> Signed-off-by: Graeme Gregory <gg@slimlogic.co.uk> Signed-off-by: Oleksandr Kozaruk <oleksandr.kozaruk@ti.com> Signed-off-by: Jonathan Cameron <jic23@kernel.org>
Diffstat (limited to 'drivers/iio/adc/twl6030-gpadc.c')
-rw-r--r--drivers/iio/adc/twl6030-gpadc.c1029
1 files changed, 1029 insertions, 0 deletions
diff --git a/drivers/iio/adc/twl6030-gpadc.c b/drivers/iio/adc/twl6030-gpadc.c
new file mode 100644
index 000000000000..a80a049c9a55
--- /dev/null
+++ b/drivers/iio/adc/twl6030-gpadc.c
@@ -0,0 +1,1029 @@
1/*
2 * TWL6030 GPADC module driver
3 *
4 * Copyright (C) 2009-2013 Texas Instruments Inc.
5 * Nishant Kamat <nskamat@ti.com>
6 * Balaji T K <balajitk@ti.com>
7 * Graeme Gregory <gg@slimlogic.co.uk>
8 * Girish S Ghongdemath <girishsg@ti.com>
9 * Ambresh K <ambresh@ti.com>
10 * Oleksandr Kozaruk <oleksandr.kozaruk@ti.com
11 *
12 * Based on twl4030-madc.c
13 * Copyright (C) 2008 Nokia Corporation
14 * Mikko Ylinen <mikko.k.ylinen@nokia.com>
15 *
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License
18 * version 2 as published by the Free Software Foundation.
19 *
20 * This program is distributed in the hope that it will be useful, but
21 * WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 * General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
28 * 02110-1301 USA
29 *
30 */
31#include <linux/init.h>
32#include <linux/interrupt.h>
33#include <linux/kernel.h>
34#include <linux/module.h>
35#include <linux/platform_device.h>
36#include <linux/of_platform.h>
37#include <linux/i2c/twl.h>
38#include <linux/iio/iio.h>
39#include <linux/iio/sysfs.h>
40
41#define DRIVER_NAME "twl6030_gpadc"
42
43/*
44 * twl6030 per TRM has 17 channels, and twl6032 has 19 channels
45 * 2 test network channels are not used,
46 * 2 die temperature channels are not used either, as it is not
47 * defined how to convert ADC value to temperature
48 */
49#define TWL6030_GPADC_USED_CHANNELS 13
50#define TWL6030_GPADC_MAX_CHANNELS 15
51#define TWL6032_GPADC_USED_CHANNELS 15
52#define TWL6032_GPADC_MAX_CHANNELS 19
53#define TWL6030_GPADC_NUM_TRIM_REGS 16
54
55#define TWL6030_GPADC_CTRL_P1 0x05
56
57#define TWL6032_GPADC_GPSELECT_ISB 0x07
58#define TWL6032_GPADC_CTRL_P1 0x08
59
60#define TWL6032_GPADC_GPCH0_LSB 0x0d
61#define TWL6032_GPADC_GPCH0_MSB 0x0e
62
63#define TWL6030_GPADC_CTRL_P1_SP1 BIT(3)
64
65#define TWL6030_GPADC_GPCH0_LSB (0x29)
66
67#define TWL6030_GPADC_RT_SW1_EOC_MASK BIT(5)
68
69#define TWL6030_GPADC_TRIM1 0xCD
70
71#define TWL6030_REG_TOGGLE1 0x90
72#define TWL6030_GPADCS BIT(1)
73#define TWL6030_GPADCR BIT(0)
74
75/**
76 * struct twl6030_chnl_calib - channel calibration
77 * @gain: slope coefficient for ideal curve
78 * @gain_error: gain error
79 * @offset_error: offset of the real curve
80 */
81struct twl6030_chnl_calib {
82 s32 gain;
83 s32 gain_error;
84 s32 offset_error;
85};
86
87/**
88 * struct twl6030_ideal_code - GPADC calibration parameters
89 * GPADC is calibrated in two points: close to the beginning and
90 * to the and of the measurable input range
91 *
92 * @channel: channel number
93 * @code1: ideal code for the input at the beginning
94 * @code2: ideal code for at the end of the range
95 * @volt1: voltage input at the beginning(low voltage)
96 * @volt2: voltage input at the end(high voltage)
97 */
98struct twl6030_ideal_code {
99 int channel;
100 u16 code1;
101 u16 code2;
102 u16 volt1;
103 u16 volt2;
104};
105
106struct twl6030_gpadc_data;
107
108/**
109 * struct twl6030_gpadc_platform_data - platform specific data
110 * @nchannels: number of GPADC channels
111 * @iio_channels: iio channels
112 * @twl6030_ideal: pointer to calibration parameters
113 * @start_conversion: pointer to ADC start conversion function
114 * @channel_to_reg pointer to ADC function to convert channel to
115 * register address for reading conversion result
116 * @calibrate: pointer to calibration function
117 */
118struct twl6030_gpadc_platform_data {
119 const int nchannels;
120 const struct iio_chan_spec *iio_channels;
121 const struct twl6030_ideal_code *ideal;
122 int (*start_conversion)(int channel);
123 u8 (*channel_to_reg)(int channel);
124 int (*calibrate)(struct twl6030_gpadc_data *gpadc);
125};
126
127/**
128 * struct twl6030_gpadc_data - GPADC data
129 * @dev: device pointer
130 * @lock: mutual exclusion lock for the structure
131 * @irq_complete: completion to signal end of conversion
132 * @twl6030_cal_tbl: pointer to calibration data for each
133 * channel with gain error and offset
134 * @pdata: pointer to device specific data
135 */
136struct twl6030_gpadc_data {
137 struct device *dev;
138 struct mutex lock;
139 struct completion irq_complete;
140 struct twl6030_chnl_calib *twl6030_cal_tbl;
141 const struct twl6030_gpadc_platform_data *pdata;
142};
143
144/*
145 * channels 11, 12, 13, 15 and 16 have no calibration data
146 * calibration offset is same for channels 1, 3, 4, 5
147 *
148 * The data is taken from GPADC_TRIM registers description.
149 * GPADC_TRIM registers keep difference between the code measured
150 * at volt1 and volt2 input voltages and corresponding code1 and code2
151 */
152static const struct twl6030_ideal_code
153 twl6030_ideal[TWL6030_GPADC_USED_CHANNELS] = {
154 [0] = { /* ch 0, external, battery type, resistor value */
155 .channel = 0,
156 .code1 = 116,
157 .code2 = 745,
158 .volt1 = 141,
159 .volt2 = 910,
160 },
161 [1] = { /* ch 1, external, battery temperature, NTC resistor value */
162 .channel = 1,
163 .code1 = 82,
164 .code2 = 900,
165 .volt1 = 100,
166 .volt2 = 1100,
167 },
168 [2] = { /* ch 2, external, audio accessory/general purpose */
169 .channel = 2,
170 .code1 = 55,
171 .code2 = 818,
172 .volt1 = 101,
173 .volt2 = 1499,
174 },
175 [3] = { /* ch 3, external, general purpose */
176 .channel = 3,
177 .code1 = 82,
178 .code2 = 900,
179 .volt1 = 100,
180 .volt2 = 1100,
181 },
182 [4] = { /* ch 4, external, temperature measurement/general purpose */
183 .channel = 4,
184 .code1 = 82,
185 .code2 = 900,
186 .volt1 = 100,
187 .volt2 = 1100,
188 },
189 [5] = { /* ch 5, external, general purpose */
190 .channel = 5,
191 .code1 = 82,
192 .code2 = 900,
193 .volt1 = 100,
194 .volt2 = 1100,
195 },
196 [6] = { /* ch 6, external, general purpose */
197 .channel = 6,
198 .code1 = 82,
199 .code2 = 900,
200 .volt1 = 100,
201 .volt2 = 1100,
202 },
203 [7] = { /* ch 7, internal, main battery */
204 .channel = 7,
205 .code1 = 614,
206 .code2 = 941,
207 .volt1 = 3001,
208 .volt2 = 4599,
209 },
210 [8] = { /* ch 8, internal, backup battery */
211 .channel = 8,
212 .code1 = 82,
213 .code2 = 688,
214 .volt1 = 501,
215 .volt2 = 4203,
216 },
217 [9] = { /* ch 9, internal, external charger input */
218 .channel = 9,
219 .code1 = 182,
220 .code2 = 818,
221 .volt1 = 2001,
222 .volt2 = 8996,
223 },
224 [10] = { /* ch 10, internal, VBUS */
225 .channel = 10,
226 .code1 = 149,
227 .code2 = 818,
228 .volt1 = 1001,
229 .volt2 = 5497,
230 },
231 [11] = { /* ch 11, internal, VBUS charging current */
232 .channel = 11,
233 },
234 /* ch 12, internal, Die temperature */
235 /* ch 13, internal, Die temperature */
236 [12] = { /* ch 14, internal, USB ID line */
237 .channel = 14,
238 .code1 = 48,
239 .code2 = 714,
240 .volt1 = 323,
241 .volt2 = 4800,
242 },
243};
244
245static const struct twl6030_ideal_code
246 twl6032_ideal[TWL6032_GPADC_USED_CHANNELS] = {
247 [0] = { /* ch 0, external, battery type, resistor value */
248 .channel = 0,
249 .code1 = 1441,
250 .code2 = 3276,
251 .volt1 = 440,
252 .volt2 = 1000,
253 },
254 [1] = { /* ch 1, external, battery temperature, NTC resistor value */
255 .channel = 1,
256 .code1 = 1441,
257 .code2 = 3276,
258 .volt1 = 440,
259 .volt2 = 1000,
260 },
261 [2] = { /* ch 2, external, audio accessory/general purpose */
262 .channel = 2,
263 .code1 = 1441,
264 .code2 = 3276,
265 .volt1 = 660,
266 .volt2 = 1500,
267 },
268 [3] = { /* ch 3, external, temperature with external diode/general
269 purpose */
270 .channel = 3,
271 .code1 = 1441,
272 .code2 = 3276,
273 .volt1 = 440,
274 .volt2 = 1000,
275 },
276 [4] = { /* ch 4, external, temperature measurement/general purpose */
277 .channel = 4,
278 .code1 = 1441,
279 .code2 = 3276,
280 .volt1 = 440,
281 .volt2 = 1000,
282 },
283 [5] = { /* ch 5, external, general purpose */
284 .channel = 5,
285 .code1 = 1441,
286 .code2 = 3276,
287 .volt1 = 440,
288 .volt2 = 1000,
289 },
290 [6] = { /* ch 6, external, general purpose */
291 .channel = 6,
292 .code1 = 1441,
293 .code2 = 3276,
294 .volt1 = 440,
295 .volt2 = 1000,
296 },
297 [7] = { /* ch7, internal, system supply */
298 .channel = 7,
299 .code1 = 1441,
300 .code2 = 3276,
301 .volt1 = 2200,
302 .volt2 = 5000,
303 },
304 [8] = { /* ch8, internal, backup battery */
305 .channel = 8,
306 .code1 = 1441,
307 .code2 = 3276,
308 .volt1 = 2200,
309 .volt2 = 5000,
310 },
311 [9] = { /* ch 9, internal, external charger input */
312 .channel = 9,
313 .code1 = 1441,
314 .code2 = 3276,
315 .volt1 = 3960,
316 .volt2 = 9000,
317 },
318 [10] = { /* ch10, internal, VBUS */
319 .channel = 10,
320 .code1 = 150,
321 .code2 = 751,
322 .volt1 = 1000,
323 .volt2 = 5000,
324 },
325 [11] = { /* ch 11, internal, VBUS DC-DC output current */
326 .channel = 11,
327 .code1 = 1441,
328 .code2 = 3276,
329 .volt1 = 660,
330 .volt2 = 1500,
331 },
332 /* ch 12, internal, Die temperature */
333 /* ch 13, internal, Die temperature */
334 [12] = { /* ch 14, internal, USB ID line */
335 .channel = 14,
336 .code1 = 1441,
337 .code2 = 3276,
338 .volt1 = 2420,
339 .volt2 = 5500,
340 },
341 /* ch 15, internal, test network */
342 /* ch 16, internal, test network */
343 [13] = { /* ch 17, internal, battery charging current */
344 .channel = 17,
345 },
346 [14] = { /* ch 18, internal, battery voltage */
347 .channel = 18,
348 .code1 = 1441,
349 .code2 = 3276,
350 .volt1 = 2200,
351 .volt2 = 5000,
352 },
353};
354
355static inline int twl6030_gpadc_write(u8 reg, u8 val)
356{
357 return twl_i2c_write_u8(TWL6030_MODULE_GPADC, val, reg);
358}
359
360static inline int twl6030_gpadc_read(u8 reg, u8 *val)
361{
362
363 return twl_i2c_read(TWL6030_MODULE_GPADC, val, reg, 2);
364}
365
366static int twl6030_gpadc_enable_irq(u8 mask)
367{
368 int ret;
369
370 ret = twl6030_interrupt_unmask(mask, REG_INT_MSK_LINE_B);
371 if (ret < 0)
372 return ret;
373
374 ret = twl6030_interrupt_unmask(mask, REG_INT_MSK_STS_B);
375
376 return ret;
377}
378
379static void twl6030_gpadc_disable_irq(u8 mask)
380{
381 twl6030_interrupt_mask(mask, REG_INT_MSK_LINE_B);
382 twl6030_interrupt_mask(mask, REG_INT_MSK_STS_B);
383}
384
385static irqreturn_t twl6030_gpadc_irq_handler(int irq, void *indio_dev)
386{
387 struct twl6030_gpadc_data *gpadc = iio_priv(indio_dev);
388
389 complete(&gpadc->irq_complete);
390
391 return IRQ_HANDLED;
392}
393
394static int twl6030_start_conversion(int channel)
395{
396 return twl6030_gpadc_write(TWL6030_GPADC_CTRL_P1,
397 TWL6030_GPADC_CTRL_P1_SP1);
398}
399
400static int twl6032_start_conversion(int channel)
401{
402 int ret;
403
404 ret = twl6030_gpadc_write(TWL6032_GPADC_GPSELECT_ISB, channel);
405 if (ret)
406 return ret;
407
408 return twl6030_gpadc_write(TWL6032_GPADC_CTRL_P1,
409 TWL6030_GPADC_CTRL_P1_SP1);
410}
411
412static u8 twl6030_channel_to_reg(int channel)
413{
414 return TWL6030_GPADC_GPCH0_LSB + 2 * channel;
415}
416
417static u8 twl6032_channel_to_reg(int channel)
418{
419 /*
420 * for any prior chosen channel, when the conversion is ready
421 * the result is avalable in GPCH0_LSB, GPCH0_MSB.
422 */
423
424 return TWL6032_GPADC_GPCH0_LSB;
425}
426
427static int twl6030_gpadc_lookup(const struct twl6030_ideal_code *ideal,
428 int channel, int size)
429{
430 int i;
431
432 for (i = 0; i < size; i++)
433 if (ideal[i].channel == channel)
434 break;
435
436 return i;
437}
438
439static int twl6030_channel_calibrated(const struct twl6030_gpadc_platform_data
440 *pdata, int channel)
441{
442 const struct twl6030_ideal_code *ideal = pdata->ideal;
443 int i;
444
445 i = twl6030_gpadc_lookup(ideal, channel, pdata->nchannels);
446 /* not calibrated channels have 0 in all structure members */
447 return pdata->ideal[i].code2;
448}
449
450static int twl6030_gpadc_make_correction(struct twl6030_gpadc_data *gpadc,
451 int channel, int raw_code)
452{
453 const struct twl6030_ideal_code *ideal = gpadc->pdata->ideal;
454 int corrected_code;
455 int i;
456
457 i = twl6030_gpadc_lookup(ideal, channel, gpadc->pdata->nchannels);
458 corrected_code = ((raw_code * 1000) -
459 gpadc->twl6030_cal_tbl[i].offset_error) /
460 gpadc->twl6030_cal_tbl[i].gain_error;
461
462 return corrected_code;
463}
464
465static int twl6030_gpadc_get_raw(struct twl6030_gpadc_data *gpadc,
466 int channel, int *res)
467{
468 u8 reg = gpadc->pdata->channel_to_reg(channel);
469 __le16 val;
470 int raw_code;
471 int ret;
472
473 ret = twl6030_gpadc_read(reg, (u8 *)&val);
474 if (ret) {
475 dev_dbg(gpadc->dev, "unable to read register 0x%X\n", reg);
476 return ret;
477 }
478
479 raw_code = le16_to_cpu(val);
480 dev_dbg(gpadc->dev, "GPADC raw code: %d", raw_code);
481
482 if (twl6030_channel_calibrated(gpadc->pdata, channel))
483 *res = twl6030_gpadc_make_correction(gpadc, channel, raw_code);
484 else
485 *res = raw_code;
486
487 return ret;
488}
489
490static int twl6030_gpadc_get_processed(struct twl6030_gpadc_data *gpadc,
491 int channel, int *val)
492{
493 const struct twl6030_ideal_code *ideal = gpadc->pdata->ideal;
494 int corrected_code;
495 int channel_value;
496 int i;
497 int ret;
498
499 ret = twl6030_gpadc_get_raw(gpadc, channel, &corrected_code);
500 if (ret)
501 return ret;
502
503 i = twl6030_gpadc_lookup(ideal, channel, gpadc->pdata->nchannels);
504 channel_value = corrected_code *
505 gpadc->twl6030_cal_tbl[i].gain;
506
507 /* Shift back into mV range */
508 channel_value /= 1000;
509
510 dev_dbg(gpadc->dev, "GPADC corrected code: %d", corrected_code);
511 dev_dbg(gpadc->dev, "GPADC value: %d", channel_value);
512
513 *val = channel_value;
514
515 return ret;
516}
517
518static int twl6030_gpadc_read_raw(struct iio_dev *indio_dev,
519 const struct iio_chan_spec *chan,
520 int *val, int *val2, long mask)
521{
522 struct twl6030_gpadc_data *gpadc = iio_priv(indio_dev);
523 int ret;
524 long timeout;
525
526 mutex_lock(&gpadc->lock);
527
528 ret = gpadc->pdata->start_conversion(chan->channel);
529 if (ret) {
530 dev_err(gpadc->dev, "failed to start conversion\n");
531 goto err;
532 }
533 /* wait for conversion to complete */
534 timeout = wait_for_completion_interruptible_timeout(
535 &gpadc->irq_complete, msecs_to_jiffies(5000));
536 if (timeout == 0) {
537 ret = -ETIMEDOUT;
538 goto err;
539 } else if (timeout < 0) {
540 goto err;
541 ret = -EINTR;
542 }
543
544 switch (mask) {
545 case IIO_CHAN_INFO_RAW:
546 ret = twl6030_gpadc_get_raw(gpadc, chan->channel, val);
547 ret = ret ? -EIO : IIO_VAL_INT;
548 break;
549
550 case IIO_CHAN_INFO_PROCESSED:
551 ret = twl6030_gpadc_get_processed(gpadc, chan->channel, val);
552 ret = ret ? -EIO : IIO_VAL_INT;
553 break;
554
555 default:
556 break;
557 }
558err:
559 mutex_unlock(&gpadc->lock);
560
561 return ret;
562}
563
564/*
565 * The GPADC channels are calibrated using a two point calibration method.
566 * The channels measured with two known values: volt1 and volt2, and
567 * ideal corresponding output codes are known: code1, code2.
568 * The difference(d1, d2) between ideal and measured codes stored in trim
569 * registers.
570 * The goal is to find offset and gain of the real curve for each calibrated
571 * channel.
572 * gain: k = 1 + ((d2 - d1) / (x2 - x1))
573 * offset: b = d1 + (k - 1) * x1
574 */
575static void twl6030_calibrate_channel(struct twl6030_gpadc_data *gpadc,
576 int channel, int d1, int d2)
577{
578 int b, k, gain, x1, x2, i;
579 const struct twl6030_ideal_code *ideal = gpadc->pdata->ideal;
580
581 i = twl6030_gpadc_lookup(ideal, channel, gpadc->pdata->nchannels);
582
583 /* Gain */
584 gain = ((ideal[i].volt2 - ideal[i].volt1) * 1000) /
585 (ideal[i].code2 - ideal[i].code1);
586
587 x1 = ideal[i].code1;
588 x2 = ideal[i].code2;
589
590 /* k - real curve gain */
591 k = 1000 + (((d2 - d1) * 1000) / (x2 - x1));
592
593 /* b - offset of the real curve gain */
594 b = (d1 * 1000) - (k - 1000) * x1;
595
596 gpadc->twl6030_cal_tbl[i].gain = gain;
597 gpadc->twl6030_cal_tbl[i].gain_error = k;
598 gpadc->twl6030_cal_tbl[i].offset_error = b;
599
600 dev_dbg(gpadc->dev, "GPADC d1 for Chn: %d = %d\n", channel, d1);
601 dev_dbg(gpadc->dev, "GPADC d2 for Chn: %d = %d\n", channel, d2);
602 dev_dbg(gpadc->dev, "GPADC x1 for Chn: %d = %d\n", channel, x1);
603 dev_dbg(gpadc->dev, "GPADC x2 for Chn: %d = %d\n", channel, x2);
604 dev_dbg(gpadc->dev, "GPADC Gain for Chn: %d = %d\n", channel, gain);
605 dev_dbg(gpadc->dev, "GPADC k for Chn: %d = %d\n", channel, k);
606 dev_dbg(gpadc->dev, "GPADC b for Chn: %d = %d\n", channel, b);
607}
608
609static inline int twl6030_gpadc_get_trim_offset(s8 d)
610{
611 /*
612 * XXX NOTE!
613 * bit 0 - sign, bit 7 - reserved, 6..1 - trim value
614 * though, the documentation states that trim value
615 * is absolute value, the correct conversion results are
616 * obtained if the value is interpreted as 2's complement.
617 */
618 __u32 temp = ((d & 0x7f) >> 1) | ((d & 1) << 6);
619
620 return sign_extend32(temp, 6);
621}
622
623static int twl6030_calibration(struct twl6030_gpadc_data *gpadc)
624{
625 int ret;
626 int chn;
627 u8 trim_regs[TWL6030_GPADC_NUM_TRIM_REGS];
628 s8 d1, d2;
629
630 /*
631 * for calibration two measurements have been performed at
632 * factory, for some channels, during the production test and
633 * have been stored in registers. This two stored values are
634 * used to correct the measurements. The values represent
635 * offsets for the given input from the output on ideal curve.
636 */
637 ret = twl_i2c_read(TWL6030_MODULE_ID2, trim_regs,
638 TWL6030_GPADC_TRIM1, TWL6030_GPADC_NUM_TRIM_REGS);
639 if (ret < 0) {
640 dev_err(gpadc->dev, "calibration failed\n");
641 return ret;
642 }
643
644 for (chn = 0; chn < TWL6030_GPADC_MAX_CHANNELS; chn++) {
645
646 switch (chn) {
647 case 0:
648 d1 = trim_regs[0];
649 d2 = trim_regs[1];
650 break;
651 case 1:
652 case 3:
653 case 4:
654 case 5:
655 case 6:
656 d1 = trim_regs[4];
657 d2 = trim_regs[5];
658 break;
659 case 2:
660 d1 = trim_regs[12];
661 d2 = trim_regs[13];
662 break;
663 case 7:
664 d1 = trim_regs[6];
665 d2 = trim_regs[7];
666 break;
667 case 8:
668 d1 = trim_regs[2];
669 d2 = trim_regs[3];
670 break;
671 case 9:
672 d1 = trim_regs[8];
673 d2 = trim_regs[9];
674 break;
675 case 10:
676 d1 = trim_regs[10];
677 d2 = trim_regs[11];
678 break;
679 case 14:
680 d1 = trim_regs[14];
681 d2 = trim_regs[15];
682 break;
683 default:
684 continue;
685 }
686
687 d1 = twl6030_gpadc_get_trim_offset(d1);
688 d2 = twl6030_gpadc_get_trim_offset(d2);
689
690 twl6030_calibrate_channel(gpadc, chn, d1, d2);
691 }
692
693 return 0;
694}
695
696static int twl6032_get_trim_value(u8 *trim_regs, unsigned int reg0,
697 unsigned int reg1, unsigned int mask0, unsigned int mask1,
698 unsigned int shift0)
699{
700 int val;
701
702 val = (trim_regs[reg0] & mask0) << shift0;
703 val |= (trim_regs[reg1] & mask1) >> 1;
704 if (trim_regs[reg1] & 0x01)
705 val = -val;
706
707 return val;
708}
709
710static int twl6032_calibration(struct twl6030_gpadc_data *gpadc)
711{
712 int chn, d1 = 0, d2 = 0, temp;
713 u8 trim_regs[TWL6030_GPADC_NUM_TRIM_REGS];
714 int ret;
715
716 ret = twl_i2c_read(TWL6030_MODULE_ID2, trim_regs,
717 TWL6030_GPADC_TRIM1, TWL6030_GPADC_NUM_TRIM_REGS);
718 if (ret < 0) {
719 dev_err(gpadc->dev, "calibration failed\n");
720 return ret;
721 }
722
723 /*
724 * Loop to calculate the value needed for returning voltages from
725 * GPADC not values.
726 *
727 * gain is calculated to 3 decimal places fixed point.
728 */
729 for (chn = 0; chn < TWL6032_GPADC_MAX_CHANNELS; chn++) {
730
731 switch (chn) {
732 case 0:
733 case 1:
734 case 2:
735 case 3:
736 case 4:
737 case 5:
738 case 6:
739 case 11:
740 case 14:
741 d1 = twl6032_get_trim_value(trim_regs, 2, 0, 0x1f,
742 0x06, 2);
743 d2 = twl6032_get_trim_value(trim_regs, 3, 1, 0x3f,
744 0x06, 2);
745 break;
746 case 8:
747 temp = twl6032_get_trim_value(trim_regs, 2, 0, 0x1f,
748 0x06, 2);
749 d1 = temp + twl6032_get_trim_value(trim_regs, 7, 6,
750 0x18, 0x1E, 1);
751
752 temp = twl6032_get_trim_value(trim_regs, 3, 1, 0x3F,
753 0x06, 2);
754 d2 = temp + twl6032_get_trim_value(trim_regs, 9, 7,
755 0x1F, 0x06, 2);
756 break;
757 case 9:
758 temp = twl6032_get_trim_value(trim_regs, 2, 0, 0x1f,
759 0x06, 2);
760 d1 = temp + twl6032_get_trim_value(trim_regs, 13, 11,
761 0x18, 0x1E, 1);
762
763 temp = twl6032_get_trim_value(trim_regs, 3, 1, 0x3f,
764 0x06, 2);
765 d2 = temp + twl6032_get_trim_value(trim_regs, 15, 13,
766 0x1F, 0x06, 1);
767 break;
768 case 10:
769 d1 = twl6032_get_trim_value(trim_regs, 10, 8, 0x0f,
770 0x0E, 3);
771 d2 = twl6032_get_trim_value(trim_regs, 14, 12, 0x0f,
772 0x0E, 3);
773 break;
774 case 7:
775 case 18:
776 temp = twl6032_get_trim_value(trim_regs, 2, 0, 0x1f,
777 0x06, 2);
778
779 d1 = (trim_regs[4] & 0x7E) >> 1;
780 if (trim_regs[4] & 0x01)
781 d1 = -d1;
782 d1 += temp;
783
784 temp = twl6032_get_trim_value(trim_regs, 3, 1, 0x3f,
785 0x06, 2);
786
787 d2 = (trim_regs[5] & 0xFE) >> 1;
788 if (trim_regs[5] & 0x01)
789 d2 = -d2;
790
791 d2 += temp;
792 break;
793 default:
794 /* No data for other channels */
795 continue;
796 }
797
798 twl6030_calibrate_channel(gpadc, chn, d1, d2);
799 }
800
801 return 0;
802}
803
804#define TWL6030_GPADC_CHAN(chn, _type, chan_info) { \
805 .type = _type, \
806 .channel = chn, \
807 .info_mask_separate = BIT(chan_info), \
808 .indexed = 1, \
809}
810
811static const struct iio_chan_spec twl6030_gpadc_iio_channels[] = {
812 TWL6030_GPADC_CHAN(0, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
813 TWL6030_GPADC_CHAN(1, IIO_TEMP, IIO_CHAN_INFO_RAW),
814 TWL6030_GPADC_CHAN(2, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
815 TWL6030_GPADC_CHAN(3, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
816 TWL6030_GPADC_CHAN(4, IIO_TEMP, IIO_CHAN_INFO_RAW),
817 TWL6030_GPADC_CHAN(5, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
818 TWL6030_GPADC_CHAN(6, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
819 TWL6030_GPADC_CHAN(7, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
820 TWL6030_GPADC_CHAN(8, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
821 TWL6030_GPADC_CHAN(9, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
822 TWL6030_GPADC_CHAN(10, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
823 TWL6030_GPADC_CHAN(11, IIO_VOLTAGE, IIO_CHAN_INFO_RAW),
824 TWL6030_GPADC_CHAN(14, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
825};
826
827static const struct iio_chan_spec twl6032_gpadc_iio_channels[] = {
828 TWL6030_GPADC_CHAN(0, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
829 TWL6030_GPADC_CHAN(1, IIO_TEMP, IIO_CHAN_INFO_RAW),
830 TWL6030_GPADC_CHAN(2, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
831 TWL6030_GPADC_CHAN(3, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
832 TWL6030_GPADC_CHAN(4, IIO_TEMP, IIO_CHAN_INFO_RAW),
833 TWL6030_GPADC_CHAN(5, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
834 TWL6030_GPADC_CHAN(6, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
835 TWL6030_GPADC_CHAN(7, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
836 TWL6030_GPADC_CHAN(8, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
837 TWL6030_GPADC_CHAN(9, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
838 TWL6030_GPADC_CHAN(10, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
839 TWL6030_GPADC_CHAN(11, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
840 TWL6030_GPADC_CHAN(14, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
841 TWL6030_GPADC_CHAN(17, IIO_VOLTAGE, IIO_CHAN_INFO_RAW),
842 TWL6030_GPADC_CHAN(18, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
843};
844
845static const struct iio_info twl6030_gpadc_iio_info = {
846 .read_raw = &twl6030_gpadc_read_raw,
847 .driver_module = THIS_MODULE,
848};
849
850static const struct twl6030_gpadc_platform_data twl6030_pdata = {
851 .iio_channels = twl6030_gpadc_iio_channels,
852 .nchannels = TWL6030_GPADC_USED_CHANNELS,
853 .ideal = twl6030_ideal,
854 .start_conversion = twl6030_start_conversion,
855 .channel_to_reg = twl6030_channel_to_reg,
856 .calibrate = twl6030_calibration,
857};
858
859static const struct twl6030_gpadc_platform_data twl6032_pdata = {
860 .iio_channels = twl6032_gpadc_iio_channels,
861 .nchannels = TWL6032_GPADC_USED_CHANNELS,
862 .ideal = twl6032_ideal,
863 .start_conversion = twl6032_start_conversion,
864 .channel_to_reg = twl6032_channel_to_reg,
865 .calibrate = twl6032_calibration,
866};
867
868static const struct of_device_id of_twl6030_match_tbl[] = {
869 {
870 .compatible = "ti,twl6030-gpadc",
871 .data = &twl6030_pdata,
872 },
873 {
874 .compatible = "ti,twl6032-gpadc",
875 .data = &twl6032_pdata,
876 },
877 { /* end */ }
878};
879
880static int twl6030_gpadc_probe(struct platform_device *pdev)
881{
882 struct device *dev = &pdev->dev;
883 struct twl6030_gpadc_data *gpadc;
884 const struct twl6030_gpadc_platform_data *pdata;
885 const struct of_device_id *match;
886 struct iio_dev *indio_dev;
887 int irq;
888 int ret;
889
890 match = of_match_device(of_match_ptr(of_twl6030_match_tbl), dev);
891 if (!match)
892 return -EINVAL;
893
894 pdata = match->data;
895
896 indio_dev = iio_device_alloc(sizeof(*gpadc));
897 if (!indio_dev) {
898 dev_err(dev, "failed allocating iio device\n");
899 ret = -ENOMEM;
900 }
901
902 gpadc = iio_priv(indio_dev);
903
904 gpadc->twl6030_cal_tbl = devm_kzalloc(dev,
905 sizeof(*gpadc->twl6030_cal_tbl) *
906 pdata->nchannels, GFP_KERNEL);
907 if (!gpadc->twl6030_cal_tbl)
908 goto err_free_device;
909
910 gpadc->dev = dev;
911 gpadc->pdata = pdata;
912
913 platform_set_drvdata(pdev, indio_dev);
914 mutex_init(&gpadc->lock);
915 init_completion(&gpadc->irq_complete);
916
917 ret = pdata->calibrate(gpadc);
918 if (ret < 0) {
919 dev_err(&pdev->dev, "failed to read calibration registers\n");
920 goto err_free_device;
921 }
922
923 irq = platform_get_irq(pdev, 0);
924 if (irq < 0) {
925 dev_err(&pdev->dev, "failed to get irq\n");
926 goto err_free_device;
927 }
928
929 ret = request_threaded_irq(irq, NULL, twl6030_gpadc_irq_handler,
930 IRQF_ONESHOT, "twl6030_gpadc", indio_dev);
931 if (ret) {
932 dev_dbg(&pdev->dev, "could not request irq\n");
933 goto err_free_device;
934 }
935
936 ret = twl6030_gpadc_enable_irq(TWL6030_GPADC_RT_SW1_EOC_MASK);
937 if (ret < 0) {
938 dev_err(&pdev->dev, "failed to enable GPADC interrupt\n");
939 goto err_free_irq;
940 }
941
942 ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, TWL6030_GPADCS,
943 TWL6030_REG_TOGGLE1);
944 if (ret < 0) {
945 dev_err(&pdev->dev, "failed to enable GPADC module\n");
946 goto err_free_irq;
947 }
948
949 indio_dev->name = DRIVER_NAME;
950 indio_dev->dev.parent = dev;
951 indio_dev->info = &twl6030_gpadc_iio_info;
952 indio_dev->modes = INDIO_DIRECT_MODE;
953 indio_dev->channels = pdata->iio_channels;
954 indio_dev->num_channels = pdata->nchannels;
955
956 ret = iio_device_register(indio_dev);
957 if (ret)
958 goto err_free_irq;
959
960 return ret;
961
962err_free_irq:
963 free_irq(irq, indio_dev);
964err_free_device:
965 iio_device_free(indio_dev);
966
967 return ret;
968}
969
970static int twl6030_gpadc_remove(struct platform_device *pdev)
971{
972 struct iio_dev *indio_dev = platform_get_drvdata(pdev);
973
974 twl6030_gpadc_disable_irq(TWL6030_GPADC_RT_SW1_EOC_MASK);
975 free_irq(platform_get_irq(pdev, 0), indio_dev);
976 iio_device_unregister(indio_dev);
977 iio_device_free(indio_dev);
978
979 return 0;
980}
981
982#ifdef CONFIG_PM_SLEEP
983static int twl6030_gpadc_suspend(struct device *pdev)
984{
985 int ret;
986
987 ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, TWL6030_GPADCR,
988 TWL6030_REG_TOGGLE1);
989 if (ret)
990 dev_err(pdev, "error reseting GPADC (%d)!\n", ret);
991
992 return 0;
993};
994
995static int twl6030_gpadc_resume(struct device *pdev)
996{
997 int ret;
998
999 ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, TWL6030_GPADCS,
1000 TWL6030_REG_TOGGLE1);
1001 if (ret)
1002 dev_err(pdev, "error setting GPADC (%d)!\n", ret);
1003
1004 return 0;
1005};
1006#endif
1007
1008static SIMPLE_DEV_PM_OPS(twl6030_gpadc_pm_ops, twl6030_gpadc_suspend,
1009 twl6030_gpadc_resume);
1010
1011static struct platform_driver twl6030_gpadc_driver = {
1012 .probe = twl6030_gpadc_probe,
1013 .remove = twl6030_gpadc_remove,
1014 .driver = {
1015 .name = DRIVER_NAME,
1016 .owner = THIS_MODULE,
1017 .pm = &twl6030_gpadc_pm_ops,
1018 .of_match_table = of_twl6030_match_tbl,
1019 },
1020};
1021
1022module_platform_driver(twl6030_gpadc_driver);
1023
1024MODULE_ALIAS("platform: " DRIVER_NAME);
1025MODULE_AUTHOR("Balaji T K <balajitk@ti.com>");
1026MODULE_AUTHOR("Graeme Gregory <gg@slimlogic.co.uk>");
1027MODULE_AUTHOR("Oleksandr Kozaruk <oleksandr.kozaruk@ti.com");
1028MODULE_DESCRIPTION("twl6030 ADC driver");
1029MODULE_LICENSE("GPL");