blob: 074eea9e4bfd252be7f3dc369833dfc8dc0cbc48 [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 Jones73482342013-02-26 10:06:55 +00001636static int ab8500_gpadc_avg_sample_print(struct seq_file *s, void *p)
1637{
1638 return seq_printf(s, "%d\n", avg_sample);
1639}
1640
1641static int ab8500_gpadc_avg_sample_open(struct inode *inode, struct file *file)
1642{
1643 return single_open(file, ab8500_gpadc_avg_sample_print,
1644 inode->i_private);
1645}
1646
1647static ssize_t ab8500_gpadc_avg_sample_write(struct file *file,
1648 const char __user *user_buf,
1649 size_t count, loff_t *ppos)
1650{
1651 struct device *dev = ((struct seq_file *)(file->private_data))->private;
1652 char buf[32];
1653 int buf_size;
1654 unsigned long user_avg_sample;
1655 int err;
1656
1657 /* Get userspace string and assure termination */
1658 buf_size = min(count, (sizeof(buf) - 1));
1659 if (copy_from_user(buf, user_buf, buf_size))
1660 return -EFAULT;
1661 buf[buf_size] = 0;
1662
1663 err = strict_strtoul(buf, 0, &user_avg_sample);
1664 if (err)
1665 return -EINVAL;
1666 if ((user_avg_sample == SAMPLE_1) || (user_avg_sample == SAMPLE_4)
1667 || (user_avg_sample == SAMPLE_8)
1668 || (user_avg_sample == SAMPLE_16)) {
1669 avg_sample = (u8) user_avg_sample;
1670 } else {
1671 dev_err(dev, "debugfs error input: "
1672 "should be egal to 1, 4, 8 or 16\n");
1673 return -EINVAL;
1674 }
1675 return buf_size;
1676}
1677
1678static const struct file_operations ab8500_gpadc_avg_sample_fops = {
1679 .open = ab8500_gpadc_avg_sample_open,
1680 .read = seq_read,
1681 .write = ab8500_gpadc_avg_sample_write,
1682 .llseek = seq_lseek,
1683 .release = single_release,
1684 .owner = THIS_MODULE,
1685};
1686
1687static int ab8500_gpadc_trig_edge_print(struct seq_file *s, void *p)
1688{
1689 return seq_printf(s, "%d\n", trig_edge);
1690}
1691
1692static int ab8500_gpadc_trig_edge_open(struct inode *inode, struct file *file)
1693{
1694 return single_open(file, ab8500_gpadc_trig_edge_print,
1695 inode->i_private);
1696}
1697
1698static ssize_t ab8500_gpadc_trig_edge_write(struct file *file,
1699 const char __user *user_buf,
1700 size_t count, loff_t *ppos)
1701{
1702 struct device *dev = ((struct seq_file *)(file->private_data))->private;
1703 char buf[32];
1704 int buf_size;
1705 unsigned long user_trig_edge;
1706 int err;
1707
1708 /* Get userspace string and assure termination */
1709 buf_size = min(count, (sizeof(buf) - 1));
1710 if (copy_from_user(buf, user_buf, buf_size))
1711 return -EFAULT;
1712 buf[buf_size] = 0;
1713
1714 err = strict_strtoul(buf, 0, &user_trig_edge);
1715 if (err)
1716 return -EINVAL;
1717 if ((user_trig_edge == RISING_EDGE)
1718 || (user_trig_edge == FALLING_EDGE)) {
1719 trig_edge = (u8) user_trig_edge;
1720 } else {
1721 dev_err(dev, "Wrong input:\n"
1722 "Enter 0. Rising edge\n"
1723 "Enter 1. Falling edge\n");
1724 return -EINVAL;
1725 }
1726 return buf_size;
1727}
1728
1729static const struct file_operations ab8500_gpadc_trig_edge_fops = {
1730 .open = ab8500_gpadc_trig_edge_open,
1731 .read = seq_read,
1732 .write = ab8500_gpadc_trig_edge_write,
1733 .llseek = seq_lseek,
1734 .release = single_release,
1735 .owner = THIS_MODULE,
1736};
1737
1738static int ab8500_gpadc_trig_timer_print(struct seq_file *s, void *p)
1739{
1740 return seq_printf(s, "%d\n", trig_timer);
1741}
1742
1743static int ab8500_gpadc_trig_timer_open(struct inode *inode, struct file *file)
1744{
1745 return single_open(file, ab8500_gpadc_trig_timer_print,
1746 inode->i_private);
1747}
1748
1749static ssize_t ab8500_gpadc_trig_timer_write(struct file *file,
1750 const char __user *user_buf,
1751 size_t count, loff_t *ppos)
1752{
1753 struct device *dev = ((struct seq_file *)(file->private_data))->private;
1754 char buf[32];
1755 int buf_size;
1756 unsigned long user_trig_timer;
1757 int err;
1758
1759 /* Get userspace string and assure termination */
1760 buf_size = min(count, (sizeof(buf) - 1));
1761 if (copy_from_user(buf, user_buf, buf_size))
1762 return -EFAULT;
1763 buf[buf_size] = 0;
1764
1765 err = strict_strtoul(buf, 0, &user_trig_timer);
1766 if (err)
1767 return -EINVAL;
1768 if ((user_trig_timer >= 0) && (user_trig_timer <= 255)) {
1769 trig_timer = (u8) user_trig_timer;
1770 } else {
1771 dev_err(dev, "debugfs error input: "
1772 "should be beetween 0 to 255\n");
1773 return -EINVAL;
1774 }
1775 return buf_size;
1776}
1777
1778static const struct file_operations ab8500_gpadc_trig_timer_fops = {
1779 .open = ab8500_gpadc_trig_timer_open,
1780 .read = seq_read,
1781 .write = ab8500_gpadc_trig_timer_write,
1782 .llseek = seq_lseek,
1783 .release = single_release,
1784 .owner = THIS_MODULE,
1785};
1786
1787static int ab8500_gpadc_conv_type_print(struct seq_file *s, void *p)
1788{
1789 return seq_printf(s, "%d\n", conv_type);
1790}
1791
1792static int ab8500_gpadc_conv_type_open(struct inode *inode, struct file *file)
1793{
1794 return single_open(file, ab8500_gpadc_conv_type_print,
1795 inode->i_private);
1796}
1797
1798static ssize_t ab8500_gpadc_conv_type_write(struct file *file,
1799 const char __user *user_buf,
1800 size_t count, loff_t *ppos)
1801{
1802 struct device *dev = ((struct seq_file *)(file->private_data))->private;
1803 char buf[32];
1804 int buf_size;
1805 unsigned long user_conv_type;
1806 int err;
1807
1808 /* Get userspace string and assure termination */
1809 buf_size = min(count, (sizeof(buf) - 1));
1810 if (copy_from_user(buf, user_buf, buf_size))
1811 return -EFAULT;
1812 buf[buf_size] = 0;
1813
1814 err = strict_strtoul(buf, 0, &user_conv_type);
1815 if (err)
1816 return -EINVAL;
1817 if ((user_conv_type == ADC_SW)
1818 || (user_conv_type == ADC_HW)) {
1819 conv_type = (u8) user_conv_type;
1820 } else {
1821 dev_err(dev, "Wrong input:\n"
1822 "Enter 0. ADC SW conversion\n"
1823 "Enter 1. ADC HW conversion\n");
1824 return -EINVAL;
1825 }
1826 return buf_size;
1827}
1828
1829static const struct file_operations ab8500_gpadc_conv_type_fops = {
1830 .open = ab8500_gpadc_conv_type_open,
1831 .read = seq_read,
1832 .write = ab8500_gpadc_conv_type_write,
1833 .llseek = seq_lseek,
1834 .release = single_release,
1835 .owner = THIS_MODULE,
1836};
1837
carriere etienne0fbce762011-04-08 16:26:36 +02001838/*
1839 * return length of an ASCII numerical value, 0 is string is not a
1840 * numerical value.
1841 * string shall start at value 1st char.
1842 * string can be tailed with \0 or space or newline chars only.
1843 * value can be decimal or hexadecimal (prefixed 0x or 0X).
1844 */
1845static int strval_len(char *b)
1846{
1847 char *s = b;
1848 if ((*s == '0') && ((*(s+1) == 'x') || (*(s+1) == 'X'))) {
1849 s += 2;
1850 for (; *s && (*s != ' ') && (*s != '\n'); s++) {
1851 if (!isxdigit(*s))
1852 return 0;
1853 }
1854 } else {
1855 if (*s == '-')
1856 s++;
1857 for (; *s && (*s != ' ') && (*s != '\n'); s++) {
1858 if (!isdigit(*s))
1859 return 0;
1860 }
1861 }
1862 return (int) (s-b);
1863}
1864
1865/*
1866 * parse hwreg input data.
1867 * update global hwreg_cfg only if input data syntax is ok.
1868 */
1869static ssize_t hwreg_common_write(char *b, struct hwreg_cfg *cfg,
1870 struct device *dev)
1871{
1872 uint write, val = 0;
1873 u8 regvalue;
1874 int ret;
1875 struct hwreg_cfg loc = {
1876 .bank = 0, /* default: invalid phys addr */
1877 .addr = 0, /* default: invalid phys addr */
1878 .fmt = 0, /* default: 32bit access, hex output */
1879 .mask = 0xFFFFFFFF, /* default: no mask */
1880 .shift = 0, /* default: no bit shift */
1881 };
1882
1883 /* read or write ? */
1884 if (!strncmp(b, "read ", 5)) {
1885 write = 0;
1886 b += 5;
1887 } else if (!strncmp(b, "write ", 6)) {
1888 write = 1;
1889 b += 6;
1890 } else
1891 return -EINVAL;
1892
1893 /* OPTIONS -l|-w|-b -s -m -o */
1894 while ((*b == ' ') || (*b == '-')) {
1895 if (*(b-1) != ' ') {
1896 b++;
1897 continue;
1898 }
1899 if ((!strncmp(b, "-d ", 3)) ||
1900 (!strncmp(b, "-dec ", 5))) {
1901 b += (*(b+2) == ' ') ? 3 : 5;
1902 loc.fmt |= (1<<0);
1903 } else if ((!strncmp(b, "-h ", 3)) ||
1904 (!strncmp(b, "-hex ", 5))) {
1905 b += (*(b+2) == ' ') ? 3 : 5;
1906 loc.fmt &= ~(1<<0);
1907 } else if ((!strncmp(b, "-m ", 3)) ||
1908 (!strncmp(b, "-mask ", 6))) {
1909 b += (*(b+2) == ' ') ? 3 : 6;
1910 if (strval_len(b) == 0)
1911 return -EINVAL;
1912 loc.mask = simple_strtoul(b, &b, 0);
1913 } else if ((!strncmp(b, "-s ", 3)) ||
1914 (!strncmp(b, "-shift ", 7))) {
1915 b += (*(b+2) == ' ') ? 3 : 7;
1916 if (strval_len(b) == 0)
1917 return -EINVAL;
1918 loc.shift = simple_strtol(b, &b, 0);
1919 } else {
1920 return -EINVAL;
1921 }
1922 }
1923 /* get arg BANK and ADDRESS */
1924 if (strval_len(b) == 0)
1925 return -EINVAL;
1926 loc.bank = simple_strtoul(b, &b, 0);
1927 while (*b == ' ')
1928 b++;
1929 if (strval_len(b) == 0)
1930 return -EINVAL;
1931 loc.addr = simple_strtoul(b, &b, 0);
1932
1933 if (write) {
1934 while (*b == ' ')
1935 b++;
1936 if (strval_len(b) == 0)
1937 return -EINVAL;
1938 val = simple_strtoul(b, &b, 0);
1939 }
1940
1941 /* args are ok, update target cfg (mainly for read) */
1942 *cfg = loc;
1943
1944#ifdef ABB_HWREG_DEBUG
1945 pr_warn("HWREG request: %s, %s, addr=0x%08X, mask=0x%X, shift=%d"
1946 "value=0x%X\n", (write) ? "write" : "read",
1947 REG_FMT_DEC(cfg) ? "decimal" : "hexa",
1948 cfg->addr, cfg->mask, cfg->shift, val);
1949#endif
1950
1951 if (!write)
1952 return 0;
1953
1954 ret = abx500_get_register_interruptible(dev,
1955 (u8)cfg->bank, (u8)cfg->addr, &regvalue);
1956 if (ret < 0) {
1957 dev_err(dev, "abx500_get_reg fail %d, %d\n",
1958 ret, __LINE__);
1959 return -EINVAL;
1960 }
1961
1962 if (cfg->shift >= 0) {
1963 regvalue &= ~(cfg->mask << (cfg->shift));
1964 val = (val & cfg->mask) << (cfg->shift);
1965 } else {
1966 regvalue &= ~(cfg->mask >> (-cfg->shift));
1967 val = (val & cfg->mask) >> (-cfg->shift);
1968 }
1969 val = val | regvalue;
1970
1971 ret = abx500_set_register_interruptible(dev,
1972 (u8)cfg->bank, (u8)cfg->addr, (u8)val);
1973 if (ret < 0) {
1974 pr_err("abx500_set_reg failed %d, %d", ret, __LINE__);
1975 return -EINVAL;
1976 }
1977
1978 return 0;
1979}
1980
1981static ssize_t ab8500_hwreg_write(struct file *file,
1982 const char __user *user_buf, size_t count, loff_t *ppos)
1983{
1984 struct device *dev = ((struct seq_file *)(file->private_data))->private;
1985 char buf[128];
1986 int buf_size, ret;
1987
1988 /* Get userspace string and assure termination */
1989 buf_size = min(count, (sizeof(buf)-1));
1990 if (copy_from_user(buf, user_buf, buf_size))
1991 return -EFAULT;
1992 buf[buf_size] = 0;
1993
1994 /* get args and process */
1995 ret = hwreg_common_write(buf, &hwreg_cfg, dev);
1996 return (ret) ? ret : buf_size;
1997}
1998
1999/*
2000 * - irq subscribe/unsubscribe stuff
2001 */
Lee Jones4b8ac082013-01-14 16:10:36 +00002002static int ab8500_subscribe_unsubscribe_print(struct seq_file *s, void *p)
2003{
2004 seq_printf(s, "%d\n", irq_first);
2005
2006 return 0;
2007}
2008
2009static int ab8500_subscribe_unsubscribe_open(struct inode *inode,
2010 struct file *file)
2011{
2012 return single_open(file, ab8500_subscribe_unsubscribe_print,
2013 inode->i_private);
2014}
2015
2016/*
Mattias Wallin0b337e72010-11-19 17:55:11 +01002017 * Userspace should use poll() on this file. When an event occur
Lee Jones4b8ac082013-01-14 16:10:36 +00002018 * the blocking poll will be released.
2019 */
2020static ssize_t show_irq(struct device *dev,
2021 struct device_attribute *attr, char *buf)
2022{
Mattias Wallin0b337e72010-11-19 17:55:11 +01002023 unsigned long name;
2024 unsigned int irq_index;
2025 int err;
Lee Jones4b8ac082013-01-14 16:10:36 +00002026
Mattias Wallin0b337e72010-11-19 17:55:11 +01002027 err = strict_strtoul(attr->attr.name, 0, &name);
2028 if (err)
2029 return err;
2030
2031 irq_index = name - irq_first;
Linus Walleijddba25f2012-02-03 11:19:05 +01002032 if (irq_index >= num_irqs)
Mattias Wallin0b337e72010-11-19 17:55:11 +01002033 return -EINVAL;
2034 else
2035 return sprintf(buf, "%u\n", irq_count[irq_index]);
2036}
Lee Jones4b8ac082013-01-14 16:10:36 +00002037
2038static ssize_t ab8500_subscribe_write(struct file *file,
2039 const char __user *user_buf,
2040 size_t count, loff_t *ppos)
2041{
2042 struct device *dev = ((struct seq_file *)(file->private_data))->private;
2043 char buf[32];
2044 int buf_size;
2045 unsigned long user_val;
2046 int err;
Mattias Wallin0b337e72010-11-19 17:55:11 +01002047 unsigned int irq_index;
Lee Jones4b8ac082013-01-14 16:10:36 +00002048
2049 /* Get userspace string and assure termination */
2050 buf_size = min(count, (sizeof(buf)-1));
2051 if (copy_from_user(buf, user_buf, buf_size))
2052 return -EFAULT;
2053 buf[buf_size] = 0;
2054
2055 err = strict_strtoul(buf, 0, &user_val);
2056 if (err)
2057 return -EINVAL;
2058 if (user_val < irq_first) {
2059 dev_err(dev, "debugfs error input < %d\n", irq_first);
2060 return -EINVAL;
2061 }
2062 if (user_val > irq_last) {
2063 dev_err(dev, "debugfs error input > %d\n", irq_last);
2064 return -EINVAL;
2065 }
2066
Mattias Wallin0b337e72010-11-19 17:55:11 +01002067 irq_index = user_val - irq_first;
Linus Walleijddba25f2012-02-03 11:19:05 +01002068 if (irq_index >= num_irqs)
Mattias Wallin0b337e72010-11-19 17:55:11 +01002069 return -EINVAL;
2070
Lee Jones4b8ac082013-01-14 16:10:36 +00002071 /*
Mattias Wallin0b337e72010-11-19 17:55:11 +01002072 * This will create a sysfs file named <irq-nr> which userspace can
Lee Jones4b8ac082013-01-14 16:10:36 +00002073 * use to select or poll and get the AB8500 events
2074 */
Mattias Wallin0b337e72010-11-19 17:55:11 +01002075 dev_attr[irq_index] = kmalloc(sizeof(struct device_attribute),
2076 GFP_KERNEL);
2077 event_name[irq_index] = kmalloc(buf_size, GFP_KERNEL);
2078 sprintf(event_name[irq_index], "%lu", user_val);
2079 dev_attr[irq_index]->show = show_irq;
2080 dev_attr[irq_index]->store = NULL;
2081 dev_attr[irq_index]->attr.name = event_name[irq_index];
2082 dev_attr[irq_index]->attr.mode = S_IRUGO;
2083 err = sysfs_create_file(&dev->kobj, &dev_attr[irq_index]->attr);
Lee Jones4b8ac082013-01-14 16:10:36 +00002084 if (err < 0) {
2085 printk(KERN_ERR "sysfs_create_file failed %d\n", err);
2086 return err;
2087 }
2088
2089 err = request_threaded_irq(user_val, NULL, ab8500_debug_handler,
2090 IRQF_SHARED | IRQF_NO_SUSPEND,
2091 "ab8500-debug", &dev->kobj);
2092 if (err < 0) {
2093 printk(KERN_ERR "request_threaded_irq failed %d, %lu\n",
2094 err, user_val);
Mattias Wallin0b337e72010-11-19 17:55:11 +01002095 sysfs_remove_file(&dev->kobj, &dev_attr[irq_index]->attr);
Lee Jones4b8ac082013-01-14 16:10:36 +00002096 return err;
2097 }
2098
2099 return buf_size;
2100}
2101
2102static ssize_t ab8500_unsubscribe_write(struct file *file,
2103 const char __user *user_buf,
2104 size_t count, loff_t *ppos)
2105{
2106 struct device *dev = ((struct seq_file *)(file->private_data))->private;
2107 char buf[32];
2108 int buf_size;
2109 unsigned long user_val;
2110 int err;
Mattias Wallin0b337e72010-11-19 17:55:11 +01002111 unsigned int irq_index;
Lee Jones4b8ac082013-01-14 16:10:36 +00002112
2113 /* Get userspace string and assure termination */
2114 buf_size = min(count, (sizeof(buf)-1));
2115 if (copy_from_user(buf, user_buf, buf_size))
2116 return -EFAULT;
2117 buf[buf_size] = 0;
2118
2119 err = strict_strtoul(buf, 0, &user_val);
2120 if (err)
2121 return -EINVAL;
2122 if (user_val < irq_first) {
2123 dev_err(dev, "debugfs error input < %d\n", irq_first);
2124 return -EINVAL;
2125 }
2126 if (user_val > irq_last) {
2127 dev_err(dev, "debugfs error input > %d\n", irq_last);
2128 return -EINVAL;
2129 }
2130
Mattias Wallin0b337e72010-11-19 17:55:11 +01002131 irq_index = user_val - irq_first;
Linus Walleijddba25f2012-02-03 11:19:05 +01002132 if (irq_index >= num_irqs)
Mattias Wallin0b337e72010-11-19 17:55:11 +01002133 return -EINVAL;
Lee Jones4b8ac082013-01-14 16:10:36 +00002134
Mattias Wallin0b337e72010-11-19 17:55:11 +01002135 /* Set irq count to 0 when unsubscribe */
2136 irq_count[irq_index] = 0;
2137
2138 if (dev_attr[irq_index])
2139 sysfs_remove_file(&dev->kobj, &dev_attr[irq_index]->attr);
2140
2141
2142 free_irq(user_val, &dev->kobj);
2143 kfree(event_name[irq_index]);
2144 kfree(dev_attr[irq_index]);
Lee Jones4b8ac082013-01-14 16:10:36 +00002145
2146 return buf_size;
2147}
2148
carriere etienne0fbce762011-04-08 16:26:36 +02002149/*
2150 * - several deubgfs nodes fops
2151 */
2152
Mattias Wallin5814fc32010-09-13 16:05:04 +02002153static const struct file_operations ab8500_bank_fops = {
Mattias Wallind7b9f322010-11-26 13:06:39 +01002154 .open = ab8500_bank_open,
2155 .write = ab8500_bank_write,
2156 .read = seq_read,
2157 .llseek = seq_lseek,
2158 .release = single_release,
2159 .owner = THIS_MODULE,
Mattias Wallin5814fc32010-09-13 16:05:04 +02002160};
2161
2162static const struct file_operations ab8500_address_fops = {
Mattias Wallind7b9f322010-11-26 13:06:39 +01002163 .open = ab8500_address_open,
2164 .write = ab8500_address_write,
2165 .read = seq_read,
2166 .llseek = seq_lseek,
2167 .release = single_release,
2168 .owner = THIS_MODULE,
Mattias Wallin5814fc32010-09-13 16:05:04 +02002169};
2170
2171static const struct file_operations ab8500_val_fops = {
Mattias Wallind7b9f322010-11-26 13:06:39 +01002172 .open = ab8500_val_open,
2173 .write = ab8500_val_write,
2174 .read = seq_read,
2175 .llseek = seq_lseek,
2176 .release = single_release,
2177 .owner = THIS_MODULE,
Mattias Wallin5814fc32010-09-13 16:05:04 +02002178};
2179
Bengt Jonsson8f0eb432012-02-14 13:01:00 +01002180static const struct file_operations ab8500_interrupts_fops = {
2181 .open = ab8500_interrupts_open,
2182 .read = seq_read,
2183 .llseek = seq_lseek,
2184 .release = single_release,
2185 .owner = THIS_MODULE,
2186};
2187
Lee Jones4b8ac082013-01-14 16:10:36 +00002188static const struct file_operations ab8500_subscribe_fops = {
2189 .open = ab8500_subscribe_unsubscribe_open,
2190 .write = ab8500_subscribe_write,
2191 .read = seq_read,
2192 .llseek = seq_lseek,
2193 .release = single_release,
2194 .owner = THIS_MODULE,
2195};
2196
2197static const struct file_operations ab8500_unsubscribe_fops = {
2198 .open = ab8500_subscribe_unsubscribe_open,
2199 .write = ab8500_unsubscribe_write,
2200 .read = seq_read,
2201 .llseek = seq_lseek,
2202 .release = single_release,
2203 .owner = THIS_MODULE,
2204};
2205
carriere etienne0fbce762011-04-08 16:26:36 +02002206static const struct file_operations ab8500_hwreg_fops = {
2207 .open = ab8500_hwreg_open,
2208 .write = ab8500_hwreg_write,
2209 .read = seq_read,
2210 .llseek = seq_lseek,
2211 .release = single_release,
2212 .owner = THIS_MODULE,
2213};
2214
Mattias Wallin5814fc32010-09-13 16:05:04 +02002215static struct dentry *ab8500_dir;
John Beckett1478a312011-05-31 13:54:27 +01002216static struct dentry *ab8500_gpadc_dir;
Mattias Wallin5814fc32010-09-13 16:05:04 +02002217
Bill Pembertonf791be42012-11-19 13:23:04 -05002218static int ab8500_debug_probe(struct platform_device *plf)
Mattias Wallin5814fc32010-09-13 16:05:04 +02002219{
carriere etienne0fbce762011-04-08 16:26:36 +02002220 struct dentry *file;
Linus Walleijddba25f2012-02-03 11:19:05 +01002221 int ret = -ENOMEM;
2222 struct ab8500 *ab8500;
Mattias Wallind7b9f322010-11-26 13:06:39 +01002223 debug_bank = AB8500_MISC;
2224 debug_address = AB8500_REV_REG & 0x00FF;
Mattias Wallin5814fc32010-09-13 16:05:04 +02002225
Linus Walleijddba25f2012-02-03 11:19:05 +01002226 ab8500 = dev_get_drvdata(plf->dev.parent);
2227 num_irqs = ab8500->mask_size;
2228
Ashok G70bad042012-02-28 10:21:00 +05302229 irq_count = kzalloc(sizeof(*irq_count)*num_irqs, GFP_KERNEL);
Linus Walleijddba25f2012-02-03 11:19:05 +01002230 if (!irq_count)
2231 return -ENOMEM;
2232
2233 dev_attr = kzalloc(sizeof(*dev_attr)*num_irqs,GFP_KERNEL);
2234 if (!dev_attr)
2235 goto out_freeirq_count;
2236
2237 event_name = kzalloc(sizeof(*event_name)*num_irqs, GFP_KERNEL);
2238 if (!event_name)
2239 goto out_freedev_attr;
2240
Lee Jones4b8ac082013-01-14 16:10:36 +00002241 irq_first = platform_get_irq_byname(plf, "IRQ_FIRST");
2242 if (irq_first < 0) {
2243 dev_err(&plf->dev, "First irq not found, err %d\n",
John Beckett1478a312011-05-31 13:54:27 +01002244 irq_first);
Linus Walleijddba25f2012-02-03 11:19:05 +01002245 ret = irq_first;
2246 goto out_freeevent_name;
Lee Jones4b8ac082013-01-14 16:10:36 +00002247 }
2248
2249 irq_last = platform_get_irq_byname(plf, "IRQ_LAST");
2250 if (irq_last < 0) {
2251 dev_err(&plf->dev, "Last irq not found, err %d\n",
John Beckett1478a312011-05-31 13:54:27 +01002252 irq_last);
Linus Walleijddba25f2012-02-03 11:19:05 +01002253 ret = irq_last;
Jonas Aaberg2cf64e22012-05-31 07:57:07 +02002254 goto out_freeevent_name;
Lee Jones4b8ac082013-01-14 16:10:36 +00002255 }
2256
Mattias Wallind7b9f322010-11-26 13:06:39 +01002257 ab8500_dir = debugfs_create_dir(AB8500_NAME_STRING, NULL);
2258 if (!ab8500_dir)
carriere etienne0fbce762011-04-08 16:26:36 +02002259 goto err;
Mattias Wallin5814fc32010-09-13 16:05:04 +02002260
John Beckett1478a312011-05-31 13:54:27 +01002261 ab8500_gpadc_dir = debugfs_create_dir(AB8500_ADC_NAME_STRING,
2262 ab8500_dir);
2263 if (!ab8500_gpadc_dir)
2264 goto err;
2265
2266 file = debugfs_create_file("all-bank-registers", S_IRUGO,
2267 ab8500_dir, &plf->dev, &ab8500_registers_fops);
carriere etienne0fbce762011-04-08 16:26:36 +02002268 if (!file)
2269 goto err;
Mattias Wallin5814fc32010-09-13 16:05:04 +02002270
Mian Yousaf Kaukab42002c62012-01-26 15:39:20 +01002271 file = debugfs_create_file("all-banks", S_IRUGO,
2272 ab8500_dir, &plf->dev, &ab8500_all_banks_fops);
2273 if (!file)
2274 goto err;
2275
John Beckett1478a312011-05-31 13:54:27 +01002276 file = debugfs_create_file("register-bank", (S_IRUGO | S_IWUSR),
2277 ab8500_dir, &plf->dev, &ab8500_bank_fops);
carriere etienne0fbce762011-04-08 16:26:36 +02002278 if (!file)
2279 goto err;
Mattias Wallin5814fc32010-09-13 16:05:04 +02002280
John Beckett1478a312011-05-31 13:54:27 +01002281 file = debugfs_create_file("register-address", (S_IRUGO | S_IWUSR),
2282 ab8500_dir, &plf->dev, &ab8500_address_fops);
carriere etienne0fbce762011-04-08 16:26:36 +02002283 if (!file)
2284 goto err;
Mattias Wallin5814fc32010-09-13 16:05:04 +02002285
John Beckett1478a312011-05-31 13:54:27 +01002286 file = debugfs_create_file("register-value", (S_IRUGO | S_IWUSR),
2287 ab8500_dir, &plf->dev, &ab8500_val_fops);
carriere etienne0fbce762011-04-08 16:26:36 +02002288 if (!file)
2289 goto err;
Mattias Wallin5814fc32010-09-13 16:05:04 +02002290
John Beckett1478a312011-05-31 13:54:27 +01002291 file = debugfs_create_file("irq-subscribe", (S_IRUGO | S_IWUSR),
2292 ab8500_dir, &plf->dev, &ab8500_subscribe_fops);
carriere etienne0fbce762011-04-08 16:26:36 +02002293 if (!file)
2294 goto err;
Lee Jones4b8ac082013-01-14 16:10:36 +00002295
Lee Jones9581ae32012-07-06 16:11:50 +02002296 if (is_ab8500(ab8500)) {
2297 debug_ranges = ab8500_debug_ranges;
Bengt Jonsson8f0eb432012-02-14 13:01:00 +01002298 num_interrupt_lines = AB8500_NR_IRQS;
Lee Jones9581ae32012-07-06 16:11:50 +02002299 } else if (is_ab8505(ab8500)) {
2300 debug_ranges = ab8505_debug_ranges;
Bengt Jonsson8f0eb432012-02-14 13:01:00 +01002301 num_interrupt_lines = AB8505_NR_IRQS;
Lee Jones9581ae32012-07-06 16:11:50 +02002302 } else if (is_ab9540(ab8500)) {
2303 debug_ranges = ab8505_debug_ranges;
Bengt Jonsson8f0eb432012-02-14 13:01:00 +01002304 num_interrupt_lines = AB9540_NR_IRQS;
Lee Jones9581ae32012-07-06 16:11:50 +02002305 } else if (is_ab8540(ab8500)) {
2306 debug_ranges = ab8505_debug_ranges;
Lee Jonese436ddf2013-02-26 10:09:41 +00002307 num_interrupt_lines = AB8540_NR_IRQS;
Lee Jones9581ae32012-07-06 16:11:50 +02002308 }
Bengt Jonsson8f0eb432012-02-14 13:01:00 +01002309
2310 file = debugfs_create_file("interrupts", (S_IRUGO),
2311 ab8500_dir, &plf->dev, &ab8500_interrupts_fops);
2312 if (!file)
2313 goto err;
2314
John Beckett1478a312011-05-31 13:54:27 +01002315 file = debugfs_create_file("irq-unsubscribe", (S_IRUGO | S_IWUSR),
2316 ab8500_dir, &plf->dev, &ab8500_unsubscribe_fops);
carriere etienne0fbce762011-04-08 16:26:36 +02002317 if (!file)
2318 goto err;
2319
John Beckett1478a312011-05-31 13:54:27 +01002320 file = debugfs_create_file("hwreg", (S_IRUGO | S_IWUSR),
2321 ab8500_dir, &plf->dev, &ab8500_hwreg_fops);
2322 if (!file)
2323 goto err;
2324
2325 file = debugfs_create_file("bat_ctrl", (S_IRUGO | S_IWUSR),
2326 ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_bat_ctrl_fops);
2327 if (!file)
2328 goto err;
2329
2330 file = debugfs_create_file("btemp_ball", (S_IRUGO | S_IWUSR),
2331 ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_btemp_ball_fops);
2332 if (!file)
2333 goto err;
2334
2335 file = debugfs_create_file("main_charger_v", (S_IRUGO | S_IWUSR),
2336 ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_main_charger_v_fops);
2337 if (!file)
2338 goto err;
2339
2340 file = debugfs_create_file("acc_detect1", (S_IRUGO | S_IWUSR),
2341 ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_acc_detect1_fops);
2342 if (!file)
2343 goto err;
2344
2345 file = debugfs_create_file("acc_detect2", (S_IRUGO | S_IWUSR),
2346 ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_acc_detect2_fops);
2347 if (!file)
2348 goto err;
2349
2350 file = debugfs_create_file("adc_aux1", (S_IRUGO | S_IWUSR),
2351 ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_aux1_fops);
2352 if (!file)
2353 goto err;
2354
2355 file = debugfs_create_file("adc_aux2", (S_IRUGO | S_IWUSR),
2356 ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_aux2_fops);
2357 if (!file)
2358 goto err;
2359
2360 file = debugfs_create_file("main_bat_v", (S_IRUGO | S_IWUSR),
2361 ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_main_bat_v_fops);
2362 if (!file)
2363 goto err;
2364
2365 file = debugfs_create_file("vbus_v", (S_IRUGO | S_IWUSR),
2366 ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_vbus_v_fops);
2367 if (!file)
2368 goto err;
2369
2370 file = debugfs_create_file("main_charger_c", (S_IRUGO | S_IWUSR),
2371 ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_main_charger_c_fops);
2372 if (!file)
2373 goto err;
2374
2375 file = debugfs_create_file("usb_charger_c", (S_IRUGO | S_IWUSR),
2376 ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_usb_charger_c_fops);
2377 if (!file)
2378 goto err;
2379
2380 file = debugfs_create_file("bk_bat_v", (S_IRUGO | S_IWUSR),
2381 ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_bk_bat_v_fops);
2382 if (!file)
2383 goto err;
2384
2385 file = debugfs_create_file("die_temp", (S_IRUGO | S_IWUSR),
2386 ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_die_temp_fops);
carriere etienne0fbce762011-04-08 16:26:36 +02002387 if (!file)
2388 goto err;
Lee Jones4b8ac082013-01-14 16:10:36 +00002389
Lee Jones73482342013-02-26 10:06:55 +00002390 file = debugfs_create_file("avg_sample", (S_IRUGO | S_IWUGO),
2391 ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_avg_sample_fops);
2392 if (!file)
2393 goto err;
2394
2395 file = debugfs_create_file("trig_edge", (S_IRUGO | S_IWUGO),
2396 ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_trig_edge_fops);
2397 if (!file)
2398 goto err;
2399
2400 file = debugfs_create_file("trig_timer", (S_IRUGO | S_IWUGO),
2401 ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_trig_timer_fops);
2402 if (!file)
2403 goto err;
2404
2405 file = debugfs_create_file("conv_type", (S_IRUGO | S_IWUGO),
2406 ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_conv_type_fops);
2407 if (!file)
2408 goto err;
2409
Mattias Wallind7b9f322010-11-26 13:06:39 +01002410 return 0;
Mattias Wallin5814fc32010-09-13 16:05:04 +02002411
carriere etienne0fbce762011-04-08 16:26:36 +02002412err:
2413 if (ab8500_dir)
2414 debugfs_remove_recursive(ab8500_dir);
Mattias Wallind7b9f322010-11-26 13:06:39 +01002415 dev_err(&plf->dev, "failed to create debugfs entries.\n");
Linus Walleijddba25f2012-02-03 11:19:05 +01002416out_freeevent_name:
2417 kfree(event_name);
2418out_freedev_attr:
2419 kfree(dev_attr);
2420out_freeirq_count:
2421 kfree(irq_count);
2422
2423 return ret;
Mattias Wallin5814fc32010-09-13 16:05:04 +02002424}
2425
Bill Pemberton4740f732012-11-19 13:26:01 -05002426static int ab8500_debug_remove(struct platform_device *plf)
Mattias Wallin5814fc32010-09-13 16:05:04 +02002427{
carriere etienne0fbce762011-04-08 16:26:36 +02002428 debugfs_remove_recursive(ab8500_dir);
Linus Walleijddba25f2012-02-03 11:19:05 +01002429 kfree(event_name);
2430 kfree(dev_attr);
2431 kfree(irq_count);
2432
Mattias Wallind7b9f322010-11-26 13:06:39 +01002433 return 0;
Mattias Wallin5814fc32010-09-13 16:05:04 +02002434}
2435
2436static struct platform_driver ab8500_debug_driver = {
Mattias Wallind7b9f322010-11-26 13:06:39 +01002437 .driver = {
2438 .name = "ab8500-debug",
2439 .owner = THIS_MODULE,
2440 },
2441 .probe = ab8500_debug_probe,
Bill Pemberton84449212012-11-19 13:20:24 -05002442 .remove = ab8500_debug_remove
Mattias Wallin5814fc32010-09-13 16:05:04 +02002443};
2444
2445static int __init ab8500_debug_init(void)
2446{
Mattias Wallind7b9f322010-11-26 13:06:39 +01002447 return platform_driver_register(&ab8500_debug_driver);
Mattias Wallin5814fc32010-09-13 16:05:04 +02002448}
2449
2450static void __exit ab8500_debug_exit(void)
2451{
Mattias Wallind7b9f322010-11-26 13:06:39 +01002452 platform_driver_unregister(&ab8500_debug_driver);
Mattias Wallin5814fc32010-09-13 16:05:04 +02002453}
2454subsys_initcall(ab8500_debug_init);
2455module_exit(ab8500_debug_exit);
2456
2457MODULE_AUTHOR("Mattias WALLIN <mattias.wallin@stericsson.com");
2458MODULE_DESCRIPTION("AB8500 DEBUG");
2459MODULE_LICENSE("GPL v2");