blob: 1e44d65e1771d1859e31ce1804ba5da5fe35cf5b [file] [log] [blame]
Mattias Wallin5814fc32010-09-13 16:05:04 +02001/*
2 * Copyright (C) ST-Ericsson SA 2010
3 *
4 * Author: Mattias Wallin <mattias.wallin@stericsson.com> for ST-Ericsson.
5 * License Terms: GNU General Public License v2
6 */
carriere etienne0fbce762011-04-08 16:26:36 +02007/*
8 * AB8500 register access
9 * ======================
10 *
11 * read:
12 * # echo BANK > <debugfs>/ab8500/register-bank
13 * # echo ADDR > <debugfs>/ab8500/register-address
14 * # cat <debugfs>/ab8500/register-value
15 *
16 * write:
17 * # echo BANK > <debugfs>/ab8500/register-bank
18 * # echo ADDR > <debugfs>/ab8500/register-address
19 * # echo VALUE > <debugfs>/ab8500/register-value
20 *
21 * read all registers from a bank:
22 * # echo BANK > <debugfs>/ab8500/register-bank
23 * # cat <debugfs>/ab8500/all-bank-register
24 *
25 * BANK target AB8500 register bank
26 * ADDR target AB8500 register address
27 * VALUE decimal or 0x-prefixed hexadecimal
28 *
29 *
30 * User Space notification on AB8500 IRQ
31 * =====================================
32 *
33 * Allows user space entity to be notified when target AB8500 IRQ occurs.
34 * When subscribed, a sysfs entry is created in ab8500.i2c platform device.
35 * One can pool this file to get target IRQ occurence information.
36 *
37 * subscribe to an AB8500 IRQ:
38 * # echo IRQ > <debugfs>/ab8500/irq-subscribe
39 *
40 * unsubscribe from an AB8500 IRQ:
41 * # echo IRQ > <debugfs>/ab8500/irq-unsubscribe
42 *
43 *
44 * AB8500 register formated read/write access
45 * ==========================================
46 *
47 * Read: read data, data>>SHIFT, data&=MASK, output data
48 * [0xABCDEF98] shift=12 mask=0xFFF => 0x00000CDE
49 * Write: read data, data &= ~(MASK<<SHIFT), data |= (VALUE<<SHIFT), write data
50 * [0xABCDEF98] shift=12 mask=0xFFF value=0x123 => [0xAB123F98]
51 *
52 * Usage:
53 * # echo "CMD [OPTIONS] BANK ADRESS [VALUE]" > $debugfs/ab8500/hwreg
54 *
55 * CMD read read access
56 * write write access
57 *
58 * BANK target reg bank
59 * ADDRESS target reg address
60 * VALUE (write) value to be updated
61 *
62 * OPTIONS
63 * -d|-dec (read) output in decimal
64 * -h|-hexa (read) output in 0x-hexa (default)
65 * -l|-w|-b 32bit (default), 16bit or 8bit reg access
66 * -m|-mask MASK 0x-hexa mask (default 0xFFFFFFFF)
67 * -s|-shift SHIFT bit shift value (read:left, write:right)
68 * -o|-offset OFFSET address offset to add to ADDRESS value
69 *
70 * Warning: bit shift operation is applied to bit-mask.
71 * Warning: bit shift direction depends on read or right command.
72 */
Mattias Wallin5814fc32010-09-13 16:05:04 +020073
74#include <linux/seq_file.h>
75#include <linux/uaccess.h>
76#include <linux/fs.h>
Paul Gortmaker4e36dd32011-07-03 15:13:27 -040077#include <linux/module.h>
Mattias Wallin5814fc32010-09-13 16:05:04 +020078#include <linux/debugfs.h>
79#include <linux/platform_device.h>
Lee Jones4b8ac082013-01-14 16:10:36 +000080#include <linux/interrupt.h>
81#include <linux/kobject.h>
82#include <linux/slab.h>
Jonas Aaberg2cf64e22012-05-31 07:57:07 +020083#include <linux/irq.h>
Mattias Wallin5814fc32010-09-13 16:05:04 +020084
85#include <linux/mfd/abx500.h>
Linus Walleij0cd5b6d02013-02-06 23:23:01 +010086#include <linux/mfd/abx500/ab8500.h>
John Beckett1478a312011-05-31 13:54:27 +010087#include <linux/mfd/abx500/ab8500-gpadc.h>
Mattias Wallin5814fc32010-09-13 16:05:04 +020088
carriere etienne0fbce762011-04-08 16:26:36 +020089#ifdef CONFIG_DEBUG_FS
90#include <linux/string.h>
91#include <linux/ctype.h>
92#endif
93
Mattias Wallin5814fc32010-09-13 16:05:04 +020094static u32 debug_bank;
95static u32 debug_address;
96
Lee Jones4b8ac082013-01-14 16:10:36 +000097static int irq_first;
98static int irq_last;
Linus Walleijddba25f2012-02-03 11:19:05 +010099static u32 *irq_count;
100static int num_irqs;
Mattias Wallin0b337e72010-11-19 17:55:11 +0100101
Linus Walleijddba25f2012-02-03 11:19:05 +0100102static struct device_attribute **dev_attr;
103static char **event_name;
Lee Jones4b8ac082013-01-14 16:10:36 +0000104
Lee Jones73482342013-02-26 10:06:55 +0000105static u8 avg_sample = SAMPLE_16;
106static u8 trig_edge = RISING_EDGE;
107static u8 conv_type = ADC_SW;
108static u8 trig_timer;
109
Mattias Wallin5814fc32010-09-13 16:05:04 +0200110/**
111 * struct ab8500_reg_range
112 * @first: the first address of the range
113 * @last: the last address of the range
114 * @perm: access permissions for the range
115 */
116struct ab8500_reg_range {
Mattias Wallind7b9f322010-11-26 13:06:39 +0100117 u8 first;
118 u8 last;
119 u8 perm;
Mattias Wallin5814fc32010-09-13 16:05:04 +0200120};
121
122/**
Lee Jones822672a2012-06-20 13:56:38 +0100123 * struct ab8500_prcmu_ranges
Mattias Wallin5814fc32010-09-13 16:05:04 +0200124 * @num_ranges: the number of ranges in the list
125 * @bankid: bank identifier
126 * @range: the list of register ranges
127 */
Lee Jones822672a2012-06-20 13:56:38 +0100128struct ab8500_prcmu_ranges {
Mattias Wallind7b9f322010-11-26 13:06:39 +0100129 u8 num_ranges;
130 u8 bankid;
131 const struct ab8500_reg_range *range;
Mattias Wallin5814fc32010-09-13 16:05:04 +0200132};
133
carriere etienne0fbce762011-04-08 16:26:36 +0200134/* hwreg- "mask" and "shift" entries ressources */
135struct hwreg_cfg {
136 u32 bank; /* target bank */
137 u32 addr; /* target address */
138 uint fmt; /* format */
139 uint mask; /* read/write mask, applied before any bit shift */
140 int shift; /* bit shift (read:right shift, write:left shift */
141};
142/* fmt bit #0: 0=hexa, 1=dec */
143#define REG_FMT_DEC(c) ((c)->fmt & 0x1)
144#define REG_FMT_HEX(c) (!REG_FMT_DEC(c))
145
146static struct hwreg_cfg hwreg_cfg = {
147 .addr = 0, /* default: invalid phys addr */
148 .fmt = 0, /* default: 32bit access, hex output */
149 .mask = 0xFFFFFFFF, /* default: no mask */
150 .shift = 0, /* default: no bit shift */
151};
152
Mattias Wallin5814fc32010-09-13 16:05:04 +0200153#define AB8500_NAME_STRING "ab8500"
John Beckett1478a312011-05-31 13:54:27 +0100154#define AB8500_ADC_NAME_STRING "gpadc"
Philippe Langlais40c064e2011-10-17 09:48:55 +0200155#define AB8500_NUM_BANKS 24
Mattias Wallin5814fc32010-09-13 16:05:04 +0200156
157#define AB8500_REV_REG 0x80
158
Lee Jones9581ae32012-07-06 16:11:50 +0200159static struct ab8500_prcmu_ranges *debug_ranges;
160
161struct ab8500_prcmu_ranges ab8500_debug_ranges[AB8500_NUM_BANKS] = {
Mattias Wallind7b9f322010-11-26 13:06:39 +0100162 [0x0] = {
163 .num_ranges = 0,
Lee Jonesfad55a82013-01-14 17:17:34 +0000164 .range = NULL,
Mattias Wallind7b9f322010-11-26 13:06:39 +0100165 },
166 [AB8500_SYS_CTRL1_BLOCK] = {
167 .num_ranges = 3,
168 .range = (struct ab8500_reg_range[]) {
169 {
170 .first = 0x00,
171 .last = 0x02,
172 },
173 {
174 .first = 0x42,
175 .last = 0x42,
176 },
177 {
178 .first = 0x80,
179 .last = 0x81,
180 },
181 },
182 },
183 [AB8500_SYS_CTRL2_BLOCK] = {
184 .num_ranges = 4,
185 .range = (struct ab8500_reg_range[]) {
186 {
187 .first = 0x00,
188 .last = 0x0D,
189 },
190 {
191 .first = 0x0F,
192 .last = 0x17,
193 },
194 {
195 .first = 0x30,
196 .last = 0x30,
197 },
198 {
199 .first = 0x32,
200 .last = 0x33,
201 },
202 },
203 },
204 [AB8500_REGU_CTRL1] = {
205 .num_ranges = 3,
206 .range = (struct ab8500_reg_range[]) {
207 {
208 .first = 0x00,
209 .last = 0x00,
210 },
211 {
212 .first = 0x03,
213 .last = 0x10,
214 },
215 {
216 .first = 0x80,
217 .last = 0x84,
218 },
219 },
220 },
221 [AB8500_REGU_CTRL2] = {
222 .num_ranges = 5,
223 .range = (struct ab8500_reg_range[]) {
224 {
225 .first = 0x00,
226 .last = 0x15,
227 },
228 {
229 .first = 0x17,
230 .last = 0x19,
231 },
232 {
233 .first = 0x1B,
234 .last = 0x1D,
235 },
236 {
237 .first = 0x1F,
238 .last = 0x22,
239 },
240 {
241 .first = 0x40,
242 .last = 0x44,
243 },
244 /* 0x80-0x8B is SIM registers and should
245 * not be accessed from here */
246 },
247 },
248 [AB8500_USB] = {
249 .num_ranges = 2,
250 .range = (struct ab8500_reg_range[]) {
251 {
252 .first = 0x80,
253 .last = 0x83,
254 },
255 {
256 .first = 0x87,
257 .last = 0x8A,
258 },
259 },
260 },
261 [AB8500_TVOUT] = {
262 .num_ranges = 9,
263 .range = (struct ab8500_reg_range[]) {
264 {
265 .first = 0x00,
266 .last = 0x12,
267 },
268 {
269 .first = 0x15,
270 .last = 0x17,
271 },
272 {
273 .first = 0x19,
274 .last = 0x21,
275 },
276 {
277 .first = 0x27,
278 .last = 0x2C,
279 },
280 {
281 .first = 0x41,
282 .last = 0x41,
283 },
284 {
285 .first = 0x45,
286 .last = 0x5B,
287 },
288 {
289 .first = 0x5D,
290 .last = 0x5D,
291 },
292 {
293 .first = 0x69,
294 .last = 0x69,
295 },
296 {
297 .first = 0x80,
298 .last = 0x81,
299 },
300 },
301 },
302 [AB8500_DBI] = {
303 .num_ranges = 0,
Mark Brown87fff232010-12-13 14:06:47 +0000304 .range = NULL,
Mattias Wallind7b9f322010-11-26 13:06:39 +0100305 },
306 [AB8500_ECI_AV_ACC] = {
307 .num_ranges = 1,
308 .range = (struct ab8500_reg_range[]) {
309 {
310 .first = 0x80,
311 .last = 0x82,
312 },
313 },
314 },
315 [0x9] = {
316 .num_ranges = 0,
Mark Brown87fff232010-12-13 14:06:47 +0000317 .range = NULL,
Mattias Wallind7b9f322010-11-26 13:06:39 +0100318 },
319 [AB8500_GPADC] = {
320 .num_ranges = 1,
321 .range = (struct ab8500_reg_range[]) {
322 {
323 .first = 0x00,
324 .last = 0x08,
325 },
326 },
327 },
328 [AB8500_CHARGER] = {
Philippe Langlais40c064e2011-10-17 09:48:55 +0200329 .num_ranges = 9,
Mattias Wallind7b9f322010-11-26 13:06:39 +0100330 .range = (struct ab8500_reg_range[]) {
331 {
332 .first = 0x00,
333 .last = 0x03,
334 },
335 {
336 .first = 0x05,
337 .last = 0x05,
338 },
339 {
340 .first = 0x40,
341 .last = 0x40,
342 },
343 {
344 .first = 0x42,
345 .last = 0x42,
346 },
347 {
348 .first = 0x44,
349 .last = 0x44,
350 },
351 {
352 .first = 0x50,
353 .last = 0x55,
354 },
355 {
356 .first = 0x80,
357 .last = 0x82,
358 },
359 {
360 .first = 0xC0,
361 .last = 0xC2,
362 },
Philippe Langlais40c064e2011-10-17 09:48:55 +0200363 {
364 .first = 0xf5,
Lee Jones9581ae32012-07-06 16:11:50 +0200365 .last = 0xf6,
Philippe Langlais40c064e2011-10-17 09:48:55 +0200366 },
Mattias Wallind7b9f322010-11-26 13:06:39 +0100367 },
368 },
369 [AB8500_GAS_GAUGE] = {
370 .num_ranges = 3,
371 .range = (struct ab8500_reg_range[]) {
372 {
373 .first = 0x00,
374 .last = 0x00,
375 },
376 {
377 .first = 0x07,
378 .last = 0x0A,
379 },
380 {
381 .first = 0x10,
382 .last = 0x14,
383 },
384 },
385 },
Philippe Langlais40c064e2011-10-17 09:48:55 +0200386 [AB8500_DEVELOPMENT] = {
387 .num_ranges = 1,
388 .range = (struct ab8500_reg_range[]) {
389 {
390 .first = 0x00,
391 .last = 0x00,
392 },
393 },
394 },
395 [AB8500_DEBUG] = {
396 .num_ranges = 1,
397 .range = (struct ab8500_reg_range[]) {
398 {
399 .first = 0x05,
400 .last = 0x07,
401 },
402 },
403 },
Mattias Wallind7b9f322010-11-26 13:06:39 +0100404 [AB8500_AUDIO] = {
405 .num_ranges = 1,
406 .range = (struct ab8500_reg_range[]) {
407 {
408 .first = 0x00,
409 .last = 0x6F,
410 },
411 },
412 },
413 [AB8500_INTERRUPT] = {
414 .num_ranges = 0,
Mark Brown87fff232010-12-13 14:06:47 +0000415 .range = NULL,
Mattias Wallind7b9f322010-11-26 13:06:39 +0100416 },
417 [AB8500_RTC] = {
418 .num_ranges = 1,
419 .range = (struct ab8500_reg_range[]) {
420 {
421 .first = 0x00,
422 .last = 0x0F,
423 },
424 },
425 },
426 [AB8500_MISC] = {
427 .num_ranges = 8,
428 .range = (struct ab8500_reg_range[]) {
429 {
430 .first = 0x00,
431 .last = 0x05,
432 },
433 {
434 .first = 0x10,
435 .last = 0x15,
436 },
437 {
438 .first = 0x20,
439 .last = 0x25,
440 },
441 {
442 .first = 0x30,
443 .last = 0x35,
444 },
445 {
446 .first = 0x40,
447 .last = 0x45,
448 },
449 {
450 .first = 0x50,
451 .last = 0x50,
452 },
453 {
454 .first = 0x60,
455 .last = 0x67,
456 },
457 {
458 .first = 0x80,
459 .last = 0x80,
460 },
461 },
462 },
463 [0x11] = {
464 .num_ranges = 0,
Mark Brown87fff232010-12-13 14:06:47 +0000465 .range = NULL,
Mattias Wallind7b9f322010-11-26 13:06:39 +0100466 },
467 [0x12] = {
468 .num_ranges = 0,
Mark Brown87fff232010-12-13 14:06:47 +0000469 .range = NULL,
Mattias Wallind7b9f322010-11-26 13:06:39 +0100470 },
471 [0x13] = {
472 .num_ranges = 0,
Mark Brown87fff232010-12-13 14:06:47 +0000473 .range = NULL,
Mattias Wallind7b9f322010-11-26 13:06:39 +0100474 },
475 [0x14] = {
476 .num_ranges = 0,
Mark Brown87fff232010-12-13 14:06:47 +0000477 .range = NULL,
Mattias Wallind7b9f322010-11-26 13:06:39 +0100478 },
479 [AB8500_OTP_EMUL] = {
480 .num_ranges = 1,
481 .range = (struct ab8500_reg_range[]) {
482 {
483 .first = 0x01,
484 .last = 0x0F,
485 },
486 },
487 },
Mattias Wallin5814fc32010-09-13 16:05:04 +0200488};
489
Lee Jones9581ae32012-07-06 16:11:50 +0200490struct ab8500_prcmu_ranges ab8505_debug_ranges[AB8500_NUM_BANKS] = {
491 [0x0] = {
492 .num_ranges = 0,
493 .range = NULL,
494 },
495 [AB8500_SYS_CTRL1_BLOCK] = {
496 .num_ranges = 5,
497 .range = (struct ab8500_reg_range[]) {
498 {
499 .first = 0x00,
500 .last = 0x04,
501 },
502 {
503 .first = 0x42,
504 .last = 0x42,
505 },
506 {
507 .first = 0x52,
508 .last = 0x52,
509 },
510 {
511 .first = 0x54,
512 .last = 0x57,
513 },
514 {
515 .first = 0x80,
516 .last = 0x83,
517 },
518 },
519 },
520 [AB8500_SYS_CTRL2_BLOCK] = {
521 .num_ranges = 5,
522 .range = (struct ab8500_reg_range[]) {
523 {
524 .first = 0x00,
525 .last = 0x0D,
526 },
527 {
528 .first = 0x0F,
529 .last = 0x17,
530 },
531 {
532 .first = 0x20,
533 .last = 0x20,
534 },
535 {
536 .first = 0x30,
537 .last = 0x30,
538 },
539 {
540 .first = 0x32,
541 .last = 0x3A,
542 },
543 },
544 },
545 [AB8500_REGU_CTRL1] = {
546 .num_ranges = 3,
547 .range = (struct ab8500_reg_range[]) {
548 {
549 .first = 0x00,
550 .last = 0x00,
551 },
552 {
553 .first = 0x03,
554 .last = 0x11,
555 },
556 {
557 .first = 0x80,
558 .last = 0x86,
559 },
560 },
561 },
562 [AB8500_REGU_CTRL2] = {
563 .num_ranges = 6,
564 .range = (struct ab8500_reg_range[]) {
565 {
566 .first = 0x00,
567 .last = 0x06,
568 },
569 {
570 .first = 0x08,
571 .last = 0x15,
572 },
573 {
574 .first = 0x17,
575 .last = 0x19,
576 },
577 {
578 .first = 0x1B,
579 .last = 0x1D,
580 },
581 {
582 .first = 0x1F,
583 .last = 0x30,
584 },
585 {
586 .first = 0x40,
587 .last = 0x48,
588 },
589 /* 0x80-0x8B is SIM registers and should
590 * not be accessed from here */
591 },
592 },
593 [AB8500_USB] = {
594 .num_ranges = 3,
595 .range = (struct ab8500_reg_range[]) {
596 {
597 .first = 0x80,
598 .last = 0x83,
599 },
600 {
601 .first = 0x87,
602 .last = 0x8A,
603 },
604 {
605 .first = 0x91,
606 .last = 0x94,
607 },
608 },
609 },
610 [AB8500_TVOUT] = {
611 .num_ranges = 0,
612 .range = NULL,
613 },
614 [AB8500_DBI] = {
615 .num_ranges = 0,
616 .range = NULL,
617 },
618 [AB8500_ECI_AV_ACC] = {
619 .num_ranges = 1,
620 .range = (struct ab8500_reg_range[]) {
621 {
622 .first = 0x80,
623 .last = 0x82,
624 },
625 },
626 },
627 [AB8500_RESERVED] = {
628 .num_ranges = 0,
629 .range = NULL,
630 },
631 [AB8500_GPADC] = {
632 .num_ranges = 1,
633 .range = (struct ab8500_reg_range[]) {
634 {
635 .first = 0x00,
636 .last = 0x08,
637 },
638 },
639 },
640 [AB8500_CHARGER] = {
641 .num_ranges = 9,
642 .range = (struct ab8500_reg_range[]) {
643 {
644 .first = 0x02,
645 .last = 0x03,
646 },
647 {
648 .first = 0x05,
649 .last = 0x05,
650 },
651 {
652 .first = 0x40,
653 .last = 0x44,
654 },
655 {
656 .first = 0x50,
657 .last = 0x57,
658 },
659 {
660 .first = 0x60,
661 .last = 0x60,
662 },
663 {
664 .first = 0xA0,
665 .last = 0xA7,
666 },
667 {
668 .first = 0xAF,
669 .last = 0xB2,
670 },
671 {
672 .first = 0xC0,
673 .last = 0xC2,
674 },
675 {
676 .first = 0xF5,
677 .last = 0xF5,
678 },
679 },
680 },
681 [AB8500_GAS_GAUGE] = {
682 .num_ranges = 3,
683 .range = (struct ab8500_reg_range[]) {
684 {
685 .first = 0x00,
686 .last = 0x00,
687 },
688 {
689 .first = 0x07,
690 .last = 0x0A,
691 },
692 {
693 .first = 0x10,
694 .last = 0x14,
695 },
696 },
697 },
698 [AB8500_AUDIO] = {
699 .num_ranges = 1,
700 .range = (struct ab8500_reg_range[]) {
701 {
702 .first = 0x00,
703 .last = 0x83,
704 },
705 },
706 },
707 [AB8500_INTERRUPT] = {
708 .num_ranges = 11,
709 .range = (struct ab8500_reg_range[]) {
710 {
711 .first = 0x00,
712 .last = 0x04,
713 },
714 {
715 .first = 0x06,
716 .last = 0x07,
717 },
718 {
719 .first = 0x09,
720 .last = 0x09,
721 },
722 {
723 .first = 0x0B,
724 .last = 0x0C,
725 },
726 {
727 .first = 0x12,
728 .last = 0x15,
729 },
730 {
731 .first = 0x18,
732 .last = 0x18,
733 },
734 /* Latch registers should not be read here */
735 {
736 .first = 0x40,
737 .last = 0x44,
738 },
739 {
740 .first = 0x46,
741 .last = 0x49,
742 },
743 {
744 .first = 0x4B,
745 .last = 0x4D,
746 },
747 {
748 .first = 0x52,
749 .last = 0x55,
750 },
751 {
752 .first = 0x58,
753 .last = 0x58,
754 },
755 /* LatchHier registers should not be read here */
756 },
757 },
758 [AB8500_RTC] = {
759 .num_ranges = 2,
760 .range = (struct ab8500_reg_range[]) {
761 {
762 .first = 0x00,
763 .last = 0x14,
764 },
765 {
766 .first = 0x16,
767 .last = 0x17,
768 },
769 },
770 },
771 [AB8500_MISC] = {
772 .num_ranges = 8,
773 .range = (struct ab8500_reg_range[]) {
774 {
775 .first = 0x00,
776 .last = 0x06,
777 },
778 {
779 .first = 0x10,
780 .last = 0x16,
781 },
782 {
783 .first = 0x20,
784 .last = 0x26,
785 },
786 {
787 .first = 0x30,
788 .last = 0x36,
789 },
790 {
791 .first = 0x40,
792 .last = 0x46,
793 },
794 {
795 .first = 0x50,
796 .last = 0x50,
797 },
798 {
799 .first = 0x60,
800 .last = 0x6B,
801 },
802 {
803 .first = 0x80,
804 .last = 0x82,
805 },
806 },
807 },
808 [AB8500_DEVELOPMENT] = {
809 .num_ranges = 2,
810 .range = (struct ab8500_reg_range[]) {
811 {
812 .first = 0x00,
813 .last = 0x00,
814 },
815 {
816 .first = 0x05,
817 .last = 0x05,
818 },
819 },
820 },
821 [AB8500_DEBUG] = {
822 .num_ranges = 1,
823 .range = (struct ab8500_reg_range[]) {
824 {
825 .first = 0x05,
826 .last = 0x07,
827 },
828 },
829 },
830 [AB8500_PROD_TEST] = {
831 .num_ranges = 0,
832 .range = NULL,
833 },
834 [AB8500_STE_TEST] = {
835 .num_ranges = 0,
836 .range = NULL,
837 },
838 [AB8500_OTP_EMUL] = {
839 .num_ranges = 1,
840 .range = (struct ab8500_reg_range[]) {
841 {
842 .first = 0x01,
843 .last = 0x15,
844 },
845 },
846 },
847};
848
Lee Jones4b8ac082013-01-14 16:10:36 +0000849static irqreturn_t ab8500_debug_handler(int irq, void *data)
850{
851 char buf[16];
852 struct kobject *kobj = (struct kobject *)data;
Mattias Wallin0b337e72010-11-19 17:55:11 +0100853 unsigned int irq_abb = irq - irq_first;
Lee Jones4b8ac082013-01-14 16:10:36 +0000854
Linus Walleijddba25f2012-02-03 11:19:05 +0100855 if (irq_abb < num_irqs)
Mattias Wallin0b337e72010-11-19 17:55:11 +0100856 irq_count[irq_abb]++;
Lee Jones4b8ac082013-01-14 16:10:36 +0000857 /*
858 * This makes it possible to use poll for events (POLLPRI | POLLERR)
Mattias Wallin0b337e72010-11-19 17:55:11 +0100859 * from userspace on sysfs file named <irq-nr>
Lee Jones4b8ac082013-01-14 16:10:36 +0000860 */
Mattias Wallin0b337e72010-11-19 17:55:11 +0100861 sprintf(buf, "%d", irq);
Lee Jones4b8ac082013-01-14 16:10:36 +0000862 sysfs_notify(kobj, NULL, buf);
863
864 return IRQ_HANDLED;
865}
866
Mian Yousaf Kaukab42002c62012-01-26 15:39:20 +0100867/* Prints to seq_file or log_buf */
868static int ab8500_registers_print(struct device *dev, u32 bank,
869 struct seq_file *s)
Mattias Wallin5814fc32010-09-13 16:05:04 +0200870{
Mattias Wallind7b9f322010-11-26 13:06:39 +0100871 unsigned int i;
Mattias Wallin5814fc32010-09-13 16:05:04 +0200872
Mattias Wallind7b9f322010-11-26 13:06:39 +0100873 for (i = 0; i < debug_ranges[bank].num_ranges; i++) {
874 u32 reg;
Mattias Wallin5814fc32010-09-13 16:05:04 +0200875
Mattias Wallind7b9f322010-11-26 13:06:39 +0100876 for (reg = debug_ranges[bank].range[i].first;
877 reg <= debug_ranges[bank].range[i].last;
878 reg++) {
879 u8 value;
880 int err;
Mattias Wallin5814fc32010-09-13 16:05:04 +0200881
Mattias Wallind7b9f322010-11-26 13:06:39 +0100882 err = abx500_get_register_interruptible(dev,
883 (u8)bank, (u8)reg, &value);
884 if (err < 0) {
885 dev_err(dev, "ab->read fail %d\n", err);
886 return err;
887 }
Mattias Wallin5814fc32010-09-13 16:05:04 +0200888
Mian Yousaf Kaukab42002c62012-01-26 15:39:20 +0100889 if (s) {
Mattias Wallincfc08492012-05-28 15:53:58 +0200890 err = seq_printf(s, " [0x%02X/0x%02X]: 0x%02X\n",
Mian Yousaf Kaukab42002c62012-01-26 15:39:20 +0100891 bank, reg, value);
892 if (err < 0) {
Mian Yousaf Kaukab42002c62012-01-26 15:39:20 +0100893 /* Error is not returned here since
894 * the output is wanted in any case */
895 return 0;
896 }
897 } else {
Mattias Wallincfc08492012-05-28 15:53:58 +0200898 printk(KERN_INFO" [0x%02X/0x%02X]: 0x%02X\n",
899 bank, reg, value);
Mattias Wallind7b9f322010-11-26 13:06:39 +0100900 }
901 }
902 }
903 return 0;
Mattias Wallin5814fc32010-09-13 16:05:04 +0200904}
905
Mian Yousaf Kaukab42002c62012-01-26 15:39:20 +0100906static int ab8500_print_bank_registers(struct seq_file *s, void *p)
907{
908 struct device *dev = s->private;
909 u32 bank = debug_bank;
910
911 seq_printf(s, AB8500_NAME_STRING " register values:\n");
912
Mattias Wallincfc08492012-05-28 15:53:58 +0200913 seq_printf(s, " bank 0x%02X:\n", bank);
Mian Yousaf Kaukab42002c62012-01-26 15:39:20 +0100914
915 ab8500_registers_print(dev, bank, s);
916 return 0;
917}
918
Mattias Wallin5814fc32010-09-13 16:05:04 +0200919static int ab8500_registers_open(struct inode *inode, struct file *file)
920{
Mian Yousaf Kaukab42002c62012-01-26 15:39:20 +0100921 return single_open(file, ab8500_print_bank_registers, inode->i_private);
Mattias Wallin5814fc32010-09-13 16:05:04 +0200922}
923
924static const struct file_operations ab8500_registers_fops = {
Mattias Wallind7b9f322010-11-26 13:06:39 +0100925 .open = ab8500_registers_open,
926 .read = seq_read,
927 .llseek = seq_lseek,
928 .release = single_release,
929 .owner = THIS_MODULE,
Mattias Wallin5814fc32010-09-13 16:05:04 +0200930};
931
Mian Yousaf Kaukab42002c62012-01-26 15:39:20 +0100932static int ab8500_print_all_banks(struct seq_file *s, void *p)
933{
934 struct device *dev = s->private;
935 unsigned int i;
936 int err;
937
938 seq_printf(s, AB8500_NAME_STRING " register values:\n");
939
940 for (i = 1; i < AB8500_NUM_BANKS; i++) {
Mattias Wallincfc08492012-05-28 15:53:58 +0200941 err = seq_printf(s, " bank 0x%02X:\n", i);
Mian Yousaf Kaukab42002c62012-01-26 15:39:20 +0100942
943 ab8500_registers_print(dev, i, s);
944 }
945 return 0;
946}
947
Mian Yousaf Kaukab1d843a62012-01-27 11:35:41 +0100948/* Dump registers to kernel log */
949void ab8500_dump_all_banks(struct device *dev)
950{
951 unsigned int i;
952
953 printk(KERN_INFO"ab8500 register values:\n");
954
955 for (i = 1; i < AB8500_NUM_BANKS; i++) {
Mattias Wallincfc08492012-05-28 15:53:58 +0200956 printk(KERN_INFO" bank 0x%02X:\n", i);
Mian Yousaf Kaukab1d843a62012-01-27 11:35:41 +0100957 ab8500_registers_print(dev, i, NULL);
958 }
959}
960
Lee Jones5ff90902013-02-12 14:35:28 +0000961/* Space for 500 registers. */
962#define DUMP_MAX_REGS 700
963struct ab8500_register_dump
964{
965 u8 bank;
966 u8 reg;
967 u8 value;
Lee Jones5ff90902013-02-12 14:35:28 +0000968} ab8500_complete_register_dump[DUMP_MAX_REGS];
969
970extern int prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size);
971
972/* This shall only be called upon kernel panic! */
973void ab8500_dump_all_banks_to_mem(void)
974{
975 int i, r = 0;
976 u8 bank;
Jonas Aaberg222460c2012-06-18 10:35:28 +0200977 int err = 0;
Lee Jones5ff90902013-02-12 14:35:28 +0000978
979 pr_info("Saving all ABB registers at \"ab8500_complete_register_dump\" "
980 "for crash analyze.\n");
981
982 for (bank = 1; bank < AB8500_NUM_BANKS; bank++) {
983 for (i = 0; i < debug_ranges[bank].num_ranges; i++) {
984 u8 reg;
985
986 for (reg = debug_ranges[bank].range[i].first;
987 reg <= debug_ranges[bank].range[i].last;
988 reg++) {
989 u8 value;
Lee Jones5ff90902013-02-12 14:35:28 +0000990
991 err = prcmu_abb_read(bank, reg, &value, 1);
992
Jonas Aaberg222460c2012-06-18 10:35:28 +0200993 if (err < 0)
994 goto out;
995
Lee Jones5ff90902013-02-12 14:35:28 +0000996 ab8500_complete_register_dump[r].bank = bank;
997 ab8500_complete_register_dump[r].reg = reg;
998 ab8500_complete_register_dump[r].value = value;
999
1000 r++;
1001
1002 if (r >= DUMP_MAX_REGS) {
1003 pr_err("%s: too many register to dump!\n",
1004 __func__);
Jonas Aaberg222460c2012-06-18 10:35:28 +02001005 err = -EINVAL;
1006 goto out;
Lee Jones5ff90902013-02-12 14:35:28 +00001007 }
1008 }
1009 }
1010 }
Jonas Aaberg222460c2012-06-18 10:35:28 +02001011out:
1012 if (err >= 0)
1013 pr_info("Saved all ABB registers.\n");
1014 else
1015 pr_info("Failed to save all ABB registers.\n");
Lee Jones5ff90902013-02-12 14:35:28 +00001016}
1017
Mian Yousaf Kaukab42002c62012-01-26 15:39:20 +01001018static int ab8500_all_banks_open(struct inode *inode, struct file *file)
1019{
1020 struct seq_file *s;
1021 int err;
1022
1023 err = single_open(file, ab8500_print_all_banks, inode->i_private);
1024 if (!err) {
1025 /* Default buf size in seq_read is not enough */
1026 s = (struct seq_file *)file->private_data;
1027 s->size = (PAGE_SIZE * 2);
1028 s->buf = kmalloc(s->size, GFP_KERNEL);
1029 if (!s->buf) {
1030 single_release(inode, file);
1031 err = -ENOMEM;
1032 }
1033 }
1034 return err;
1035}
1036
1037static const struct file_operations ab8500_all_banks_fops = {
1038 .open = ab8500_all_banks_open,
1039 .read = seq_read,
1040 .llseek = seq_lseek,
1041 .release = single_release,
1042 .owner = THIS_MODULE,
1043};
1044
Mattias Wallin5814fc32010-09-13 16:05:04 +02001045static int ab8500_bank_print(struct seq_file *s, void *p)
1046{
Mattias Wallincfc08492012-05-28 15:53:58 +02001047 return seq_printf(s, "0x%02X\n", debug_bank);
Mattias Wallin5814fc32010-09-13 16:05:04 +02001048}
1049
1050static int ab8500_bank_open(struct inode *inode, struct file *file)
1051{
Mattias Wallind7b9f322010-11-26 13:06:39 +01001052 return single_open(file, ab8500_bank_print, inode->i_private);
Mattias Wallin5814fc32010-09-13 16:05:04 +02001053}
1054
1055static ssize_t ab8500_bank_write(struct file *file,
Mattias Wallind7b9f322010-11-26 13:06:39 +01001056 const char __user *user_buf,
1057 size_t count, loff_t *ppos)
Mattias Wallin5814fc32010-09-13 16:05:04 +02001058{
Mattias Wallind7b9f322010-11-26 13:06:39 +01001059 struct device *dev = ((struct seq_file *)(file->private_data))->private;
Mattias Wallind7b9f322010-11-26 13:06:39 +01001060 unsigned long user_bank;
1061 int err;
Mattias Wallin5814fc32010-09-13 16:05:04 +02001062
Mattias Wallind7b9f322010-11-26 13:06:39 +01001063 /* Get userspace string and assure termination */
Peter Huewe8504d632011-06-06 22:43:32 +02001064 err = kstrtoul_from_user(user_buf, count, 0, &user_bank);
Mattias Wallind7b9f322010-11-26 13:06:39 +01001065 if (err)
Peter Huewe8504d632011-06-06 22:43:32 +02001066 return err;
Mattias Wallin5814fc32010-09-13 16:05:04 +02001067
Mattias Wallind7b9f322010-11-26 13:06:39 +01001068 if (user_bank >= AB8500_NUM_BANKS) {
1069 dev_err(dev, "debugfs error input > number of banks\n");
1070 return -EINVAL;
1071 }
Mattias Wallin5814fc32010-09-13 16:05:04 +02001072
Mattias Wallind7b9f322010-11-26 13:06:39 +01001073 debug_bank = user_bank;
Mattias Wallin5814fc32010-09-13 16:05:04 +02001074
Peter Huewe8504d632011-06-06 22:43:32 +02001075 return count;
Mattias Wallin5814fc32010-09-13 16:05:04 +02001076}
1077
1078static int ab8500_address_print(struct seq_file *s, void *p)
1079{
Mattias Wallind7b9f322010-11-26 13:06:39 +01001080 return seq_printf(s, "0x%02X\n", debug_address);
Mattias Wallin5814fc32010-09-13 16:05:04 +02001081}
1082
1083static int ab8500_address_open(struct inode *inode, struct file *file)
1084{
Mattias Wallind7b9f322010-11-26 13:06:39 +01001085 return single_open(file, ab8500_address_print, inode->i_private);
Mattias Wallin5814fc32010-09-13 16:05:04 +02001086}
1087
1088static ssize_t ab8500_address_write(struct file *file,
Mattias Wallind7b9f322010-11-26 13:06:39 +01001089 const char __user *user_buf,
1090 size_t count, loff_t *ppos)
Mattias Wallin5814fc32010-09-13 16:05:04 +02001091{
Mattias Wallind7b9f322010-11-26 13:06:39 +01001092 struct device *dev = ((struct seq_file *)(file->private_data))->private;
Mattias Wallind7b9f322010-11-26 13:06:39 +01001093 unsigned long user_address;
1094 int err;
Mattias Wallin5814fc32010-09-13 16:05:04 +02001095
Mattias Wallind7b9f322010-11-26 13:06:39 +01001096 /* Get userspace string and assure termination */
Peter Huewe8504d632011-06-06 22:43:32 +02001097 err = kstrtoul_from_user(user_buf, count, 0, &user_address);
Mattias Wallind7b9f322010-11-26 13:06:39 +01001098 if (err)
Peter Huewe8504d632011-06-06 22:43:32 +02001099 return err;
1100
Mattias Wallind7b9f322010-11-26 13:06:39 +01001101 if (user_address > 0xff) {
1102 dev_err(dev, "debugfs error input > 0xff\n");
1103 return -EINVAL;
1104 }
1105 debug_address = user_address;
Peter Huewe8504d632011-06-06 22:43:32 +02001106 return count;
Mattias Wallin5814fc32010-09-13 16:05:04 +02001107}
1108
1109static int ab8500_val_print(struct seq_file *s, void *p)
1110{
Mattias Wallind7b9f322010-11-26 13:06:39 +01001111 struct device *dev = s->private;
1112 int ret;
1113 u8 regvalue;
Mattias Wallin5814fc32010-09-13 16:05:04 +02001114
Mattias Wallind7b9f322010-11-26 13:06:39 +01001115 ret = abx500_get_register_interruptible(dev,
1116 (u8)debug_bank, (u8)debug_address, &regvalue);
1117 if (ret < 0) {
1118 dev_err(dev, "abx500_get_reg fail %d, %d\n",
1119 ret, __LINE__);
1120 return -EINVAL;
1121 }
1122 seq_printf(s, "0x%02X\n", regvalue);
Mattias Wallin5814fc32010-09-13 16:05:04 +02001123
Mattias Wallind7b9f322010-11-26 13:06:39 +01001124 return 0;
Mattias Wallin5814fc32010-09-13 16:05:04 +02001125}
1126
1127static int ab8500_val_open(struct inode *inode, struct file *file)
1128{
Mattias Wallind7b9f322010-11-26 13:06:39 +01001129 return single_open(file, ab8500_val_print, inode->i_private);
Mattias Wallin5814fc32010-09-13 16:05:04 +02001130}
1131
1132static ssize_t ab8500_val_write(struct file *file,
Mattias Wallind7b9f322010-11-26 13:06:39 +01001133 const char __user *user_buf,
1134 size_t count, loff_t *ppos)
Mattias Wallin5814fc32010-09-13 16:05:04 +02001135{
Mattias Wallind7b9f322010-11-26 13:06:39 +01001136 struct device *dev = ((struct seq_file *)(file->private_data))->private;
Mattias Wallind7b9f322010-11-26 13:06:39 +01001137 unsigned long user_val;
1138 int err;
Mattias Wallin5814fc32010-09-13 16:05:04 +02001139
Mattias Wallind7b9f322010-11-26 13:06:39 +01001140 /* Get userspace string and assure termination */
Peter Huewe8504d632011-06-06 22:43:32 +02001141 err = kstrtoul_from_user(user_buf, count, 0, &user_val);
Mattias Wallind7b9f322010-11-26 13:06:39 +01001142 if (err)
Peter Huewe8504d632011-06-06 22:43:32 +02001143 return err;
1144
Mattias Wallind7b9f322010-11-26 13:06:39 +01001145 if (user_val > 0xff) {
1146 dev_err(dev, "debugfs error input > 0xff\n");
1147 return -EINVAL;
1148 }
1149 err = abx500_set_register_interruptible(dev,
1150 (u8)debug_bank, debug_address, (u8)user_val);
1151 if (err < 0) {
1152 printk(KERN_ERR "abx500_set_reg failed %d, %d", err, __LINE__);
1153 return -EINVAL;
1154 }
Mattias Wallin5814fc32010-09-13 16:05:04 +02001155
Peter Huewe8504d632011-06-06 22:43:32 +02001156 return count;
Mattias Wallin5814fc32010-09-13 16:05:04 +02001157}
1158
carriere etienne0fbce762011-04-08 16:26:36 +02001159/*
Bengt Jonsson8f0eb432012-02-14 13:01:00 +01001160 * Interrupt status
1161 */
1162static u32 num_interrupts[AB8500_MAX_NR_IRQS];
Jonas Aaberg2cf64e22012-05-31 07:57:07 +02001163static u32 num_wake_interrupts[AB8500_MAX_NR_IRQS];
Bengt Jonsson8f0eb432012-02-14 13:01:00 +01001164static int num_interrupt_lines;
1165
Jonas Aaberg2cf64e22012-05-31 07:57:07 +02001166bool __attribute__((weak)) suspend_test_wake_cause_interrupt_is_mine(u32 my_int)
1167{
1168 return false;
1169}
1170
Bengt Jonsson8f0eb432012-02-14 13:01:00 +01001171void ab8500_debug_register_interrupt(int line)
1172{
Jonas Aaberg2cf64e22012-05-31 07:57:07 +02001173 if (line < num_interrupt_lines) {
Bengt Jonsson8f0eb432012-02-14 13:01:00 +01001174 num_interrupts[line]++;
Jonas Aaberg2cf64e22012-05-31 07:57:07 +02001175 if (suspend_test_wake_cause_interrupt_is_mine(IRQ_DB8500_AB8500))
1176 num_wake_interrupts[line]++;
1177 }
Bengt Jonsson8f0eb432012-02-14 13:01:00 +01001178}
1179
1180static int ab8500_interrupts_print(struct seq_file *s, void *p)
1181{
1182 int line;
1183
Jonas Aaberg2cf64e22012-05-31 07:57:07 +02001184 seq_printf(s, "name: number: number of: wake:\n");
Bengt Jonsson8f0eb432012-02-14 13:01:00 +01001185
Jonas Aaberg2cf64e22012-05-31 07:57:07 +02001186 for (line = 0; line < num_interrupt_lines; line++) {
1187 struct irq_desc *desc = irq_to_desc(line + irq_first);
1188 struct irqaction *action = desc->action;
1189
1190 seq_printf(s, "%3i: %6i %4i", line,
1191 num_interrupts[line],
1192 num_wake_interrupts[line]);
1193
1194 if (desc && desc->name)
1195 seq_printf(s, "-%-8s", desc->name);
1196 if (action) {
1197 seq_printf(s, " %s", action->name);
1198 while ((action = action->next) != NULL)
1199 seq_printf(s, ", %s", action->name);
1200 }
1201 seq_putc(s, '\n');
1202 }
Bengt Jonsson8f0eb432012-02-14 13:01:00 +01001203
1204 return 0;
1205}
1206
1207static int ab8500_interrupts_open(struct inode *inode, struct file *file)
1208{
1209 return single_open(file, ab8500_interrupts_print, inode->i_private);
1210}
1211
1212/*
carriere etienne0fbce762011-04-08 16:26:36 +02001213 * - HWREG DB8500 formated routines
1214 */
1215static int ab8500_hwreg_print(struct seq_file *s, void *d)
1216{
1217 struct device *dev = s->private;
1218 int ret;
1219 u8 regvalue;
1220
1221 ret = abx500_get_register_interruptible(dev,
1222 (u8)hwreg_cfg.bank, (u8)hwreg_cfg.addr, &regvalue);
1223 if (ret < 0) {
1224 dev_err(dev, "abx500_get_reg fail %d, %d\n",
1225 ret, __LINE__);
1226 return -EINVAL;
1227 }
1228
1229 if (hwreg_cfg.shift >= 0)
1230 regvalue >>= hwreg_cfg.shift;
1231 else
1232 regvalue <<= -hwreg_cfg.shift;
1233 regvalue &= hwreg_cfg.mask;
1234
1235 if (REG_FMT_DEC(&hwreg_cfg))
1236 seq_printf(s, "%d\n", regvalue);
1237 else
1238 seq_printf(s, "0x%02X\n", regvalue);
1239 return 0;
1240}
1241
1242static int ab8500_hwreg_open(struct inode *inode, struct file *file)
1243{
1244 return single_open(file, ab8500_hwreg_print, inode->i_private);
1245}
1246
John Beckett1478a312011-05-31 13:54:27 +01001247static int ab8500_gpadc_bat_ctrl_print(struct seq_file *s, void *p)
1248{
1249 int bat_ctrl_raw;
1250 int bat_ctrl_convert;
1251 struct ab8500_gpadc *gpadc;
1252
Philippe Langlais8908c042012-04-18 15:52:59 +02001253 gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
Lee Jones73482342013-02-26 10:06:55 +00001254 bat_ctrl_raw = ab8500_gpadc_read_raw(gpadc, BAT_CTRL,
1255 avg_sample, trig_edge, trig_timer, conv_type);
John Beckett1478a312011-05-31 13:54:27 +01001256 bat_ctrl_convert = ab8500_gpadc_ad_to_voltage(gpadc,
Lee Jones73482342013-02-26 10:06:55 +00001257 BAT_CTRL, bat_ctrl_raw);
John Beckett1478a312011-05-31 13:54:27 +01001258
1259 return seq_printf(s, "%d,0x%X\n",
1260 bat_ctrl_convert, bat_ctrl_raw);
1261}
1262
1263static int ab8500_gpadc_bat_ctrl_open(struct inode *inode, struct file *file)
1264{
1265 return single_open(file, ab8500_gpadc_bat_ctrl_print, inode->i_private);
1266}
1267
1268static const struct file_operations ab8500_gpadc_bat_ctrl_fops = {
1269 .open = ab8500_gpadc_bat_ctrl_open,
1270 .read = seq_read,
1271 .llseek = seq_lseek,
1272 .release = single_release,
1273 .owner = THIS_MODULE,
1274};
1275
1276static int ab8500_gpadc_btemp_ball_print(struct seq_file *s, void *p)
1277{
1278 int btemp_ball_raw;
1279 int btemp_ball_convert;
1280 struct ab8500_gpadc *gpadc;
1281
Philippe Langlais8908c042012-04-18 15:52:59 +02001282 gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
Lee Jones73482342013-02-26 10:06:55 +00001283 btemp_ball_raw = ab8500_gpadc_read_raw(gpadc, BTEMP_BALL,
1284 avg_sample, trig_edge, trig_timer, conv_type);
John Beckett1478a312011-05-31 13:54:27 +01001285 btemp_ball_convert = ab8500_gpadc_ad_to_voltage(gpadc, BTEMP_BALL,
Lee Jones73482342013-02-26 10:06:55 +00001286 btemp_ball_raw);
John Beckett1478a312011-05-31 13:54:27 +01001287
1288 return seq_printf(s,
1289 "%d,0x%X\n", btemp_ball_convert, btemp_ball_raw);
1290}
1291
1292static int ab8500_gpadc_btemp_ball_open(struct inode *inode,
1293 struct file *file)
1294{
1295 return single_open(file, ab8500_gpadc_btemp_ball_print, inode->i_private);
1296}
1297
1298static const struct file_operations ab8500_gpadc_btemp_ball_fops = {
1299 .open = ab8500_gpadc_btemp_ball_open,
1300 .read = seq_read,
1301 .llseek = seq_lseek,
1302 .release = single_release,
1303 .owner = THIS_MODULE,
1304};
1305
1306static int ab8500_gpadc_main_charger_v_print(struct seq_file *s, void *p)
1307{
1308 int main_charger_v_raw;
1309 int main_charger_v_convert;
1310 struct ab8500_gpadc *gpadc;
1311
Philippe Langlais8908c042012-04-18 15:52:59 +02001312 gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
Lee Jones73482342013-02-26 10:06:55 +00001313 main_charger_v_raw = ab8500_gpadc_read_raw(gpadc, MAIN_CHARGER_V,
1314 avg_sample, trig_edge, trig_timer, conv_type);
John Beckett1478a312011-05-31 13:54:27 +01001315 main_charger_v_convert = ab8500_gpadc_ad_to_voltage(gpadc,
Lee Jones73482342013-02-26 10:06:55 +00001316 MAIN_CHARGER_V, main_charger_v_raw);
John Beckett1478a312011-05-31 13:54:27 +01001317
1318 return seq_printf(s, "%d,0x%X\n",
1319 main_charger_v_convert, main_charger_v_raw);
1320}
1321
1322static int ab8500_gpadc_main_charger_v_open(struct inode *inode,
1323 struct file *file)
1324{
1325 return single_open(file, ab8500_gpadc_main_charger_v_print,
1326 inode->i_private);
1327}
1328
1329static const struct file_operations ab8500_gpadc_main_charger_v_fops = {
1330 .open = ab8500_gpadc_main_charger_v_open,
1331 .read = seq_read,
1332 .llseek = seq_lseek,
1333 .release = single_release,
1334 .owner = THIS_MODULE,
1335};
1336
1337static int ab8500_gpadc_acc_detect1_print(struct seq_file *s, void *p)
1338{
1339 int acc_detect1_raw;
1340 int acc_detect1_convert;
1341 struct ab8500_gpadc *gpadc;
1342
Philippe Langlais8908c042012-04-18 15:52:59 +02001343 gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
Lee Jones73482342013-02-26 10:06:55 +00001344 acc_detect1_raw = ab8500_gpadc_read_raw(gpadc, ACC_DETECT1,
1345 avg_sample, trig_edge, trig_timer, conv_type);
John Beckett1478a312011-05-31 13:54:27 +01001346 acc_detect1_convert = ab8500_gpadc_ad_to_voltage(gpadc, ACC_DETECT1,
Lee Jones73482342013-02-26 10:06:55 +00001347 acc_detect1_raw);
John Beckett1478a312011-05-31 13:54:27 +01001348
1349 return seq_printf(s, "%d,0x%X\n",
1350 acc_detect1_convert, acc_detect1_raw);
1351}
1352
1353static int ab8500_gpadc_acc_detect1_open(struct inode *inode,
1354 struct file *file)
1355{
1356 return single_open(file, ab8500_gpadc_acc_detect1_print,
1357 inode->i_private);
1358}
1359
1360static const struct file_operations ab8500_gpadc_acc_detect1_fops = {
1361 .open = ab8500_gpadc_acc_detect1_open,
1362 .read = seq_read,
1363 .llseek = seq_lseek,
1364 .release = single_release,
1365 .owner = THIS_MODULE,
1366};
1367
1368static int ab8500_gpadc_acc_detect2_print(struct seq_file *s, void *p)
1369{
1370 int acc_detect2_raw;
1371 int acc_detect2_convert;
1372 struct ab8500_gpadc *gpadc;
1373
Philippe Langlais8908c042012-04-18 15:52:59 +02001374 gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
Lee Jones73482342013-02-26 10:06:55 +00001375 acc_detect2_raw = ab8500_gpadc_read_raw(gpadc, ACC_DETECT2,
1376 avg_sample, trig_edge, trig_timer, conv_type);
John Beckett1478a312011-05-31 13:54:27 +01001377 acc_detect2_convert = ab8500_gpadc_ad_to_voltage(gpadc,
Lee Jones73482342013-02-26 10:06:55 +00001378 ACC_DETECT2, acc_detect2_raw);
John Beckett1478a312011-05-31 13:54:27 +01001379
1380 return seq_printf(s, "%d,0x%X\n",
1381 acc_detect2_convert, acc_detect2_raw);
1382}
1383
1384static int ab8500_gpadc_acc_detect2_open(struct inode *inode,
1385 struct file *file)
1386{
1387 return single_open(file, ab8500_gpadc_acc_detect2_print,
1388 inode->i_private);
1389}
1390
1391static const struct file_operations ab8500_gpadc_acc_detect2_fops = {
1392 .open = ab8500_gpadc_acc_detect2_open,
1393 .read = seq_read,
1394 .llseek = seq_lseek,
1395 .release = single_release,
1396 .owner = THIS_MODULE,
1397};
1398
1399static int ab8500_gpadc_aux1_print(struct seq_file *s, void *p)
1400{
1401 int aux1_raw;
1402 int aux1_convert;
1403 struct ab8500_gpadc *gpadc;
1404
Philippe Langlais8908c042012-04-18 15:52:59 +02001405 gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
Lee Jones73482342013-02-26 10:06:55 +00001406 aux1_raw = ab8500_gpadc_read_raw(gpadc, ADC_AUX1,
1407 avg_sample, trig_edge, trig_timer, conv_type);
John Beckett1478a312011-05-31 13:54:27 +01001408 aux1_convert = ab8500_gpadc_ad_to_voltage(gpadc, ADC_AUX1,
Lee Jones73482342013-02-26 10:06:55 +00001409 aux1_raw);
John Beckett1478a312011-05-31 13:54:27 +01001410
1411 return seq_printf(s, "%d,0x%X\n",
1412 aux1_convert, aux1_raw);
1413}
1414
1415static int ab8500_gpadc_aux1_open(struct inode *inode, struct file *file)
1416{
1417 return single_open(file, ab8500_gpadc_aux1_print, inode->i_private);
1418}
1419
1420static const struct file_operations ab8500_gpadc_aux1_fops = {
1421 .open = ab8500_gpadc_aux1_open,
1422 .read = seq_read,
1423 .llseek = seq_lseek,
1424 .release = single_release,
1425 .owner = THIS_MODULE,
1426};
1427
1428static int ab8500_gpadc_aux2_print(struct seq_file *s, void *p)
1429{
1430 int aux2_raw;
1431 int aux2_convert;
1432 struct ab8500_gpadc *gpadc;
1433
Philippe Langlais8908c042012-04-18 15:52:59 +02001434 gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
Lee Jones73482342013-02-26 10:06:55 +00001435 aux2_raw = ab8500_gpadc_read_raw(gpadc, ADC_AUX2,
1436 avg_sample, trig_edge, trig_timer, conv_type);
John Beckett1478a312011-05-31 13:54:27 +01001437 aux2_convert = ab8500_gpadc_ad_to_voltage(gpadc, ADC_AUX2,
Lee Jones73482342013-02-26 10:06:55 +00001438 aux2_raw);
John Beckett1478a312011-05-31 13:54:27 +01001439
1440 return seq_printf(s, "%d,0x%X\n",
1441 aux2_convert, aux2_raw);
1442}
1443
1444static int ab8500_gpadc_aux2_open(struct inode *inode, struct file *file)
1445{
1446 return single_open(file, ab8500_gpadc_aux2_print, inode->i_private);
1447}
1448
1449static const struct file_operations ab8500_gpadc_aux2_fops = {
1450 .open = ab8500_gpadc_aux2_open,
1451 .read = seq_read,
1452 .llseek = seq_lseek,
1453 .release = single_release,
1454 .owner = THIS_MODULE,
1455};
1456
1457static int ab8500_gpadc_main_bat_v_print(struct seq_file *s, void *p)
1458{
1459 int main_bat_v_raw;
1460 int main_bat_v_convert;
1461 struct ab8500_gpadc *gpadc;
1462
Philippe Langlais8908c042012-04-18 15:52:59 +02001463 gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
Lee Jones73482342013-02-26 10:06:55 +00001464 main_bat_v_raw = ab8500_gpadc_read_raw(gpadc, MAIN_BAT_V,
1465 avg_sample, trig_edge, trig_timer, conv_type);
John Beckett1478a312011-05-31 13:54:27 +01001466 main_bat_v_convert = ab8500_gpadc_ad_to_voltage(gpadc, MAIN_BAT_V,
Lee Jones73482342013-02-26 10:06:55 +00001467 main_bat_v_raw);
John Beckett1478a312011-05-31 13:54:27 +01001468
1469 return seq_printf(s, "%d,0x%X\n",
1470 main_bat_v_convert, main_bat_v_raw);
1471}
1472
1473static int ab8500_gpadc_main_bat_v_open(struct inode *inode,
1474 struct file *file)
1475{
1476 return single_open(file, ab8500_gpadc_main_bat_v_print, inode->i_private);
1477}
1478
1479static const struct file_operations ab8500_gpadc_main_bat_v_fops = {
1480 .open = ab8500_gpadc_main_bat_v_open,
1481 .read = seq_read,
1482 .llseek = seq_lseek,
1483 .release = single_release,
1484 .owner = THIS_MODULE,
1485};
1486
1487static int ab8500_gpadc_vbus_v_print(struct seq_file *s, void *p)
1488{
1489 int vbus_v_raw;
1490 int vbus_v_convert;
1491 struct ab8500_gpadc *gpadc;
1492
Philippe Langlais8908c042012-04-18 15:52:59 +02001493 gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
Lee Jones73482342013-02-26 10:06:55 +00001494 vbus_v_raw = ab8500_gpadc_read_raw(gpadc, VBUS_V,
1495 avg_sample, trig_edge, trig_timer, conv_type);
John Beckett1478a312011-05-31 13:54:27 +01001496 vbus_v_convert = ab8500_gpadc_ad_to_voltage(gpadc, VBUS_V,
Lee Jones73482342013-02-26 10:06:55 +00001497 vbus_v_raw);
John Beckett1478a312011-05-31 13:54:27 +01001498
1499 return seq_printf(s, "%d,0x%X\n",
1500 vbus_v_convert, vbus_v_raw);
1501}
1502
1503static int ab8500_gpadc_vbus_v_open(struct inode *inode, struct file *file)
1504{
1505 return single_open(file, ab8500_gpadc_vbus_v_print, inode->i_private);
1506}
1507
1508static const struct file_operations ab8500_gpadc_vbus_v_fops = {
1509 .open = ab8500_gpadc_vbus_v_open,
1510 .read = seq_read,
1511 .llseek = seq_lseek,
1512 .release = single_release,
1513 .owner = THIS_MODULE,
1514};
1515
1516static int ab8500_gpadc_main_charger_c_print(struct seq_file *s, void *p)
1517{
1518 int main_charger_c_raw;
1519 int main_charger_c_convert;
1520 struct ab8500_gpadc *gpadc;
1521
Philippe Langlais8908c042012-04-18 15:52:59 +02001522 gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
Lee Jones73482342013-02-26 10:06:55 +00001523 main_charger_c_raw = ab8500_gpadc_read_raw(gpadc, MAIN_CHARGER_C,
1524 avg_sample, trig_edge, trig_timer, conv_type);
John Beckett1478a312011-05-31 13:54:27 +01001525 main_charger_c_convert = ab8500_gpadc_ad_to_voltage(gpadc,
Lee Jones73482342013-02-26 10:06:55 +00001526 MAIN_CHARGER_C, main_charger_c_raw);
John Beckett1478a312011-05-31 13:54:27 +01001527
1528 return seq_printf(s, "%d,0x%X\n",
1529 main_charger_c_convert, main_charger_c_raw);
1530}
1531
1532static int ab8500_gpadc_main_charger_c_open(struct inode *inode,
1533 struct file *file)
1534{
1535 return single_open(file, ab8500_gpadc_main_charger_c_print,
1536 inode->i_private);
1537}
1538
1539static const struct file_operations ab8500_gpadc_main_charger_c_fops = {
1540 .open = ab8500_gpadc_main_charger_c_open,
1541 .read = seq_read,
1542 .llseek = seq_lseek,
1543 .release = single_release,
1544 .owner = THIS_MODULE,
1545};
1546
1547static int ab8500_gpadc_usb_charger_c_print(struct seq_file *s, void *p)
1548{
1549 int usb_charger_c_raw;
1550 int usb_charger_c_convert;
1551 struct ab8500_gpadc *gpadc;
1552
Philippe Langlais8908c042012-04-18 15:52:59 +02001553 gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
Lee Jones73482342013-02-26 10:06:55 +00001554 usb_charger_c_raw = ab8500_gpadc_read_raw(gpadc, USB_CHARGER_C,
1555 avg_sample, trig_edge, trig_timer, conv_type);
John Beckett1478a312011-05-31 13:54:27 +01001556 usb_charger_c_convert = ab8500_gpadc_ad_to_voltage(gpadc,
Lee Jones73482342013-02-26 10:06:55 +00001557 USB_CHARGER_C, usb_charger_c_raw);
John Beckett1478a312011-05-31 13:54:27 +01001558
1559 return seq_printf(s, "%d,0x%X\n",
1560 usb_charger_c_convert, usb_charger_c_raw);
1561}
1562
1563static int ab8500_gpadc_usb_charger_c_open(struct inode *inode,
1564 struct file *file)
1565{
1566 return single_open(file, ab8500_gpadc_usb_charger_c_print,
1567 inode->i_private);
1568}
1569
1570static const struct file_operations ab8500_gpadc_usb_charger_c_fops = {
1571 .open = ab8500_gpadc_usb_charger_c_open,
1572 .read = seq_read,
1573 .llseek = seq_lseek,
1574 .release = single_release,
1575 .owner = THIS_MODULE,
1576};
1577
1578static int ab8500_gpadc_bk_bat_v_print(struct seq_file *s, void *p)
1579{
1580 int bk_bat_v_raw;
1581 int bk_bat_v_convert;
1582 struct ab8500_gpadc *gpadc;
1583
Philippe Langlais8908c042012-04-18 15:52:59 +02001584 gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
Lee Jones73482342013-02-26 10:06:55 +00001585 bk_bat_v_raw = ab8500_gpadc_read_raw(gpadc, BK_BAT_V,
1586 avg_sample, trig_edge, trig_timer, conv_type);
John Beckett1478a312011-05-31 13:54:27 +01001587 bk_bat_v_convert = ab8500_gpadc_ad_to_voltage(gpadc,
Lee Jones73482342013-02-26 10:06:55 +00001588 BK_BAT_V, bk_bat_v_raw);
John Beckett1478a312011-05-31 13:54:27 +01001589
1590 return seq_printf(s, "%d,0x%X\n",
1591 bk_bat_v_convert, bk_bat_v_raw);
1592}
1593
1594static int ab8500_gpadc_bk_bat_v_open(struct inode *inode, struct file *file)
1595{
1596 return single_open(file, ab8500_gpadc_bk_bat_v_print, inode->i_private);
1597}
1598
1599static const struct file_operations ab8500_gpadc_bk_bat_v_fops = {
1600 .open = ab8500_gpadc_bk_bat_v_open,
1601 .read = seq_read,
1602 .llseek = seq_lseek,
1603 .release = single_release,
1604 .owner = THIS_MODULE,
1605};
1606
1607static int ab8500_gpadc_die_temp_print(struct seq_file *s, void *p)
1608{
1609 int die_temp_raw;
1610 int die_temp_convert;
1611 struct ab8500_gpadc *gpadc;
1612
Philippe Langlais8908c042012-04-18 15:52:59 +02001613 gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
Lee Jones73482342013-02-26 10:06:55 +00001614 die_temp_raw = ab8500_gpadc_read_raw(gpadc, DIE_TEMP,
1615 avg_sample, trig_edge, trig_timer, conv_type);
John Beckett1478a312011-05-31 13:54:27 +01001616 die_temp_convert = ab8500_gpadc_ad_to_voltage(gpadc, DIE_TEMP,
Lee Jones73482342013-02-26 10:06:55 +00001617 die_temp_raw);
John Beckett1478a312011-05-31 13:54:27 +01001618
1619 return seq_printf(s, "%d,0x%X\n",
1620 die_temp_convert, die_temp_raw);
1621}
1622
1623static int ab8500_gpadc_die_temp_open(struct inode *inode, struct file *file)
1624{
1625 return single_open(file, ab8500_gpadc_die_temp_print, inode->i_private);
1626}
1627
1628static const struct file_operations ab8500_gpadc_die_temp_fops = {
1629 .open = ab8500_gpadc_die_temp_open,
1630 .read = seq_read,
1631 .llseek = seq_lseek,
1632 .release = single_release,
1633 .owner = THIS_MODULE,
1634};
1635
Lee Jonesbc6b4132013-02-26 14:02:31 +00001636static int ab8540_gpadc_xtal_temp_print(struct seq_file *s, void *p)
1637{
1638 int xtal_temp_raw;
1639 int xtal_temp_convert;
1640 struct ab8500_gpadc *gpadc;
1641
1642 gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
1643 xtal_temp_raw = ab8500_gpadc_read_raw(gpadc, XTAL_TEMP,
1644 avg_sample, trig_edge, trig_timer, conv_type);
1645 xtal_temp_convert = ab8500_gpadc_ad_to_voltage(gpadc, XTAL_TEMP,
1646 xtal_temp_raw);
1647
1648 return seq_printf(s, "%d,0x%X\n",
1649 xtal_temp_convert, xtal_temp_raw);
1650}
1651
1652static int ab8540_gpadc_xtal_temp_open(struct inode *inode, struct file *file)
1653{
1654 return single_open(file, ab8540_gpadc_xtal_temp_print,
1655 inode->i_private);
1656}
1657
1658static const struct file_operations ab8540_gpadc_xtal_temp_fops = {
1659 .open = ab8540_gpadc_xtal_temp_open,
1660 .read = seq_read,
1661 .llseek = seq_lseek,
1662 .release = single_release,
1663 .owner = THIS_MODULE,
1664};
1665
1666static int ab8540_gpadc_vbat_true_meas_print(struct seq_file *s, void *p)
1667{
1668 int vbat_true_meas_raw;
1669 int vbat_true_meas_convert;
1670 struct ab8500_gpadc *gpadc;
1671
1672 gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
1673 vbat_true_meas_raw = ab8500_gpadc_read_raw(gpadc, VBAT_TRUE_MEAS,
1674 avg_sample, trig_edge, trig_timer, conv_type);
1675 vbat_true_meas_convert = ab8500_gpadc_ad_to_voltage(gpadc, VBAT_TRUE_MEAS,
1676 vbat_true_meas_raw);
1677
1678 return seq_printf(s, "%d,0x%X\n",
1679 vbat_true_meas_convert, vbat_true_meas_raw);
1680}
1681
1682static int ab8540_gpadc_vbat_true_meas_open(struct inode *inode,
1683 struct file *file)
1684{
1685 return single_open(file, ab8540_gpadc_vbat_true_meas_print,
1686 inode->i_private);
1687}
1688
1689static const struct file_operations ab8540_gpadc_vbat_true_meas_fops = {
1690 .open = ab8540_gpadc_vbat_true_meas_open,
1691 .read = seq_read,
1692 .llseek = seq_lseek,
1693 .release = single_release,
1694 .owner = THIS_MODULE,
1695};
1696
1697static int ab8540_gpadc_bat_ctrl_and_ibat_print(struct seq_file *s, void *p)
1698{
1699 int bat_ctrl_raw;
1700 int bat_ctrl_convert;
1701 int ibat_raw;
1702 int ibat_convert;
1703 struct ab8500_gpadc *gpadc;
1704
1705 gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
1706 bat_ctrl_raw = ab8500_gpadc_double_read_raw(gpadc, BAT_CTRL_AND_IBAT,
1707 avg_sample, trig_edge, trig_timer, conv_type, &ibat_raw);
1708
1709 bat_ctrl_convert = ab8500_gpadc_ad_to_voltage(gpadc, BAT_CTRL,
1710 bat_ctrl_raw);
1711 ibat_convert = ab8500_gpadc_ad_to_voltage(gpadc, IBAT_VIRTUAL_CHANNEL,
1712 ibat_raw);
1713
1714 return seq_printf(s, "%d,0x%X\n" "%d,0x%X\n",
1715 bat_ctrl_convert, bat_ctrl_raw,
1716 ibat_convert, ibat_raw);
1717}
1718
1719static int ab8540_gpadc_bat_ctrl_and_ibat_open(struct inode *inode,
1720 struct file *file)
1721{
1722 return single_open(file, ab8540_gpadc_bat_ctrl_and_ibat_print,
1723 inode->i_private);
1724}
1725
1726static const struct file_operations ab8540_gpadc_bat_ctrl_and_ibat_fops = {
1727 .open = ab8540_gpadc_bat_ctrl_and_ibat_open,
1728 .read = seq_read,
1729 .llseek = seq_lseek,
1730 .release = single_release,
1731 .owner = THIS_MODULE,
1732};
1733
1734static int ab8540_gpadc_vbat_meas_and_ibat_print(struct seq_file *s, void *p)
1735{
1736 int vbat_meas_raw;
1737 int vbat_meas_convert;
1738 int ibat_raw;
1739 int ibat_convert;
1740 struct ab8500_gpadc *gpadc;
1741
1742 gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
1743 vbat_meas_raw = ab8500_gpadc_double_read_raw(gpadc, VBAT_MEAS_AND_IBAT,
1744 avg_sample, trig_edge, trig_timer, conv_type, &ibat_raw);
1745 vbat_meas_convert = ab8500_gpadc_ad_to_voltage(gpadc, MAIN_BAT_V,
1746 vbat_meas_raw);
1747 ibat_convert = ab8500_gpadc_ad_to_voltage(gpadc, IBAT_VIRTUAL_CHANNEL,
1748 ibat_raw);
1749
1750 return seq_printf(s, "%d,0x%X\n" "%d,0x%X\n",
1751 vbat_meas_convert, vbat_meas_raw,
1752 ibat_convert, ibat_raw);
1753}
1754
1755static int ab8540_gpadc_vbat_meas_and_ibat_open(struct inode *inode,
1756 struct file *file)
1757{
1758 return single_open(file, ab8540_gpadc_vbat_meas_and_ibat_print,
1759 inode->i_private);
1760}
1761
1762static const struct file_operations ab8540_gpadc_vbat_meas_and_ibat_fops = {
1763 .open = ab8540_gpadc_vbat_meas_and_ibat_open,
1764 .read = seq_read,
1765 .llseek = seq_lseek,
1766 .release = single_release,
1767 .owner = THIS_MODULE,
1768};
1769
1770static int ab8540_gpadc_vbat_true_meas_and_ibat_print(struct seq_file *s, void *p)
1771{
1772 int vbat_true_meas_raw;
1773 int vbat_true_meas_convert;
1774 int ibat_raw;
1775 int ibat_convert;
1776 struct ab8500_gpadc *gpadc;
1777
1778 gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
1779 vbat_true_meas_raw = ab8500_gpadc_double_read_raw(gpadc,
1780 VBAT_TRUE_MEAS_AND_IBAT, avg_sample, trig_edge,
1781 trig_timer, conv_type, &ibat_raw);
1782 vbat_true_meas_convert = ab8500_gpadc_ad_to_voltage(gpadc,
1783 VBAT_TRUE_MEAS, vbat_true_meas_raw);
1784 ibat_convert = ab8500_gpadc_ad_to_voltage(gpadc, IBAT_VIRTUAL_CHANNEL,
1785 ibat_raw);
1786
1787 return seq_printf(s, "%d,0x%X\n" "%d,0x%X\n",
1788 vbat_true_meas_convert, vbat_true_meas_raw,
1789 ibat_convert, ibat_raw);
1790}
1791
1792static int ab8540_gpadc_vbat_true_meas_and_ibat_open(struct inode *inode,
1793 struct file *file)
1794{
1795 return single_open(file, ab8540_gpadc_vbat_true_meas_and_ibat_print,
1796 inode->i_private);
1797}
1798
1799static const struct file_operations ab8540_gpadc_vbat_true_meas_and_ibat_fops = {
1800 .open = ab8540_gpadc_vbat_true_meas_and_ibat_open,
1801 .read = seq_read,
1802 .llseek = seq_lseek,
1803 .release = single_release,
1804 .owner = THIS_MODULE,
1805};
1806
1807static int ab8540_gpadc_bat_temp_and_ibat_print(struct seq_file *s, void *p)
1808{
1809 int bat_temp_raw;
1810 int bat_temp_convert;
1811 int ibat_raw;
1812 int ibat_convert;
1813 struct ab8500_gpadc *gpadc;
1814
1815 gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
1816 bat_temp_raw = ab8500_gpadc_double_read_raw(gpadc, BAT_TEMP_AND_IBAT,
1817 avg_sample, trig_edge, trig_timer, conv_type, &ibat_raw);
1818 bat_temp_convert = ab8500_gpadc_ad_to_voltage(gpadc, BTEMP_BALL,
1819 bat_temp_raw);
1820 ibat_convert = ab8500_gpadc_ad_to_voltage(gpadc, IBAT_VIRTUAL_CHANNEL,
1821 ibat_raw);
1822
1823 return seq_printf(s, "%d,0x%X\n" "%d,0x%X\n",
1824 bat_temp_convert, bat_temp_raw,
1825 ibat_convert, ibat_raw);
1826}
1827
1828static int ab8540_gpadc_bat_temp_and_ibat_open(struct inode *inode,
1829 struct file *file)
1830{
1831 return single_open(file, ab8540_gpadc_bat_temp_and_ibat_print,
1832 inode->i_private);
1833}
1834
1835static const struct file_operations ab8540_gpadc_bat_temp_and_ibat_fops = {
1836 .open = ab8540_gpadc_bat_temp_and_ibat_open,
1837 .read = seq_read,
1838 .llseek = seq_lseek,
1839 .release = single_release,
1840 .owner = THIS_MODULE,
1841};
1842
1843static int ab8540_gpadc_otp_cal_print(struct seq_file *s, void *p)
1844{
1845 struct ab8500_gpadc *gpadc;
1846 u16 vmain_l, vmain_h, btemp_l, btemp_h;
1847 u16 vbat_l, vbat_h, ibat_l, ibat_h;
1848
1849 gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
1850 ab8540_gpadc_get_otp(gpadc, &vmain_l, &vmain_h, &btemp_l, &btemp_h,
1851 &vbat_l, &vbat_h, &ibat_l, &ibat_h);
1852 return seq_printf(s, "VMAIN_L:0x%X\n"
1853 "VMAIN_H:0x%X\n"
1854 "BTEMP_L:0x%X\n"
1855 "BTEMP_H:0x%X\n"
1856 "VBAT_L:0x%X\n"
1857 "VBAT_H:0x%X\n"
1858 "IBAT_L:0x%X\n"
1859 "IBAT_H:0x%X\n"
1860 ,
1861 vmain_l,
1862 vmain_h,
1863 btemp_l,
1864 btemp_h,
1865 vbat_l,
1866 vbat_h,
1867 ibat_l,
1868 ibat_h);
1869}
1870
1871static int ab8540_gpadc_otp_cal_open(struct inode *inode, struct file *file)
1872{
1873 return single_open(file, ab8540_gpadc_otp_cal_print, inode->i_private);
1874}
1875
1876static const struct file_operations ab8540_gpadc_otp_calib_fops = {
1877 .open = ab8540_gpadc_otp_cal_open,
1878 .read = seq_read,
1879 .llseek = seq_lseek,
1880 .release = single_release,
1881 .owner = THIS_MODULE,
1882};
1883
Lee Jones73482342013-02-26 10:06:55 +00001884static int ab8500_gpadc_avg_sample_print(struct seq_file *s, void *p)
1885{
1886 return seq_printf(s, "%d\n", avg_sample);
1887}
1888
1889static int ab8500_gpadc_avg_sample_open(struct inode *inode, struct file *file)
1890{
1891 return single_open(file, ab8500_gpadc_avg_sample_print,
1892 inode->i_private);
1893}
1894
1895static ssize_t ab8500_gpadc_avg_sample_write(struct file *file,
1896 const char __user *user_buf,
1897 size_t count, loff_t *ppos)
1898{
1899 struct device *dev = ((struct seq_file *)(file->private_data))->private;
1900 char buf[32];
1901 int buf_size;
1902 unsigned long user_avg_sample;
1903 int err;
1904
1905 /* Get userspace string and assure termination */
1906 buf_size = min(count, (sizeof(buf) - 1));
1907 if (copy_from_user(buf, user_buf, buf_size))
1908 return -EFAULT;
1909 buf[buf_size] = 0;
1910
1911 err = strict_strtoul(buf, 0, &user_avg_sample);
1912 if (err)
1913 return -EINVAL;
1914 if ((user_avg_sample == SAMPLE_1) || (user_avg_sample == SAMPLE_4)
1915 || (user_avg_sample == SAMPLE_8)
1916 || (user_avg_sample == SAMPLE_16)) {
1917 avg_sample = (u8) user_avg_sample;
1918 } else {
1919 dev_err(dev, "debugfs error input: "
1920 "should be egal to 1, 4, 8 or 16\n");
1921 return -EINVAL;
1922 }
1923 return buf_size;
1924}
1925
1926static const struct file_operations ab8500_gpadc_avg_sample_fops = {
1927 .open = ab8500_gpadc_avg_sample_open,
1928 .read = seq_read,
1929 .write = ab8500_gpadc_avg_sample_write,
1930 .llseek = seq_lseek,
1931 .release = single_release,
1932 .owner = THIS_MODULE,
1933};
1934
1935static int ab8500_gpadc_trig_edge_print(struct seq_file *s, void *p)
1936{
1937 return seq_printf(s, "%d\n", trig_edge);
1938}
1939
1940static int ab8500_gpadc_trig_edge_open(struct inode *inode, struct file *file)
1941{
1942 return single_open(file, ab8500_gpadc_trig_edge_print,
1943 inode->i_private);
1944}
1945
1946static ssize_t ab8500_gpadc_trig_edge_write(struct file *file,
1947 const char __user *user_buf,
1948 size_t count, loff_t *ppos)
1949{
1950 struct device *dev = ((struct seq_file *)(file->private_data))->private;
1951 char buf[32];
1952 int buf_size;
1953 unsigned long user_trig_edge;
1954 int err;
1955
1956 /* Get userspace string and assure termination */
1957 buf_size = min(count, (sizeof(buf) - 1));
1958 if (copy_from_user(buf, user_buf, buf_size))
1959 return -EFAULT;
1960 buf[buf_size] = 0;
1961
1962 err = strict_strtoul(buf, 0, &user_trig_edge);
1963 if (err)
1964 return -EINVAL;
1965 if ((user_trig_edge == RISING_EDGE)
1966 || (user_trig_edge == FALLING_EDGE)) {
1967 trig_edge = (u8) user_trig_edge;
1968 } else {
1969 dev_err(dev, "Wrong input:\n"
1970 "Enter 0. Rising edge\n"
1971 "Enter 1. Falling edge\n");
1972 return -EINVAL;
1973 }
1974 return buf_size;
1975}
1976
1977static const struct file_operations ab8500_gpadc_trig_edge_fops = {
1978 .open = ab8500_gpadc_trig_edge_open,
1979 .read = seq_read,
1980 .write = ab8500_gpadc_trig_edge_write,
1981 .llseek = seq_lseek,
1982 .release = single_release,
1983 .owner = THIS_MODULE,
1984};
1985
1986static int ab8500_gpadc_trig_timer_print(struct seq_file *s, void *p)
1987{
1988 return seq_printf(s, "%d\n", trig_timer);
1989}
1990
1991static int ab8500_gpadc_trig_timer_open(struct inode *inode, struct file *file)
1992{
1993 return single_open(file, ab8500_gpadc_trig_timer_print,
1994 inode->i_private);
1995}
1996
1997static ssize_t ab8500_gpadc_trig_timer_write(struct file *file,
1998 const char __user *user_buf,
1999 size_t count, loff_t *ppos)
2000{
2001 struct device *dev = ((struct seq_file *)(file->private_data))->private;
2002 char buf[32];
2003 int buf_size;
2004 unsigned long user_trig_timer;
2005 int err;
2006
2007 /* Get userspace string and assure termination */
2008 buf_size = min(count, (sizeof(buf) - 1));
2009 if (copy_from_user(buf, user_buf, buf_size))
2010 return -EFAULT;
2011 buf[buf_size] = 0;
2012
2013 err = strict_strtoul(buf, 0, &user_trig_timer);
2014 if (err)
2015 return -EINVAL;
2016 if ((user_trig_timer >= 0) && (user_trig_timer <= 255)) {
2017 trig_timer = (u8) user_trig_timer;
2018 } else {
2019 dev_err(dev, "debugfs error input: "
2020 "should be beetween 0 to 255\n");
2021 return -EINVAL;
2022 }
2023 return buf_size;
2024}
2025
2026static const struct file_operations ab8500_gpadc_trig_timer_fops = {
2027 .open = ab8500_gpadc_trig_timer_open,
2028 .read = seq_read,
2029 .write = ab8500_gpadc_trig_timer_write,
2030 .llseek = seq_lseek,
2031 .release = single_release,
2032 .owner = THIS_MODULE,
2033};
2034
2035static int ab8500_gpadc_conv_type_print(struct seq_file *s, void *p)
2036{
2037 return seq_printf(s, "%d\n", conv_type);
2038}
2039
2040static int ab8500_gpadc_conv_type_open(struct inode *inode, struct file *file)
2041{
2042 return single_open(file, ab8500_gpadc_conv_type_print,
2043 inode->i_private);
2044}
2045
2046static ssize_t ab8500_gpadc_conv_type_write(struct file *file,
2047 const char __user *user_buf,
2048 size_t count, loff_t *ppos)
2049{
2050 struct device *dev = ((struct seq_file *)(file->private_data))->private;
2051 char buf[32];
2052 int buf_size;
2053 unsigned long user_conv_type;
2054 int err;
2055
2056 /* Get userspace string and assure termination */
2057 buf_size = min(count, (sizeof(buf) - 1));
2058 if (copy_from_user(buf, user_buf, buf_size))
2059 return -EFAULT;
2060 buf[buf_size] = 0;
2061
2062 err = strict_strtoul(buf, 0, &user_conv_type);
2063 if (err)
2064 return -EINVAL;
2065 if ((user_conv_type == ADC_SW)
2066 || (user_conv_type == ADC_HW)) {
2067 conv_type = (u8) user_conv_type;
2068 } else {
2069 dev_err(dev, "Wrong input:\n"
2070 "Enter 0. ADC SW conversion\n"
2071 "Enter 1. ADC HW conversion\n");
2072 return -EINVAL;
2073 }
2074 return buf_size;
2075}
2076
2077static const struct file_operations ab8500_gpadc_conv_type_fops = {
2078 .open = ab8500_gpadc_conv_type_open,
2079 .read = seq_read,
2080 .write = ab8500_gpadc_conv_type_write,
2081 .llseek = seq_lseek,
2082 .release = single_release,
2083 .owner = THIS_MODULE,
2084};
2085
carriere etienne0fbce762011-04-08 16:26:36 +02002086/*
2087 * return length of an ASCII numerical value, 0 is string is not a
2088 * numerical value.
2089 * string shall start at value 1st char.
2090 * string can be tailed with \0 or space or newline chars only.
2091 * value can be decimal or hexadecimal (prefixed 0x or 0X).
2092 */
2093static int strval_len(char *b)
2094{
2095 char *s = b;
2096 if ((*s == '0') && ((*(s+1) == 'x') || (*(s+1) == 'X'))) {
2097 s += 2;
2098 for (; *s && (*s != ' ') && (*s != '\n'); s++) {
2099 if (!isxdigit(*s))
2100 return 0;
2101 }
2102 } else {
2103 if (*s == '-')
2104 s++;
2105 for (; *s && (*s != ' ') && (*s != '\n'); s++) {
2106 if (!isdigit(*s))
2107 return 0;
2108 }
2109 }
2110 return (int) (s-b);
2111}
2112
2113/*
2114 * parse hwreg input data.
2115 * update global hwreg_cfg only if input data syntax is ok.
2116 */
2117static ssize_t hwreg_common_write(char *b, struct hwreg_cfg *cfg,
2118 struct device *dev)
2119{
2120 uint write, val = 0;
2121 u8 regvalue;
2122 int ret;
2123 struct hwreg_cfg loc = {
2124 .bank = 0, /* default: invalid phys addr */
2125 .addr = 0, /* default: invalid phys addr */
2126 .fmt = 0, /* default: 32bit access, hex output */
2127 .mask = 0xFFFFFFFF, /* default: no mask */
2128 .shift = 0, /* default: no bit shift */
2129 };
2130
2131 /* read or write ? */
2132 if (!strncmp(b, "read ", 5)) {
2133 write = 0;
2134 b += 5;
2135 } else if (!strncmp(b, "write ", 6)) {
2136 write = 1;
2137 b += 6;
2138 } else
2139 return -EINVAL;
2140
2141 /* OPTIONS -l|-w|-b -s -m -o */
2142 while ((*b == ' ') || (*b == '-')) {
2143 if (*(b-1) != ' ') {
2144 b++;
2145 continue;
2146 }
2147 if ((!strncmp(b, "-d ", 3)) ||
2148 (!strncmp(b, "-dec ", 5))) {
2149 b += (*(b+2) == ' ') ? 3 : 5;
2150 loc.fmt |= (1<<0);
2151 } else if ((!strncmp(b, "-h ", 3)) ||
2152 (!strncmp(b, "-hex ", 5))) {
2153 b += (*(b+2) == ' ') ? 3 : 5;
2154 loc.fmt &= ~(1<<0);
2155 } else if ((!strncmp(b, "-m ", 3)) ||
2156 (!strncmp(b, "-mask ", 6))) {
2157 b += (*(b+2) == ' ') ? 3 : 6;
2158 if (strval_len(b) == 0)
2159 return -EINVAL;
2160 loc.mask = simple_strtoul(b, &b, 0);
2161 } else if ((!strncmp(b, "-s ", 3)) ||
2162 (!strncmp(b, "-shift ", 7))) {
2163 b += (*(b+2) == ' ') ? 3 : 7;
2164 if (strval_len(b) == 0)
2165 return -EINVAL;
2166 loc.shift = simple_strtol(b, &b, 0);
2167 } else {
2168 return -EINVAL;
2169 }
2170 }
2171 /* get arg BANK and ADDRESS */
2172 if (strval_len(b) == 0)
2173 return -EINVAL;
2174 loc.bank = simple_strtoul(b, &b, 0);
2175 while (*b == ' ')
2176 b++;
2177 if (strval_len(b) == 0)
2178 return -EINVAL;
2179 loc.addr = simple_strtoul(b, &b, 0);
2180
2181 if (write) {
2182 while (*b == ' ')
2183 b++;
2184 if (strval_len(b) == 0)
2185 return -EINVAL;
2186 val = simple_strtoul(b, &b, 0);
2187 }
2188
2189 /* args are ok, update target cfg (mainly for read) */
2190 *cfg = loc;
2191
2192#ifdef ABB_HWREG_DEBUG
2193 pr_warn("HWREG request: %s, %s, addr=0x%08X, mask=0x%X, shift=%d"
2194 "value=0x%X\n", (write) ? "write" : "read",
2195 REG_FMT_DEC(cfg) ? "decimal" : "hexa",
2196 cfg->addr, cfg->mask, cfg->shift, val);
2197#endif
2198
2199 if (!write)
2200 return 0;
2201
2202 ret = abx500_get_register_interruptible(dev,
2203 (u8)cfg->bank, (u8)cfg->addr, &regvalue);
2204 if (ret < 0) {
2205 dev_err(dev, "abx500_get_reg fail %d, %d\n",
2206 ret, __LINE__);
2207 return -EINVAL;
2208 }
2209
2210 if (cfg->shift >= 0) {
2211 regvalue &= ~(cfg->mask << (cfg->shift));
2212 val = (val & cfg->mask) << (cfg->shift);
2213 } else {
2214 regvalue &= ~(cfg->mask >> (-cfg->shift));
2215 val = (val & cfg->mask) >> (-cfg->shift);
2216 }
2217 val = val | regvalue;
2218
2219 ret = abx500_set_register_interruptible(dev,
2220 (u8)cfg->bank, (u8)cfg->addr, (u8)val);
2221 if (ret < 0) {
2222 pr_err("abx500_set_reg failed %d, %d", ret, __LINE__);
2223 return -EINVAL;
2224 }
2225
2226 return 0;
2227}
2228
2229static ssize_t ab8500_hwreg_write(struct file *file,
2230 const char __user *user_buf, size_t count, loff_t *ppos)
2231{
2232 struct device *dev = ((struct seq_file *)(file->private_data))->private;
2233 char buf[128];
2234 int buf_size, ret;
2235
2236 /* Get userspace string and assure termination */
2237 buf_size = min(count, (sizeof(buf)-1));
2238 if (copy_from_user(buf, user_buf, buf_size))
2239 return -EFAULT;
2240 buf[buf_size] = 0;
2241
2242 /* get args and process */
2243 ret = hwreg_common_write(buf, &hwreg_cfg, dev);
2244 return (ret) ? ret : buf_size;
2245}
2246
2247/*
2248 * - irq subscribe/unsubscribe stuff
2249 */
Lee Jones4b8ac082013-01-14 16:10:36 +00002250static int ab8500_subscribe_unsubscribe_print(struct seq_file *s, void *p)
2251{
2252 seq_printf(s, "%d\n", irq_first);
2253
2254 return 0;
2255}
2256
2257static int ab8500_subscribe_unsubscribe_open(struct inode *inode,
2258 struct file *file)
2259{
2260 return single_open(file, ab8500_subscribe_unsubscribe_print,
2261 inode->i_private);
2262}
2263
2264/*
Mattias Wallin0b337e72010-11-19 17:55:11 +01002265 * Userspace should use poll() on this file. When an event occur
Lee Jones4b8ac082013-01-14 16:10:36 +00002266 * the blocking poll will be released.
2267 */
2268static ssize_t show_irq(struct device *dev,
2269 struct device_attribute *attr, char *buf)
2270{
Mattias Wallin0b337e72010-11-19 17:55:11 +01002271 unsigned long name;
2272 unsigned int irq_index;
2273 int err;
Lee Jones4b8ac082013-01-14 16:10:36 +00002274
Mattias Wallin0b337e72010-11-19 17:55:11 +01002275 err = strict_strtoul(attr->attr.name, 0, &name);
2276 if (err)
2277 return err;
2278
2279 irq_index = name - irq_first;
Linus Walleijddba25f2012-02-03 11:19:05 +01002280 if (irq_index >= num_irqs)
Mattias Wallin0b337e72010-11-19 17:55:11 +01002281 return -EINVAL;
2282 else
2283 return sprintf(buf, "%u\n", irq_count[irq_index]);
2284}
Lee Jones4b8ac082013-01-14 16:10:36 +00002285
2286static ssize_t ab8500_subscribe_write(struct file *file,
2287 const char __user *user_buf,
2288 size_t count, loff_t *ppos)
2289{
2290 struct device *dev = ((struct seq_file *)(file->private_data))->private;
2291 char buf[32];
2292 int buf_size;
2293 unsigned long user_val;
2294 int err;
Mattias Wallin0b337e72010-11-19 17:55:11 +01002295 unsigned int irq_index;
Lee Jones4b8ac082013-01-14 16:10:36 +00002296
2297 /* Get userspace string and assure termination */
2298 buf_size = min(count, (sizeof(buf)-1));
2299 if (copy_from_user(buf, user_buf, buf_size))
2300 return -EFAULT;
2301 buf[buf_size] = 0;
2302
2303 err = strict_strtoul(buf, 0, &user_val);
2304 if (err)
2305 return -EINVAL;
2306 if (user_val < irq_first) {
2307 dev_err(dev, "debugfs error input < %d\n", irq_first);
2308 return -EINVAL;
2309 }
2310 if (user_val > irq_last) {
2311 dev_err(dev, "debugfs error input > %d\n", irq_last);
2312 return -EINVAL;
2313 }
2314
Mattias Wallin0b337e72010-11-19 17:55:11 +01002315 irq_index = user_val - irq_first;
Linus Walleijddba25f2012-02-03 11:19:05 +01002316 if (irq_index >= num_irqs)
Mattias Wallin0b337e72010-11-19 17:55:11 +01002317 return -EINVAL;
2318
Lee Jones4b8ac082013-01-14 16:10:36 +00002319 /*
Mattias Wallin0b337e72010-11-19 17:55:11 +01002320 * This will create a sysfs file named <irq-nr> which userspace can
Lee Jones4b8ac082013-01-14 16:10:36 +00002321 * use to select or poll and get the AB8500 events
2322 */
Mattias Wallin0b337e72010-11-19 17:55:11 +01002323 dev_attr[irq_index] = kmalloc(sizeof(struct device_attribute),
2324 GFP_KERNEL);
2325 event_name[irq_index] = kmalloc(buf_size, GFP_KERNEL);
2326 sprintf(event_name[irq_index], "%lu", user_val);
2327 dev_attr[irq_index]->show = show_irq;
2328 dev_attr[irq_index]->store = NULL;
2329 dev_attr[irq_index]->attr.name = event_name[irq_index];
2330 dev_attr[irq_index]->attr.mode = S_IRUGO;
2331 err = sysfs_create_file(&dev->kobj, &dev_attr[irq_index]->attr);
Lee Jones4b8ac082013-01-14 16:10:36 +00002332 if (err < 0) {
2333 printk(KERN_ERR "sysfs_create_file failed %d\n", err);
2334 return err;
2335 }
2336
2337 err = request_threaded_irq(user_val, NULL, ab8500_debug_handler,
2338 IRQF_SHARED | IRQF_NO_SUSPEND,
2339 "ab8500-debug", &dev->kobj);
2340 if (err < 0) {
2341 printk(KERN_ERR "request_threaded_irq failed %d, %lu\n",
2342 err, user_val);
Mattias Wallin0b337e72010-11-19 17:55:11 +01002343 sysfs_remove_file(&dev->kobj, &dev_attr[irq_index]->attr);
Lee Jones4b8ac082013-01-14 16:10:36 +00002344 return err;
2345 }
2346
2347 return buf_size;
2348}
2349
2350static ssize_t ab8500_unsubscribe_write(struct file *file,
2351 const char __user *user_buf,
2352 size_t count, loff_t *ppos)
2353{
2354 struct device *dev = ((struct seq_file *)(file->private_data))->private;
2355 char buf[32];
2356 int buf_size;
2357 unsigned long user_val;
2358 int err;
Mattias Wallin0b337e72010-11-19 17:55:11 +01002359 unsigned int irq_index;
Lee Jones4b8ac082013-01-14 16:10:36 +00002360
2361 /* Get userspace string and assure termination */
2362 buf_size = min(count, (sizeof(buf)-1));
2363 if (copy_from_user(buf, user_buf, buf_size))
2364 return -EFAULT;
2365 buf[buf_size] = 0;
2366
2367 err = strict_strtoul(buf, 0, &user_val);
2368 if (err)
2369 return -EINVAL;
2370 if (user_val < irq_first) {
2371 dev_err(dev, "debugfs error input < %d\n", irq_first);
2372 return -EINVAL;
2373 }
2374 if (user_val > irq_last) {
2375 dev_err(dev, "debugfs error input > %d\n", irq_last);
2376 return -EINVAL;
2377 }
2378
Mattias Wallin0b337e72010-11-19 17:55:11 +01002379 irq_index = user_val - irq_first;
Linus Walleijddba25f2012-02-03 11:19:05 +01002380 if (irq_index >= num_irqs)
Mattias Wallin0b337e72010-11-19 17:55:11 +01002381 return -EINVAL;
Lee Jones4b8ac082013-01-14 16:10:36 +00002382
Mattias Wallin0b337e72010-11-19 17:55:11 +01002383 /* Set irq count to 0 when unsubscribe */
2384 irq_count[irq_index] = 0;
2385
2386 if (dev_attr[irq_index])
2387 sysfs_remove_file(&dev->kobj, &dev_attr[irq_index]->attr);
2388
2389
2390 free_irq(user_val, &dev->kobj);
2391 kfree(event_name[irq_index]);
2392 kfree(dev_attr[irq_index]);
Lee Jones4b8ac082013-01-14 16:10:36 +00002393
2394 return buf_size;
2395}
2396
carriere etienne0fbce762011-04-08 16:26:36 +02002397/*
2398 * - several deubgfs nodes fops
2399 */
2400
Mattias Wallin5814fc32010-09-13 16:05:04 +02002401static const struct file_operations ab8500_bank_fops = {
Mattias Wallind7b9f322010-11-26 13:06:39 +01002402 .open = ab8500_bank_open,
2403 .write = ab8500_bank_write,
2404 .read = seq_read,
2405 .llseek = seq_lseek,
2406 .release = single_release,
2407 .owner = THIS_MODULE,
Mattias Wallin5814fc32010-09-13 16:05:04 +02002408};
2409
2410static const struct file_operations ab8500_address_fops = {
Mattias Wallind7b9f322010-11-26 13:06:39 +01002411 .open = ab8500_address_open,
2412 .write = ab8500_address_write,
2413 .read = seq_read,
2414 .llseek = seq_lseek,
2415 .release = single_release,
2416 .owner = THIS_MODULE,
Mattias Wallin5814fc32010-09-13 16:05:04 +02002417};
2418
2419static const struct file_operations ab8500_val_fops = {
Mattias Wallind7b9f322010-11-26 13:06:39 +01002420 .open = ab8500_val_open,
2421 .write = ab8500_val_write,
2422 .read = seq_read,
2423 .llseek = seq_lseek,
2424 .release = single_release,
2425 .owner = THIS_MODULE,
Mattias Wallin5814fc32010-09-13 16:05:04 +02002426};
2427
Bengt Jonsson8f0eb432012-02-14 13:01:00 +01002428static const struct file_operations ab8500_interrupts_fops = {
2429 .open = ab8500_interrupts_open,
2430 .read = seq_read,
2431 .llseek = seq_lseek,
2432 .release = single_release,
2433 .owner = THIS_MODULE,
2434};
2435
Lee Jones4b8ac082013-01-14 16:10:36 +00002436static const struct file_operations ab8500_subscribe_fops = {
2437 .open = ab8500_subscribe_unsubscribe_open,
2438 .write = ab8500_subscribe_write,
2439 .read = seq_read,
2440 .llseek = seq_lseek,
2441 .release = single_release,
2442 .owner = THIS_MODULE,
2443};
2444
2445static const struct file_operations ab8500_unsubscribe_fops = {
2446 .open = ab8500_subscribe_unsubscribe_open,
2447 .write = ab8500_unsubscribe_write,
2448 .read = seq_read,
2449 .llseek = seq_lseek,
2450 .release = single_release,
2451 .owner = THIS_MODULE,
2452};
2453
carriere etienne0fbce762011-04-08 16:26:36 +02002454static const struct file_operations ab8500_hwreg_fops = {
2455 .open = ab8500_hwreg_open,
2456 .write = ab8500_hwreg_write,
2457 .read = seq_read,
2458 .llseek = seq_lseek,
2459 .release = single_release,
2460 .owner = THIS_MODULE,
2461};
2462
Mattias Wallin5814fc32010-09-13 16:05:04 +02002463static struct dentry *ab8500_dir;
John Beckett1478a312011-05-31 13:54:27 +01002464static struct dentry *ab8500_gpadc_dir;
Mattias Wallin5814fc32010-09-13 16:05:04 +02002465
Bill Pembertonf791be42012-11-19 13:23:04 -05002466static int ab8500_debug_probe(struct platform_device *plf)
Mattias Wallin5814fc32010-09-13 16:05:04 +02002467{
carriere etienne0fbce762011-04-08 16:26:36 +02002468 struct dentry *file;
Linus Walleijddba25f2012-02-03 11:19:05 +01002469 int ret = -ENOMEM;
2470 struct ab8500 *ab8500;
Mattias Wallind7b9f322010-11-26 13:06:39 +01002471 debug_bank = AB8500_MISC;
2472 debug_address = AB8500_REV_REG & 0x00FF;
Mattias Wallin5814fc32010-09-13 16:05:04 +02002473
Linus Walleijddba25f2012-02-03 11:19:05 +01002474 ab8500 = dev_get_drvdata(plf->dev.parent);
2475 num_irqs = ab8500->mask_size;
2476
Ashok G70bad042012-02-28 10:21:00 +05302477 irq_count = kzalloc(sizeof(*irq_count)*num_irqs, GFP_KERNEL);
Linus Walleijddba25f2012-02-03 11:19:05 +01002478 if (!irq_count)
2479 return -ENOMEM;
2480
2481 dev_attr = kzalloc(sizeof(*dev_attr)*num_irqs,GFP_KERNEL);
2482 if (!dev_attr)
2483 goto out_freeirq_count;
2484
2485 event_name = kzalloc(sizeof(*event_name)*num_irqs, GFP_KERNEL);
2486 if (!event_name)
2487 goto out_freedev_attr;
2488
Lee Jones4b8ac082013-01-14 16:10:36 +00002489 irq_first = platform_get_irq_byname(plf, "IRQ_FIRST");
2490 if (irq_first < 0) {
2491 dev_err(&plf->dev, "First irq not found, err %d\n",
John Beckett1478a312011-05-31 13:54:27 +01002492 irq_first);
Linus Walleijddba25f2012-02-03 11:19:05 +01002493 ret = irq_first;
2494 goto out_freeevent_name;
Lee Jones4b8ac082013-01-14 16:10:36 +00002495 }
2496
2497 irq_last = platform_get_irq_byname(plf, "IRQ_LAST");
2498 if (irq_last < 0) {
2499 dev_err(&plf->dev, "Last irq not found, err %d\n",
John Beckett1478a312011-05-31 13:54:27 +01002500 irq_last);
Linus Walleijddba25f2012-02-03 11:19:05 +01002501 ret = irq_last;
Jonas Aaberg2cf64e22012-05-31 07:57:07 +02002502 goto out_freeevent_name;
Lee Jones4b8ac082013-01-14 16:10:36 +00002503 }
2504
Mattias Wallind7b9f322010-11-26 13:06:39 +01002505 ab8500_dir = debugfs_create_dir(AB8500_NAME_STRING, NULL);
2506 if (!ab8500_dir)
carriere etienne0fbce762011-04-08 16:26:36 +02002507 goto err;
Mattias Wallin5814fc32010-09-13 16:05:04 +02002508
John Beckett1478a312011-05-31 13:54:27 +01002509 ab8500_gpadc_dir = debugfs_create_dir(AB8500_ADC_NAME_STRING,
2510 ab8500_dir);
2511 if (!ab8500_gpadc_dir)
2512 goto err;
2513
2514 file = debugfs_create_file("all-bank-registers", S_IRUGO,
2515 ab8500_dir, &plf->dev, &ab8500_registers_fops);
carriere etienne0fbce762011-04-08 16:26:36 +02002516 if (!file)
2517 goto err;
Mattias Wallin5814fc32010-09-13 16:05:04 +02002518
Mian Yousaf Kaukab42002c62012-01-26 15:39:20 +01002519 file = debugfs_create_file("all-banks", S_IRUGO,
2520 ab8500_dir, &plf->dev, &ab8500_all_banks_fops);
2521 if (!file)
2522 goto err;
2523
John Beckett1478a312011-05-31 13:54:27 +01002524 file = debugfs_create_file("register-bank", (S_IRUGO | S_IWUSR),
2525 ab8500_dir, &plf->dev, &ab8500_bank_fops);
carriere etienne0fbce762011-04-08 16:26:36 +02002526 if (!file)
2527 goto err;
Mattias Wallin5814fc32010-09-13 16:05:04 +02002528
John Beckett1478a312011-05-31 13:54:27 +01002529 file = debugfs_create_file("register-address", (S_IRUGO | S_IWUSR),
2530 ab8500_dir, &plf->dev, &ab8500_address_fops);
carriere etienne0fbce762011-04-08 16:26:36 +02002531 if (!file)
2532 goto err;
Mattias Wallin5814fc32010-09-13 16:05:04 +02002533
John Beckett1478a312011-05-31 13:54:27 +01002534 file = debugfs_create_file("register-value", (S_IRUGO | S_IWUSR),
2535 ab8500_dir, &plf->dev, &ab8500_val_fops);
carriere etienne0fbce762011-04-08 16:26:36 +02002536 if (!file)
2537 goto err;
Mattias Wallin5814fc32010-09-13 16:05:04 +02002538
John Beckett1478a312011-05-31 13:54:27 +01002539 file = debugfs_create_file("irq-subscribe", (S_IRUGO | S_IWUSR),
2540 ab8500_dir, &plf->dev, &ab8500_subscribe_fops);
carriere etienne0fbce762011-04-08 16:26:36 +02002541 if (!file)
2542 goto err;
Lee Jones4b8ac082013-01-14 16:10:36 +00002543
Lee Jones9581ae32012-07-06 16:11:50 +02002544 if (is_ab8500(ab8500)) {
2545 debug_ranges = ab8500_debug_ranges;
Bengt Jonsson8f0eb432012-02-14 13:01:00 +01002546 num_interrupt_lines = AB8500_NR_IRQS;
Lee Jones9581ae32012-07-06 16:11:50 +02002547 } else if (is_ab8505(ab8500)) {
2548 debug_ranges = ab8505_debug_ranges;
Bengt Jonsson8f0eb432012-02-14 13:01:00 +01002549 num_interrupt_lines = AB8505_NR_IRQS;
Lee Jones9581ae32012-07-06 16:11:50 +02002550 } else if (is_ab9540(ab8500)) {
2551 debug_ranges = ab8505_debug_ranges;
Bengt Jonsson8f0eb432012-02-14 13:01:00 +01002552 num_interrupt_lines = AB9540_NR_IRQS;
Lee Jones9581ae32012-07-06 16:11:50 +02002553 } else if (is_ab8540(ab8500)) {
2554 debug_ranges = ab8505_debug_ranges;
Lee Jonese436ddf2013-02-26 10:09:41 +00002555 num_interrupt_lines = AB8540_NR_IRQS;
Lee Jones9581ae32012-07-06 16:11:50 +02002556 }
Bengt Jonsson8f0eb432012-02-14 13:01:00 +01002557
2558 file = debugfs_create_file("interrupts", (S_IRUGO),
2559 ab8500_dir, &plf->dev, &ab8500_interrupts_fops);
2560 if (!file)
2561 goto err;
2562
John Beckett1478a312011-05-31 13:54:27 +01002563 file = debugfs_create_file("irq-unsubscribe", (S_IRUGO | S_IWUSR),
2564 ab8500_dir, &plf->dev, &ab8500_unsubscribe_fops);
carriere etienne0fbce762011-04-08 16:26:36 +02002565 if (!file)
2566 goto err;
2567
John Beckett1478a312011-05-31 13:54:27 +01002568 file = debugfs_create_file("hwreg", (S_IRUGO | S_IWUSR),
2569 ab8500_dir, &plf->dev, &ab8500_hwreg_fops);
2570 if (!file)
2571 goto err;
2572
2573 file = debugfs_create_file("bat_ctrl", (S_IRUGO | S_IWUSR),
2574 ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_bat_ctrl_fops);
2575 if (!file)
2576 goto err;
2577
2578 file = debugfs_create_file("btemp_ball", (S_IRUGO | S_IWUSR),
2579 ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_btemp_ball_fops);
2580 if (!file)
2581 goto err;
2582
2583 file = debugfs_create_file("main_charger_v", (S_IRUGO | S_IWUSR),
2584 ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_main_charger_v_fops);
2585 if (!file)
2586 goto err;
2587
2588 file = debugfs_create_file("acc_detect1", (S_IRUGO | S_IWUSR),
2589 ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_acc_detect1_fops);
2590 if (!file)
2591 goto err;
2592
2593 file = debugfs_create_file("acc_detect2", (S_IRUGO | S_IWUSR),
2594 ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_acc_detect2_fops);
2595 if (!file)
2596 goto err;
2597
2598 file = debugfs_create_file("adc_aux1", (S_IRUGO | S_IWUSR),
2599 ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_aux1_fops);
2600 if (!file)
2601 goto err;
2602
2603 file = debugfs_create_file("adc_aux2", (S_IRUGO | S_IWUSR),
2604 ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_aux2_fops);
2605 if (!file)
2606 goto err;
2607
2608 file = debugfs_create_file("main_bat_v", (S_IRUGO | S_IWUSR),
2609 ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_main_bat_v_fops);
2610 if (!file)
2611 goto err;
2612
2613 file = debugfs_create_file("vbus_v", (S_IRUGO | S_IWUSR),
2614 ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_vbus_v_fops);
2615 if (!file)
2616 goto err;
2617
2618 file = debugfs_create_file("main_charger_c", (S_IRUGO | S_IWUSR),
2619 ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_main_charger_c_fops);
2620 if (!file)
2621 goto err;
2622
2623 file = debugfs_create_file("usb_charger_c", (S_IRUGO | S_IWUSR),
2624 ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_usb_charger_c_fops);
2625 if (!file)
2626 goto err;
2627
2628 file = debugfs_create_file("bk_bat_v", (S_IRUGO | S_IWUSR),
2629 ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_bk_bat_v_fops);
2630 if (!file)
2631 goto err;
2632
2633 file = debugfs_create_file("die_temp", (S_IRUGO | S_IWUSR),
2634 ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_die_temp_fops);
carriere etienne0fbce762011-04-08 16:26:36 +02002635 if (!file)
2636 goto err;
Lee Jonesbc6b4132013-02-26 14:02:31 +00002637 if (is_ab8540(ab8500)) {
2638 file = debugfs_create_file("xtal_temp", (S_IRUGO | S_IWUGO),
2639 ab8500_gpadc_dir, &plf->dev, &ab8540_gpadc_xtal_temp_fops);
2640 if (!file)
2641 goto err;
2642 file = debugfs_create_file("vbattruemeas", (S_IRUGO | S_IWUGO),
2643 ab8500_gpadc_dir, &plf->dev,
2644 &ab8540_gpadc_vbat_true_meas_fops);
2645 if (!file)
2646 goto err;
2647 file = debugfs_create_file("batctrl_and_ibat",
2648 (S_IRUGO | S_IWUGO), ab8500_gpadc_dir,
2649 &plf->dev, &ab8540_gpadc_bat_ctrl_and_ibat_fops);
2650 if (!file)
2651 goto err;
2652 file = debugfs_create_file("vbatmeas_and_ibat",
2653 (S_IRUGO | S_IWUGO), ab8500_gpadc_dir,
2654 &plf->dev,
2655 &ab8540_gpadc_vbat_meas_and_ibat_fops);
2656 if (!file)
2657 goto err;
2658 file = debugfs_create_file("vbattruemeas_and_ibat",
2659 (S_IRUGO | S_IWUGO), ab8500_gpadc_dir,
2660 &plf->dev,
2661 &ab8540_gpadc_vbat_true_meas_and_ibat_fops);
2662 if (!file)
2663 goto err;
2664 file = debugfs_create_file("battemp_and_ibat",
2665 (S_IRUGO | S_IWUGO), ab8500_gpadc_dir,
2666 &plf->dev, &ab8540_gpadc_bat_temp_and_ibat_fops);
2667 if (!file)
2668 goto err;
2669 file = debugfs_create_file("otp_calib", (S_IRUGO | S_IWUGO),
2670 ab8500_gpadc_dir, &plf->dev, &ab8540_gpadc_otp_calib_fops);
2671 if (!file)
2672 goto err;
2673 }
Lee Jones73482342013-02-26 10:06:55 +00002674 file = debugfs_create_file("avg_sample", (S_IRUGO | S_IWUGO),
2675 ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_avg_sample_fops);
2676 if (!file)
2677 goto err;
2678
2679 file = debugfs_create_file("trig_edge", (S_IRUGO | S_IWUGO),
2680 ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_trig_edge_fops);
2681 if (!file)
2682 goto err;
2683
2684 file = debugfs_create_file("trig_timer", (S_IRUGO | S_IWUGO),
2685 ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_trig_timer_fops);
2686 if (!file)
2687 goto err;
2688
2689 file = debugfs_create_file("conv_type", (S_IRUGO | S_IWUGO),
2690 ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_conv_type_fops);
2691 if (!file)
2692 goto err;
2693
Mattias Wallind7b9f322010-11-26 13:06:39 +01002694 return 0;
Mattias Wallin5814fc32010-09-13 16:05:04 +02002695
carriere etienne0fbce762011-04-08 16:26:36 +02002696err:
2697 if (ab8500_dir)
2698 debugfs_remove_recursive(ab8500_dir);
Mattias Wallind7b9f322010-11-26 13:06:39 +01002699 dev_err(&plf->dev, "failed to create debugfs entries.\n");
Linus Walleijddba25f2012-02-03 11:19:05 +01002700out_freeevent_name:
2701 kfree(event_name);
2702out_freedev_attr:
2703 kfree(dev_attr);
2704out_freeirq_count:
2705 kfree(irq_count);
2706
2707 return ret;
Mattias Wallin5814fc32010-09-13 16:05:04 +02002708}
2709
Bill Pemberton4740f732012-11-19 13:26:01 -05002710static int ab8500_debug_remove(struct platform_device *plf)
Mattias Wallin5814fc32010-09-13 16:05:04 +02002711{
carriere etienne0fbce762011-04-08 16:26:36 +02002712 debugfs_remove_recursive(ab8500_dir);
Linus Walleijddba25f2012-02-03 11:19:05 +01002713 kfree(event_name);
2714 kfree(dev_attr);
2715 kfree(irq_count);
2716
Mattias Wallind7b9f322010-11-26 13:06:39 +01002717 return 0;
Mattias Wallin5814fc32010-09-13 16:05:04 +02002718}
2719
2720static struct platform_driver ab8500_debug_driver = {
Mattias Wallind7b9f322010-11-26 13:06:39 +01002721 .driver = {
2722 .name = "ab8500-debug",
2723 .owner = THIS_MODULE,
2724 },
2725 .probe = ab8500_debug_probe,
Bill Pemberton84449212012-11-19 13:20:24 -05002726 .remove = ab8500_debug_remove
Mattias Wallin5814fc32010-09-13 16:05:04 +02002727};
2728
2729static int __init ab8500_debug_init(void)
2730{
Mattias Wallind7b9f322010-11-26 13:06:39 +01002731 return platform_driver_register(&ab8500_debug_driver);
Mattias Wallin5814fc32010-09-13 16:05:04 +02002732}
2733
2734static void __exit ab8500_debug_exit(void)
2735{
Mattias Wallind7b9f322010-11-26 13:06:39 +01002736 platform_driver_unregister(&ab8500_debug_driver);
Mattias Wallin5814fc32010-09-13 16:05:04 +02002737}
2738subsys_initcall(ab8500_debug_init);
2739module_exit(ab8500_debug_exit);
2740
2741MODULE_AUTHOR("Mattias WALLIN <mattias.wallin@stericsson.com");
2742MODULE_DESCRIPTION("AB8500 DEBUG");
2743MODULE_LICENSE("GPL v2");