blob: 862dbfeb619e63fee5e9c1b45ae5a4c5308d83b6 [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 Jones971480f2012-11-19 12:20:03 +0100849struct ab8500_prcmu_ranges ab8540_debug_ranges[AB8500_NUM_BANKS] = {
850 [AB8500_M_FSM_RANK] = {
851 .num_ranges = 1,
852 .range = (struct ab8500_reg_range[]) {
853 {
854 .first = 0x00,
855 .last = 0x0B,
856 },
857 },
858 },
859 [AB8500_SYS_CTRL1_BLOCK] = {
860 .num_ranges = 6,
861 .range = (struct ab8500_reg_range[]) {
862 {
863 .first = 0x00,
864 .last = 0x04,
865 },
866 {
867 .first = 0x42,
868 .last = 0x42,
869 },
870 {
871 .first = 0x50,
872 .last = 0x54,
873 },
874 {
875 .first = 0x57,
876 .last = 0x57,
877 },
878 {
879 .first = 0x80,
880 .last = 0x83,
881 },
882 {
883 .first = 0x90,
884 .last = 0x90,
885 },
886 },
887 },
888 [AB8500_SYS_CTRL2_BLOCK] = {
889 .num_ranges = 5,
890 .range = (struct ab8500_reg_range[]) {
891 {
892 .first = 0x00,
893 .last = 0x0D,
894 },
895 {
896 .first = 0x0F,
897 .last = 0x10,
898 },
899 {
900 .first = 0x20,
901 .last = 0x21,
902 },
903 {
904 .first = 0x32,
905 .last = 0x3C,
906 },
907 {
908 .first = 0x40,
909 .last = 0x42,
910 },
911 },
912 },
913 [AB8500_REGU_CTRL1] = {
914 .num_ranges = 4,
915 .range = (struct ab8500_reg_range[]) {
916 {
917 .first = 0x03,
918 .last = 0x15,
919 },
920 {
921 .first = 0x20,
922 .last = 0x20,
923 },
924 {
925 .first = 0x80,
926 .last = 0x85,
927 },
928 {
929 .first = 0x87,
930 .last = 0x88,
931 },
932 },
933 },
934 [AB8500_REGU_CTRL2] = {
935 .num_ranges = 8,
936 .range = (struct ab8500_reg_range[]) {
937 {
938 .first = 0x00,
939 .last = 0x06,
940 },
941 {
942 .first = 0x08,
943 .last = 0x15,
944 },
945 {
946 .first = 0x17,
947 .last = 0x19,
948 },
949 {
950 .first = 0x1B,
951 .last = 0x1D,
952 },
953 {
954 .first = 0x1F,
955 .last = 0x2F,
956 },
957 {
958 .first = 0x31,
959 .last = 0x3A,
960 },
961 {
962 .first = 0x43,
963 .last = 0x44,
964 },
965 {
966 .first = 0x48,
967 .last = 0x49,
968 },
969 },
970 },
971 [AB8500_USB] = {
972 .num_ranges = 3,
973 .range = (struct ab8500_reg_range[]) {
974 {
975 .first = 0x80,
976 .last = 0x83,
977 },
978 {
979 .first = 0x87,
980 .last = 0x8A,
981 },
982 {
983 .first = 0x91,
984 .last = 0x94,
985 },
986 },
987 },
988 [AB8500_TVOUT] = {
989 .num_ranges = 0,
990 .range = NULL
991 },
992 [AB8500_DBI] = {
993 .num_ranges = 4,
994 .range = (struct ab8500_reg_range[]) {
995 {
996 .first = 0x00,
997 .last = 0x07,
998 },
999 {
1000 .first = 0x10,
1001 .last = 0x11,
1002 },
1003 {
1004 .first = 0x20,
1005 .last = 0x21,
1006 },
1007 {
1008 .first = 0x30,
1009 .last = 0x43,
1010 },
1011 },
1012 },
1013 [AB8500_ECI_AV_ACC] = {
1014 .num_ranges = 2,
1015 .range = (struct ab8500_reg_range[]) {
1016 {
1017 .first = 0x00,
1018 .last = 0x03,
1019 },
1020 {
1021 .first = 0x80,
1022 .last = 0x82,
1023 },
1024 },
1025 },
1026 [AB8500_RESERVED] = {
1027 .num_ranges = 0,
1028 .range = NULL,
1029 },
1030 [AB8500_GPADC] = {
1031 .num_ranges = 4,
1032 .range = (struct ab8500_reg_range[]) {
1033 {
1034 .first = 0x00,
1035 .last = 0x01,
1036 },
1037 {
1038 .first = 0x04,
1039 .last = 0x06,
1040 },
1041 {
1042 .first = 0x09,
1043 .last = 0x0A,
1044 },
1045 {
1046 .first = 0x10,
1047 .last = 0x14,
1048 },
1049 },
1050 },
1051 [AB8500_CHARGER] = {
1052 .num_ranges = 10,
1053 .range = (struct ab8500_reg_range[]) {
1054 {
1055 .first = 0x00,
1056 .last = 0x00,
1057 },
1058 {
1059 .first = 0x02,
1060 .last = 0x05,
1061 },
1062 {
1063 .first = 0x40,
1064 .last = 0x44,
1065 },
1066 {
1067 .first = 0x50,
1068 .last = 0x57,
1069 },
1070 {
1071 .first = 0x60,
1072 .last = 0x60,
1073 },
1074 {
1075 .first = 0x70,
1076 .last = 0x70,
1077 },
1078 {
1079 .first = 0xA0,
1080 .last = 0xA9,
1081 },
1082 {
1083 .first = 0xAF,
1084 .last = 0xB2,
1085 },
1086 {
1087 .first = 0xC0,
1088 .last = 0xC6,
1089 },
1090 {
1091 .first = 0xF5,
1092 .last = 0xF5,
1093 },
1094 },
1095 },
1096 [AB8500_GAS_GAUGE] = {
1097 .num_ranges = 3,
1098 .range = (struct ab8500_reg_range[]) {
1099 {
1100 .first = 0x00,
1101 .last = 0x00,
1102 },
1103 {
1104 .first = 0x07,
1105 .last = 0x0A,
1106 },
1107 {
1108 .first = 0x10,
1109 .last = 0x14,
1110 },
1111 },
1112 },
1113 [AB8500_AUDIO] = {
1114 .num_ranges = 1,
1115 .range = (struct ab8500_reg_range[]) {
1116 {
1117 .first = 0x00,
1118 .last = 0x9f,
1119 },
1120 },
1121 },
1122 [AB8500_INTERRUPT] = {
1123 .num_ranges = 6,
1124 .range = (struct ab8500_reg_range[]) {
1125 {
1126 .first = 0x00,
1127 .last = 0x05,
1128 },
1129 {
1130 .first = 0x0B,
1131 .last = 0x0D,
1132 },
1133 {
1134 .first = 0x12,
1135 .last = 0x20,
1136 },
1137 /* Latch registers should not be read here */
1138 {
1139 .first = 0x40,
1140 .last = 0x45,
1141 },
1142 {
1143 .first = 0x4B,
1144 .last = 0x4D,
1145 },
1146 {
1147 .first = 0x52,
1148 .last = 0x60,
1149 },
1150 /* LatchHier registers should not be read here */
1151 },
1152 },
1153 [AB8500_RTC] = {
1154 .num_ranges = 3,
1155 .range = (struct ab8500_reg_range[]) {
1156 {
1157 .first = 0x00,
1158 .last = 0x07,
1159 },
1160 {
1161 .first = 0x0B,
1162 .last = 0x18,
1163 },
1164 {
1165 .first = 0x20,
1166 .last = 0x25,
1167 },
1168 },
1169 },
1170 [AB8500_MISC] = {
1171 .num_ranges = 9,
1172 .range = (struct ab8500_reg_range[]) {
1173 {
1174 .first = 0x00,
1175 .last = 0x06,
1176 },
1177 {
1178 .first = 0x10,
1179 .last = 0x16,
1180 },
1181 {
1182 .first = 0x20,
1183 .last = 0x26,
1184 },
1185 {
1186 .first = 0x30,
1187 .last = 0x36,
1188 },
1189 {
1190 .first = 0x40,
1191 .last = 0x49,
1192 },
1193 {
1194 .first = 0x50,
1195 .last = 0x50,
1196 },
1197 {
1198 .first = 0x60,
1199 .last = 0x6B,
1200 },
1201 {
1202 .first = 0x70,
1203 .last = 0x74,
1204 },
1205 {
1206 .first = 0x80,
1207 .last = 0x82,
1208 },
1209 },
1210 },
1211 [AB8500_DEVELOPMENT] = {
1212 .num_ranges = 3,
1213 .range = (struct ab8500_reg_range[]) {
1214 {
1215 .first = 0x00,
1216 .last = 0x01,
1217 },
1218 {
1219 .first = 0x06,
1220 .last = 0x06,
1221 },
1222 {
1223 .first = 0x10,
1224 .last = 0x21,
1225 },
1226 },
1227 },
1228 [AB8500_DEBUG] = {
1229 .num_ranges = 3,
1230 .range = (struct ab8500_reg_range[]) {
1231 {
1232 .first = 0x01,
1233 .last = 0x0C,
1234 },
1235 {
1236 .first = 0x0E,
1237 .last = 0x11,
1238 },
1239 {
1240 .first = 0x80,
1241 .last = 0x81,
1242 },
1243 },
1244 },
1245 [AB8500_PROD_TEST] = {
1246 .num_ranges = 0,
1247 .range = NULL,
1248 },
1249 [AB8500_STE_TEST] = {
1250 .num_ranges = 0,
1251 .range = NULL,
1252 },
1253 [AB8500_OTP_EMUL] = {
1254 .num_ranges = 1,
1255 .range = (struct ab8500_reg_range[]) {
1256 {
1257 .first = 0x00,
1258 .last = 0x3F,
1259 },
1260 },
1261 },
1262};
1263
1264
Lee Jones4b8ac082013-01-14 16:10:36 +00001265static irqreturn_t ab8500_debug_handler(int irq, void *data)
1266{
1267 char buf[16];
1268 struct kobject *kobj = (struct kobject *)data;
Mattias Wallin0b337e72010-11-19 17:55:11 +01001269 unsigned int irq_abb = irq - irq_first;
Lee Jones4b8ac082013-01-14 16:10:36 +00001270
Linus Walleijddba25f2012-02-03 11:19:05 +01001271 if (irq_abb < num_irqs)
Mattias Wallin0b337e72010-11-19 17:55:11 +01001272 irq_count[irq_abb]++;
Lee Jones4b8ac082013-01-14 16:10:36 +00001273 /*
1274 * This makes it possible to use poll for events (POLLPRI | POLLERR)
Mattias Wallin0b337e72010-11-19 17:55:11 +01001275 * from userspace on sysfs file named <irq-nr>
Lee Jones4b8ac082013-01-14 16:10:36 +00001276 */
Mattias Wallin0b337e72010-11-19 17:55:11 +01001277 sprintf(buf, "%d", irq);
Lee Jones4b8ac082013-01-14 16:10:36 +00001278 sysfs_notify(kobj, NULL, buf);
1279
1280 return IRQ_HANDLED;
1281}
1282
Mian Yousaf Kaukab42002c62012-01-26 15:39:20 +01001283/* Prints to seq_file or log_buf */
1284static int ab8500_registers_print(struct device *dev, u32 bank,
1285 struct seq_file *s)
Mattias Wallin5814fc32010-09-13 16:05:04 +02001286{
Mattias Wallind7b9f322010-11-26 13:06:39 +01001287 unsigned int i;
Mattias Wallin5814fc32010-09-13 16:05:04 +02001288
Mattias Wallind7b9f322010-11-26 13:06:39 +01001289 for (i = 0; i < debug_ranges[bank].num_ranges; i++) {
1290 u32 reg;
Mattias Wallin5814fc32010-09-13 16:05:04 +02001291
Mattias Wallind7b9f322010-11-26 13:06:39 +01001292 for (reg = debug_ranges[bank].range[i].first;
1293 reg <= debug_ranges[bank].range[i].last;
1294 reg++) {
1295 u8 value;
1296 int err;
Mattias Wallin5814fc32010-09-13 16:05:04 +02001297
Mattias Wallind7b9f322010-11-26 13:06:39 +01001298 err = abx500_get_register_interruptible(dev,
1299 (u8)bank, (u8)reg, &value);
1300 if (err < 0) {
1301 dev_err(dev, "ab->read fail %d\n", err);
1302 return err;
1303 }
Mattias Wallin5814fc32010-09-13 16:05:04 +02001304
Mian Yousaf Kaukab42002c62012-01-26 15:39:20 +01001305 if (s) {
Mattias Wallincfc08492012-05-28 15:53:58 +02001306 err = seq_printf(s, " [0x%02X/0x%02X]: 0x%02X\n",
Mian Yousaf Kaukab42002c62012-01-26 15:39:20 +01001307 bank, reg, value);
1308 if (err < 0) {
Mian Yousaf Kaukab42002c62012-01-26 15:39:20 +01001309 /* Error is not returned here since
1310 * the output is wanted in any case */
1311 return 0;
1312 }
1313 } else {
Mattias Wallincfc08492012-05-28 15:53:58 +02001314 printk(KERN_INFO" [0x%02X/0x%02X]: 0x%02X\n",
1315 bank, reg, value);
Mattias Wallind7b9f322010-11-26 13:06:39 +01001316 }
1317 }
1318 }
1319 return 0;
Mattias Wallin5814fc32010-09-13 16:05:04 +02001320}
1321
Mian Yousaf Kaukab42002c62012-01-26 15:39:20 +01001322static int ab8500_print_bank_registers(struct seq_file *s, void *p)
1323{
1324 struct device *dev = s->private;
1325 u32 bank = debug_bank;
1326
1327 seq_printf(s, AB8500_NAME_STRING " register values:\n");
1328
Mattias Wallincfc08492012-05-28 15:53:58 +02001329 seq_printf(s, " bank 0x%02X:\n", bank);
Mian Yousaf Kaukab42002c62012-01-26 15:39:20 +01001330
1331 ab8500_registers_print(dev, bank, s);
1332 return 0;
1333}
1334
Mattias Wallin5814fc32010-09-13 16:05:04 +02001335static int ab8500_registers_open(struct inode *inode, struct file *file)
1336{
Mian Yousaf Kaukab42002c62012-01-26 15:39:20 +01001337 return single_open(file, ab8500_print_bank_registers, inode->i_private);
Mattias Wallin5814fc32010-09-13 16:05:04 +02001338}
1339
1340static const struct file_operations ab8500_registers_fops = {
Mattias Wallind7b9f322010-11-26 13:06:39 +01001341 .open = ab8500_registers_open,
1342 .read = seq_read,
1343 .llseek = seq_lseek,
1344 .release = single_release,
1345 .owner = THIS_MODULE,
Mattias Wallin5814fc32010-09-13 16:05:04 +02001346};
1347
Mian Yousaf Kaukab42002c62012-01-26 15:39:20 +01001348static int ab8500_print_all_banks(struct seq_file *s, void *p)
1349{
1350 struct device *dev = s->private;
1351 unsigned int i;
1352 int err;
1353
1354 seq_printf(s, AB8500_NAME_STRING " register values:\n");
1355
Lee Jones971480f2012-11-19 12:20:03 +01001356 for (i = 0; i < AB8500_NUM_BANKS; i++) {
Mattias Wallincfc08492012-05-28 15:53:58 +02001357 err = seq_printf(s, " bank 0x%02X:\n", i);
Mian Yousaf Kaukab42002c62012-01-26 15:39:20 +01001358
1359 ab8500_registers_print(dev, i, s);
1360 }
1361 return 0;
1362}
1363
Mian Yousaf Kaukab1d843a62012-01-27 11:35:41 +01001364/* Dump registers to kernel log */
1365void ab8500_dump_all_banks(struct device *dev)
1366{
1367 unsigned int i;
1368
1369 printk(KERN_INFO"ab8500 register values:\n");
1370
1371 for (i = 1; i < AB8500_NUM_BANKS; i++) {
Mattias Wallincfc08492012-05-28 15:53:58 +02001372 printk(KERN_INFO" bank 0x%02X:\n", i);
Mian Yousaf Kaukab1d843a62012-01-27 11:35:41 +01001373 ab8500_registers_print(dev, i, NULL);
1374 }
1375}
1376
Lee Jones5ff90902013-02-12 14:35:28 +00001377/* Space for 500 registers. */
1378#define DUMP_MAX_REGS 700
1379struct ab8500_register_dump
1380{
1381 u8 bank;
1382 u8 reg;
1383 u8 value;
Lee Jones5ff90902013-02-12 14:35:28 +00001384} ab8500_complete_register_dump[DUMP_MAX_REGS];
1385
1386extern int prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size);
1387
1388/* This shall only be called upon kernel panic! */
1389void ab8500_dump_all_banks_to_mem(void)
1390{
1391 int i, r = 0;
1392 u8 bank;
Jonas Aaberg222460c2012-06-18 10:35:28 +02001393 int err = 0;
Lee Jones5ff90902013-02-12 14:35:28 +00001394
1395 pr_info("Saving all ABB registers at \"ab8500_complete_register_dump\" "
1396 "for crash analyze.\n");
1397
Lee Jones971480f2012-11-19 12:20:03 +01001398 for (bank = 0; bank < AB8500_NUM_BANKS; bank++) {
Lee Jones5ff90902013-02-12 14:35:28 +00001399 for (i = 0; i < debug_ranges[bank].num_ranges; i++) {
1400 u8 reg;
1401
1402 for (reg = debug_ranges[bank].range[i].first;
1403 reg <= debug_ranges[bank].range[i].last;
1404 reg++) {
1405 u8 value;
Lee Jones5ff90902013-02-12 14:35:28 +00001406
1407 err = prcmu_abb_read(bank, reg, &value, 1);
1408
Jonas Aaberg222460c2012-06-18 10:35:28 +02001409 if (err < 0)
1410 goto out;
1411
Lee Jones5ff90902013-02-12 14:35:28 +00001412 ab8500_complete_register_dump[r].bank = bank;
1413 ab8500_complete_register_dump[r].reg = reg;
1414 ab8500_complete_register_dump[r].value = value;
1415
1416 r++;
1417
1418 if (r >= DUMP_MAX_REGS) {
1419 pr_err("%s: too many register to dump!\n",
1420 __func__);
Jonas Aaberg222460c2012-06-18 10:35:28 +02001421 err = -EINVAL;
1422 goto out;
Lee Jones5ff90902013-02-12 14:35:28 +00001423 }
1424 }
1425 }
1426 }
Jonas Aaberg222460c2012-06-18 10:35:28 +02001427out:
1428 if (err >= 0)
1429 pr_info("Saved all ABB registers.\n");
1430 else
1431 pr_info("Failed to save all ABB registers.\n");
Lee Jones5ff90902013-02-12 14:35:28 +00001432}
1433
Mian Yousaf Kaukab42002c62012-01-26 15:39:20 +01001434static int ab8500_all_banks_open(struct inode *inode, struct file *file)
1435{
1436 struct seq_file *s;
1437 int err;
1438
1439 err = single_open(file, ab8500_print_all_banks, inode->i_private);
1440 if (!err) {
1441 /* Default buf size in seq_read is not enough */
1442 s = (struct seq_file *)file->private_data;
1443 s->size = (PAGE_SIZE * 2);
1444 s->buf = kmalloc(s->size, GFP_KERNEL);
1445 if (!s->buf) {
1446 single_release(inode, file);
1447 err = -ENOMEM;
1448 }
1449 }
1450 return err;
1451}
1452
1453static const struct file_operations ab8500_all_banks_fops = {
1454 .open = ab8500_all_banks_open,
1455 .read = seq_read,
1456 .llseek = seq_lseek,
1457 .release = single_release,
1458 .owner = THIS_MODULE,
1459};
1460
Mattias Wallin5814fc32010-09-13 16:05:04 +02001461static int ab8500_bank_print(struct seq_file *s, void *p)
1462{
Mattias Wallincfc08492012-05-28 15:53:58 +02001463 return seq_printf(s, "0x%02X\n", debug_bank);
Mattias Wallin5814fc32010-09-13 16:05:04 +02001464}
1465
1466static int ab8500_bank_open(struct inode *inode, struct file *file)
1467{
Mattias Wallind7b9f322010-11-26 13:06:39 +01001468 return single_open(file, ab8500_bank_print, inode->i_private);
Mattias Wallin5814fc32010-09-13 16:05:04 +02001469}
1470
1471static ssize_t ab8500_bank_write(struct file *file,
Mattias Wallind7b9f322010-11-26 13:06:39 +01001472 const char __user *user_buf,
1473 size_t count, loff_t *ppos)
Mattias Wallin5814fc32010-09-13 16:05:04 +02001474{
Mattias Wallind7b9f322010-11-26 13:06:39 +01001475 struct device *dev = ((struct seq_file *)(file->private_data))->private;
Mattias Wallind7b9f322010-11-26 13:06:39 +01001476 unsigned long user_bank;
1477 int err;
Mattias Wallin5814fc32010-09-13 16:05:04 +02001478
Mattias Wallind7b9f322010-11-26 13:06:39 +01001479 /* Get userspace string and assure termination */
Peter Huewe8504d632011-06-06 22:43:32 +02001480 err = kstrtoul_from_user(user_buf, count, 0, &user_bank);
Mattias Wallind7b9f322010-11-26 13:06:39 +01001481 if (err)
Peter Huewe8504d632011-06-06 22:43:32 +02001482 return err;
Mattias Wallin5814fc32010-09-13 16:05:04 +02001483
Mattias Wallind7b9f322010-11-26 13:06:39 +01001484 if (user_bank >= AB8500_NUM_BANKS) {
1485 dev_err(dev, "debugfs error input > number of banks\n");
1486 return -EINVAL;
1487 }
Mattias Wallin5814fc32010-09-13 16:05:04 +02001488
Mattias Wallind7b9f322010-11-26 13:06:39 +01001489 debug_bank = user_bank;
Mattias Wallin5814fc32010-09-13 16:05:04 +02001490
Peter Huewe8504d632011-06-06 22:43:32 +02001491 return count;
Mattias Wallin5814fc32010-09-13 16:05:04 +02001492}
1493
1494static int ab8500_address_print(struct seq_file *s, void *p)
1495{
Mattias Wallind7b9f322010-11-26 13:06:39 +01001496 return seq_printf(s, "0x%02X\n", debug_address);
Mattias Wallin5814fc32010-09-13 16:05:04 +02001497}
1498
1499static int ab8500_address_open(struct inode *inode, struct file *file)
1500{
Mattias Wallind7b9f322010-11-26 13:06:39 +01001501 return single_open(file, ab8500_address_print, inode->i_private);
Mattias Wallin5814fc32010-09-13 16:05:04 +02001502}
1503
1504static ssize_t ab8500_address_write(struct file *file,
Mattias Wallind7b9f322010-11-26 13:06:39 +01001505 const char __user *user_buf,
1506 size_t count, loff_t *ppos)
Mattias Wallin5814fc32010-09-13 16:05:04 +02001507{
Mattias Wallind7b9f322010-11-26 13:06:39 +01001508 struct device *dev = ((struct seq_file *)(file->private_data))->private;
Mattias Wallind7b9f322010-11-26 13:06:39 +01001509 unsigned long user_address;
1510 int err;
Mattias Wallin5814fc32010-09-13 16:05:04 +02001511
Mattias Wallind7b9f322010-11-26 13:06:39 +01001512 /* Get userspace string and assure termination */
Peter Huewe8504d632011-06-06 22:43:32 +02001513 err = kstrtoul_from_user(user_buf, count, 0, &user_address);
Mattias Wallind7b9f322010-11-26 13:06:39 +01001514 if (err)
Peter Huewe8504d632011-06-06 22:43:32 +02001515 return err;
1516
Mattias Wallind7b9f322010-11-26 13:06:39 +01001517 if (user_address > 0xff) {
1518 dev_err(dev, "debugfs error input > 0xff\n");
1519 return -EINVAL;
1520 }
1521 debug_address = user_address;
Peter Huewe8504d632011-06-06 22:43:32 +02001522 return count;
Mattias Wallin5814fc32010-09-13 16:05:04 +02001523}
1524
1525static int ab8500_val_print(struct seq_file *s, void *p)
1526{
Mattias Wallind7b9f322010-11-26 13:06:39 +01001527 struct device *dev = s->private;
1528 int ret;
1529 u8 regvalue;
Mattias Wallin5814fc32010-09-13 16:05:04 +02001530
Mattias Wallind7b9f322010-11-26 13:06:39 +01001531 ret = abx500_get_register_interruptible(dev,
1532 (u8)debug_bank, (u8)debug_address, &regvalue);
1533 if (ret < 0) {
1534 dev_err(dev, "abx500_get_reg fail %d, %d\n",
1535 ret, __LINE__);
1536 return -EINVAL;
1537 }
1538 seq_printf(s, "0x%02X\n", regvalue);
Mattias Wallin5814fc32010-09-13 16:05:04 +02001539
Mattias Wallind7b9f322010-11-26 13:06:39 +01001540 return 0;
Mattias Wallin5814fc32010-09-13 16:05:04 +02001541}
1542
1543static int ab8500_val_open(struct inode *inode, struct file *file)
1544{
Mattias Wallind7b9f322010-11-26 13:06:39 +01001545 return single_open(file, ab8500_val_print, inode->i_private);
Mattias Wallin5814fc32010-09-13 16:05:04 +02001546}
1547
1548static ssize_t ab8500_val_write(struct file *file,
Mattias Wallind7b9f322010-11-26 13:06:39 +01001549 const char __user *user_buf,
1550 size_t count, loff_t *ppos)
Mattias Wallin5814fc32010-09-13 16:05:04 +02001551{
Mattias Wallind7b9f322010-11-26 13:06:39 +01001552 struct device *dev = ((struct seq_file *)(file->private_data))->private;
Mattias Wallind7b9f322010-11-26 13:06:39 +01001553 unsigned long user_val;
1554 int err;
Mattias Wallin5814fc32010-09-13 16:05:04 +02001555
Mattias Wallind7b9f322010-11-26 13:06:39 +01001556 /* Get userspace string and assure termination */
Peter Huewe8504d632011-06-06 22:43:32 +02001557 err = kstrtoul_from_user(user_buf, count, 0, &user_val);
Mattias Wallind7b9f322010-11-26 13:06:39 +01001558 if (err)
Peter Huewe8504d632011-06-06 22:43:32 +02001559 return err;
1560
Mattias Wallind7b9f322010-11-26 13:06:39 +01001561 if (user_val > 0xff) {
1562 dev_err(dev, "debugfs error input > 0xff\n");
1563 return -EINVAL;
1564 }
1565 err = abx500_set_register_interruptible(dev,
1566 (u8)debug_bank, debug_address, (u8)user_val);
1567 if (err < 0) {
1568 printk(KERN_ERR "abx500_set_reg failed %d, %d", err, __LINE__);
1569 return -EINVAL;
1570 }
Mattias Wallin5814fc32010-09-13 16:05:04 +02001571
Peter Huewe8504d632011-06-06 22:43:32 +02001572 return count;
Mattias Wallin5814fc32010-09-13 16:05:04 +02001573}
1574
carriere etienne0fbce762011-04-08 16:26:36 +02001575/*
Bengt Jonsson8f0eb432012-02-14 13:01:00 +01001576 * Interrupt status
1577 */
1578static u32 num_interrupts[AB8500_MAX_NR_IRQS];
Jonas Aaberg2cf64e22012-05-31 07:57:07 +02001579static u32 num_wake_interrupts[AB8500_MAX_NR_IRQS];
Bengt Jonsson8f0eb432012-02-14 13:01:00 +01001580static int num_interrupt_lines;
1581
Jonas Aaberg2cf64e22012-05-31 07:57:07 +02001582bool __attribute__((weak)) suspend_test_wake_cause_interrupt_is_mine(u32 my_int)
1583{
1584 return false;
1585}
1586
Bengt Jonsson8f0eb432012-02-14 13:01:00 +01001587void ab8500_debug_register_interrupt(int line)
1588{
Jonas Aaberg2cf64e22012-05-31 07:57:07 +02001589 if (line < num_interrupt_lines) {
Bengt Jonsson8f0eb432012-02-14 13:01:00 +01001590 num_interrupts[line]++;
Jonas Aaberg2cf64e22012-05-31 07:57:07 +02001591 if (suspend_test_wake_cause_interrupt_is_mine(IRQ_DB8500_AB8500))
1592 num_wake_interrupts[line]++;
1593 }
Bengt Jonsson8f0eb432012-02-14 13:01:00 +01001594}
1595
1596static int ab8500_interrupts_print(struct seq_file *s, void *p)
1597{
1598 int line;
1599
Jonas Aaberg2cf64e22012-05-31 07:57:07 +02001600 seq_printf(s, "name: number: number of: wake:\n");
Bengt Jonsson8f0eb432012-02-14 13:01:00 +01001601
Jonas Aaberg2cf64e22012-05-31 07:57:07 +02001602 for (line = 0; line < num_interrupt_lines; line++) {
1603 struct irq_desc *desc = irq_to_desc(line + irq_first);
1604 struct irqaction *action = desc->action;
1605
1606 seq_printf(s, "%3i: %6i %4i", line,
1607 num_interrupts[line],
1608 num_wake_interrupts[line]);
1609
1610 if (desc && desc->name)
1611 seq_printf(s, "-%-8s", desc->name);
1612 if (action) {
1613 seq_printf(s, " %s", action->name);
1614 while ((action = action->next) != NULL)
1615 seq_printf(s, ", %s", action->name);
1616 }
1617 seq_putc(s, '\n');
1618 }
Bengt Jonsson8f0eb432012-02-14 13:01:00 +01001619
1620 return 0;
1621}
1622
1623static int ab8500_interrupts_open(struct inode *inode, struct file *file)
1624{
1625 return single_open(file, ab8500_interrupts_print, inode->i_private);
1626}
1627
1628/*
carriere etienne0fbce762011-04-08 16:26:36 +02001629 * - HWREG DB8500 formated routines
1630 */
1631static int ab8500_hwreg_print(struct seq_file *s, void *d)
1632{
1633 struct device *dev = s->private;
1634 int ret;
1635 u8 regvalue;
1636
1637 ret = abx500_get_register_interruptible(dev,
1638 (u8)hwreg_cfg.bank, (u8)hwreg_cfg.addr, &regvalue);
1639 if (ret < 0) {
1640 dev_err(dev, "abx500_get_reg fail %d, %d\n",
1641 ret, __LINE__);
1642 return -EINVAL;
1643 }
1644
1645 if (hwreg_cfg.shift >= 0)
1646 regvalue >>= hwreg_cfg.shift;
1647 else
1648 regvalue <<= -hwreg_cfg.shift;
1649 regvalue &= hwreg_cfg.mask;
1650
1651 if (REG_FMT_DEC(&hwreg_cfg))
1652 seq_printf(s, "%d\n", regvalue);
1653 else
1654 seq_printf(s, "0x%02X\n", regvalue);
1655 return 0;
1656}
1657
1658static int ab8500_hwreg_open(struct inode *inode, struct file *file)
1659{
1660 return single_open(file, ab8500_hwreg_print, inode->i_private);
1661}
1662
Lee Jonesc7ebaee2013-02-26 14:03:33 +00001663#define AB8500_SUPPLY_CONTROL_CONFIG_1 0x01
1664#define AB8500_SUPPLY_CONTROL_REG 0x00
1665#define AB8500_FIRST_SIM_REG 0x80
1666#define AB8500_LAST_SIM_REG 0x8B
1667#define AB8505_LAST_SIM_REG 0x8C
1668
1669static int ab8500_print_modem_registers(struct seq_file *s, void *p)
1670{
1671 struct device *dev = s->private;
1672 struct ab8500 *ab8500;
1673 int err;
1674 u8 value;
1675 u8 orig_value;
1676 u32 bank = AB8500_REGU_CTRL2;
1677 u32 last_sim_reg = AB8500_LAST_SIM_REG;
1678 u32 reg;
1679
1680 ab8500 = dev_get_drvdata(dev->parent);
1681 dev_warn(dev, "WARNING! This operation can interfer with modem side\n"
1682 "and should only be done with care\n");
1683
1684 err = abx500_get_register_interruptible(dev,
1685 AB8500_REGU_CTRL1, AB8500_SUPPLY_CONTROL_REG, &orig_value);
1686 if (err < 0) {
1687 dev_err(dev, "ab->read fail %d\n", err);
1688 return err;
1689 }
1690 /* Config 1 will allow APE side to read SIM registers */
1691 err = abx500_set_register_interruptible(dev,
1692 AB8500_REGU_CTRL1, AB8500_SUPPLY_CONTROL_REG,
1693 AB8500_SUPPLY_CONTROL_CONFIG_1);
1694 if (err < 0) {
1695 dev_err(dev, "ab->write fail %d\n", err);
1696 return err;
1697 }
1698
1699 seq_printf(s, " bank 0x%02X:\n", bank);
1700
1701 if (is_ab9540(ab8500) || is_ab8505(ab8500))
1702 last_sim_reg = AB8505_LAST_SIM_REG;
1703
1704 for (reg = AB8500_FIRST_SIM_REG; reg <= last_sim_reg; reg++) {
1705 err = abx500_get_register_interruptible(dev,
1706 bank, reg, &value);
1707 if (err < 0) {
1708 dev_err(dev, "ab->read fail %d\n", err);
1709 return err;
1710 }
1711 err = seq_printf(s, " [0x%02X/0x%02X]: 0x%02X\n",
1712 bank, reg, value);
1713 }
1714 err = abx500_set_register_interruptible(dev,
1715 AB8500_REGU_CTRL1, AB8500_SUPPLY_CONTROL_REG, orig_value);
1716 if (err < 0) {
1717 dev_err(dev, "ab->write fail %d\n", err);
1718 return err;
1719 }
1720 return 0;
1721}
1722
1723static int ab8500_modem_open(struct inode *inode, struct file *file)
1724{
1725 return single_open(file, ab8500_print_modem_registers, inode->i_private);
1726}
1727
1728static const struct file_operations ab8500_modem_fops = {
1729 .open = ab8500_modem_open,
1730 .read = seq_read,
1731 .llseek = seq_lseek,
1732 .release = single_release,
1733 .owner = THIS_MODULE,
1734};
1735
John Beckett1478a312011-05-31 13:54:27 +01001736static int ab8500_gpadc_bat_ctrl_print(struct seq_file *s, void *p)
1737{
1738 int bat_ctrl_raw;
1739 int bat_ctrl_convert;
1740 struct ab8500_gpadc *gpadc;
1741
Philippe Langlais8908c042012-04-18 15:52:59 +02001742 gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
Lee Jones73482342013-02-26 10:06:55 +00001743 bat_ctrl_raw = ab8500_gpadc_read_raw(gpadc, BAT_CTRL,
1744 avg_sample, trig_edge, trig_timer, conv_type);
John Beckett1478a312011-05-31 13:54:27 +01001745 bat_ctrl_convert = ab8500_gpadc_ad_to_voltage(gpadc,
Lee Jones73482342013-02-26 10:06:55 +00001746 BAT_CTRL, bat_ctrl_raw);
John Beckett1478a312011-05-31 13:54:27 +01001747
1748 return seq_printf(s, "%d,0x%X\n",
1749 bat_ctrl_convert, bat_ctrl_raw);
1750}
1751
1752static int ab8500_gpadc_bat_ctrl_open(struct inode *inode, struct file *file)
1753{
1754 return single_open(file, ab8500_gpadc_bat_ctrl_print, inode->i_private);
1755}
1756
1757static const struct file_operations ab8500_gpadc_bat_ctrl_fops = {
1758 .open = ab8500_gpadc_bat_ctrl_open,
1759 .read = seq_read,
1760 .llseek = seq_lseek,
1761 .release = single_release,
1762 .owner = THIS_MODULE,
1763};
1764
1765static int ab8500_gpadc_btemp_ball_print(struct seq_file *s, void *p)
1766{
1767 int btemp_ball_raw;
1768 int btemp_ball_convert;
1769 struct ab8500_gpadc *gpadc;
1770
Philippe Langlais8908c042012-04-18 15:52:59 +02001771 gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
Lee Jones73482342013-02-26 10:06:55 +00001772 btemp_ball_raw = ab8500_gpadc_read_raw(gpadc, BTEMP_BALL,
1773 avg_sample, trig_edge, trig_timer, conv_type);
John Beckett1478a312011-05-31 13:54:27 +01001774 btemp_ball_convert = ab8500_gpadc_ad_to_voltage(gpadc, BTEMP_BALL,
Lee Jones73482342013-02-26 10:06:55 +00001775 btemp_ball_raw);
John Beckett1478a312011-05-31 13:54:27 +01001776
1777 return seq_printf(s,
1778 "%d,0x%X\n", btemp_ball_convert, btemp_ball_raw);
1779}
1780
1781static int ab8500_gpadc_btemp_ball_open(struct inode *inode,
1782 struct file *file)
1783{
1784 return single_open(file, ab8500_gpadc_btemp_ball_print, inode->i_private);
1785}
1786
1787static const struct file_operations ab8500_gpadc_btemp_ball_fops = {
1788 .open = ab8500_gpadc_btemp_ball_open,
1789 .read = seq_read,
1790 .llseek = seq_lseek,
1791 .release = single_release,
1792 .owner = THIS_MODULE,
1793};
1794
1795static int ab8500_gpadc_main_charger_v_print(struct seq_file *s, void *p)
1796{
1797 int main_charger_v_raw;
1798 int main_charger_v_convert;
1799 struct ab8500_gpadc *gpadc;
1800
Philippe Langlais8908c042012-04-18 15:52:59 +02001801 gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
Lee Jones73482342013-02-26 10:06:55 +00001802 main_charger_v_raw = ab8500_gpadc_read_raw(gpadc, MAIN_CHARGER_V,
1803 avg_sample, trig_edge, trig_timer, conv_type);
John Beckett1478a312011-05-31 13:54:27 +01001804 main_charger_v_convert = ab8500_gpadc_ad_to_voltage(gpadc,
Lee Jones73482342013-02-26 10:06:55 +00001805 MAIN_CHARGER_V, main_charger_v_raw);
John Beckett1478a312011-05-31 13:54:27 +01001806
1807 return seq_printf(s, "%d,0x%X\n",
1808 main_charger_v_convert, main_charger_v_raw);
1809}
1810
1811static int ab8500_gpadc_main_charger_v_open(struct inode *inode,
1812 struct file *file)
1813{
1814 return single_open(file, ab8500_gpadc_main_charger_v_print,
1815 inode->i_private);
1816}
1817
1818static const struct file_operations ab8500_gpadc_main_charger_v_fops = {
1819 .open = ab8500_gpadc_main_charger_v_open,
1820 .read = seq_read,
1821 .llseek = seq_lseek,
1822 .release = single_release,
1823 .owner = THIS_MODULE,
1824};
1825
1826static int ab8500_gpadc_acc_detect1_print(struct seq_file *s, void *p)
1827{
1828 int acc_detect1_raw;
1829 int acc_detect1_convert;
1830 struct ab8500_gpadc *gpadc;
1831
Philippe Langlais8908c042012-04-18 15:52:59 +02001832 gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
Lee Jones73482342013-02-26 10:06:55 +00001833 acc_detect1_raw = ab8500_gpadc_read_raw(gpadc, ACC_DETECT1,
1834 avg_sample, trig_edge, trig_timer, conv_type);
John Beckett1478a312011-05-31 13:54:27 +01001835 acc_detect1_convert = ab8500_gpadc_ad_to_voltage(gpadc, ACC_DETECT1,
Lee Jones73482342013-02-26 10:06:55 +00001836 acc_detect1_raw);
John Beckett1478a312011-05-31 13:54:27 +01001837
1838 return seq_printf(s, "%d,0x%X\n",
1839 acc_detect1_convert, acc_detect1_raw);
1840}
1841
1842static int ab8500_gpadc_acc_detect1_open(struct inode *inode,
1843 struct file *file)
1844{
1845 return single_open(file, ab8500_gpadc_acc_detect1_print,
1846 inode->i_private);
1847}
1848
1849static const struct file_operations ab8500_gpadc_acc_detect1_fops = {
1850 .open = ab8500_gpadc_acc_detect1_open,
1851 .read = seq_read,
1852 .llseek = seq_lseek,
1853 .release = single_release,
1854 .owner = THIS_MODULE,
1855};
1856
1857static int ab8500_gpadc_acc_detect2_print(struct seq_file *s, void *p)
1858{
1859 int acc_detect2_raw;
1860 int acc_detect2_convert;
1861 struct ab8500_gpadc *gpadc;
1862
Philippe Langlais8908c042012-04-18 15:52:59 +02001863 gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
Lee Jones73482342013-02-26 10:06:55 +00001864 acc_detect2_raw = ab8500_gpadc_read_raw(gpadc, ACC_DETECT2,
1865 avg_sample, trig_edge, trig_timer, conv_type);
John Beckett1478a312011-05-31 13:54:27 +01001866 acc_detect2_convert = ab8500_gpadc_ad_to_voltage(gpadc,
Lee Jones73482342013-02-26 10:06:55 +00001867 ACC_DETECT2, acc_detect2_raw);
John Beckett1478a312011-05-31 13:54:27 +01001868
1869 return seq_printf(s, "%d,0x%X\n",
1870 acc_detect2_convert, acc_detect2_raw);
1871}
1872
1873static int ab8500_gpadc_acc_detect2_open(struct inode *inode,
1874 struct file *file)
1875{
1876 return single_open(file, ab8500_gpadc_acc_detect2_print,
1877 inode->i_private);
1878}
1879
1880static const struct file_operations ab8500_gpadc_acc_detect2_fops = {
1881 .open = ab8500_gpadc_acc_detect2_open,
1882 .read = seq_read,
1883 .llseek = seq_lseek,
1884 .release = single_release,
1885 .owner = THIS_MODULE,
1886};
1887
1888static int ab8500_gpadc_aux1_print(struct seq_file *s, void *p)
1889{
1890 int aux1_raw;
1891 int aux1_convert;
1892 struct ab8500_gpadc *gpadc;
1893
Philippe Langlais8908c042012-04-18 15:52:59 +02001894 gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
Lee Jones73482342013-02-26 10:06:55 +00001895 aux1_raw = ab8500_gpadc_read_raw(gpadc, ADC_AUX1,
1896 avg_sample, trig_edge, trig_timer, conv_type);
John Beckett1478a312011-05-31 13:54:27 +01001897 aux1_convert = ab8500_gpadc_ad_to_voltage(gpadc, ADC_AUX1,
Lee Jones73482342013-02-26 10:06:55 +00001898 aux1_raw);
John Beckett1478a312011-05-31 13:54:27 +01001899
1900 return seq_printf(s, "%d,0x%X\n",
1901 aux1_convert, aux1_raw);
1902}
1903
1904static int ab8500_gpadc_aux1_open(struct inode *inode, struct file *file)
1905{
1906 return single_open(file, ab8500_gpadc_aux1_print, inode->i_private);
1907}
1908
1909static const struct file_operations ab8500_gpadc_aux1_fops = {
1910 .open = ab8500_gpadc_aux1_open,
1911 .read = seq_read,
1912 .llseek = seq_lseek,
1913 .release = single_release,
1914 .owner = THIS_MODULE,
1915};
1916
1917static int ab8500_gpadc_aux2_print(struct seq_file *s, void *p)
1918{
1919 int aux2_raw;
1920 int aux2_convert;
1921 struct ab8500_gpadc *gpadc;
1922
Philippe Langlais8908c042012-04-18 15:52:59 +02001923 gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
Lee Jones73482342013-02-26 10:06:55 +00001924 aux2_raw = ab8500_gpadc_read_raw(gpadc, ADC_AUX2,
1925 avg_sample, trig_edge, trig_timer, conv_type);
John Beckett1478a312011-05-31 13:54:27 +01001926 aux2_convert = ab8500_gpadc_ad_to_voltage(gpadc, ADC_AUX2,
Lee Jones73482342013-02-26 10:06:55 +00001927 aux2_raw);
John Beckett1478a312011-05-31 13:54:27 +01001928
1929 return seq_printf(s, "%d,0x%X\n",
1930 aux2_convert, aux2_raw);
1931}
1932
1933static int ab8500_gpadc_aux2_open(struct inode *inode, struct file *file)
1934{
1935 return single_open(file, ab8500_gpadc_aux2_print, inode->i_private);
1936}
1937
1938static const struct file_operations ab8500_gpadc_aux2_fops = {
1939 .open = ab8500_gpadc_aux2_open,
1940 .read = seq_read,
1941 .llseek = seq_lseek,
1942 .release = single_release,
1943 .owner = THIS_MODULE,
1944};
1945
1946static int ab8500_gpadc_main_bat_v_print(struct seq_file *s, void *p)
1947{
1948 int main_bat_v_raw;
1949 int main_bat_v_convert;
1950 struct ab8500_gpadc *gpadc;
1951
Philippe Langlais8908c042012-04-18 15:52:59 +02001952 gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
Lee Jones73482342013-02-26 10:06:55 +00001953 main_bat_v_raw = ab8500_gpadc_read_raw(gpadc, MAIN_BAT_V,
1954 avg_sample, trig_edge, trig_timer, conv_type);
John Beckett1478a312011-05-31 13:54:27 +01001955 main_bat_v_convert = ab8500_gpadc_ad_to_voltage(gpadc, MAIN_BAT_V,
Lee Jones73482342013-02-26 10:06:55 +00001956 main_bat_v_raw);
John Beckett1478a312011-05-31 13:54:27 +01001957
1958 return seq_printf(s, "%d,0x%X\n",
1959 main_bat_v_convert, main_bat_v_raw);
1960}
1961
1962static int ab8500_gpadc_main_bat_v_open(struct inode *inode,
1963 struct file *file)
1964{
1965 return single_open(file, ab8500_gpadc_main_bat_v_print, inode->i_private);
1966}
1967
1968static const struct file_operations ab8500_gpadc_main_bat_v_fops = {
1969 .open = ab8500_gpadc_main_bat_v_open,
1970 .read = seq_read,
1971 .llseek = seq_lseek,
1972 .release = single_release,
1973 .owner = THIS_MODULE,
1974};
1975
1976static int ab8500_gpadc_vbus_v_print(struct seq_file *s, void *p)
1977{
1978 int vbus_v_raw;
1979 int vbus_v_convert;
1980 struct ab8500_gpadc *gpadc;
1981
Philippe Langlais8908c042012-04-18 15:52:59 +02001982 gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
Lee Jones73482342013-02-26 10:06:55 +00001983 vbus_v_raw = ab8500_gpadc_read_raw(gpadc, VBUS_V,
1984 avg_sample, trig_edge, trig_timer, conv_type);
John Beckett1478a312011-05-31 13:54:27 +01001985 vbus_v_convert = ab8500_gpadc_ad_to_voltage(gpadc, VBUS_V,
Lee Jones73482342013-02-26 10:06:55 +00001986 vbus_v_raw);
John Beckett1478a312011-05-31 13:54:27 +01001987
1988 return seq_printf(s, "%d,0x%X\n",
1989 vbus_v_convert, vbus_v_raw);
1990}
1991
1992static int ab8500_gpadc_vbus_v_open(struct inode *inode, struct file *file)
1993{
1994 return single_open(file, ab8500_gpadc_vbus_v_print, inode->i_private);
1995}
1996
1997static const struct file_operations ab8500_gpadc_vbus_v_fops = {
1998 .open = ab8500_gpadc_vbus_v_open,
1999 .read = seq_read,
2000 .llseek = seq_lseek,
2001 .release = single_release,
2002 .owner = THIS_MODULE,
2003};
2004
2005static int ab8500_gpadc_main_charger_c_print(struct seq_file *s, void *p)
2006{
2007 int main_charger_c_raw;
2008 int main_charger_c_convert;
2009 struct ab8500_gpadc *gpadc;
2010
Philippe Langlais8908c042012-04-18 15:52:59 +02002011 gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
Lee Jones73482342013-02-26 10:06:55 +00002012 main_charger_c_raw = ab8500_gpadc_read_raw(gpadc, MAIN_CHARGER_C,
2013 avg_sample, trig_edge, trig_timer, conv_type);
John Beckett1478a312011-05-31 13:54:27 +01002014 main_charger_c_convert = ab8500_gpadc_ad_to_voltage(gpadc,
Lee Jones73482342013-02-26 10:06:55 +00002015 MAIN_CHARGER_C, main_charger_c_raw);
John Beckett1478a312011-05-31 13:54:27 +01002016
2017 return seq_printf(s, "%d,0x%X\n",
2018 main_charger_c_convert, main_charger_c_raw);
2019}
2020
2021static int ab8500_gpadc_main_charger_c_open(struct inode *inode,
2022 struct file *file)
2023{
2024 return single_open(file, ab8500_gpadc_main_charger_c_print,
2025 inode->i_private);
2026}
2027
2028static const struct file_operations ab8500_gpadc_main_charger_c_fops = {
2029 .open = ab8500_gpadc_main_charger_c_open,
2030 .read = seq_read,
2031 .llseek = seq_lseek,
2032 .release = single_release,
2033 .owner = THIS_MODULE,
2034};
2035
2036static int ab8500_gpadc_usb_charger_c_print(struct seq_file *s, void *p)
2037{
2038 int usb_charger_c_raw;
2039 int usb_charger_c_convert;
2040 struct ab8500_gpadc *gpadc;
2041
Philippe Langlais8908c042012-04-18 15:52:59 +02002042 gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
Lee Jones73482342013-02-26 10:06:55 +00002043 usb_charger_c_raw = ab8500_gpadc_read_raw(gpadc, USB_CHARGER_C,
2044 avg_sample, trig_edge, trig_timer, conv_type);
John Beckett1478a312011-05-31 13:54:27 +01002045 usb_charger_c_convert = ab8500_gpadc_ad_to_voltage(gpadc,
Lee Jones73482342013-02-26 10:06:55 +00002046 USB_CHARGER_C, usb_charger_c_raw);
John Beckett1478a312011-05-31 13:54:27 +01002047
2048 return seq_printf(s, "%d,0x%X\n",
2049 usb_charger_c_convert, usb_charger_c_raw);
2050}
2051
2052static int ab8500_gpadc_usb_charger_c_open(struct inode *inode,
2053 struct file *file)
2054{
2055 return single_open(file, ab8500_gpadc_usb_charger_c_print,
2056 inode->i_private);
2057}
2058
2059static const struct file_operations ab8500_gpadc_usb_charger_c_fops = {
2060 .open = ab8500_gpadc_usb_charger_c_open,
2061 .read = seq_read,
2062 .llseek = seq_lseek,
2063 .release = single_release,
2064 .owner = THIS_MODULE,
2065};
2066
2067static int ab8500_gpadc_bk_bat_v_print(struct seq_file *s, void *p)
2068{
2069 int bk_bat_v_raw;
2070 int bk_bat_v_convert;
2071 struct ab8500_gpadc *gpadc;
2072
Philippe Langlais8908c042012-04-18 15:52:59 +02002073 gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
Lee Jones73482342013-02-26 10:06:55 +00002074 bk_bat_v_raw = ab8500_gpadc_read_raw(gpadc, BK_BAT_V,
2075 avg_sample, trig_edge, trig_timer, conv_type);
John Beckett1478a312011-05-31 13:54:27 +01002076 bk_bat_v_convert = ab8500_gpadc_ad_to_voltage(gpadc,
Lee Jones73482342013-02-26 10:06:55 +00002077 BK_BAT_V, bk_bat_v_raw);
John Beckett1478a312011-05-31 13:54:27 +01002078
2079 return seq_printf(s, "%d,0x%X\n",
2080 bk_bat_v_convert, bk_bat_v_raw);
2081}
2082
2083static int ab8500_gpadc_bk_bat_v_open(struct inode *inode, struct file *file)
2084{
2085 return single_open(file, ab8500_gpadc_bk_bat_v_print, inode->i_private);
2086}
2087
2088static const struct file_operations ab8500_gpadc_bk_bat_v_fops = {
2089 .open = ab8500_gpadc_bk_bat_v_open,
2090 .read = seq_read,
2091 .llseek = seq_lseek,
2092 .release = single_release,
2093 .owner = THIS_MODULE,
2094};
2095
2096static int ab8500_gpadc_die_temp_print(struct seq_file *s, void *p)
2097{
2098 int die_temp_raw;
2099 int die_temp_convert;
2100 struct ab8500_gpadc *gpadc;
2101
Philippe Langlais8908c042012-04-18 15:52:59 +02002102 gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
Lee Jones73482342013-02-26 10:06:55 +00002103 die_temp_raw = ab8500_gpadc_read_raw(gpadc, DIE_TEMP,
2104 avg_sample, trig_edge, trig_timer, conv_type);
John Beckett1478a312011-05-31 13:54:27 +01002105 die_temp_convert = ab8500_gpadc_ad_to_voltage(gpadc, DIE_TEMP,
Lee Jones73482342013-02-26 10:06:55 +00002106 die_temp_raw);
John Beckett1478a312011-05-31 13:54:27 +01002107
2108 return seq_printf(s, "%d,0x%X\n",
2109 die_temp_convert, die_temp_raw);
2110}
2111
2112static int ab8500_gpadc_die_temp_open(struct inode *inode, struct file *file)
2113{
2114 return single_open(file, ab8500_gpadc_die_temp_print, inode->i_private);
2115}
2116
2117static const struct file_operations ab8500_gpadc_die_temp_fops = {
2118 .open = ab8500_gpadc_die_temp_open,
2119 .read = seq_read,
2120 .llseek = seq_lseek,
2121 .release = single_release,
2122 .owner = THIS_MODULE,
2123};
2124
Lee Jones127629d2013-02-26 14:04:37 +00002125static int ab8500_gpadc_usb_id_print(struct seq_file *s, void *p)
2126{
2127 int usb_id_raw;
2128 int usb_id_convert;
2129 struct ab8500_gpadc *gpadc;
2130
2131 gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
2132 usb_id_raw = ab8500_gpadc_read_raw(gpadc, USB_ID,
2133 avg_sample, trig_edge, trig_timer, conv_type);
2134 usb_id_convert = ab8500_gpadc_ad_to_voltage(gpadc, USB_ID,
2135 usb_id_raw);
2136
2137 return seq_printf(s, "%d,0x%X\n",
2138 usb_id_convert, usb_id_raw);
2139}
2140
2141static int ab8500_gpadc_usb_id_open(struct inode *inode, struct file *file)
2142{
2143 return single_open(file, ab8500_gpadc_usb_id_print, inode->i_private);
2144}
2145
2146static const struct file_operations ab8500_gpadc_usb_id_fops = {
2147 .open = ab8500_gpadc_usb_id_open,
2148 .read = seq_read,
2149 .llseek = seq_lseek,
2150 .release = single_release,
2151 .owner = THIS_MODULE,
2152};
2153
Lee Jonesbc6b4132013-02-26 14:02:31 +00002154static int ab8540_gpadc_xtal_temp_print(struct seq_file *s, void *p)
2155{
2156 int xtal_temp_raw;
2157 int xtal_temp_convert;
2158 struct ab8500_gpadc *gpadc;
2159
2160 gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
2161 xtal_temp_raw = ab8500_gpadc_read_raw(gpadc, XTAL_TEMP,
2162 avg_sample, trig_edge, trig_timer, conv_type);
2163 xtal_temp_convert = ab8500_gpadc_ad_to_voltage(gpadc, XTAL_TEMP,
2164 xtal_temp_raw);
2165
2166 return seq_printf(s, "%d,0x%X\n",
2167 xtal_temp_convert, xtal_temp_raw);
2168}
2169
2170static int ab8540_gpadc_xtal_temp_open(struct inode *inode, struct file *file)
2171{
2172 return single_open(file, ab8540_gpadc_xtal_temp_print,
2173 inode->i_private);
2174}
2175
2176static const struct file_operations ab8540_gpadc_xtal_temp_fops = {
2177 .open = ab8540_gpadc_xtal_temp_open,
2178 .read = seq_read,
2179 .llseek = seq_lseek,
2180 .release = single_release,
2181 .owner = THIS_MODULE,
2182};
2183
2184static int ab8540_gpadc_vbat_true_meas_print(struct seq_file *s, void *p)
2185{
2186 int vbat_true_meas_raw;
2187 int vbat_true_meas_convert;
2188 struct ab8500_gpadc *gpadc;
2189
2190 gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
2191 vbat_true_meas_raw = ab8500_gpadc_read_raw(gpadc, VBAT_TRUE_MEAS,
2192 avg_sample, trig_edge, trig_timer, conv_type);
2193 vbat_true_meas_convert = ab8500_gpadc_ad_to_voltage(gpadc, VBAT_TRUE_MEAS,
2194 vbat_true_meas_raw);
2195
2196 return seq_printf(s, "%d,0x%X\n",
2197 vbat_true_meas_convert, vbat_true_meas_raw);
2198}
2199
2200static int ab8540_gpadc_vbat_true_meas_open(struct inode *inode,
2201 struct file *file)
2202{
2203 return single_open(file, ab8540_gpadc_vbat_true_meas_print,
2204 inode->i_private);
2205}
2206
2207static const struct file_operations ab8540_gpadc_vbat_true_meas_fops = {
2208 .open = ab8540_gpadc_vbat_true_meas_open,
2209 .read = seq_read,
2210 .llseek = seq_lseek,
2211 .release = single_release,
2212 .owner = THIS_MODULE,
2213};
2214
2215static int ab8540_gpadc_bat_ctrl_and_ibat_print(struct seq_file *s, void *p)
2216{
2217 int bat_ctrl_raw;
2218 int bat_ctrl_convert;
2219 int ibat_raw;
2220 int ibat_convert;
2221 struct ab8500_gpadc *gpadc;
2222
2223 gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
2224 bat_ctrl_raw = ab8500_gpadc_double_read_raw(gpadc, BAT_CTRL_AND_IBAT,
2225 avg_sample, trig_edge, trig_timer, conv_type, &ibat_raw);
2226
2227 bat_ctrl_convert = ab8500_gpadc_ad_to_voltage(gpadc, BAT_CTRL,
2228 bat_ctrl_raw);
2229 ibat_convert = ab8500_gpadc_ad_to_voltage(gpadc, IBAT_VIRTUAL_CHANNEL,
2230 ibat_raw);
2231
2232 return seq_printf(s, "%d,0x%X\n" "%d,0x%X\n",
2233 bat_ctrl_convert, bat_ctrl_raw,
2234 ibat_convert, ibat_raw);
2235}
2236
2237static int ab8540_gpadc_bat_ctrl_and_ibat_open(struct inode *inode,
2238 struct file *file)
2239{
2240 return single_open(file, ab8540_gpadc_bat_ctrl_and_ibat_print,
2241 inode->i_private);
2242}
2243
2244static const struct file_operations ab8540_gpadc_bat_ctrl_and_ibat_fops = {
2245 .open = ab8540_gpadc_bat_ctrl_and_ibat_open,
2246 .read = seq_read,
2247 .llseek = seq_lseek,
2248 .release = single_release,
2249 .owner = THIS_MODULE,
2250};
2251
2252static int ab8540_gpadc_vbat_meas_and_ibat_print(struct seq_file *s, void *p)
2253{
2254 int vbat_meas_raw;
2255 int vbat_meas_convert;
2256 int ibat_raw;
2257 int ibat_convert;
2258 struct ab8500_gpadc *gpadc;
2259
2260 gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
2261 vbat_meas_raw = ab8500_gpadc_double_read_raw(gpadc, VBAT_MEAS_AND_IBAT,
2262 avg_sample, trig_edge, trig_timer, conv_type, &ibat_raw);
2263 vbat_meas_convert = ab8500_gpadc_ad_to_voltage(gpadc, MAIN_BAT_V,
2264 vbat_meas_raw);
2265 ibat_convert = ab8500_gpadc_ad_to_voltage(gpadc, IBAT_VIRTUAL_CHANNEL,
2266 ibat_raw);
2267
2268 return seq_printf(s, "%d,0x%X\n" "%d,0x%X\n",
2269 vbat_meas_convert, vbat_meas_raw,
2270 ibat_convert, ibat_raw);
2271}
2272
2273static int ab8540_gpadc_vbat_meas_and_ibat_open(struct inode *inode,
2274 struct file *file)
2275{
2276 return single_open(file, ab8540_gpadc_vbat_meas_and_ibat_print,
2277 inode->i_private);
2278}
2279
2280static const struct file_operations ab8540_gpadc_vbat_meas_and_ibat_fops = {
2281 .open = ab8540_gpadc_vbat_meas_and_ibat_open,
2282 .read = seq_read,
2283 .llseek = seq_lseek,
2284 .release = single_release,
2285 .owner = THIS_MODULE,
2286};
2287
2288static int ab8540_gpadc_vbat_true_meas_and_ibat_print(struct seq_file *s, void *p)
2289{
2290 int vbat_true_meas_raw;
2291 int vbat_true_meas_convert;
2292 int ibat_raw;
2293 int ibat_convert;
2294 struct ab8500_gpadc *gpadc;
2295
2296 gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
2297 vbat_true_meas_raw = ab8500_gpadc_double_read_raw(gpadc,
2298 VBAT_TRUE_MEAS_AND_IBAT, avg_sample, trig_edge,
2299 trig_timer, conv_type, &ibat_raw);
2300 vbat_true_meas_convert = ab8500_gpadc_ad_to_voltage(gpadc,
2301 VBAT_TRUE_MEAS, vbat_true_meas_raw);
2302 ibat_convert = ab8500_gpadc_ad_to_voltage(gpadc, IBAT_VIRTUAL_CHANNEL,
2303 ibat_raw);
2304
2305 return seq_printf(s, "%d,0x%X\n" "%d,0x%X\n",
2306 vbat_true_meas_convert, vbat_true_meas_raw,
2307 ibat_convert, ibat_raw);
2308}
2309
2310static int ab8540_gpadc_vbat_true_meas_and_ibat_open(struct inode *inode,
2311 struct file *file)
2312{
2313 return single_open(file, ab8540_gpadc_vbat_true_meas_and_ibat_print,
2314 inode->i_private);
2315}
2316
2317static const struct file_operations ab8540_gpadc_vbat_true_meas_and_ibat_fops = {
2318 .open = ab8540_gpadc_vbat_true_meas_and_ibat_open,
2319 .read = seq_read,
2320 .llseek = seq_lseek,
2321 .release = single_release,
2322 .owner = THIS_MODULE,
2323};
2324
2325static int ab8540_gpadc_bat_temp_and_ibat_print(struct seq_file *s, void *p)
2326{
2327 int bat_temp_raw;
2328 int bat_temp_convert;
2329 int ibat_raw;
2330 int ibat_convert;
2331 struct ab8500_gpadc *gpadc;
2332
2333 gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
2334 bat_temp_raw = ab8500_gpadc_double_read_raw(gpadc, BAT_TEMP_AND_IBAT,
2335 avg_sample, trig_edge, trig_timer, conv_type, &ibat_raw);
2336 bat_temp_convert = ab8500_gpadc_ad_to_voltage(gpadc, BTEMP_BALL,
2337 bat_temp_raw);
2338 ibat_convert = ab8500_gpadc_ad_to_voltage(gpadc, IBAT_VIRTUAL_CHANNEL,
2339 ibat_raw);
2340
2341 return seq_printf(s, "%d,0x%X\n" "%d,0x%X\n",
2342 bat_temp_convert, bat_temp_raw,
2343 ibat_convert, ibat_raw);
2344}
2345
2346static int ab8540_gpadc_bat_temp_and_ibat_open(struct inode *inode,
2347 struct file *file)
2348{
2349 return single_open(file, ab8540_gpadc_bat_temp_and_ibat_print,
2350 inode->i_private);
2351}
2352
2353static const struct file_operations ab8540_gpadc_bat_temp_and_ibat_fops = {
2354 .open = ab8540_gpadc_bat_temp_and_ibat_open,
2355 .read = seq_read,
2356 .llseek = seq_lseek,
2357 .release = single_release,
2358 .owner = THIS_MODULE,
2359};
2360
2361static int ab8540_gpadc_otp_cal_print(struct seq_file *s, void *p)
2362{
2363 struct ab8500_gpadc *gpadc;
2364 u16 vmain_l, vmain_h, btemp_l, btemp_h;
2365 u16 vbat_l, vbat_h, ibat_l, ibat_h;
2366
2367 gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
2368 ab8540_gpadc_get_otp(gpadc, &vmain_l, &vmain_h, &btemp_l, &btemp_h,
2369 &vbat_l, &vbat_h, &ibat_l, &ibat_h);
2370 return seq_printf(s, "VMAIN_L:0x%X\n"
2371 "VMAIN_H:0x%X\n"
2372 "BTEMP_L:0x%X\n"
2373 "BTEMP_H:0x%X\n"
2374 "VBAT_L:0x%X\n"
2375 "VBAT_H:0x%X\n"
2376 "IBAT_L:0x%X\n"
2377 "IBAT_H:0x%X\n"
2378 ,
2379 vmain_l,
2380 vmain_h,
2381 btemp_l,
2382 btemp_h,
2383 vbat_l,
2384 vbat_h,
2385 ibat_l,
2386 ibat_h);
2387}
2388
2389static int ab8540_gpadc_otp_cal_open(struct inode *inode, struct file *file)
2390{
2391 return single_open(file, ab8540_gpadc_otp_cal_print, inode->i_private);
2392}
2393
2394static const struct file_operations ab8540_gpadc_otp_calib_fops = {
2395 .open = ab8540_gpadc_otp_cal_open,
2396 .read = seq_read,
2397 .llseek = seq_lseek,
2398 .release = single_release,
2399 .owner = THIS_MODULE,
2400};
2401
Lee Jones73482342013-02-26 10:06:55 +00002402static int ab8500_gpadc_avg_sample_print(struct seq_file *s, void *p)
2403{
2404 return seq_printf(s, "%d\n", avg_sample);
2405}
2406
2407static int ab8500_gpadc_avg_sample_open(struct inode *inode, struct file *file)
2408{
2409 return single_open(file, ab8500_gpadc_avg_sample_print,
2410 inode->i_private);
2411}
2412
2413static ssize_t ab8500_gpadc_avg_sample_write(struct file *file,
2414 const char __user *user_buf,
2415 size_t count, loff_t *ppos)
2416{
2417 struct device *dev = ((struct seq_file *)(file->private_data))->private;
2418 char buf[32];
2419 int buf_size;
2420 unsigned long user_avg_sample;
2421 int err;
2422
2423 /* Get userspace string and assure termination */
2424 buf_size = min(count, (sizeof(buf) - 1));
2425 if (copy_from_user(buf, user_buf, buf_size))
2426 return -EFAULT;
2427 buf[buf_size] = 0;
2428
2429 err = strict_strtoul(buf, 0, &user_avg_sample);
2430 if (err)
2431 return -EINVAL;
2432 if ((user_avg_sample == SAMPLE_1) || (user_avg_sample == SAMPLE_4)
2433 || (user_avg_sample == SAMPLE_8)
2434 || (user_avg_sample == SAMPLE_16)) {
2435 avg_sample = (u8) user_avg_sample;
2436 } else {
2437 dev_err(dev, "debugfs error input: "
2438 "should be egal to 1, 4, 8 or 16\n");
2439 return -EINVAL;
2440 }
2441 return buf_size;
2442}
2443
2444static const struct file_operations ab8500_gpadc_avg_sample_fops = {
2445 .open = ab8500_gpadc_avg_sample_open,
2446 .read = seq_read,
2447 .write = ab8500_gpadc_avg_sample_write,
2448 .llseek = seq_lseek,
2449 .release = single_release,
2450 .owner = THIS_MODULE,
2451};
2452
2453static int ab8500_gpadc_trig_edge_print(struct seq_file *s, void *p)
2454{
2455 return seq_printf(s, "%d\n", trig_edge);
2456}
2457
2458static int ab8500_gpadc_trig_edge_open(struct inode *inode, struct file *file)
2459{
2460 return single_open(file, ab8500_gpadc_trig_edge_print,
2461 inode->i_private);
2462}
2463
2464static ssize_t ab8500_gpadc_trig_edge_write(struct file *file,
2465 const char __user *user_buf,
2466 size_t count, loff_t *ppos)
2467{
2468 struct device *dev = ((struct seq_file *)(file->private_data))->private;
2469 char buf[32];
2470 int buf_size;
2471 unsigned long user_trig_edge;
2472 int err;
2473
2474 /* Get userspace string and assure termination */
2475 buf_size = min(count, (sizeof(buf) - 1));
2476 if (copy_from_user(buf, user_buf, buf_size))
2477 return -EFAULT;
2478 buf[buf_size] = 0;
2479
2480 err = strict_strtoul(buf, 0, &user_trig_edge);
2481 if (err)
2482 return -EINVAL;
2483 if ((user_trig_edge == RISING_EDGE)
2484 || (user_trig_edge == FALLING_EDGE)) {
2485 trig_edge = (u8) user_trig_edge;
2486 } else {
2487 dev_err(dev, "Wrong input:\n"
2488 "Enter 0. Rising edge\n"
2489 "Enter 1. Falling edge\n");
2490 return -EINVAL;
2491 }
2492 return buf_size;
2493}
2494
2495static const struct file_operations ab8500_gpadc_trig_edge_fops = {
2496 .open = ab8500_gpadc_trig_edge_open,
2497 .read = seq_read,
2498 .write = ab8500_gpadc_trig_edge_write,
2499 .llseek = seq_lseek,
2500 .release = single_release,
2501 .owner = THIS_MODULE,
2502};
2503
2504static int ab8500_gpadc_trig_timer_print(struct seq_file *s, void *p)
2505{
2506 return seq_printf(s, "%d\n", trig_timer);
2507}
2508
2509static int ab8500_gpadc_trig_timer_open(struct inode *inode, struct file *file)
2510{
2511 return single_open(file, ab8500_gpadc_trig_timer_print,
2512 inode->i_private);
2513}
2514
2515static ssize_t ab8500_gpadc_trig_timer_write(struct file *file,
2516 const char __user *user_buf,
2517 size_t count, loff_t *ppos)
2518{
2519 struct device *dev = ((struct seq_file *)(file->private_data))->private;
2520 char buf[32];
2521 int buf_size;
2522 unsigned long user_trig_timer;
2523 int err;
2524
2525 /* Get userspace string and assure termination */
2526 buf_size = min(count, (sizeof(buf) - 1));
2527 if (copy_from_user(buf, user_buf, buf_size))
2528 return -EFAULT;
2529 buf[buf_size] = 0;
2530
2531 err = strict_strtoul(buf, 0, &user_trig_timer);
2532 if (err)
2533 return -EINVAL;
2534 if ((user_trig_timer >= 0) && (user_trig_timer <= 255)) {
2535 trig_timer = (u8) user_trig_timer;
2536 } else {
2537 dev_err(dev, "debugfs error input: "
2538 "should be beetween 0 to 255\n");
2539 return -EINVAL;
2540 }
2541 return buf_size;
2542}
2543
2544static const struct file_operations ab8500_gpadc_trig_timer_fops = {
2545 .open = ab8500_gpadc_trig_timer_open,
2546 .read = seq_read,
2547 .write = ab8500_gpadc_trig_timer_write,
2548 .llseek = seq_lseek,
2549 .release = single_release,
2550 .owner = THIS_MODULE,
2551};
2552
2553static int ab8500_gpadc_conv_type_print(struct seq_file *s, void *p)
2554{
2555 return seq_printf(s, "%d\n", conv_type);
2556}
2557
2558static int ab8500_gpadc_conv_type_open(struct inode *inode, struct file *file)
2559{
2560 return single_open(file, ab8500_gpadc_conv_type_print,
2561 inode->i_private);
2562}
2563
2564static ssize_t ab8500_gpadc_conv_type_write(struct file *file,
2565 const char __user *user_buf,
2566 size_t count, loff_t *ppos)
2567{
2568 struct device *dev = ((struct seq_file *)(file->private_data))->private;
2569 char buf[32];
2570 int buf_size;
2571 unsigned long user_conv_type;
2572 int err;
2573
2574 /* Get userspace string and assure termination */
2575 buf_size = min(count, (sizeof(buf) - 1));
2576 if (copy_from_user(buf, user_buf, buf_size))
2577 return -EFAULT;
2578 buf[buf_size] = 0;
2579
2580 err = strict_strtoul(buf, 0, &user_conv_type);
2581 if (err)
2582 return -EINVAL;
2583 if ((user_conv_type == ADC_SW)
2584 || (user_conv_type == ADC_HW)) {
2585 conv_type = (u8) user_conv_type;
2586 } else {
2587 dev_err(dev, "Wrong input:\n"
2588 "Enter 0. ADC SW conversion\n"
2589 "Enter 1. ADC HW conversion\n");
2590 return -EINVAL;
2591 }
2592 return buf_size;
2593}
2594
2595static const struct file_operations ab8500_gpadc_conv_type_fops = {
2596 .open = ab8500_gpadc_conv_type_open,
2597 .read = seq_read,
2598 .write = ab8500_gpadc_conv_type_write,
2599 .llseek = seq_lseek,
2600 .release = single_release,
2601 .owner = THIS_MODULE,
2602};
2603
carriere etienne0fbce762011-04-08 16:26:36 +02002604/*
2605 * return length of an ASCII numerical value, 0 is string is not a
2606 * numerical value.
2607 * string shall start at value 1st char.
2608 * string can be tailed with \0 or space or newline chars only.
2609 * value can be decimal or hexadecimal (prefixed 0x or 0X).
2610 */
2611static int strval_len(char *b)
2612{
2613 char *s = b;
2614 if ((*s == '0') && ((*(s+1) == 'x') || (*(s+1) == 'X'))) {
2615 s += 2;
2616 for (; *s && (*s != ' ') && (*s != '\n'); s++) {
2617 if (!isxdigit(*s))
2618 return 0;
2619 }
2620 } else {
2621 if (*s == '-')
2622 s++;
2623 for (; *s && (*s != ' ') && (*s != '\n'); s++) {
2624 if (!isdigit(*s))
2625 return 0;
2626 }
2627 }
2628 return (int) (s-b);
2629}
2630
2631/*
2632 * parse hwreg input data.
2633 * update global hwreg_cfg only if input data syntax is ok.
2634 */
2635static ssize_t hwreg_common_write(char *b, struct hwreg_cfg *cfg,
2636 struct device *dev)
2637{
2638 uint write, val = 0;
2639 u8 regvalue;
2640 int ret;
2641 struct hwreg_cfg loc = {
2642 .bank = 0, /* default: invalid phys addr */
2643 .addr = 0, /* default: invalid phys addr */
2644 .fmt = 0, /* default: 32bit access, hex output */
2645 .mask = 0xFFFFFFFF, /* default: no mask */
2646 .shift = 0, /* default: no bit shift */
2647 };
2648
2649 /* read or write ? */
2650 if (!strncmp(b, "read ", 5)) {
2651 write = 0;
2652 b += 5;
2653 } else if (!strncmp(b, "write ", 6)) {
2654 write = 1;
2655 b += 6;
2656 } else
2657 return -EINVAL;
2658
2659 /* OPTIONS -l|-w|-b -s -m -o */
2660 while ((*b == ' ') || (*b == '-')) {
2661 if (*(b-1) != ' ') {
2662 b++;
2663 continue;
2664 }
2665 if ((!strncmp(b, "-d ", 3)) ||
2666 (!strncmp(b, "-dec ", 5))) {
2667 b += (*(b+2) == ' ') ? 3 : 5;
2668 loc.fmt |= (1<<0);
2669 } else if ((!strncmp(b, "-h ", 3)) ||
2670 (!strncmp(b, "-hex ", 5))) {
2671 b += (*(b+2) == ' ') ? 3 : 5;
2672 loc.fmt &= ~(1<<0);
2673 } else if ((!strncmp(b, "-m ", 3)) ||
2674 (!strncmp(b, "-mask ", 6))) {
2675 b += (*(b+2) == ' ') ? 3 : 6;
2676 if (strval_len(b) == 0)
2677 return -EINVAL;
2678 loc.mask = simple_strtoul(b, &b, 0);
2679 } else if ((!strncmp(b, "-s ", 3)) ||
2680 (!strncmp(b, "-shift ", 7))) {
2681 b += (*(b+2) == ' ') ? 3 : 7;
2682 if (strval_len(b) == 0)
2683 return -EINVAL;
2684 loc.shift = simple_strtol(b, &b, 0);
2685 } else {
2686 return -EINVAL;
2687 }
2688 }
2689 /* get arg BANK and ADDRESS */
2690 if (strval_len(b) == 0)
2691 return -EINVAL;
2692 loc.bank = simple_strtoul(b, &b, 0);
2693 while (*b == ' ')
2694 b++;
2695 if (strval_len(b) == 0)
2696 return -EINVAL;
2697 loc.addr = simple_strtoul(b, &b, 0);
2698
2699 if (write) {
2700 while (*b == ' ')
2701 b++;
2702 if (strval_len(b) == 0)
2703 return -EINVAL;
2704 val = simple_strtoul(b, &b, 0);
2705 }
2706
2707 /* args are ok, update target cfg (mainly for read) */
2708 *cfg = loc;
2709
2710#ifdef ABB_HWREG_DEBUG
2711 pr_warn("HWREG request: %s, %s, addr=0x%08X, mask=0x%X, shift=%d"
2712 "value=0x%X\n", (write) ? "write" : "read",
2713 REG_FMT_DEC(cfg) ? "decimal" : "hexa",
2714 cfg->addr, cfg->mask, cfg->shift, val);
2715#endif
2716
2717 if (!write)
2718 return 0;
2719
2720 ret = abx500_get_register_interruptible(dev,
2721 (u8)cfg->bank, (u8)cfg->addr, &regvalue);
2722 if (ret < 0) {
2723 dev_err(dev, "abx500_get_reg fail %d, %d\n",
2724 ret, __LINE__);
2725 return -EINVAL;
2726 }
2727
2728 if (cfg->shift >= 0) {
2729 regvalue &= ~(cfg->mask << (cfg->shift));
2730 val = (val & cfg->mask) << (cfg->shift);
2731 } else {
2732 regvalue &= ~(cfg->mask >> (-cfg->shift));
2733 val = (val & cfg->mask) >> (-cfg->shift);
2734 }
2735 val = val | regvalue;
2736
2737 ret = abx500_set_register_interruptible(dev,
2738 (u8)cfg->bank, (u8)cfg->addr, (u8)val);
2739 if (ret < 0) {
2740 pr_err("abx500_set_reg failed %d, %d", ret, __LINE__);
2741 return -EINVAL;
2742 }
2743
2744 return 0;
2745}
2746
2747static ssize_t ab8500_hwreg_write(struct file *file,
2748 const char __user *user_buf, size_t count, loff_t *ppos)
2749{
2750 struct device *dev = ((struct seq_file *)(file->private_data))->private;
2751 char buf[128];
2752 int buf_size, ret;
2753
2754 /* Get userspace string and assure termination */
2755 buf_size = min(count, (sizeof(buf)-1));
2756 if (copy_from_user(buf, user_buf, buf_size))
2757 return -EFAULT;
2758 buf[buf_size] = 0;
2759
2760 /* get args and process */
2761 ret = hwreg_common_write(buf, &hwreg_cfg, dev);
2762 return (ret) ? ret : buf_size;
2763}
2764
2765/*
2766 * - irq subscribe/unsubscribe stuff
2767 */
Lee Jones4b8ac082013-01-14 16:10:36 +00002768static int ab8500_subscribe_unsubscribe_print(struct seq_file *s, void *p)
2769{
2770 seq_printf(s, "%d\n", irq_first);
2771
2772 return 0;
2773}
2774
2775static int ab8500_subscribe_unsubscribe_open(struct inode *inode,
2776 struct file *file)
2777{
2778 return single_open(file, ab8500_subscribe_unsubscribe_print,
2779 inode->i_private);
2780}
2781
2782/*
Mattias Wallin0b337e72010-11-19 17:55:11 +01002783 * Userspace should use poll() on this file. When an event occur
Lee Jones4b8ac082013-01-14 16:10:36 +00002784 * the blocking poll will be released.
2785 */
2786static ssize_t show_irq(struct device *dev,
2787 struct device_attribute *attr, char *buf)
2788{
Mattias Wallin0b337e72010-11-19 17:55:11 +01002789 unsigned long name;
2790 unsigned int irq_index;
2791 int err;
Lee Jones4b8ac082013-01-14 16:10:36 +00002792
Mattias Wallin0b337e72010-11-19 17:55:11 +01002793 err = strict_strtoul(attr->attr.name, 0, &name);
2794 if (err)
2795 return err;
2796
2797 irq_index = name - irq_first;
Linus Walleijddba25f2012-02-03 11:19:05 +01002798 if (irq_index >= num_irqs)
Mattias Wallin0b337e72010-11-19 17:55:11 +01002799 return -EINVAL;
2800 else
2801 return sprintf(buf, "%u\n", irq_count[irq_index]);
2802}
Lee Jones4b8ac082013-01-14 16:10:36 +00002803
2804static ssize_t ab8500_subscribe_write(struct file *file,
2805 const char __user *user_buf,
2806 size_t count, loff_t *ppos)
2807{
2808 struct device *dev = ((struct seq_file *)(file->private_data))->private;
2809 char buf[32];
2810 int buf_size;
2811 unsigned long user_val;
2812 int err;
Mattias Wallin0b337e72010-11-19 17:55:11 +01002813 unsigned int irq_index;
Lee Jones4b8ac082013-01-14 16:10:36 +00002814
2815 /* Get userspace string and assure termination */
2816 buf_size = min(count, (sizeof(buf)-1));
2817 if (copy_from_user(buf, user_buf, buf_size))
2818 return -EFAULT;
2819 buf[buf_size] = 0;
2820
2821 err = strict_strtoul(buf, 0, &user_val);
2822 if (err)
2823 return -EINVAL;
2824 if (user_val < irq_first) {
2825 dev_err(dev, "debugfs error input < %d\n", irq_first);
2826 return -EINVAL;
2827 }
2828 if (user_val > irq_last) {
2829 dev_err(dev, "debugfs error input > %d\n", irq_last);
2830 return -EINVAL;
2831 }
2832
Mattias Wallin0b337e72010-11-19 17:55:11 +01002833 irq_index = user_val - irq_first;
Linus Walleijddba25f2012-02-03 11:19:05 +01002834 if (irq_index >= num_irqs)
Mattias Wallin0b337e72010-11-19 17:55:11 +01002835 return -EINVAL;
2836
Lee Jones4b8ac082013-01-14 16:10:36 +00002837 /*
Mattias Wallin0b337e72010-11-19 17:55:11 +01002838 * This will create a sysfs file named <irq-nr> which userspace can
Lee Jones4b8ac082013-01-14 16:10:36 +00002839 * use to select or poll and get the AB8500 events
2840 */
Mattias Wallin0b337e72010-11-19 17:55:11 +01002841 dev_attr[irq_index] = kmalloc(sizeof(struct device_attribute),
2842 GFP_KERNEL);
2843 event_name[irq_index] = kmalloc(buf_size, GFP_KERNEL);
2844 sprintf(event_name[irq_index], "%lu", user_val);
2845 dev_attr[irq_index]->show = show_irq;
2846 dev_attr[irq_index]->store = NULL;
2847 dev_attr[irq_index]->attr.name = event_name[irq_index];
2848 dev_attr[irq_index]->attr.mode = S_IRUGO;
2849 err = sysfs_create_file(&dev->kobj, &dev_attr[irq_index]->attr);
Lee Jones4b8ac082013-01-14 16:10:36 +00002850 if (err < 0) {
2851 printk(KERN_ERR "sysfs_create_file failed %d\n", err);
2852 return err;
2853 }
2854
2855 err = request_threaded_irq(user_val, NULL, ab8500_debug_handler,
2856 IRQF_SHARED | IRQF_NO_SUSPEND,
2857 "ab8500-debug", &dev->kobj);
2858 if (err < 0) {
2859 printk(KERN_ERR "request_threaded_irq failed %d, %lu\n",
2860 err, user_val);
Mattias Wallin0b337e72010-11-19 17:55:11 +01002861 sysfs_remove_file(&dev->kobj, &dev_attr[irq_index]->attr);
Lee Jones4b8ac082013-01-14 16:10:36 +00002862 return err;
2863 }
2864
2865 return buf_size;
2866}
2867
2868static ssize_t ab8500_unsubscribe_write(struct file *file,
2869 const char __user *user_buf,
2870 size_t count, loff_t *ppos)
2871{
2872 struct device *dev = ((struct seq_file *)(file->private_data))->private;
2873 char buf[32];
2874 int buf_size;
2875 unsigned long user_val;
2876 int err;
Mattias Wallin0b337e72010-11-19 17:55:11 +01002877 unsigned int irq_index;
Lee Jones4b8ac082013-01-14 16:10:36 +00002878
2879 /* Get userspace string and assure termination */
2880 buf_size = min(count, (sizeof(buf)-1));
2881 if (copy_from_user(buf, user_buf, buf_size))
2882 return -EFAULT;
2883 buf[buf_size] = 0;
2884
2885 err = strict_strtoul(buf, 0, &user_val);
2886 if (err)
2887 return -EINVAL;
2888 if (user_val < irq_first) {
2889 dev_err(dev, "debugfs error input < %d\n", irq_first);
2890 return -EINVAL;
2891 }
2892 if (user_val > irq_last) {
2893 dev_err(dev, "debugfs error input > %d\n", irq_last);
2894 return -EINVAL;
2895 }
2896
Mattias Wallin0b337e72010-11-19 17:55:11 +01002897 irq_index = user_val - irq_first;
Linus Walleijddba25f2012-02-03 11:19:05 +01002898 if (irq_index >= num_irqs)
Mattias Wallin0b337e72010-11-19 17:55:11 +01002899 return -EINVAL;
Lee Jones4b8ac082013-01-14 16:10:36 +00002900
Mattias Wallin0b337e72010-11-19 17:55:11 +01002901 /* Set irq count to 0 when unsubscribe */
2902 irq_count[irq_index] = 0;
2903
2904 if (dev_attr[irq_index])
2905 sysfs_remove_file(&dev->kobj, &dev_attr[irq_index]->attr);
2906
2907
2908 free_irq(user_val, &dev->kobj);
2909 kfree(event_name[irq_index]);
2910 kfree(dev_attr[irq_index]);
Lee Jones4b8ac082013-01-14 16:10:36 +00002911
2912 return buf_size;
2913}
2914
carriere etienne0fbce762011-04-08 16:26:36 +02002915/*
2916 * - several deubgfs nodes fops
2917 */
2918
Mattias Wallin5814fc32010-09-13 16:05:04 +02002919static const struct file_operations ab8500_bank_fops = {
Mattias Wallind7b9f322010-11-26 13:06:39 +01002920 .open = ab8500_bank_open,
2921 .write = ab8500_bank_write,
2922 .read = seq_read,
2923 .llseek = seq_lseek,
2924 .release = single_release,
2925 .owner = THIS_MODULE,
Mattias Wallin5814fc32010-09-13 16:05:04 +02002926};
2927
2928static const struct file_operations ab8500_address_fops = {
Mattias Wallind7b9f322010-11-26 13:06:39 +01002929 .open = ab8500_address_open,
2930 .write = ab8500_address_write,
2931 .read = seq_read,
2932 .llseek = seq_lseek,
2933 .release = single_release,
2934 .owner = THIS_MODULE,
Mattias Wallin5814fc32010-09-13 16:05:04 +02002935};
2936
2937static const struct file_operations ab8500_val_fops = {
Mattias Wallind7b9f322010-11-26 13:06:39 +01002938 .open = ab8500_val_open,
2939 .write = ab8500_val_write,
2940 .read = seq_read,
2941 .llseek = seq_lseek,
2942 .release = single_release,
2943 .owner = THIS_MODULE,
Mattias Wallin5814fc32010-09-13 16:05:04 +02002944};
2945
Bengt Jonsson8f0eb432012-02-14 13:01:00 +01002946static const struct file_operations ab8500_interrupts_fops = {
2947 .open = ab8500_interrupts_open,
2948 .read = seq_read,
2949 .llseek = seq_lseek,
2950 .release = single_release,
2951 .owner = THIS_MODULE,
2952};
2953
Lee Jones4b8ac082013-01-14 16:10:36 +00002954static const struct file_operations ab8500_subscribe_fops = {
2955 .open = ab8500_subscribe_unsubscribe_open,
2956 .write = ab8500_subscribe_write,
2957 .read = seq_read,
2958 .llseek = seq_lseek,
2959 .release = single_release,
2960 .owner = THIS_MODULE,
2961};
2962
2963static const struct file_operations ab8500_unsubscribe_fops = {
2964 .open = ab8500_subscribe_unsubscribe_open,
2965 .write = ab8500_unsubscribe_write,
2966 .read = seq_read,
2967 .llseek = seq_lseek,
2968 .release = single_release,
2969 .owner = THIS_MODULE,
2970};
2971
carriere etienne0fbce762011-04-08 16:26:36 +02002972static const struct file_operations ab8500_hwreg_fops = {
2973 .open = ab8500_hwreg_open,
2974 .write = ab8500_hwreg_write,
2975 .read = seq_read,
2976 .llseek = seq_lseek,
2977 .release = single_release,
2978 .owner = THIS_MODULE,
2979};
2980
Mattias Wallin5814fc32010-09-13 16:05:04 +02002981static struct dentry *ab8500_dir;
John Beckett1478a312011-05-31 13:54:27 +01002982static struct dentry *ab8500_gpadc_dir;
Mattias Wallin5814fc32010-09-13 16:05:04 +02002983
Bill Pembertonf791be42012-11-19 13:23:04 -05002984static int ab8500_debug_probe(struct platform_device *plf)
Mattias Wallin5814fc32010-09-13 16:05:04 +02002985{
carriere etienne0fbce762011-04-08 16:26:36 +02002986 struct dentry *file;
Linus Walleijddba25f2012-02-03 11:19:05 +01002987 int ret = -ENOMEM;
2988 struct ab8500 *ab8500;
Mattias Wallind7b9f322010-11-26 13:06:39 +01002989 debug_bank = AB8500_MISC;
2990 debug_address = AB8500_REV_REG & 0x00FF;
Mattias Wallin5814fc32010-09-13 16:05:04 +02002991
Linus Walleijddba25f2012-02-03 11:19:05 +01002992 ab8500 = dev_get_drvdata(plf->dev.parent);
2993 num_irqs = ab8500->mask_size;
2994
Ashok G70bad042012-02-28 10:21:00 +05302995 irq_count = kzalloc(sizeof(*irq_count)*num_irqs, GFP_KERNEL);
Linus Walleijddba25f2012-02-03 11:19:05 +01002996 if (!irq_count)
2997 return -ENOMEM;
2998
2999 dev_attr = kzalloc(sizeof(*dev_attr)*num_irqs,GFP_KERNEL);
3000 if (!dev_attr)
3001 goto out_freeirq_count;
3002
3003 event_name = kzalloc(sizeof(*event_name)*num_irqs, GFP_KERNEL);
3004 if (!event_name)
3005 goto out_freedev_attr;
3006
Lee Jones4b8ac082013-01-14 16:10:36 +00003007 irq_first = platform_get_irq_byname(plf, "IRQ_FIRST");
3008 if (irq_first < 0) {
3009 dev_err(&plf->dev, "First irq not found, err %d\n",
John Beckett1478a312011-05-31 13:54:27 +01003010 irq_first);
Linus Walleijddba25f2012-02-03 11:19:05 +01003011 ret = irq_first;
3012 goto out_freeevent_name;
Lee Jones4b8ac082013-01-14 16:10:36 +00003013 }
3014
3015 irq_last = platform_get_irq_byname(plf, "IRQ_LAST");
3016 if (irq_last < 0) {
3017 dev_err(&plf->dev, "Last irq not found, err %d\n",
John Beckett1478a312011-05-31 13:54:27 +01003018 irq_last);
Linus Walleijddba25f2012-02-03 11:19:05 +01003019 ret = irq_last;
Jonas Aaberg2cf64e22012-05-31 07:57:07 +02003020 goto out_freeevent_name;
Lee Jones4b8ac082013-01-14 16:10:36 +00003021 }
3022
Mattias Wallind7b9f322010-11-26 13:06:39 +01003023 ab8500_dir = debugfs_create_dir(AB8500_NAME_STRING, NULL);
3024 if (!ab8500_dir)
carriere etienne0fbce762011-04-08 16:26:36 +02003025 goto err;
Mattias Wallin5814fc32010-09-13 16:05:04 +02003026
John Beckett1478a312011-05-31 13:54:27 +01003027 ab8500_gpadc_dir = debugfs_create_dir(AB8500_ADC_NAME_STRING,
3028 ab8500_dir);
3029 if (!ab8500_gpadc_dir)
3030 goto err;
3031
3032 file = debugfs_create_file("all-bank-registers", S_IRUGO,
3033 ab8500_dir, &plf->dev, &ab8500_registers_fops);
carriere etienne0fbce762011-04-08 16:26:36 +02003034 if (!file)
3035 goto err;
Mattias Wallin5814fc32010-09-13 16:05:04 +02003036
Mian Yousaf Kaukab42002c62012-01-26 15:39:20 +01003037 file = debugfs_create_file("all-banks", S_IRUGO,
3038 ab8500_dir, &plf->dev, &ab8500_all_banks_fops);
3039 if (!file)
3040 goto err;
3041
Lee Jonesf38487f2013-02-26 14:09:08 +00003042 file = debugfs_create_file("register-bank", (S_IRUGO | S_IWUSR | S_IWGRP),
John Beckett1478a312011-05-31 13:54:27 +01003043 ab8500_dir, &plf->dev, &ab8500_bank_fops);
carriere etienne0fbce762011-04-08 16:26:36 +02003044 if (!file)
3045 goto err;
Mattias Wallin5814fc32010-09-13 16:05:04 +02003046
Lee Jonesf38487f2013-02-26 14:09:08 +00003047 file = debugfs_create_file("register-address", (S_IRUGO | S_IWUSR | S_IWGRP),
John Beckett1478a312011-05-31 13:54:27 +01003048 ab8500_dir, &plf->dev, &ab8500_address_fops);
carriere etienne0fbce762011-04-08 16:26:36 +02003049 if (!file)
3050 goto err;
Mattias Wallin5814fc32010-09-13 16:05:04 +02003051
Lee Jonesf38487f2013-02-26 14:09:08 +00003052 file = debugfs_create_file("register-value", (S_IRUGO | S_IWUSR | S_IWGRP),
John Beckett1478a312011-05-31 13:54:27 +01003053 ab8500_dir, &plf->dev, &ab8500_val_fops);
carriere etienne0fbce762011-04-08 16:26:36 +02003054 if (!file)
3055 goto err;
Mattias Wallin5814fc32010-09-13 16:05:04 +02003056
Lee Jonesf38487f2013-02-26 14:09:08 +00003057 file = debugfs_create_file("irq-subscribe", (S_IRUGO | S_IWUSR | S_IWGRP),
John Beckett1478a312011-05-31 13:54:27 +01003058 ab8500_dir, &plf->dev, &ab8500_subscribe_fops);
carriere etienne0fbce762011-04-08 16:26:36 +02003059 if (!file)
3060 goto err;
Lee Jones4b8ac082013-01-14 16:10:36 +00003061
Lee Jones9581ae32012-07-06 16:11:50 +02003062 if (is_ab8500(ab8500)) {
3063 debug_ranges = ab8500_debug_ranges;
Bengt Jonsson8f0eb432012-02-14 13:01:00 +01003064 num_interrupt_lines = AB8500_NR_IRQS;
Lee Jones9581ae32012-07-06 16:11:50 +02003065 } else if (is_ab8505(ab8500)) {
3066 debug_ranges = ab8505_debug_ranges;
Bengt Jonsson8f0eb432012-02-14 13:01:00 +01003067 num_interrupt_lines = AB8505_NR_IRQS;
Lee Jones9581ae32012-07-06 16:11:50 +02003068 } else if (is_ab9540(ab8500)) {
3069 debug_ranges = ab8505_debug_ranges;
Bengt Jonsson8f0eb432012-02-14 13:01:00 +01003070 num_interrupt_lines = AB9540_NR_IRQS;
Lee Jones9581ae32012-07-06 16:11:50 +02003071 } else if (is_ab8540(ab8500)) {
Lee Jones971480f2012-11-19 12:20:03 +01003072 debug_ranges = ab8540_debug_ranges;
Lee Jonese436ddf2013-02-26 10:09:41 +00003073 num_interrupt_lines = AB8540_NR_IRQS;
Lee Jones9581ae32012-07-06 16:11:50 +02003074 }
Bengt Jonsson8f0eb432012-02-14 13:01:00 +01003075
3076 file = debugfs_create_file("interrupts", (S_IRUGO),
3077 ab8500_dir, &plf->dev, &ab8500_interrupts_fops);
3078 if (!file)
3079 goto err;
3080
Lee Jonesf38487f2013-02-26 14:09:08 +00003081 file = debugfs_create_file("irq-unsubscribe", (S_IRUGO | S_IWUSR | S_IWGRP),
John Beckett1478a312011-05-31 13:54:27 +01003082 ab8500_dir, &plf->dev, &ab8500_unsubscribe_fops);
carriere etienne0fbce762011-04-08 16:26:36 +02003083 if (!file)
3084 goto err;
3085
Lee Jonesf38487f2013-02-26 14:09:08 +00003086 file = debugfs_create_file("hwreg", (S_IRUGO | S_IWUSR | S_IWGRP),
John Beckett1478a312011-05-31 13:54:27 +01003087 ab8500_dir, &plf->dev, &ab8500_hwreg_fops);
3088 if (!file)
3089 goto err;
3090
Lee Jonesf38487f2013-02-26 14:09:08 +00003091 file = debugfs_create_file("all-modem-registers", (S_IRUGO | S_IWUSR | S_IWGRP),
Lee Jonesc7ebaee2013-02-26 14:03:33 +00003092 ab8500_dir, &plf->dev, &ab8500_modem_fops);
3093 if (!file)
3094 goto err;
3095
Lee Jonesf38487f2013-02-26 14:09:08 +00003096 file = debugfs_create_file("bat_ctrl", (S_IRUGO | S_IWUSR | S_IWGRP),
John Beckett1478a312011-05-31 13:54:27 +01003097 ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_bat_ctrl_fops);
3098 if (!file)
3099 goto err;
3100
Lee Jonesf38487f2013-02-26 14:09:08 +00003101 file = debugfs_create_file("btemp_ball", (S_IRUGO | S_IWUSR | S_IWGRP),
John Beckett1478a312011-05-31 13:54:27 +01003102 ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_btemp_ball_fops);
3103 if (!file)
3104 goto err;
3105
Lee Jonesf38487f2013-02-26 14:09:08 +00003106 file = debugfs_create_file("main_charger_v", (S_IRUGO | S_IWUSR | S_IWGRP),
John Beckett1478a312011-05-31 13:54:27 +01003107 ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_main_charger_v_fops);
3108 if (!file)
3109 goto err;
3110
Lee Jonesf38487f2013-02-26 14:09:08 +00003111 file = debugfs_create_file("acc_detect1", (S_IRUGO | S_IWUSR | S_IWGRP),
John Beckett1478a312011-05-31 13:54:27 +01003112 ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_acc_detect1_fops);
3113 if (!file)
3114 goto err;
3115
Lee Jonesf38487f2013-02-26 14:09:08 +00003116 file = debugfs_create_file("acc_detect2", (S_IRUGO | S_IWUSR | S_IWGRP),
John Beckett1478a312011-05-31 13:54:27 +01003117 ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_acc_detect2_fops);
3118 if (!file)
3119 goto err;
3120
Lee Jonesf38487f2013-02-26 14:09:08 +00003121 file = debugfs_create_file("adc_aux1", (S_IRUGO | S_IWUSR | S_IWGRP),
John Beckett1478a312011-05-31 13:54:27 +01003122 ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_aux1_fops);
3123 if (!file)
3124 goto err;
3125
Lee Jonesf38487f2013-02-26 14:09:08 +00003126 file = debugfs_create_file("adc_aux2", (S_IRUGO | S_IWUSR | S_IWGRP),
John Beckett1478a312011-05-31 13:54:27 +01003127 ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_aux2_fops);
3128 if (!file)
3129 goto err;
3130
Lee Jonesf38487f2013-02-26 14:09:08 +00003131 file = debugfs_create_file("main_bat_v", (S_IRUGO | S_IWUSR | S_IWGRP),
John Beckett1478a312011-05-31 13:54:27 +01003132 ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_main_bat_v_fops);
3133 if (!file)
3134 goto err;
3135
Lee Jonesf38487f2013-02-26 14:09:08 +00003136 file = debugfs_create_file("vbus_v", (S_IRUGO | S_IWUSR | S_IWGRP),
John Beckett1478a312011-05-31 13:54:27 +01003137 ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_vbus_v_fops);
3138 if (!file)
3139 goto err;
3140
Lee Jonesf38487f2013-02-26 14:09:08 +00003141 file = debugfs_create_file("main_charger_c", (S_IRUGO | S_IWUSR | S_IWGRP),
John Beckett1478a312011-05-31 13:54:27 +01003142 ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_main_charger_c_fops);
3143 if (!file)
3144 goto err;
3145
Lee Jonesf38487f2013-02-26 14:09:08 +00003146 file = debugfs_create_file("usb_charger_c", (S_IRUGO | S_IWUSR | S_IWGRP),
John Beckett1478a312011-05-31 13:54:27 +01003147 ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_usb_charger_c_fops);
3148 if (!file)
3149 goto err;
3150
Lee Jonesf38487f2013-02-26 14:09:08 +00003151 file = debugfs_create_file("bk_bat_v", (S_IRUGO | S_IWUSR | S_IWGRP),
John Beckett1478a312011-05-31 13:54:27 +01003152 ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_bk_bat_v_fops);
3153 if (!file)
3154 goto err;
3155
Lee Jonesf38487f2013-02-26 14:09:08 +00003156 file = debugfs_create_file("die_temp", (S_IRUGO | S_IWUSR | S_IWGRP),
John Beckett1478a312011-05-31 13:54:27 +01003157 ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_die_temp_fops);
carriere etienne0fbce762011-04-08 16:26:36 +02003158 if (!file)
3159 goto err;
Lee Jones127629d2013-02-26 14:04:37 +00003160
Lee Jonesf38487f2013-02-26 14:09:08 +00003161 file = debugfs_create_file("usb_id", (S_IRUGO | S_IWUSR | S_IWGRP),
Lee Jones127629d2013-02-26 14:04:37 +00003162 ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_usb_id_fops);
3163 if (!file)
3164 goto err;
3165
Lee Jonesbc6b4132013-02-26 14:02:31 +00003166 if (is_ab8540(ab8500)) {
Lee Jonesf38487f2013-02-26 14:09:08 +00003167 file = debugfs_create_file("xtal_temp", (S_IRUGO | S_IWUSR | S_IWGRP),
Lee Jonesbc6b4132013-02-26 14:02:31 +00003168 ab8500_gpadc_dir, &plf->dev, &ab8540_gpadc_xtal_temp_fops);
3169 if (!file)
3170 goto err;
Lee Jonesf38487f2013-02-26 14:09:08 +00003171 file = debugfs_create_file("vbattruemeas", (S_IRUGO | S_IWUSR | S_IWGRP),
Lee Jonesbc6b4132013-02-26 14:02:31 +00003172 ab8500_gpadc_dir, &plf->dev,
3173 &ab8540_gpadc_vbat_true_meas_fops);
3174 if (!file)
3175 goto err;
3176 file = debugfs_create_file("batctrl_and_ibat",
3177 (S_IRUGO | S_IWUGO), ab8500_gpadc_dir,
3178 &plf->dev, &ab8540_gpadc_bat_ctrl_and_ibat_fops);
3179 if (!file)
3180 goto err;
3181 file = debugfs_create_file("vbatmeas_and_ibat",
3182 (S_IRUGO | S_IWUGO), ab8500_gpadc_dir,
3183 &plf->dev,
3184 &ab8540_gpadc_vbat_meas_and_ibat_fops);
3185 if (!file)
3186 goto err;
3187 file = debugfs_create_file("vbattruemeas_and_ibat",
3188 (S_IRUGO | S_IWUGO), ab8500_gpadc_dir,
3189 &plf->dev,
3190 &ab8540_gpadc_vbat_true_meas_and_ibat_fops);
3191 if (!file)
3192 goto err;
3193 file = debugfs_create_file("battemp_and_ibat",
3194 (S_IRUGO | S_IWUGO), ab8500_gpadc_dir,
3195 &plf->dev, &ab8540_gpadc_bat_temp_and_ibat_fops);
3196 if (!file)
3197 goto err;
Lee Jonesf38487f2013-02-26 14:09:08 +00003198 file = debugfs_create_file("otp_calib", (S_IRUGO | S_IWUSR | S_IWGRP),
Lee Jonesbc6b4132013-02-26 14:02:31 +00003199 ab8500_gpadc_dir, &plf->dev, &ab8540_gpadc_otp_calib_fops);
3200 if (!file)
3201 goto err;
3202 }
Lee Jonesf38487f2013-02-26 14:09:08 +00003203 file = debugfs_create_file("avg_sample", (S_IRUGO | S_IWUSR | S_IWGRP),
Lee Jones73482342013-02-26 10:06:55 +00003204 ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_avg_sample_fops);
3205 if (!file)
3206 goto err;
3207
Lee Jonesf38487f2013-02-26 14:09:08 +00003208 file = debugfs_create_file("trig_edge", (S_IRUGO | S_IWUSR | S_IWGRP),
Lee Jones73482342013-02-26 10:06:55 +00003209 ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_trig_edge_fops);
3210 if (!file)
3211 goto err;
3212
Lee Jonesf38487f2013-02-26 14:09:08 +00003213 file = debugfs_create_file("trig_timer", (S_IRUGO | S_IWUSR | S_IWGRP),
Lee Jones73482342013-02-26 10:06:55 +00003214 ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_trig_timer_fops);
3215 if (!file)
3216 goto err;
3217
Lee Jonesf38487f2013-02-26 14:09:08 +00003218 file = debugfs_create_file("conv_type", (S_IRUGO | S_IWUSR | S_IWGRP),
Lee Jones73482342013-02-26 10:06:55 +00003219 ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_conv_type_fops);
3220 if (!file)
3221 goto err;
3222
Mattias Wallind7b9f322010-11-26 13:06:39 +01003223 return 0;
Mattias Wallin5814fc32010-09-13 16:05:04 +02003224
carriere etienne0fbce762011-04-08 16:26:36 +02003225err:
3226 if (ab8500_dir)
3227 debugfs_remove_recursive(ab8500_dir);
Mattias Wallind7b9f322010-11-26 13:06:39 +01003228 dev_err(&plf->dev, "failed to create debugfs entries.\n");
Linus Walleijddba25f2012-02-03 11:19:05 +01003229out_freeevent_name:
3230 kfree(event_name);
3231out_freedev_attr:
3232 kfree(dev_attr);
3233out_freeirq_count:
3234 kfree(irq_count);
3235
3236 return ret;
Mattias Wallin5814fc32010-09-13 16:05:04 +02003237}
3238
Bill Pemberton4740f732012-11-19 13:26:01 -05003239static int ab8500_debug_remove(struct platform_device *plf)
Mattias Wallin5814fc32010-09-13 16:05:04 +02003240{
carriere etienne0fbce762011-04-08 16:26:36 +02003241 debugfs_remove_recursive(ab8500_dir);
Linus Walleijddba25f2012-02-03 11:19:05 +01003242 kfree(event_name);
3243 kfree(dev_attr);
3244 kfree(irq_count);
3245
Mattias Wallind7b9f322010-11-26 13:06:39 +01003246 return 0;
Mattias Wallin5814fc32010-09-13 16:05:04 +02003247}
3248
3249static struct platform_driver ab8500_debug_driver = {
Mattias Wallind7b9f322010-11-26 13:06:39 +01003250 .driver = {
3251 .name = "ab8500-debug",
3252 .owner = THIS_MODULE,
3253 },
3254 .probe = ab8500_debug_probe,
Bill Pemberton84449212012-11-19 13:20:24 -05003255 .remove = ab8500_debug_remove
Mattias Wallin5814fc32010-09-13 16:05:04 +02003256};
3257
3258static int __init ab8500_debug_init(void)
3259{
Mattias Wallind7b9f322010-11-26 13:06:39 +01003260 return platform_driver_register(&ab8500_debug_driver);
Mattias Wallin5814fc32010-09-13 16:05:04 +02003261}
3262
3263static void __exit ab8500_debug_exit(void)
3264{
Mattias Wallind7b9f322010-11-26 13:06:39 +01003265 platform_driver_unregister(&ab8500_debug_driver);
Mattias Wallin5814fc32010-09-13 16:05:04 +02003266}
3267subsys_initcall(ab8500_debug_init);
3268module_exit(ab8500_debug_exit);
3269
3270MODULE_AUTHOR("Mattias WALLIN <mattias.wallin@stericsson.com");
3271MODULE_DESCRIPTION("AB8500 DEBUG");
3272MODULE_LICENSE("GPL v2");