1
2
3
4
5
6
7
8
9#include <linux/init.h>
10#include <linux/module.h>
11#include <linux/device.h>
12#include <linux/interrupt.h>
13#include <linux/spinlock.h>
14#include <linux/delay.h>
15#include <linux/platform_device.h>
16#include <linux/completion.h>
17#include <linux/regulator/consumer.h>
18#include <linux/err.h>
19#include <linux/slab.h>
20#include <linux/list.h>
21#include <linux/mfd/ab8500.h>
22#include <linux/mfd/abx500.h>
23#include <linux/mfd/ab8500/gpadc.h>
24
25
26
27
28
29#define AB8500_GPADC_CTRL1_REG 0x00
30#define AB8500_GPADC_CTRL2_REG 0x01
31#define AB8500_GPADC_CTRL3_REG 0x02
32#define AB8500_GPADC_AUTO_TIMER_REG 0x03
33#define AB8500_GPADC_STAT_REG 0x04
34#define AB8500_GPADC_MANDATAL_REG 0x05
35#define AB8500_GPADC_MANDATAH_REG 0x06
36#define AB8500_GPADC_AUTODATAL_REG 0x07
37#define AB8500_GPADC_AUTODATAH_REG 0x08
38#define AB8500_GPADC_MUX_CTRL_REG 0x09
39
40
41
42
43
44#define AB8500_GPADC_CAL_1 0x0F
45#define AB8500_GPADC_CAL_2 0x10
46#define AB8500_GPADC_CAL_3 0x11
47#define AB8500_GPADC_CAL_4 0x12
48#define AB8500_GPADC_CAL_5 0x13
49#define AB8500_GPADC_CAL_6 0x14
50#define AB8500_GPADC_CAL_7 0x15
51
52
53#define EN_VINTCORE12 0x04
54#define EN_VTVOUT 0x02
55#define EN_GPADC 0x01
56#define DIS_GPADC 0x00
57#define SW_AVG_16 0x60
58#define ADC_SW_CONV 0x04
59#define EN_ICHAR 0x80
60#define EN_BUF 0x40
61#define DIS_ZERO 0x00
62#define GPADC_BUSY 0x01
63
64
65#define ADC_RESOLUTION 1024
66#define ADC_CH_BTEMP_MIN 0
67#define ADC_CH_BTEMP_MAX 1350
68#define ADC_CH_DIETEMP_MIN 0
69#define ADC_CH_DIETEMP_MAX 1350
70#define ADC_CH_CHG_V_MIN 0
71#define ADC_CH_CHG_V_MAX 20030
72#define ADC_CH_ACCDET2_MIN 0
73#define ADC_CH_ACCDET2_MAX 2500
74#define ADC_CH_VBAT_MIN 2300
75#define ADC_CH_VBAT_MAX 4800
76#define ADC_CH_CHG_I_MIN 0
77#define ADC_CH_CHG_I_MAX 1500
78#define ADC_CH_BKBAT_MIN 0
79#define ADC_CH_BKBAT_MAX 3200
80
81
82#define CALIB_SCALE 1000
83
84enum cal_channels {
85 ADC_INPUT_VMAIN = 0,
86 ADC_INPUT_BTEMP,
87 ADC_INPUT_VBAT,
88 NBR_CAL_INPUTS,
89};
90
91
92
93
94
95
96
97struct adc_cal_data {
98 u64 gain;
99 u64 offset;
100};
101
102
103
104
105
106
107
108
109
110
111
112
113
114struct ab8500_gpadc {
115 struct device *dev;
116 struct list_head node;
117 struct completion ab8500_gpadc_complete;
118 struct mutex ab8500_gpadc_lock;
119 struct regulator *regu;
120 int irq;
121 struct adc_cal_data cal_data[NBR_CAL_INPUTS];
122};
123
124static LIST_HEAD(ab8500_gpadc_list);
125
126
127
128
129
130struct ab8500_gpadc *ab8500_gpadc_get(char *name)
131{
132 struct ab8500_gpadc *gpadc;
133
134 list_for_each_entry(gpadc, &ab8500_gpadc_list, node) {
135 if (!strcmp(name, dev_name(gpadc->dev)))
136 return gpadc;
137 }
138
139 return ERR_PTR(-ENOENT);
140}
141EXPORT_SYMBOL(ab8500_gpadc_get);
142
143static int ab8500_gpadc_ad_to_voltage(struct ab8500_gpadc *gpadc, u8 input,
144 int ad_value)
145{
146 int res;
147
148 switch (input) {
149 case MAIN_CHARGER_V:
150
151 if (!gpadc->cal_data[ADC_INPUT_VMAIN].gain) {
152 res = ADC_CH_CHG_V_MIN + (ADC_CH_CHG_V_MAX -
153 ADC_CH_CHG_V_MIN) * ad_value /
154 ADC_RESOLUTION;
155 break;
156 }
157
158 res = (int) (ad_value * gpadc->cal_data[ADC_INPUT_VMAIN].gain +
159 gpadc->cal_data[ADC_INPUT_VMAIN].offset) / CALIB_SCALE;
160 break;
161
162 case BAT_CTRL:
163 case BTEMP_BALL:
164 case ACC_DETECT1:
165 case ADC_AUX1:
166 case ADC_AUX2:
167
168 if (!gpadc->cal_data[ADC_INPUT_BTEMP].gain) {
169 res = ADC_CH_BTEMP_MIN + (ADC_CH_BTEMP_MAX -
170 ADC_CH_BTEMP_MIN) * ad_value /
171 ADC_RESOLUTION;
172 break;
173 }
174
175 res = (int) (ad_value * gpadc->cal_data[ADC_INPUT_BTEMP].gain +
176 gpadc->cal_data[ADC_INPUT_BTEMP].offset) / CALIB_SCALE;
177 break;
178
179 case MAIN_BAT_V:
180
181 if (!gpadc->cal_data[ADC_INPUT_VBAT].gain) {
182 res = ADC_CH_VBAT_MIN + (ADC_CH_VBAT_MAX -
183 ADC_CH_VBAT_MIN) * ad_value /
184 ADC_RESOLUTION;
185 break;
186 }
187
188 res = (int) (ad_value * gpadc->cal_data[ADC_INPUT_VBAT].gain +
189 gpadc->cal_data[ADC_INPUT_VBAT].offset) / CALIB_SCALE;
190 break;
191
192 case DIE_TEMP:
193 res = ADC_CH_DIETEMP_MIN +
194 (ADC_CH_DIETEMP_MAX - ADC_CH_DIETEMP_MIN) * ad_value /
195 ADC_RESOLUTION;
196 break;
197
198 case ACC_DETECT2:
199 res = ADC_CH_ACCDET2_MIN +
200 (ADC_CH_ACCDET2_MAX - ADC_CH_ACCDET2_MIN) * ad_value /
201 ADC_RESOLUTION;
202 break;
203
204 case VBUS_V:
205 res = ADC_CH_CHG_V_MIN +
206 (ADC_CH_CHG_V_MAX - ADC_CH_CHG_V_MIN) * ad_value /
207 ADC_RESOLUTION;
208 break;
209
210 case MAIN_CHARGER_C:
211 case USB_CHARGER_C:
212 res = ADC_CH_CHG_I_MIN +
213 (ADC_CH_CHG_I_MAX - ADC_CH_CHG_I_MIN) * ad_value /
214 ADC_RESOLUTION;
215 break;
216
217 case BK_BAT_V:
218 res = ADC_CH_BKBAT_MIN +
219 (ADC_CH_BKBAT_MAX - ADC_CH_BKBAT_MIN) * ad_value /
220 ADC_RESOLUTION;
221 break;
222
223 default:
224 dev_err(gpadc->dev,
225 "unknown channel, not possible to convert\n");
226 res = -EINVAL;
227 break;
228
229 }
230 return res;
231}
232
233
234
235
236
237
238
239
240int ab8500_gpadc_convert(struct ab8500_gpadc *gpadc, u8 input)
241{
242 int ret;
243 u16 data = 0;
244 int looplimit = 0;
245 u8 val, low_data, high_data;
246
247 if (!gpadc)
248 return -ENODEV;
249
250 mutex_lock(&gpadc->ab8500_gpadc_lock);
251
252 regulator_enable(gpadc->regu);
253
254
255 do {
256 ret = abx500_get_register_interruptible(gpadc->dev,
257 AB8500_GPADC, AB8500_GPADC_STAT_REG, &val);
258 if (ret < 0)
259 goto out;
260 if (!(val & GPADC_BUSY))
261 break;
262 msleep(10);
263 } while (++looplimit < 10);
264 if (looplimit >= 10 && (val & GPADC_BUSY)) {
265 dev_err(gpadc->dev, "gpadc_conversion: GPADC busy");
266 ret = -EINVAL;
267 goto out;
268 }
269
270
271 ret = abx500_mask_and_set_register_interruptible(gpadc->dev,
272 AB8500_GPADC, AB8500_GPADC_CTRL1_REG, EN_GPADC, EN_GPADC);
273 if (ret < 0) {
274 dev_err(gpadc->dev, "gpadc_conversion: enable gpadc failed\n");
275 goto out;
276 }
277
278 ret = abx500_set_register_interruptible(gpadc->dev, AB8500_GPADC,
279 AB8500_GPADC_CTRL2_REG, (input | SW_AVG_16));
280 if (ret < 0) {
281 dev_err(gpadc->dev,
282 "gpadc_conversion: set avg samples failed\n");
283 goto out;
284 }
285
286
287
288
289 switch (input) {
290 case MAIN_CHARGER_C:
291 case USB_CHARGER_C:
292 ret = abx500_mask_and_set_register_interruptible(gpadc->dev,
293 AB8500_GPADC, AB8500_GPADC_CTRL1_REG,
294 EN_BUF | EN_ICHAR,
295 EN_BUF | EN_ICHAR);
296 break;
297 default:
298 ret = abx500_mask_and_set_register_interruptible(gpadc->dev,
299 AB8500_GPADC, AB8500_GPADC_CTRL1_REG, EN_BUF, EN_BUF);
300 break;
301 }
302 if (ret < 0) {
303 dev_err(gpadc->dev,
304 "gpadc_conversion: select falling edge failed\n");
305 goto out;
306 }
307 ret = abx500_mask_and_set_register_interruptible(gpadc->dev,
308 AB8500_GPADC, AB8500_GPADC_CTRL1_REG, ADC_SW_CONV, ADC_SW_CONV);
309 if (ret < 0) {
310 dev_err(gpadc->dev,
311 "gpadc_conversion: start s/w conversion failed\n");
312 goto out;
313 }
314
315 if (!wait_for_completion_timeout(&gpadc->ab8500_gpadc_complete, 2*HZ)) {
316 dev_err(gpadc->dev,
317 "timeout: didn't receive GPADC conversion interrupt\n");
318 ret = -EINVAL;
319 goto out;
320 }
321
322
323 ret = abx500_get_register_interruptible(gpadc->dev, AB8500_GPADC,
324 AB8500_GPADC_MANDATAL_REG, &low_data);
325 if (ret < 0) {
326 dev_err(gpadc->dev, "gpadc_conversion: read low data failed\n");
327 goto out;
328 }
329
330 ret = abx500_get_register_interruptible(gpadc->dev, AB8500_GPADC,
331 AB8500_GPADC_MANDATAH_REG, &high_data);
332 if (ret < 0) {
333 dev_err(gpadc->dev,
334 "gpadc_conversion: read high data failed\n");
335 goto out;
336 }
337
338 data = (high_data << 8) | low_data;
339
340 ret = abx500_set_register_interruptible(gpadc->dev, AB8500_GPADC,
341 AB8500_GPADC_CTRL1_REG, DIS_GPADC);
342 if (ret < 0) {
343 dev_err(gpadc->dev, "gpadc_conversion: disable gpadc failed\n");
344 goto out;
345 }
346
347 regulator_disable(gpadc->regu);
348 mutex_unlock(&gpadc->ab8500_gpadc_lock);
349 ret = ab8500_gpadc_ad_to_voltage(gpadc, input, data);
350 return ret;
351
352out:
353
354
355
356
357
358
359 (void) abx500_set_register_interruptible(gpadc->dev, AB8500_GPADC,
360 AB8500_GPADC_CTRL1_REG, DIS_GPADC);
361 regulator_disable(gpadc->regu);
362 mutex_unlock(&gpadc->ab8500_gpadc_lock);
363 dev_err(gpadc->dev,
364 "gpadc_conversion: Failed to AD convert channel %d\n", input);
365 return ret;
366}
367EXPORT_SYMBOL(ab8500_gpadc_convert);
368
369
370
371
372
373
374
375
376
377
378
379static irqreturn_t ab8500_bm_gpswadcconvend_handler(int irq, void *_gpadc)
380{
381 struct ab8500_gpadc *gpadc = _gpadc;
382
383 complete(&gpadc->ab8500_gpadc_complete);
384
385 return IRQ_HANDLED;
386}
387
388static int otp_cal_regs[] = {
389 AB8500_GPADC_CAL_1,
390 AB8500_GPADC_CAL_2,
391 AB8500_GPADC_CAL_3,
392 AB8500_GPADC_CAL_4,
393 AB8500_GPADC_CAL_5,
394 AB8500_GPADC_CAL_6,
395 AB8500_GPADC_CAL_7,
396};
397
398static void ab8500_gpadc_read_calibration_data(struct ab8500_gpadc *gpadc)
399{
400 int i;
401 int ret[ARRAY_SIZE(otp_cal_regs)];
402 u8 gpadc_cal[ARRAY_SIZE(otp_cal_regs)];
403
404 int vmain_high, vmain_low;
405 int btemp_high, btemp_low;
406 int vbat_high, vbat_low;
407
408
409 for (i = 0; i < ARRAY_SIZE(otp_cal_regs); i++) {
410 ret[i] = abx500_get_register_interruptible(gpadc->dev,
411 AB8500_OTP_EMUL, otp_cal_regs[i], &gpadc_cal[i]);
412 if (ret[i] < 0)
413 dev_err(gpadc->dev, "%s: read otp reg 0x%02x failed\n",
414 __func__, otp_cal_regs[i]);
415 }
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457 if (!(ret[0] < 0 || ret[1] < 0 || ret[2] < 0)) {
458 vmain_high = (((gpadc_cal[0] & 0x03) << 8) |
459 ((gpadc_cal[1] & 0x3F) << 2) |
460 ((gpadc_cal[2] & 0xC0) >> 6));
461
462 vmain_low = ((gpadc_cal[2] & 0x3E) >> 1);
463
464 gpadc->cal_data[ADC_INPUT_VMAIN].gain = CALIB_SCALE *
465 (19500 - 315) / (vmain_high - vmain_low);
466
467 gpadc->cal_data[ADC_INPUT_VMAIN].offset = CALIB_SCALE * 19500 -
468 (CALIB_SCALE * (19500 - 315) /
469 (vmain_high - vmain_low)) * vmain_high;
470 } else {
471 gpadc->cal_data[ADC_INPUT_VMAIN].gain = 0;
472 }
473
474
475 if (!(ret[2] < 0 || ret[3] < 0 || ret[4] < 0)) {
476 btemp_high = (((gpadc_cal[2] & 0x01) << 9) |
477 (gpadc_cal[3] << 1) |
478 ((gpadc_cal[4] & 0x80) >> 7));
479
480 btemp_low = ((gpadc_cal[4] & 0x7C) >> 2);
481
482 gpadc->cal_data[ADC_INPUT_BTEMP].gain =
483 CALIB_SCALE * (1300 - 21) / (btemp_high - btemp_low);
484
485 gpadc->cal_data[ADC_INPUT_BTEMP].offset = CALIB_SCALE * 1300 -
486 (CALIB_SCALE * (1300 - 21) /
487 (btemp_high - btemp_low)) * btemp_high;
488 } else {
489 gpadc->cal_data[ADC_INPUT_BTEMP].gain = 0;
490 }
491
492
493 if (!(ret[4] < 0 || ret[5] < 0 || ret[6] < 0)) {
494 vbat_high = (((gpadc_cal[4] & 0x03) << 8) | gpadc_cal[5]);
495 vbat_low = ((gpadc_cal[6] & 0xFC) >> 2);
496
497 gpadc->cal_data[ADC_INPUT_VBAT].gain = CALIB_SCALE *
498 (4700 - 2380) / (vbat_high - vbat_low);
499
500 gpadc->cal_data[ADC_INPUT_VBAT].offset = CALIB_SCALE * 4700 -
501 (CALIB_SCALE * (4700 - 2380) /
502 (vbat_high - vbat_low)) * vbat_high;
503 } else {
504 gpadc->cal_data[ADC_INPUT_VBAT].gain = 0;
505 }
506
507 dev_dbg(gpadc->dev, "VMAIN gain %llu offset %llu\n",
508 gpadc->cal_data[ADC_INPUT_VMAIN].gain,
509 gpadc->cal_data[ADC_INPUT_VMAIN].offset);
510
511 dev_dbg(gpadc->dev, "BTEMP gain %llu offset %llu\n",
512 gpadc->cal_data[ADC_INPUT_BTEMP].gain,
513 gpadc->cal_data[ADC_INPUT_BTEMP].offset);
514
515 dev_dbg(gpadc->dev, "VBAT gain %llu offset %llu\n",
516 gpadc->cal_data[ADC_INPUT_VBAT].gain,
517 gpadc->cal_data[ADC_INPUT_VBAT].offset);
518}
519
520static int __devinit ab8500_gpadc_probe(struct platform_device *pdev)
521{
522 int ret = 0;
523 struct ab8500_gpadc *gpadc;
524
525 gpadc = kzalloc(sizeof(struct ab8500_gpadc), GFP_KERNEL);
526 if (!gpadc) {
527 dev_err(&pdev->dev, "Error: No memory\n");
528 return -ENOMEM;
529 }
530
531 gpadc->irq = platform_get_irq_byname(pdev, "SW_CONV_END");
532 if (gpadc->irq < 0) {
533 dev_err(gpadc->dev, "failed to get platform irq-%d\n",
534 gpadc->irq);
535 ret = gpadc->irq;
536 goto fail;
537 }
538
539 gpadc->dev = &pdev->dev;
540 mutex_init(&gpadc->ab8500_gpadc_lock);
541
542
543 init_completion(&gpadc->ab8500_gpadc_complete);
544
545
546 ret = request_threaded_irq(gpadc->irq, NULL,
547 ab8500_bm_gpswadcconvend_handler,
548 IRQF_NO_SUSPEND | IRQF_SHARED, "ab8500-gpadc", gpadc);
549 if (ret < 0) {
550 dev_err(gpadc->dev, "Failed to register interrupt, irq: %d\n",
551 gpadc->irq);
552 goto fail;
553 }
554
555
556 gpadc->regu = regulator_get(&pdev->dev, "vddadc");
557 if (IS_ERR(gpadc->regu)) {
558 ret = PTR_ERR(gpadc->regu);
559 dev_err(gpadc->dev, "failed to get vtvout LDO\n");
560 goto fail_irq;
561 }
562 ab8500_gpadc_read_calibration_data(gpadc);
563 list_add_tail(&gpadc->node, &ab8500_gpadc_list);
564 dev_dbg(gpadc->dev, "probe success\n");
565 return 0;
566fail_irq:
567 free_irq(gpadc->irq, gpadc);
568fail:
569 kfree(gpadc);
570 gpadc = NULL;
571 return ret;
572}
573
574static int __devexit ab8500_gpadc_remove(struct platform_device *pdev)
575{
576 struct ab8500_gpadc *gpadc = platform_get_drvdata(pdev);
577
578
579 list_del(&gpadc->node);
580
581 free_irq(gpadc->irq, gpadc);
582
583 regulator_put(gpadc->regu);
584 kfree(gpadc);
585 gpadc = NULL;
586 return 0;
587}
588
589static struct platform_driver ab8500_gpadc_driver = {
590 .probe = ab8500_gpadc_probe,
591 .remove = __devexit_p(ab8500_gpadc_remove),
592 .driver = {
593 .name = "ab8500-gpadc",
594 .owner = THIS_MODULE,
595 },
596};
597
598static int __init ab8500_gpadc_init(void)
599{
600 return platform_driver_register(&ab8500_gpadc_driver);
601}
602
603static void __exit ab8500_gpadc_exit(void)
604{
605 platform_driver_unregister(&ab8500_gpadc_driver);
606}
607
608subsys_initcall_sync(ab8500_gpadc_init);
609module_exit(ab8500_gpadc_exit);
610
611MODULE_LICENSE("GPL v2");
612MODULE_AUTHOR("Arun R Murthy, Daniel Willerud, Johan Palsson");
613MODULE_ALIAS("platform:ab8500_gpadc");
614MODULE_DESCRIPTION("AB8500 GPADC driver");
615