blob: 69d9fffe5b5cd43d3ebe084860e9a096c6d549fd [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
Linus Walleij69991812013-04-12 17:02:09 +020097static int irq_ab8500;
Lee Jones4b8ac082013-01-14 16:10:36 +000098static int irq_first;
99static int irq_last;
Linus Walleijddba25f2012-02-03 11:19:05 +0100100static u32 *irq_count;
101static int num_irqs;
Mattias Wallin0b337e72010-11-19 17:55:11 +0100102
Linus Walleijddba25f2012-02-03 11:19:05 +0100103static struct device_attribute **dev_attr;
104static char **event_name;
Lee Jones4b8ac082013-01-14 16:10:36 +0000105
Lee Jones73482342013-02-26 10:06:55 +0000106static u8 avg_sample = SAMPLE_16;
107static u8 trig_edge = RISING_EDGE;
108static u8 conv_type = ADC_SW;
109static u8 trig_timer;
110
Mattias Wallin5814fc32010-09-13 16:05:04 +0200111/**
112 * struct ab8500_reg_range
113 * @first: the first address of the range
114 * @last: the last address of the range
115 * @perm: access permissions for the range
116 */
117struct ab8500_reg_range {
Mattias Wallind7b9f322010-11-26 13:06:39 +0100118 u8 first;
119 u8 last;
120 u8 perm;
Mattias Wallin5814fc32010-09-13 16:05:04 +0200121};
122
123/**
Lee Jones822672a2012-06-20 13:56:38 +0100124 * struct ab8500_prcmu_ranges
Mattias Wallin5814fc32010-09-13 16:05:04 +0200125 * @num_ranges: the number of ranges in the list
126 * @bankid: bank identifier
127 * @range: the list of register ranges
128 */
Lee Jones822672a2012-06-20 13:56:38 +0100129struct ab8500_prcmu_ranges {
Mattias Wallind7b9f322010-11-26 13:06:39 +0100130 u8 num_ranges;
131 u8 bankid;
132 const struct ab8500_reg_range *range;
Mattias Wallin5814fc32010-09-13 16:05:04 +0200133};
134
carriere etienne0fbce762011-04-08 16:26:36 +0200135/* hwreg- "mask" and "shift" entries ressources */
136struct hwreg_cfg {
137 u32 bank; /* target bank */
Lee Jones43621752014-07-14 18:29:16 +0100138 unsigned long addr; /* target address */
carriere etienne0fbce762011-04-08 16:26:36 +0200139 uint fmt; /* format */
Lee Jones43621752014-07-14 18:29:16 +0100140 unsigned long mask; /* read/write mask, applied before any bit shift */
141 long shift; /* bit shift (read:right shift, write:left shift */
carriere etienne0fbce762011-04-08 16:26:36 +0200142};
143/* fmt bit #0: 0=hexa, 1=dec */
144#define REG_FMT_DEC(c) ((c)->fmt & 0x1)
145#define REG_FMT_HEX(c) (!REG_FMT_DEC(c))
146
147static struct hwreg_cfg hwreg_cfg = {
148 .addr = 0, /* default: invalid phys addr */
149 .fmt = 0, /* default: 32bit access, hex output */
150 .mask = 0xFFFFFFFF, /* default: no mask */
151 .shift = 0, /* default: no bit shift */
152};
153
Mattias Wallin5814fc32010-09-13 16:05:04 +0200154#define AB8500_NAME_STRING "ab8500"
John Beckett1478a312011-05-31 13:54:27 +0100155#define AB8500_ADC_NAME_STRING "gpadc"
Philippe Langlais40c064e2011-10-17 09:48:55 +0200156#define AB8500_NUM_BANKS 24
Mattias Wallin5814fc32010-09-13 16:05:04 +0200157
158#define AB8500_REV_REG 0x80
159
Lee Jones9581ae32012-07-06 16:11:50 +0200160static struct ab8500_prcmu_ranges *debug_ranges;
161
Sachin Kamat8455eae2013-08-23 17:37:42 +0530162static struct ab8500_prcmu_ranges ab8500_debug_ranges[AB8500_NUM_BANKS] = {
Mattias Wallind7b9f322010-11-26 13:06:39 +0100163 [0x0] = {
164 .num_ranges = 0,
Lee Jonesfad55a82013-01-14 17:17:34 +0000165 .range = NULL,
Mattias Wallind7b9f322010-11-26 13:06:39 +0100166 },
167 [AB8500_SYS_CTRL1_BLOCK] = {
168 .num_ranges = 3,
169 .range = (struct ab8500_reg_range[]) {
170 {
171 .first = 0x00,
172 .last = 0x02,
173 },
174 {
175 .first = 0x42,
176 .last = 0x42,
177 },
178 {
179 .first = 0x80,
180 .last = 0x81,
181 },
182 },
183 },
184 [AB8500_SYS_CTRL2_BLOCK] = {
185 .num_ranges = 4,
186 .range = (struct ab8500_reg_range[]) {
187 {
188 .first = 0x00,
189 .last = 0x0D,
190 },
191 {
192 .first = 0x0F,
193 .last = 0x17,
194 },
195 {
196 .first = 0x30,
197 .last = 0x30,
198 },
199 {
200 .first = 0x32,
201 .last = 0x33,
202 },
203 },
204 },
205 [AB8500_REGU_CTRL1] = {
206 .num_ranges = 3,
207 .range = (struct ab8500_reg_range[]) {
208 {
209 .first = 0x00,
210 .last = 0x00,
211 },
212 {
213 .first = 0x03,
214 .last = 0x10,
215 },
216 {
217 .first = 0x80,
218 .last = 0x84,
219 },
220 },
221 },
222 [AB8500_REGU_CTRL2] = {
223 .num_ranges = 5,
224 .range = (struct ab8500_reg_range[]) {
225 {
226 .first = 0x00,
227 .last = 0x15,
228 },
229 {
230 .first = 0x17,
231 .last = 0x19,
232 },
233 {
234 .first = 0x1B,
235 .last = 0x1D,
236 },
237 {
238 .first = 0x1F,
239 .last = 0x22,
240 },
241 {
242 .first = 0x40,
243 .last = 0x44,
244 },
Lee Jonesde6a7692015-10-28 09:27:32 +0000245 /*
246 * 0x80-0x8B are SIM registers and should
247 * not be accessed from here
248 */
Mattias Wallind7b9f322010-11-26 13:06:39 +0100249 },
250 },
251 [AB8500_USB] = {
252 .num_ranges = 2,
253 .range = (struct ab8500_reg_range[]) {
254 {
255 .first = 0x80,
256 .last = 0x83,
257 },
258 {
259 .first = 0x87,
260 .last = 0x8A,
261 },
262 },
263 },
264 [AB8500_TVOUT] = {
265 .num_ranges = 9,
266 .range = (struct ab8500_reg_range[]) {
267 {
268 .first = 0x00,
269 .last = 0x12,
270 },
271 {
272 .first = 0x15,
273 .last = 0x17,
274 },
275 {
276 .first = 0x19,
277 .last = 0x21,
278 },
279 {
280 .first = 0x27,
281 .last = 0x2C,
282 },
283 {
284 .first = 0x41,
285 .last = 0x41,
286 },
287 {
288 .first = 0x45,
289 .last = 0x5B,
290 },
291 {
292 .first = 0x5D,
293 .last = 0x5D,
294 },
295 {
296 .first = 0x69,
297 .last = 0x69,
298 },
299 {
300 .first = 0x80,
301 .last = 0x81,
302 },
303 },
304 },
305 [AB8500_DBI] = {
306 .num_ranges = 0,
Mark Brown87fff232010-12-13 14:06:47 +0000307 .range = NULL,
Mattias Wallind7b9f322010-11-26 13:06:39 +0100308 },
309 [AB8500_ECI_AV_ACC] = {
310 .num_ranges = 1,
311 .range = (struct ab8500_reg_range[]) {
312 {
313 .first = 0x80,
314 .last = 0x82,
315 },
316 },
317 },
318 [0x9] = {
319 .num_ranges = 0,
Mark Brown87fff232010-12-13 14:06:47 +0000320 .range = NULL,
Mattias Wallind7b9f322010-11-26 13:06:39 +0100321 },
322 [AB8500_GPADC] = {
323 .num_ranges = 1,
324 .range = (struct ab8500_reg_range[]) {
325 {
326 .first = 0x00,
327 .last = 0x08,
328 },
329 },
330 },
331 [AB8500_CHARGER] = {
Philippe Langlais40c064e2011-10-17 09:48:55 +0200332 .num_ranges = 9,
Mattias Wallind7b9f322010-11-26 13:06:39 +0100333 .range = (struct ab8500_reg_range[]) {
334 {
335 .first = 0x00,
336 .last = 0x03,
337 },
338 {
339 .first = 0x05,
340 .last = 0x05,
341 },
342 {
343 .first = 0x40,
344 .last = 0x40,
345 },
346 {
347 .first = 0x42,
348 .last = 0x42,
349 },
350 {
351 .first = 0x44,
352 .last = 0x44,
353 },
354 {
355 .first = 0x50,
356 .last = 0x55,
357 },
358 {
359 .first = 0x80,
360 .last = 0x82,
361 },
362 {
363 .first = 0xC0,
364 .last = 0xC2,
365 },
Philippe Langlais40c064e2011-10-17 09:48:55 +0200366 {
367 .first = 0xf5,
Lee Jones9581ae32012-07-06 16:11:50 +0200368 .last = 0xf6,
Philippe Langlais40c064e2011-10-17 09:48:55 +0200369 },
Mattias Wallind7b9f322010-11-26 13:06:39 +0100370 },
371 },
372 [AB8500_GAS_GAUGE] = {
373 .num_ranges = 3,
374 .range = (struct ab8500_reg_range[]) {
375 {
376 .first = 0x00,
377 .last = 0x00,
378 },
379 {
380 .first = 0x07,
381 .last = 0x0A,
382 },
383 {
384 .first = 0x10,
385 .last = 0x14,
386 },
387 },
388 },
Philippe Langlais40c064e2011-10-17 09:48:55 +0200389 [AB8500_DEVELOPMENT] = {
390 .num_ranges = 1,
391 .range = (struct ab8500_reg_range[]) {
392 {
393 .first = 0x00,
394 .last = 0x00,
395 },
396 },
397 },
398 [AB8500_DEBUG] = {
399 .num_ranges = 1,
400 .range = (struct ab8500_reg_range[]) {
401 {
402 .first = 0x05,
403 .last = 0x07,
404 },
405 },
406 },
Mattias Wallind7b9f322010-11-26 13:06:39 +0100407 [AB8500_AUDIO] = {
408 .num_ranges = 1,
409 .range = (struct ab8500_reg_range[]) {
410 {
411 .first = 0x00,
412 .last = 0x6F,
413 },
414 },
415 },
416 [AB8500_INTERRUPT] = {
417 .num_ranges = 0,
Mark Brown87fff232010-12-13 14:06:47 +0000418 .range = NULL,
Mattias Wallind7b9f322010-11-26 13:06:39 +0100419 },
420 [AB8500_RTC] = {
421 .num_ranges = 1,
422 .range = (struct ab8500_reg_range[]) {
423 {
424 .first = 0x00,
425 .last = 0x0F,
426 },
427 },
428 },
429 [AB8500_MISC] = {
430 .num_ranges = 8,
431 .range = (struct ab8500_reg_range[]) {
432 {
433 .first = 0x00,
434 .last = 0x05,
435 },
436 {
437 .first = 0x10,
438 .last = 0x15,
439 },
440 {
441 .first = 0x20,
442 .last = 0x25,
443 },
444 {
445 .first = 0x30,
446 .last = 0x35,
447 },
448 {
449 .first = 0x40,
450 .last = 0x45,
451 },
452 {
453 .first = 0x50,
454 .last = 0x50,
455 },
456 {
457 .first = 0x60,
458 .last = 0x67,
459 },
460 {
461 .first = 0x80,
462 .last = 0x80,
463 },
464 },
465 },
466 [0x11] = {
467 .num_ranges = 0,
Mark Brown87fff232010-12-13 14:06:47 +0000468 .range = NULL,
Mattias Wallind7b9f322010-11-26 13:06:39 +0100469 },
470 [0x12] = {
471 .num_ranges = 0,
Mark Brown87fff232010-12-13 14:06:47 +0000472 .range = NULL,
Mattias Wallind7b9f322010-11-26 13:06:39 +0100473 },
474 [0x13] = {
475 .num_ranges = 0,
Mark Brown87fff232010-12-13 14:06:47 +0000476 .range = NULL,
Mattias Wallind7b9f322010-11-26 13:06:39 +0100477 },
478 [0x14] = {
479 .num_ranges = 0,
Mark Brown87fff232010-12-13 14:06:47 +0000480 .range = NULL,
Mattias Wallind7b9f322010-11-26 13:06:39 +0100481 },
482 [AB8500_OTP_EMUL] = {
483 .num_ranges = 1,
484 .range = (struct ab8500_reg_range[]) {
485 {
486 .first = 0x01,
487 .last = 0x0F,
488 },
489 },
490 },
Mattias Wallin5814fc32010-09-13 16:05:04 +0200491};
492
Sachin Kamat8455eae2013-08-23 17:37:42 +0530493static struct ab8500_prcmu_ranges ab8505_debug_ranges[AB8500_NUM_BANKS] = {
Lee Jones9581ae32012-07-06 16:11:50 +0200494 [0x0] = {
495 .num_ranges = 0,
496 .range = NULL,
497 },
498 [AB8500_SYS_CTRL1_BLOCK] = {
499 .num_ranges = 5,
500 .range = (struct ab8500_reg_range[]) {
501 {
502 .first = 0x00,
503 .last = 0x04,
504 },
505 {
506 .first = 0x42,
507 .last = 0x42,
508 },
509 {
510 .first = 0x52,
511 .last = 0x52,
512 },
513 {
514 .first = 0x54,
515 .last = 0x57,
516 },
517 {
518 .first = 0x80,
519 .last = 0x83,
520 },
521 },
522 },
523 [AB8500_SYS_CTRL2_BLOCK] = {
524 .num_ranges = 5,
525 .range = (struct ab8500_reg_range[]) {
526 {
527 .first = 0x00,
528 .last = 0x0D,
529 },
530 {
531 .first = 0x0F,
532 .last = 0x17,
533 },
534 {
535 .first = 0x20,
536 .last = 0x20,
537 },
538 {
539 .first = 0x30,
540 .last = 0x30,
541 },
542 {
543 .first = 0x32,
544 .last = 0x3A,
545 },
546 },
547 },
548 [AB8500_REGU_CTRL1] = {
549 .num_ranges = 3,
550 .range = (struct ab8500_reg_range[]) {
551 {
552 .first = 0x00,
553 .last = 0x00,
554 },
555 {
556 .first = 0x03,
557 .last = 0x11,
558 },
559 {
560 .first = 0x80,
561 .last = 0x86,
562 },
563 },
564 },
565 [AB8500_REGU_CTRL2] = {
566 .num_ranges = 6,
567 .range = (struct ab8500_reg_range[]) {
568 {
569 .first = 0x00,
570 .last = 0x06,
571 },
572 {
573 .first = 0x08,
574 .last = 0x15,
575 },
576 {
577 .first = 0x17,
578 .last = 0x19,
579 },
580 {
581 .first = 0x1B,
582 .last = 0x1D,
583 },
584 {
585 .first = 0x1F,
586 .last = 0x30,
587 },
588 {
589 .first = 0x40,
590 .last = 0x48,
591 },
Lee Jonesde6a7692015-10-28 09:27:32 +0000592 /*
593 * 0x80-0x8B are SIM registers and should
594 * not be accessed from here
595 */
Lee Jones9581ae32012-07-06 16:11:50 +0200596 },
597 },
598 [AB8500_USB] = {
599 .num_ranges = 3,
600 .range = (struct ab8500_reg_range[]) {
601 {
602 .first = 0x80,
603 .last = 0x83,
604 },
605 {
606 .first = 0x87,
607 .last = 0x8A,
608 },
609 {
610 .first = 0x91,
611 .last = 0x94,
612 },
613 },
614 },
615 [AB8500_TVOUT] = {
616 .num_ranges = 0,
617 .range = NULL,
618 },
619 [AB8500_DBI] = {
620 .num_ranges = 0,
621 .range = NULL,
622 },
623 [AB8500_ECI_AV_ACC] = {
624 .num_ranges = 1,
625 .range = (struct ab8500_reg_range[]) {
626 {
627 .first = 0x80,
628 .last = 0x82,
629 },
630 },
631 },
632 [AB8500_RESERVED] = {
633 .num_ranges = 0,
634 .range = NULL,
635 },
636 [AB8500_GPADC] = {
637 .num_ranges = 1,
638 .range = (struct ab8500_reg_range[]) {
639 {
640 .first = 0x00,
641 .last = 0x08,
642 },
643 },
644 },
645 [AB8500_CHARGER] = {
646 .num_ranges = 9,
647 .range = (struct ab8500_reg_range[]) {
648 {
649 .first = 0x02,
650 .last = 0x03,
651 },
652 {
653 .first = 0x05,
654 .last = 0x05,
655 },
656 {
657 .first = 0x40,
658 .last = 0x44,
659 },
660 {
661 .first = 0x50,
662 .last = 0x57,
663 },
664 {
665 .first = 0x60,
666 .last = 0x60,
667 },
668 {
669 .first = 0xA0,
670 .last = 0xA7,
671 },
672 {
673 .first = 0xAF,
674 .last = 0xB2,
675 },
676 {
677 .first = 0xC0,
678 .last = 0xC2,
679 },
680 {
681 .first = 0xF5,
682 .last = 0xF5,
683 },
684 },
685 },
686 [AB8500_GAS_GAUGE] = {
687 .num_ranges = 3,
688 .range = (struct ab8500_reg_range[]) {
689 {
690 .first = 0x00,
691 .last = 0x00,
692 },
693 {
694 .first = 0x07,
695 .last = 0x0A,
696 },
697 {
698 .first = 0x10,
699 .last = 0x14,
700 },
701 },
702 },
703 [AB8500_AUDIO] = {
704 .num_ranges = 1,
705 .range = (struct ab8500_reg_range[]) {
706 {
707 .first = 0x00,
708 .last = 0x83,
709 },
710 },
711 },
712 [AB8500_INTERRUPT] = {
713 .num_ranges = 11,
714 .range = (struct ab8500_reg_range[]) {
715 {
716 .first = 0x00,
717 .last = 0x04,
718 },
719 {
720 .first = 0x06,
721 .last = 0x07,
722 },
723 {
724 .first = 0x09,
725 .last = 0x09,
726 },
727 {
728 .first = 0x0B,
729 .last = 0x0C,
730 },
731 {
732 .first = 0x12,
733 .last = 0x15,
734 },
735 {
736 .first = 0x18,
737 .last = 0x18,
738 },
739 /* Latch registers should not be read here */
740 {
741 .first = 0x40,
742 .last = 0x44,
743 },
744 {
745 .first = 0x46,
746 .last = 0x49,
747 },
748 {
749 .first = 0x4B,
750 .last = 0x4D,
751 },
752 {
753 .first = 0x52,
754 .last = 0x55,
755 },
756 {
757 .first = 0x58,
758 .last = 0x58,
759 },
760 /* LatchHier registers should not be read here */
761 },
762 },
763 [AB8500_RTC] = {
764 .num_ranges = 2,
765 .range = (struct ab8500_reg_range[]) {
766 {
767 .first = 0x00,
768 .last = 0x14,
769 },
770 {
771 .first = 0x16,
772 .last = 0x17,
773 },
774 },
775 },
776 [AB8500_MISC] = {
777 .num_ranges = 8,
778 .range = (struct ab8500_reg_range[]) {
779 {
780 .first = 0x00,
781 .last = 0x06,
782 },
783 {
784 .first = 0x10,
785 .last = 0x16,
786 },
787 {
788 .first = 0x20,
789 .last = 0x26,
790 },
791 {
792 .first = 0x30,
793 .last = 0x36,
794 },
795 {
796 .first = 0x40,
797 .last = 0x46,
798 },
799 {
800 .first = 0x50,
801 .last = 0x50,
802 },
803 {
804 .first = 0x60,
805 .last = 0x6B,
806 },
807 {
808 .first = 0x80,
809 .last = 0x82,
810 },
811 },
812 },
813 [AB8500_DEVELOPMENT] = {
814 .num_ranges = 2,
815 .range = (struct ab8500_reg_range[]) {
816 {
817 .first = 0x00,
818 .last = 0x00,
819 },
820 {
821 .first = 0x05,
822 .last = 0x05,
823 },
824 },
825 },
826 [AB8500_DEBUG] = {
827 .num_ranges = 1,
828 .range = (struct ab8500_reg_range[]) {
829 {
830 .first = 0x05,
831 .last = 0x07,
832 },
833 },
834 },
835 [AB8500_PROD_TEST] = {
836 .num_ranges = 0,
837 .range = NULL,
838 },
839 [AB8500_STE_TEST] = {
840 .num_ranges = 0,
841 .range = NULL,
842 },
843 [AB8500_OTP_EMUL] = {
844 .num_ranges = 1,
845 .range = (struct ab8500_reg_range[]) {
846 {
847 .first = 0x01,
848 .last = 0x15,
849 },
850 },
851 },
852};
853
Sachin Kamat8455eae2013-08-23 17:37:42 +0530854static struct ab8500_prcmu_ranges ab8540_debug_ranges[AB8500_NUM_BANKS] = {
Lee Jones971480f2012-11-19 12:20:03 +0100855 [AB8500_M_FSM_RANK] = {
856 .num_ranges = 1,
857 .range = (struct ab8500_reg_range[]) {
858 {
859 .first = 0x00,
860 .last = 0x0B,
861 },
862 },
863 },
864 [AB8500_SYS_CTRL1_BLOCK] = {
865 .num_ranges = 6,
866 .range = (struct ab8500_reg_range[]) {
867 {
868 .first = 0x00,
869 .last = 0x04,
870 },
871 {
872 .first = 0x42,
873 .last = 0x42,
874 },
875 {
876 .first = 0x50,
877 .last = 0x54,
878 },
879 {
880 .first = 0x57,
881 .last = 0x57,
882 },
883 {
884 .first = 0x80,
885 .last = 0x83,
886 },
887 {
888 .first = 0x90,
889 .last = 0x90,
890 },
891 },
892 },
893 [AB8500_SYS_CTRL2_BLOCK] = {
894 .num_ranges = 5,
895 .range = (struct ab8500_reg_range[]) {
896 {
897 .first = 0x00,
898 .last = 0x0D,
899 },
900 {
901 .first = 0x0F,
902 .last = 0x10,
903 },
904 {
905 .first = 0x20,
906 .last = 0x21,
907 },
908 {
909 .first = 0x32,
910 .last = 0x3C,
911 },
912 {
913 .first = 0x40,
914 .last = 0x42,
915 },
916 },
917 },
918 [AB8500_REGU_CTRL1] = {
919 .num_ranges = 4,
920 .range = (struct ab8500_reg_range[]) {
921 {
922 .first = 0x03,
923 .last = 0x15,
924 },
925 {
926 .first = 0x20,
927 .last = 0x20,
928 },
929 {
930 .first = 0x80,
931 .last = 0x85,
932 },
933 {
934 .first = 0x87,
935 .last = 0x88,
936 },
937 },
938 },
939 [AB8500_REGU_CTRL2] = {
940 .num_ranges = 8,
941 .range = (struct ab8500_reg_range[]) {
942 {
943 .first = 0x00,
944 .last = 0x06,
945 },
946 {
947 .first = 0x08,
948 .last = 0x15,
949 },
950 {
951 .first = 0x17,
952 .last = 0x19,
953 },
954 {
955 .first = 0x1B,
956 .last = 0x1D,
957 },
958 {
959 .first = 0x1F,
960 .last = 0x2F,
961 },
962 {
963 .first = 0x31,
964 .last = 0x3A,
965 },
966 {
967 .first = 0x43,
968 .last = 0x44,
969 },
970 {
971 .first = 0x48,
972 .last = 0x49,
973 },
974 },
975 },
976 [AB8500_USB] = {
977 .num_ranges = 3,
978 .range = (struct ab8500_reg_range[]) {
979 {
980 .first = 0x80,
981 .last = 0x83,
982 },
983 {
984 .first = 0x87,
985 .last = 0x8A,
986 },
987 {
988 .first = 0x91,
989 .last = 0x94,
990 },
991 },
992 },
993 [AB8500_TVOUT] = {
994 .num_ranges = 0,
995 .range = NULL
996 },
997 [AB8500_DBI] = {
998 .num_ranges = 4,
999 .range = (struct ab8500_reg_range[]) {
1000 {
1001 .first = 0x00,
1002 .last = 0x07,
1003 },
1004 {
1005 .first = 0x10,
1006 .last = 0x11,
1007 },
1008 {
1009 .first = 0x20,
1010 .last = 0x21,
1011 },
1012 {
1013 .first = 0x30,
1014 .last = 0x43,
1015 },
1016 },
1017 },
1018 [AB8500_ECI_AV_ACC] = {
1019 .num_ranges = 2,
1020 .range = (struct ab8500_reg_range[]) {
1021 {
1022 .first = 0x00,
1023 .last = 0x03,
1024 },
1025 {
1026 .first = 0x80,
1027 .last = 0x82,
1028 },
1029 },
1030 },
1031 [AB8500_RESERVED] = {
1032 .num_ranges = 0,
1033 .range = NULL,
1034 },
1035 [AB8500_GPADC] = {
1036 .num_ranges = 4,
1037 .range = (struct ab8500_reg_range[]) {
1038 {
1039 .first = 0x00,
1040 .last = 0x01,
1041 },
1042 {
1043 .first = 0x04,
1044 .last = 0x06,
1045 },
1046 {
1047 .first = 0x09,
1048 .last = 0x0A,
1049 },
1050 {
1051 .first = 0x10,
1052 .last = 0x14,
1053 },
1054 },
1055 },
1056 [AB8500_CHARGER] = {
1057 .num_ranges = 10,
1058 .range = (struct ab8500_reg_range[]) {
1059 {
1060 .first = 0x00,
1061 .last = 0x00,
1062 },
1063 {
1064 .first = 0x02,
1065 .last = 0x05,
1066 },
1067 {
1068 .first = 0x40,
1069 .last = 0x44,
1070 },
1071 {
1072 .first = 0x50,
1073 .last = 0x57,
1074 },
1075 {
1076 .first = 0x60,
1077 .last = 0x60,
1078 },
1079 {
1080 .first = 0x70,
1081 .last = 0x70,
1082 },
1083 {
1084 .first = 0xA0,
1085 .last = 0xA9,
1086 },
1087 {
1088 .first = 0xAF,
1089 .last = 0xB2,
1090 },
1091 {
1092 .first = 0xC0,
1093 .last = 0xC6,
1094 },
1095 {
1096 .first = 0xF5,
1097 .last = 0xF5,
1098 },
1099 },
1100 },
1101 [AB8500_GAS_GAUGE] = {
1102 .num_ranges = 3,
1103 .range = (struct ab8500_reg_range[]) {
1104 {
1105 .first = 0x00,
1106 .last = 0x00,
1107 },
1108 {
1109 .first = 0x07,
1110 .last = 0x0A,
1111 },
1112 {
1113 .first = 0x10,
1114 .last = 0x14,
1115 },
1116 },
1117 },
1118 [AB8500_AUDIO] = {
1119 .num_ranges = 1,
1120 .range = (struct ab8500_reg_range[]) {
1121 {
1122 .first = 0x00,
1123 .last = 0x9f,
1124 },
1125 },
1126 },
1127 [AB8500_INTERRUPT] = {
1128 .num_ranges = 6,
1129 .range = (struct ab8500_reg_range[]) {
1130 {
1131 .first = 0x00,
1132 .last = 0x05,
1133 },
1134 {
1135 .first = 0x0B,
1136 .last = 0x0D,
1137 },
1138 {
1139 .first = 0x12,
1140 .last = 0x20,
1141 },
1142 /* Latch registers should not be read here */
1143 {
1144 .first = 0x40,
1145 .last = 0x45,
1146 },
1147 {
1148 .first = 0x4B,
1149 .last = 0x4D,
1150 },
1151 {
1152 .first = 0x52,
1153 .last = 0x60,
1154 },
1155 /* LatchHier registers should not be read here */
1156 },
1157 },
1158 [AB8500_RTC] = {
1159 .num_ranges = 3,
1160 .range = (struct ab8500_reg_range[]) {
1161 {
1162 .first = 0x00,
1163 .last = 0x07,
1164 },
1165 {
1166 .first = 0x0B,
1167 .last = 0x18,
1168 },
1169 {
1170 .first = 0x20,
1171 .last = 0x25,
1172 },
1173 },
1174 },
1175 [AB8500_MISC] = {
1176 .num_ranges = 9,
1177 .range = (struct ab8500_reg_range[]) {
1178 {
1179 .first = 0x00,
1180 .last = 0x06,
1181 },
1182 {
1183 .first = 0x10,
1184 .last = 0x16,
1185 },
1186 {
1187 .first = 0x20,
1188 .last = 0x26,
1189 },
1190 {
1191 .first = 0x30,
1192 .last = 0x36,
1193 },
1194 {
1195 .first = 0x40,
1196 .last = 0x49,
1197 },
1198 {
1199 .first = 0x50,
1200 .last = 0x50,
1201 },
1202 {
1203 .first = 0x60,
1204 .last = 0x6B,
1205 },
1206 {
1207 .first = 0x70,
1208 .last = 0x74,
1209 },
1210 {
1211 .first = 0x80,
1212 .last = 0x82,
1213 },
1214 },
1215 },
1216 [AB8500_DEVELOPMENT] = {
1217 .num_ranges = 3,
1218 .range = (struct ab8500_reg_range[]) {
1219 {
1220 .first = 0x00,
1221 .last = 0x01,
1222 },
1223 {
1224 .first = 0x06,
1225 .last = 0x06,
1226 },
1227 {
1228 .first = 0x10,
1229 .last = 0x21,
1230 },
1231 },
1232 },
1233 [AB8500_DEBUG] = {
1234 .num_ranges = 3,
1235 .range = (struct ab8500_reg_range[]) {
1236 {
1237 .first = 0x01,
1238 .last = 0x0C,
1239 },
1240 {
1241 .first = 0x0E,
1242 .last = 0x11,
1243 },
1244 {
1245 .first = 0x80,
1246 .last = 0x81,
1247 },
1248 },
1249 },
1250 [AB8500_PROD_TEST] = {
1251 .num_ranges = 0,
1252 .range = NULL,
1253 },
1254 [AB8500_STE_TEST] = {
1255 .num_ranges = 0,
1256 .range = NULL,
1257 },
1258 [AB8500_OTP_EMUL] = {
1259 .num_ranges = 1,
1260 .range = (struct ab8500_reg_range[]) {
1261 {
1262 .first = 0x00,
1263 .last = 0x3F,
1264 },
1265 },
1266 },
1267};
1268
1269
Lee Jones4b8ac082013-01-14 16:10:36 +00001270static irqreturn_t ab8500_debug_handler(int irq, void *data)
1271{
1272 char buf[16];
1273 struct kobject *kobj = (struct kobject *)data;
Mattias Wallin0b337e72010-11-19 17:55:11 +01001274 unsigned int irq_abb = irq - irq_first;
Lee Jones4b8ac082013-01-14 16:10:36 +00001275
Linus Walleijddba25f2012-02-03 11:19:05 +01001276 if (irq_abb < num_irqs)
Mattias Wallin0b337e72010-11-19 17:55:11 +01001277 irq_count[irq_abb]++;
Lee Jones4b8ac082013-01-14 16:10:36 +00001278 /*
1279 * This makes it possible to use poll for events (POLLPRI | POLLERR)
Mattias Wallin0b337e72010-11-19 17:55:11 +01001280 * from userspace on sysfs file named <irq-nr>
Lee Jones4b8ac082013-01-14 16:10:36 +00001281 */
Mattias Wallin0b337e72010-11-19 17:55:11 +01001282 sprintf(buf, "%d", irq);
Lee Jones4b8ac082013-01-14 16:10:36 +00001283 sysfs_notify(kobj, NULL, buf);
1284
1285 return IRQ_HANDLED;
1286}
1287
Mian Yousaf Kaukab42002c62012-01-26 15:39:20 +01001288/* Prints to seq_file or log_buf */
1289static int ab8500_registers_print(struct device *dev, u32 bank,
Joe Perches9a503a72015-02-21 18:53:43 -08001290 struct seq_file *s)
Mattias Wallin5814fc32010-09-13 16:05:04 +02001291{
Mattias Wallind7b9f322010-11-26 13:06:39 +01001292 unsigned int i;
Mattias Wallin5814fc32010-09-13 16:05:04 +02001293
Mattias Wallind7b9f322010-11-26 13:06:39 +01001294 for (i = 0; i < debug_ranges[bank].num_ranges; i++) {
1295 u32 reg;
Mattias Wallin5814fc32010-09-13 16:05:04 +02001296
Mattias Wallind7b9f322010-11-26 13:06:39 +01001297 for (reg = debug_ranges[bank].range[i].first;
1298 reg <= debug_ranges[bank].range[i].last;
1299 reg++) {
1300 u8 value;
1301 int err;
Mattias Wallin5814fc32010-09-13 16:05:04 +02001302
Mattias Wallind7b9f322010-11-26 13:06:39 +01001303 err = abx500_get_register_interruptible(dev,
1304 (u8)bank, (u8)reg, &value);
1305 if (err < 0) {
1306 dev_err(dev, "ab->read fail %d\n", err);
1307 return err;
1308 }
Mattias Wallin5814fc32010-09-13 16:05:04 +02001309
Mian Yousaf Kaukab42002c62012-01-26 15:39:20 +01001310 if (s) {
Joe Perches9a503a72015-02-21 18:53:43 -08001311 seq_printf(s, " [0x%02X/0x%02X]: 0x%02X\n",
1312 bank, reg, value);
Lee Jonesde6a7692015-10-28 09:27:32 +00001313 /*
1314 * Error is not returned here since
1315 * the output is wanted in any case
1316 */
Joe Perches9a503a72015-02-21 18:53:43 -08001317 if (seq_has_overflowed(s))
Mian Yousaf Kaukab42002c62012-01-26 15:39:20 +01001318 return 0;
Mian Yousaf Kaukab42002c62012-01-26 15:39:20 +01001319 } else {
Lee Jones43621752014-07-14 18:29:16 +01001320 dev_info(dev, " [0x%02X/0x%02X]: 0x%02X\n",
1321 bank, reg, value);
Mattias Wallind7b9f322010-11-26 13:06:39 +01001322 }
1323 }
1324 }
Joe Perches9a503a72015-02-21 18:53:43 -08001325
Mattias Wallind7b9f322010-11-26 13:06:39 +01001326 return 0;
Mattias Wallin5814fc32010-09-13 16:05:04 +02001327}
1328
Mian Yousaf Kaukab42002c62012-01-26 15:39:20 +01001329static int ab8500_print_bank_registers(struct seq_file *s, void *p)
1330{
1331 struct device *dev = s->private;
1332 u32 bank = debug_bank;
1333
Lee Jones43621752014-07-14 18:29:16 +01001334 seq_puts(s, AB8500_NAME_STRING " register values:\n");
Mian Yousaf Kaukab42002c62012-01-26 15:39:20 +01001335
Mattias Wallincfc08492012-05-28 15:53:58 +02001336 seq_printf(s, " bank 0x%02X:\n", bank);
Mian Yousaf Kaukab42002c62012-01-26 15:39:20 +01001337
Joe Perches9a503a72015-02-21 18:53:43 -08001338 return ab8500_registers_print(dev, bank, s);
Mian Yousaf Kaukab42002c62012-01-26 15:39:20 +01001339}
1340
Mattias Wallin5814fc32010-09-13 16:05:04 +02001341static int ab8500_registers_open(struct inode *inode, struct file *file)
1342{
Mian Yousaf Kaukab42002c62012-01-26 15:39:20 +01001343 return single_open(file, ab8500_print_bank_registers, inode->i_private);
Mattias Wallin5814fc32010-09-13 16:05:04 +02001344}
1345
1346static const struct file_operations ab8500_registers_fops = {
Mattias Wallind7b9f322010-11-26 13:06:39 +01001347 .open = ab8500_registers_open,
1348 .read = seq_read,
1349 .llseek = seq_lseek,
1350 .release = single_release,
1351 .owner = THIS_MODULE,
Mattias Wallin5814fc32010-09-13 16:05:04 +02001352};
1353
Mian Yousaf Kaukab42002c62012-01-26 15:39:20 +01001354static int ab8500_print_all_banks(struct seq_file *s, void *p)
1355{
1356 struct device *dev = s->private;
1357 unsigned int i;
Mian Yousaf Kaukab42002c62012-01-26 15:39:20 +01001358
Lee Jones43621752014-07-14 18:29:16 +01001359 seq_puts(s, AB8500_NAME_STRING " register values:\n");
Mian Yousaf Kaukab42002c62012-01-26 15:39:20 +01001360
Lee Jones971480f2012-11-19 12:20:03 +01001361 for (i = 0; i < AB8500_NUM_BANKS; i++) {
Joe Perches9a503a72015-02-21 18:53:43 -08001362 int err;
Mian Yousaf Kaukab42002c62012-01-26 15:39:20 +01001363
Joe Perches9a503a72015-02-21 18:53:43 -08001364 seq_printf(s, " bank 0x%02X:\n", i);
1365 err = ab8500_registers_print(dev, i, s);
1366 if (err)
1367 return err;
Mian Yousaf Kaukab42002c62012-01-26 15:39:20 +01001368 }
1369 return 0;
1370}
1371
Mian Yousaf Kaukab1d843a62012-01-27 11:35:41 +01001372/* Dump registers to kernel log */
1373void ab8500_dump_all_banks(struct device *dev)
1374{
1375 unsigned int i;
1376
Lee Jones43621752014-07-14 18:29:16 +01001377 dev_info(dev, "ab8500 register values:\n");
Mian Yousaf Kaukab1d843a62012-01-27 11:35:41 +01001378
1379 for (i = 1; i < AB8500_NUM_BANKS; i++) {
Lee Jones43621752014-07-14 18:29:16 +01001380 dev_info(dev, " bank 0x%02X:\n", i);
Mian Yousaf Kaukab1d843a62012-01-27 11:35:41 +01001381 ab8500_registers_print(dev, i, NULL);
1382 }
1383}
1384
Lee Jones5ff90902013-02-12 14:35:28 +00001385/* Space for 500 registers. */
1386#define DUMP_MAX_REGS 700
Sachin Kamat8455eae2013-08-23 17:37:42 +05301387static struct ab8500_register_dump
Lee Jones5ff90902013-02-12 14:35:28 +00001388{
1389 u8 bank;
1390 u8 reg;
1391 u8 value;
Lee Jones5ff90902013-02-12 14:35:28 +00001392} ab8500_complete_register_dump[DUMP_MAX_REGS];
1393
Lee Jones5ff90902013-02-12 14:35:28 +00001394/* This shall only be called upon kernel panic! */
1395void ab8500_dump_all_banks_to_mem(void)
1396{
1397 int i, r = 0;
1398 u8 bank;
Jonas Aaberg222460c2012-06-18 10:35:28 +02001399 int err = 0;
Lee Jones5ff90902013-02-12 14:35:28 +00001400
Lee Jones43621752014-07-14 18:29:16 +01001401 pr_info("Saving all ABB registers for crash analysis.\n");
Lee Jones5ff90902013-02-12 14:35:28 +00001402
Lee Jones971480f2012-11-19 12:20:03 +01001403 for (bank = 0; bank < AB8500_NUM_BANKS; bank++) {
Lee Jones5ff90902013-02-12 14:35:28 +00001404 for (i = 0; i < debug_ranges[bank].num_ranges; i++) {
1405 u8 reg;
1406
1407 for (reg = debug_ranges[bank].range[i].first;
1408 reg <= debug_ranges[bank].range[i].last;
1409 reg++) {
1410 u8 value;
Lee Jones5ff90902013-02-12 14:35:28 +00001411
1412 err = prcmu_abb_read(bank, reg, &value, 1);
1413
Jonas Aaberg222460c2012-06-18 10:35:28 +02001414 if (err < 0)
1415 goto out;
1416
Lee Jones5ff90902013-02-12 14:35:28 +00001417 ab8500_complete_register_dump[r].bank = bank;
1418 ab8500_complete_register_dump[r].reg = reg;
1419 ab8500_complete_register_dump[r].value = value;
1420
1421 r++;
1422
1423 if (r >= DUMP_MAX_REGS) {
1424 pr_err("%s: too many register to dump!\n",
1425 __func__);
Jonas Aaberg222460c2012-06-18 10:35:28 +02001426 err = -EINVAL;
1427 goto out;
Lee Jones5ff90902013-02-12 14:35:28 +00001428 }
1429 }
1430 }
1431 }
Jonas Aaberg222460c2012-06-18 10:35:28 +02001432out:
1433 if (err >= 0)
1434 pr_info("Saved all ABB registers.\n");
1435 else
1436 pr_info("Failed to save all ABB registers.\n");
Lee Jones5ff90902013-02-12 14:35:28 +00001437}
1438
Mian Yousaf Kaukab42002c62012-01-26 15:39:20 +01001439static int ab8500_all_banks_open(struct inode *inode, struct file *file)
1440{
1441 struct seq_file *s;
1442 int err;
1443
1444 err = single_open(file, ab8500_print_all_banks, inode->i_private);
1445 if (!err) {
1446 /* Default buf size in seq_read is not enough */
1447 s = (struct seq_file *)file->private_data;
1448 s->size = (PAGE_SIZE * 2);
1449 s->buf = kmalloc(s->size, GFP_KERNEL);
1450 if (!s->buf) {
1451 single_release(inode, file);
1452 err = -ENOMEM;
1453 }
1454 }
1455 return err;
1456}
1457
1458static const struct file_operations ab8500_all_banks_fops = {
1459 .open = ab8500_all_banks_open,
1460 .read = seq_read,
1461 .llseek = seq_lseek,
1462 .release = single_release,
1463 .owner = THIS_MODULE,
1464};
1465
Mattias Wallin5814fc32010-09-13 16:05:04 +02001466static int ab8500_bank_print(struct seq_file *s, void *p)
1467{
Joe Perches9a503a72015-02-21 18:53:43 -08001468 seq_printf(s, "0x%02X\n", debug_bank);
1469 return 0;
Mattias Wallin5814fc32010-09-13 16:05:04 +02001470}
1471
1472static int ab8500_bank_open(struct inode *inode, struct file *file)
1473{
Mattias Wallind7b9f322010-11-26 13:06:39 +01001474 return single_open(file, ab8500_bank_print, inode->i_private);
Mattias Wallin5814fc32010-09-13 16:05:04 +02001475}
1476
1477static ssize_t ab8500_bank_write(struct file *file,
Mattias Wallind7b9f322010-11-26 13:06:39 +01001478 const char __user *user_buf,
1479 size_t count, loff_t *ppos)
Mattias Wallin5814fc32010-09-13 16:05:04 +02001480{
Mattias Wallind7b9f322010-11-26 13:06:39 +01001481 struct device *dev = ((struct seq_file *)(file->private_data))->private;
Mattias Wallind7b9f322010-11-26 13:06:39 +01001482 unsigned long user_bank;
1483 int err;
Mattias Wallin5814fc32010-09-13 16:05:04 +02001484
Peter Huewe8504d632011-06-06 22:43:32 +02001485 err = kstrtoul_from_user(user_buf, count, 0, &user_bank);
Mattias Wallind7b9f322010-11-26 13:06:39 +01001486 if (err)
Peter Huewe8504d632011-06-06 22:43:32 +02001487 return err;
Mattias Wallin5814fc32010-09-13 16:05:04 +02001488
Mattias Wallind7b9f322010-11-26 13:06:39 +01001489 if (user_bank >= AB8500_NUM_BANKS) {
1490 dev_err(dev, "debugfs error input > number of banks\n");
1491 return -EINVAL;
1492 }
Mattias Wallin5814fc32010-09-13 16:05:04 +02001493
Mattias Wallind7b9f322010-11-26 13:06:39 +01001494 debug_bank = user_bank;
Mattias Wallin5814fc32010-09-13 16:05:04 +02001495
Peter Huewe8504d632011-06-06 22:43:32 +02001496 return count;
Mattias Wallin5814fc32010-09-13 16:05:04 +02001497}
1498
1499static int ab8500_address_print(struct seq_file *s, void *p)
1500{
Joe Perches9a503a72015-02-21 18:53:43 -08001501 seq_printf(s, "0x%02X\n", debug_address);
1502 return 0;
Mattias Wallin5814fc32010-09-13 16:05:04 +02001503}
1504
1505static int ab8500_address_open(struct inode *inode, struct file *file)
1506{
Mattias Wallind7b9f322010-11-26 13:06:39 +01001507 return single_open(file, ab8500_address_print, inode->i_private);
Mattias Wallin5814fc32010-09-13 16:05:04 +02001508}
1509
1510static ssize_t ab8500_address_write(struct file *file,
Lee Jones9f9ba152013-02-26 12:05:15 +00001511 const char __user *user_buf,
1512 size_t count, loff_t *ppos)
Mattias Wallin5814fc32010-09-13 16:05:04 +02001513{
Mattias Wallind7b9f322010-11-26 13:06:39 +01001514 struct device *dev = ((struct seq_file *)(file->private_data))->private;
Mattias Wallind7b9f322010-11-26 13:06:39 +01001515 unsigned long user_address;
1516 int err;
Mattias Wallin5814fc32010-09-13 16:05:04 +02001517
Peter Huewe8504d632011-06-06 22:43:32 +02001518 err = kstrtoul_from_user(user_buf, count, 0, &user_address);
Mattias Wallind7b9f322010-11-26 13:06:39 +01001519 if (err)
Peter Huewe8504d632011-06-06 22:43:32 +02001520 return err;
1521
Mattias Wallind7b9f322010-11-26 13:06:39 +01001522 if (user_address > 0xff) {
1523 dev_err(dev, "debugfs error input > 0xff\n");
1524 return -EINVAL;
1525 }
1526 debug_address = user_address;
srinidhi kasagar7b830ae2012-11-23 15:11:00 +05301527
Peter Huewe8504d632011-06-06 22:43:32 +02001528 return count;
Mattias Wallin5814fc32010-09-13 16:05:04 +02001529}
1530
1531static int ab8500_val_print(struct seq_file *s, void *p)
1532{
Mattias Wallind7b9f322010-11-26 13:06:39 +01001533 struct device *dev = s->private;
1534 int ret;
1535 u8 regvalue;
Mattias Wallin5814fc32010-09-13 16:05:04 +02001536
Mattias Wallind7b9f322010-11-26 13:06:39 +01001537 ret = abx500_get_register_interruptible(dev,
1538 (u8)debug_bank, (u8)debug_address, &regvalue);
1539 if (ret < 0) {
1540 dev_err(dev, "abx500_get_reg fail %d, %d\n",
1541 ret, __LINE__);
1542 return -EINVAL;
1543 }
1544 seq_printf(s, "0x%02X\n", regvalue);
Mattias Wallin5814fc32010-09-13 16:05:04 +02001545
Mattias Wallind7b9f322010-11-26 13:06:39 +01001546 return 0;
Mattias Wallin5814fc32010-09-13 16:05:04 +02001547}
1548
1549static int ab8500_val_open(struct inode *inode, struct file *file)
1550{
Mattias Wallind7b9f322010-11-26 13:06:39 +01001551 return single_open(file, ab8500_val_print, inode->i_private);
Mattias Wallin5814fc32010-09-13 16:05:04 +02001552}
1553
1554static ssize_t ab8500_val_write(struct file *file,
Lee Jones9f9ba152013-02-26 12:05:15 +00001555 const char __user *user_buf,
1556 size_t count, loff_t *ppos)
Mattias Wallin5814fc32010-09-13 16:05:04 +02001557{
Mattias Wallind7b9f322010-11-26 13:06:39 +01001558 struct device *dev = ((struct seq_file *)(file->private_data))->private;
Mattias Wallind7b9f322010-11-26 13:06:39 +01001559 unsigned long user_val;
1560 int err;
Mattias Wallin5814fc32010-09-13 16:05:04 +02001561
Peter Huewe8504d632011-06-06 22:43:32 +02001562 err = kstrtoul_from_user(user_buf, count, 0, &user_val);
Mattias Wallind7b9f322010-11-26 13:06:39 +01001563 if (err)
Peter Huewe8504d632011-06-06 22:43:32 +02001564 return err;
1565
Mattias Wallind7b9f322010-11-26 13:06:39 +01001566 if (user_val > 0xff) {
1567 dev_err(dev, "debugfs error input > 0xff\n");
1568 return -EINVAL;
1569 }
1570 err = abx500_set_register_interruptible(dev,
1571 (u8)debug_bank, debug_address, (u8)user_val);
1572 if (err < 0) {
Lee Jones43621752014-07-14 18:29:16 +01001573 pr_err("abx500_set_reg failed %d, %d", err, __LINE__);
Mattias Wallind7b9f322010-11-26 13:06:39 +01001574 return -EINVAL;
1575 }
Mattias Wallin5814fc32010-09-13 16:05:04 +02001576
Peter Huewe8504d632011-06-06 22:43:32 +02001577 return count;
Mattias Wallin5814fc32010-09-13 16:05:04 +02001578}
1579
carriere etienne0fbce762011-04-08 16:26:36 +02001580/*
Bengt Jonsson8f0eb432012-02-14 13:01:00 +01001581 * Interrupt status
1582 */
1583static u32 num_interrupts[AB8500_MAX_NR_IRQS];
Jonas Aaberg2cf64e22012-05-31 07:57:07 +02001584static u32 num_wake_interrupts[AB8500_MAX_NR_IRQS];
Bengt Jonsson8f0eb432012-02-14 13:01:00 +01001585static int num_interrupt_lines;
1586
Jonas Aaberg2cf64e22012-05-31 07:57:07 +02001587bool __attribute__((weak)) suspend_test_wake_cause_interrupt_is_mine(u32 my_int)
1588{
1589 return false;
1590}
1591
Bengt Jonsson8f0eb432012-02-14 13:01:00 +01001592void ab8500_debug_register_interrupt(int line)
1593{
Jonas Aaberg2cf64e22012-05-31 07:57:07 +02001594 if (line < num_interrupt_lines) {
Bengt Jonsson8f0eb432012-02-14 13:01:00 +01001595 num_interrupts[line]++;
Linus Walleij69991812013-04-12 17:02:09 +02001596 if (suspend_test_wake_cause_interrupt_is_mine(irq_ab8500))
Jonas Aaberg2cf64e22012-05-31 07:57:07 +02001597 num_wake_interrupts[line]++;
1598 }
Bengt Jonsson8f0eb432012-02-14 13:01:00 +01001599}
1600
1601static int ab8500_interrupts_print(struct seq_file *s, void *p)
1602{
1603 int line;
1604
Lee Jones43621752014-07-14 18:29:16 +01001605 seq_puts(s, "name: number: number of: wake:\n");
Bengt Jonsson8f0eb432012-02-14 13:01:00 +01001606
Jonas Aaberg2cf64e22012-05-31 07:57:07 +02001607 for (line = 0; line < num_interrupt_lines; line++) {
1608 struct irq_desc *desc = irq_to_desc(line + irq_first);
Jonas Aaberg2cf64e22012-05-31 07:57:07 +02001609
Joe Perches9a503a72015-02-21 18:53:43 -08001610 seq_printf(s, "%3i: %6i %4i",
1611 line,
Jonas Aaberg2cf64e22012-05-31 07:57:07 +02001612 num_interrupts[line],
1613 num_wake_interrupts[line]);
1614
1615 if (desc && desc->name)
1616 seq_printf(s, "-%-8s", desc->name);
Dan Carpenter7c0b2382013-11-13 10:40:30 +03001617 if (desc && desc->action) {
1618 struct irqaction *action = desc->action;
1619
Jonas Aaberg2cf64e22012-05-31 07:57:07 +02001620 seq_printf(s, " %s", action->name);
1621 while ((action = action->next) != NULL)
1622 seq_printf(s, ", %s", action->name);
1623 }
1624 seq_putc(s, '\n');
1625 }
Bengt Jonsson8f0eb432012-02-14 13:01:00 +01001626
1627 return 0;
1628}
1629
1630static int ab8500_interrupts_open(struct inode *inode, struct file *file)
1631{
1632 return single_open(file, ab8500_interrupts_print, inode->i_private);
1633}
1634
1635/*
carriere etienne0fbce762011-04-08 16:26:36 +02001636 * - HWREG DB8500 formated routines
1637 */
1638static int ab8500_hwreg_print(struct seq_file *s, void *d)
1639{
1640 struct device *dev = s->private;
1641 int ret;
1642 u8 regvalue;
1643
1644 ret = abx500_get_register_interruptible(dev,
1645 (u8)hwreg_cfg.bank, (u8)hwreg_cfg.addr, &regvalue);
1646 if (ret < 0) {
1647 dev_err(dev, "abx500_get_reg fail %d, %d\n",
1648 ret, __LINE__);
1649 return -EINVAL;
1650 }
1651
1652 if (hwreg_cfg.shift >= 0)
1653 regvalue >>= hwreg_cfg.shift;
1654 else
1655 regvalue <<= -hwreg_cfg.shift;
1656 regvalue &= hwreg_cfg.mask;
1657
1658 if (REG_FMT_DEC(&hwreg_cfg))
1659 seq_printf(s, "%d\n", regvalue);
1660 else
1661 seq_printf(s, "0x%02X\n", regvalue);
1662 return 0;
1663}
1664
1665static int ab8500_hwreg_open(struct inode *inode, struct file *file)
1666{
1667 return single_open(file, ab8500_hwreg_print, inode->i_private);
1668}
1669
Lee Jonesc7ebaee2013-02-26 14:03:33 +00001670#define AB8500_SUPPLY_CONTROL_CONFIG_1 0x01
1671#define AB8500_SUPPLY_CONTROL_REG 0x00
1672#define AB8500_FIRST_SIM_REG 0x80
1673#define AB8500_LAST_SIM_REG 0x8B
1674#define AB8505_LAST_SIM_REG 0x8C
1675
1676static int ab8500_print_modem_registers(struct seq_file *s, void *p)
1677{
1678 struct device *dev = s->private;
1679 struct ab8500 *ab8500;
1680 int err;
1681 u8 value;
1682 u8 orig_value;
1683 u32 bank = AB8500_REGU_CTRL2;
1684 u32 last_sim_reg = AB8500_LAST_SIM_REG;
1685 u32 reg;
1686
1687 ab8500 = dev_get_drvdata(dev->parent);
1688 dev_warn(dev, "WARNING! This operation can interfer with modem side\n"
1689 "and should only be done with care\n");
1690
1691 err = abx500_get_register_interruptible(dev,
1692 AB8500_REGU_CTRL1, AB8500_SUPPLY_CONTROL_REG, &orig_value);
1693 if (err < 0) {
1694 dev_err(dev, "ab->read fail %d\n", err);
1695 return err;
1696 }
1697 /* Config 1 will allow APE side to read SIM registers */
1698 err = abx500_set_register_interruptible(dev,
1699 AB8500_REGU_CTRL1, AB8500_SUPPLY_CONTROL_REG,
1700 AB8500_SUPPLY_CONTROL_CONFIG_1);
1701 if (err < 0) {
1702 dev_err(dev, "ab->write fail %d\n", err);
1703 return err;
1704 }
1705
1706 seq_printf(s, " bank 0x%02X:\n", bank);
1707
1708 if (is_ab9540(ab8500) || is_ab8505(ab8500))
1709 last_sim_reg = AB8505_LAST_SIM_REG;
1710
1711 for (reg = AB8500_FIRST_SIM_REG; reg <= last_sim_reg; reg++) {
1712 err = abx500_get_register_interruptible(dev,
1713 bank, reg, &value);
1714 if (err < 0) {
1715 dev_err(dev, "ab->read fail %d\n", err);
1716 return err;
1717 }
Joe Perches9a503a72015-02-21 18:53:43 -08001718 seq_printf(s, " [0x%02X/0x%02X]: 0x%02X\n", bank, reg, value);
Lee Jonesc7ebaee2013-02-26 14:03:33 +00001719 }
1720 err = abx500_set_register_interruptible(dev,
1721 AB8500_REGU_CTRL1, AB8500_SUPPLY_CONTROL_REG, orig_value);
1722 if (err < 0) {
1723 dev_err(dev, "ab->write fail %d\n", err);
1724 return err;
1725 }
1726 return 0;
1727}
1728
1729static int ab8500_modem_open(struct inode *inode, struct file *file)
1730{
Lee Jones43621752014-07-14 18:29:16 +01001731 return single_open(file, ab8500_print_modem_registers,
1732 inode->i_private);
Lee Jonesc7ebaee2013-02-26 14:03:33 +00001733}
1734
1735static const struct file_operations ab8500_modem_fops = {
1736 .open = ab8500_modem_open,
1737 .read = seq_read,
1738 .llseek = seq_lseek,
1739 .release = single_release,
1740 .owner = THIS_MODULE,
1741};
1742
John Beckett1478a312011-05-31 13:54:27 +01001743static int ab8500_gpadc_bat_ctrl_print(struct seq_file *s, void *p)
1744{
1745 int bat_ctrl_raw;
1746 int bat_ctrl_convert;
1747 struct ab8500_gpadc *gpadc;
1748
Philippe Langlais8908c042012-04-18 15:52:59 +02001749 gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
Lee Jones73482342013-02-26 10:06:55 +00001750 bat_ctrl_raw = ab8500_gpadc_read_raw(gpadc, BAT_CTRL,
1751 avg_sample, trig_edge, trig_timer, conv_type);
John Beckett1478a312011-05-31 13:54:27 +01001752 bat_ctrl_convert = ab8500_gpadc_ad_to_voltage(gpadc,
Lee Jones73482342013-02-26 10:06:55 +00001753 BAT_CTRL, bat_ctrl_raw);
John Beckett1478a312011-05-31 13:54:27 +01001754
Joe Perches9a503a72015-02-21 18:53:43 -08001755 seq_printf(s, "%d,0x%X\n", bat_ctrl_convert, bat_ctrl_raw);
1756
1757 return 0;
John Beckett1478a312011-05-31 13:54:27 +01001758}
1759
1760static int ab8500_gpadc_bat_ctrl_open(struct inode *inode, struct file *file)
1761{
Lee Jones43621752014-07-14 18:29:16 +01001762 return single_open(file, ab8500_gpadc_bat_ctrl_print,
1763 inode->i_private);
John Beckett1478a312011-05-31 13:54:27 +01001764}
1765
1766static const struct file_operations ab8500_gpadc_bat_ctrl_fops = {
1767 .open = ab8500_gpadc_bat_ctrl_open,
1768 .read = seq_read,
1769 .llseek = seq_lseek,
1770 .release = single_release,
1771 .owner = THIS_MODULE,
1772};
1773
1774static int ab8500_gpadc_btemp_ball_print(struct seq_file *s, void *p)
1775{
1776 int btemp_ball_raw;
1777 int btemp_ball_convert;
1778 struct ab8500_gpadc *gpadc;
1779
Philippe Langlais8908c042012-04-18 15:52:59 +02001780 gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
Lee Jones73482342013-02-26 10:06:55 +00001781 btemp_ball_raw = ab8500_gpadc_read_raw(gpadc, BTEMP_BALL,
1782 avg_sample, trig_edge, trig_timer, conv_type);
John Beckett1478a312011-05-31 13:54:27 +01001783 btemp_ball_convert = ab8500_gpadc_ad_to_voltage(gpadc, BTEMP_BALL,
Lee Jones73482342013-02-26 10:06:55 +00001784 btemp_ball_raw);
John Beckett1478a312011-05-31 13:54:27 +01001785
Joe Perches9a503a72015-02-21 18:53:43 -08001786 seq_printf(s, "%d,0x%X\n", btemp_ball_convert, btemp_ball_raw);
1787
1788 return 0;
John Beckett1478a312011-05-31 13:54:27 +01001789}
1790
1791static int ab8500_gpadc_btemp_ball_open(struct inode *inode,
Lee Jones9f9ba152013-02-26 12:05:15 +00001792 struct file *file)
John Beckett1478a312011-05-31 13:54:27 +01001793{
Lee Jones43621752014-07-14 18:29:16 +01001794 return single_open(file, ab8500_gpadc_btemp_ball_print,
1795 inode->i_private);
John Beckett1478a312011-05-31 13:54:27 +01001796}
1797
1798static const struct file_operations ab8500_gpadc_btemp_ball_fops = {
1799 .open = ab8500_gpadc_btemp_ball_open,
1800 .read = seq_read,
1801 .llseek = seq_lseek,
1802 .release = single_release,
1803 .owner = THIS_MODULE,
1804};
1805
1806static int ab8500_gpadc_main_charger_v_print(struct seq_file *s, void *p)
1807{
1808 int main_charger_v_raw;
1809 int main_charger_v_convert;
1810 struct ab8500_gpadc *gpadc;
1811
Philippe Langlais8908c042012-04-18 15:52:59 +02001812 gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
Lee Jones73482342013-02-26 10:06:55 +00001813 main_charger_v_raw = ab8500_gpadc_read_raw(gpadc, MAIN_CHARGER_V,
1814 avg_sample, trig_edge, trig_timer, conv_type);
John Beckett1478a312011-05-31 13:54:27 +01001815 main_charger_v_convert = ab8500_gpadc_ad_to_voltage(gpadc,
Lee Jones73482342013-02-26 10:06:55 +00001816 MAIN_CHARGER_V, main_charger_v_raw);
John Beckett1478a312011-05-31 13:54:27 +01001817
Joe Perches9a503a72015-02-21 18:53:43 -08001818 seq_printf(s, "%d,0x%X\n", main_charger_v_convert, main_charger_v_raw);
1819
1820 return 0;
John Beckett1478a312011-05-31 13:54:27 +01001821}
1822
1823static int ab8500_gpadc_main_charger_v_open(struct inode *inode,
Lee Jones9f9ba152013-02-26 12:05:15 +00001824 struct file *file)
John Beckett1478a312011-05-31 13:54:27 +01001825{
1826 return single_open(file, ab8500_gpadc_main_charger_v_print,
Lee Jones9f9ba152013-02-26 12:05:15 +00001827 inode->i_private);
John Beckett1478a312011-05-31 13:54:27 +01001828}
1829
1830static const struct file_operations ab8500_gpadc_main_charger_v_fops = {
1831 .open = ab8500_gpadc_main_charger_v_open,
1832 .read = seq_read,
1833 .llseek = seq_lseek,
1834 .release = single_release,
1835 .owner = THIS_MODULE,
1836};
1837
1838static int ab8500_gpadc_acc_detect1_print(struct seq_file *s, void *p)
1839{
1840 int acc_detect1_raw;
1841 int acc_detect1_convert;
1842 struct ab8500_gpadc *gpadc;
1843
Philippe Langlais8908c042012-04-18 15:52:59 +02001844 gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
Lee Jones73482342013-02-26 10:06:55 +00001845 acc_detect1_raw = ab8500_gpadc_read_raw(gpadc, ACC_DETECT1,
1846 avg_sample, trig_edge, trig_timer, conv_type);
John Beckett1478a312011-05-31 13:54:27 +01001847 acc_detect1_convert = ab8500_gpadc_ad_to_voltage(gpadc, ACC_DETECT1,
Lee Jones73482342013-02-26 10:06:55 +00001848 acc_detect1_raw);
John Beckett1478a312011-05-31 13:54:27 +01001849
Joe Perches9a503a72015-02-21 18:53:43 -08001850 seq_printf(s, "%d,0x%X\n", acc_detect1_convert, acc_detect1_raw);
1851
1852 return 0;
John Beckett1478a312011-05-31 13:54:27 +01001853}
1854
1855static int ab8500_gpadc_acc_detect1_open(struct inode *inode,
Lee Jones9f9ba152013-02-26 12:05:15 +00001856 struct file *file)
John Beckett1478a312011-05-31 13:54:27 +01001857{
1858 return single_open(file, ab8500_gpadc_acc_detect1_print,
Lee Jones9f9ba152013-02-26 12:05:15 +00001859 inode->i_private);
John Beckett1478a312011-05-31 13:54:27 +01001860}
1861
1862static const struct file_operations ab8500_gpadc_acc_detect1_fops = {
1863 .open = ab8500_gpadc_acc_detect1_open,
1864 .read = seq_read,
1865 .llseek = seq_lseek,
1866 .release = single_release,
1867 .owner = THIS_MODULE,
1868};
1869
1870static int ab8500_gpadc_acc_detect2_print(struct seq_file *s, void *p)
1871{
1872 int acc_detect2_raw;
1873 int acc_detect2_convert;
1874 struct ab8500_gpadc *gpadc;
1875
Philippe Langlais8908c042012-04-18 15:52:59 +02001876 gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
Lee Jones73482342013-02-26 10:06:55 +00001877 acc_detect2_raw = ab8500_gpadc_read_raw(gpadc, ACC_DETECT2,
1878 avg_sample, trig_edge, trig_timer, conv_type);
John Beckett1478a312011-05-31 13:54:27 +01001879 acc_detect2_convert = ab8500_gpadc_ad_to_voltage(gpadc,
Lee Jones73482342013-02-26 10:06:55 +00001880 ACC_DETECT2, acc_detect2_raw);
John Beckett1478a312011-05-31 13:54:27 +01001881
Joe Perches9a503a72015-02-21 18:53:43 -08001882 seq_printf(s, "%d,0x%X\n", acc_detect2_convert, acc_detect2_raw);
1883
1884 return 0;
John Beckett1478a312011-05-31 13:54:27 +01001885}
1886
1887static int ab8500_gpadc_acc_detect2_open(struct inode *inode,
1888 struct file *file)
1889{
1890 return single_open(file, ab8500_gpadc_acc_detect2_print,
Lee Jones9f9ba152013-02-26 12:05:15 +00001891 inode->i_private);
John Beckett1478a312011-05-31 13:54:27 +01001892}
1893
1894static const struct file_operations ab8500_gpadc_acc_detect2_fops = {
1895 .open = ab8500_gpadc_acc_detect2_open,
1896 .read = seq_read,
1897 .llseek = seq_lseek,
1898 .release = single_release,
1899 .owner = THIS_MODULE,
1900};
1901
1902static int ab8500_gpadc_aux1_print(struct seq_file *s, void *p)
1903{
1904 int aux1_raw;
1905 int aux1_convert;
1906 struct ab8500_gpadc *gpadc;
1907
Philippe Langlais8908c042012-04-18 15:52:59 +02001908 gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
Lee Jones73482342013-02-26 10:06:55 +00001909 aux1_raw = ab8500_gpadc_read_raw(gpadc, ADC_AUX1,
1910 avg_sample, trig_edge, trig_timer, conv_type);
John Beckett1478a312011-05-31 13:54:27 +01001911 aux1_convert = ab8500_gpadc_ad_to_voltage(gpadc, ADC_AUX1,
Lee Jones73482342013-02-26 10:06:55 +00001912 aux1_raw);
John Beckett1478a312011-05-31 13:54:27 +01001913
Joe Perches9a503a72015-02-21 18:53:43 -08001914 seq_printf(s, "%d,0x%X\n", aux1_convert, aux1_raw);
1915
1916 return 0;
John Beckett1478a312011-05-31 13:54:27 +01001917}
1918
1919static int ab8500_gpadc_aux1_open(struct inode *inode, struct file *file)
1920{
1921 return single_open(file, ab8500_gpadc_aux1_print, inode->i_private);
1922}
1923
1924static const struct file_operations ab8500_gpadc_aux1_fops = {
1925 .open = ab8500_gpadc_aux1_open,
1926 .read = seq_read,
1927 .llseek = seq_lseek,
1928 .release = single_release,
1929 .owner = THIS_MODULE,
1930};
1931
1932static int ab8500_gpadc_aux2_print(struct seq_file *s, void *p)
1933{
1934 int aux2_raw;
1935 int aux2_convert;
1936 struct ab8500_gpadc *gpadc;
1937
Philippe Langlais8908c042012-04-18 15:52:59 +02001938 gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
Lee Jones73482342013-02-26 10:06:55 +00001939 aux2_raw = ab8500_gpadc_read_raw(gpadc, ADC_AUX2,
1940 avg_sample, trig_edge, trig_timer, conv_type);
John Beckett1478a312011-05-31 13:54:27 +01001941 aux2_convert = ab8500_gpadc_ad_to_voltage(gpadc, ADC_AUX2,
Lee Jones73482342013-02-26 10:06:55 +00001942 aux2_raw);
John Beckett1478a312011-05-31 13:54:27 +01001943
Joe Perches9a503a72015-02-21 18:53:43 -08001944 seq_printf(s, "%d,0x%X\n", aux2_convert, aux2_raw);
1945
1946 return 0;
John Beckett1478a312011-05-31 13:54:27 +01001947}
1948
1949static int ab8500_gpadc_aux2_open(struct inode *inode, struct file *file)
1950{
1951 return single_open(file, ab8500_gpadc_aux2_print, inode->i_private);
1952}
1953
1954static const struct file_operations ab8500_gpadc_aux2_fops = {
1955 .open = ab8500_gpadc_aux2_open,
1956 .read = seq_read,
1957 .llseek = seq_lseek,
1958 .release = single_release,
1959 .owner = THIS_MODULE,
1960};
1961
1962static int ab8500_gpadc_main_bat_v_print(struct seq_file *s, void *p)
1963{
1964 int main_bat_v_raw;
1965 int main_bat_v_convert;
1966 struct ab8500_gpadc *gpadc;
1967
Philippe Langlais8908c042012-04-18 15:52:59 +02001968 gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
Lee Jones73482342013-02-26 10:06:55 +00001969 main_bat_v_raw = ab8500_gpadc_read_raw(gpadc, MAIN_BAT_V,
1970 avg_sample, trig_edge, trig_timer, conv_type);
John Beckett1478a312011-05-31 13:54:27 +01001971 main_bat_v_convert = ab8500_gpadc_ad_to_voltage(gpadc, MAIN_BAT_V,
Lee Jones73482342013-02-26 10:06:55 +00001972 main_bat_v_raw);
John Beckett1478a312011-05-31 13:54:27 +01001973
Joe Perches9a503a72015-02-21 18:53:43 -08001974 seq_printf(s, "%d,0x%X\n", main_bat_v_convert, main_bat_v_raw);
1975
1976 return 0;
John Beckett1478a312011-05-31 13:54:27 +01001977}
1978
1979static int ab8500_gpadc_main_bat_v_open(struct inode *inode,
Lee Jones9f9ba152013-02-26 12:05:15 +00001980 struct file *file)
John Beckett1478a312011-05-31 13:54:27 +01001981{
Lee Jones43621752014-07-14 18:29:16 +01001982 return single_open(file, ab8500_gpadc_main_bat_v_print,
1983 inode->i_private);
John Beckett1478a312011-05-31 13:54:27 +01001984}
1985
1986static const struct file_operations ab8500_gpadc_main_bat_v_fops = {
1987 .open = ab8500_gpadc_main_bat_v_open,
1988 .read = seq_read,
1989 .llseek = seq_lseek,
1990 .release = single_release,
1991 .owner = THIS_MODULE,
1992};
1993
1994static int ab8500_gpadc_vbus_v_print(struct seq_file *s, void *p)
1995{
1996 int vbus_v_raw;
1997 int vbus_v_convert;
1998 struct ab8500_gpadc *gpadc;
1999
Philippe Langlais8908c042012-04-18 15:52:59 +02002000 gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
Lee Jones73482342013-02-26 10:06:55 +00002001 vbus_v_raw = ab8500_gpadc_read_raw(gpadc, VBUS_V,
2002 avg_sample, trig_edge, trig_timer, conv_type);
John Beckett1478a312011-05-31 13:54:27 +01002003 vbus_v_convert = ab8500_gpadc_ad_to_voltage(gpadc, VBUS_V,
Lee Jones73482342013-02-26 10:06:55 +00002004 vbus_v_raw);
John Beckett1478a312011-05-31 13:54:27 +01002005
Joe Perches9a503a72015-02-21 18:53:43 -08002006 seq_printf(s, "%d,0x%X\n", vbus_v_convert, vbus_v_raw);
2007
2008 return 0;
John Beckett1478a312011-05-31 13:54:27 +01002009}
2010
2011static int ab8500_gpadc_vbus_v_open(struct inode *inode, struct file *file)
2012{
2013 return single_open(file, ab8500_gpadc_vbus_v_print, inode->i_private);
2014}
2015
2016static const struct file_operations ab8500_gpadc_vbus_v_fops = {
2017 .open = ab8500_gpadc_vbus_v_open,
2018 .read = seq_read,
2019 .llseek = seq_lseek,
2020 .release = single_release,
2021 .owner = THIS_MODULE,
2022};
2023
2024static int ab8500_gpadc_main_charger_c_print(struct seq_file *s, void *p)
2025{
2026 int main_charger_c_raw;
2027 int main_charger_c_convert;
2028 struct ab8500_gpadc *gpadc;
2029
Philippe Langlais8908c042012-04-18 15:52:59 +02002030 gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
Lee Jones73482342013-02-26 10:06:55 +00002031 main_charger_c_raw = ab8500_gpadc_read_raw(gpadc, MAIN_CHARGER_C,
2032 avg_sample, trig_edge, trig_timer, conv_type);
John Beckett1478a312011-05-31 13:54:27 +01002033 main_charger_c_convert = ab8500_gpadc_ad_to_voltage(gpadc,
Lee Jones73482342013-02-26 10:06:55 +00002034 MAIN_CHARGER_C, main_charger_c_raw);
John Beckett1478a312011-05-31 13:54:27 +01002035
Joe Perches9a503a72015-02-21 18:53:43 -08002036 seq_printf(s, "%d,0x%X\n", main_charger_c_convert, main_charger_c_raw);
2037
2038 return 0;
John Beckett1478a312011-05-31 13:54:27 +01002039}
2040
2041static int ab8500_gpadc_main_charger_c_open(struct inode *inode,
2042 struct file *file)
2043{
2044 return single_open(file, ab8500_gpadc_main_charger_c_print,
Lee Jones9f9ba152013-02-26 12:05:15 +00002045 inode->i_private);
John Beckett1478a312011-05-31 13:54:27 +01002046}
2047
2048static const struct file_operations ab8500_gpadc_main_charger_c_fops = {
2049 .open = ab8500_gpadc_main_charger_c_open,
2050 .read = seq_read,
2051 .llseek = seq_lseek,
2052 .release = single_release,
2053 .owner = THIS_MODULE,
2054};
2055
2056static int ab8500_gpadc_usb_charger_c_print(struct seq_file *s, void *p)
2057{
2058 int usb_charger_c_raw;
2059 int usb_charger_c_convert;
2060 struct ab8500_gpadc *gpadc;
2061
Philippe Langlais8908c042012-04-18 15:52:59 +02002062 gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
Lee Jones73482342013-02-26 10:06:55 +00002063 usb_charger_c_raw = ab8500_gpadc_read_raw(gpadc, USB_CHARGER_C,
2064 avg_sample, trig_edge, trig_timer, conv_type);
John Beckett1478a312011-05-31 13:54:27 +01002065 usb_charger_c_convert = ab8500_gpadc_ad_to_voltage(gpadc,
Lee Jones73482342013-02-26 10:06:55 +00002066 USB_CHARGER_C, usb_charger_c_raw);
John Beckett1478a312011-05-31 13:54:27 +01002067
Joe Perches9a503a72015-02-21 18:53:43 -08002068 seq_printf(s, "%d,0x%X\n", usb_charger_c_convert, usb_charger_c_raw);
2069
2070 return 0;
John Beckett1478a312011-05-31 13:54:27 +01002071}
2072
2073static int ab8500_gpadc_usb_charger_c_open(struct inode *inode,
2074 struct file *file)
2075{
2076 return single_open(file, ab8500_gpadc_usb_charger_c_print,
Lee Jones9f9ba152013-02-26 12:05:15 +00002077 inode->i_private);
John Beckett1478a312011-05-31 13:54:27 +01002078}
2079
2080static const struct file_operations ab8500_gpadc_usb_charger_c_fops = {
2081 .open = ab8500_gpadc_usb_charger_c_open,
2082 .read = seq_read,
2083 .llseek = seq_lseek,
2084 .release = single_release,
2085 .owner = THIS_MODULE,
2086};
2087
2088static int ab8500_gpadc_bk_bat_v_print(struct seq_file *s, void *p)
2089{
2090 int bk_bat_v_raw;
2091 int bk_bat_v_convert;
2092 struct ab8500_gpadc *gpadc;
2093
Philippe Langlais8908c042012-04-18 15:52:59 +02002094 gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
Lee Jones73482342013-02-26 10:06:55 +00002095 bk_bat_v_raw = ab8500_gpadc_read_raw(gpadc, BK_BAT_V,
2096 avg_sample, trig_edge, trig_timer, conv_type);
John Beckett1478a312011-05-31 13:54:27 +01002097 bk_bat_v_convert = ab8500_gpadc_ad_to_voltage(gpadc,
Lee Jones73482342013-02-26 10:06:55 +00002098 BK_BAT_V, bk_bat_v_raw);
John Beckett1478a312011-05-31 13:54:27 +01002099
Joe Perches9a503a72015-02-21 18:53:43 -08002100 seq_printf(s, "%d,0x%X\n", bk_bat_v_convert, bk_bat_v_raw);
2101
2102 return 0;
John Beckett1478a312011-05-31 13:54:27 +01002103}
2104
2105static int ab8500_gpadc_bk_bat_v_open(struct inode *inode, struct file *file)
2106{
Lee Jones43621752014-07-14 18:29:16 +01002107 return single_open(file, ab8500_gpadc_bk_bat_v_print,
2108 inode->i_private);
John Beckett1478a312011-05-31 13:54:27 +01002109}
2110
2111static const struct file_operations ab8500_gpadc_bk_bat_v_fops = {
2112 .open = ab8500_gpadc_bk_bat_v_open,
2113 .read = seq_read,
2114 .llseek = seq_lseek,
2115 .release = single_release,
2116 .owner = THIS_MODULE,
2117};
2118
2119static int ab8500_gpadc_die_temp_print(struct seq_file *s, void *p)
2120{
2121 int die_temp_raw;
2122 int die_temp_convert;
2123 struct ab8500_gpadc *gpadc;
2124
Philippe Langlais8908c042012-04-18 15:52:59 +02002125 gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
Lee Jones73482342013-02-26 10:06:55 +00002126 die_temp_raw = ab8500_gpadc_read_raw(gpadc, DIE_TEMP,
2127 avg_sample, trig_edge, trig_timer, conv_type);
John Beckett1478a312011-05-31 13:54:27 +01002128 die_temp_convert = ab8500_gpadc_ad_to_voltage(gpadc, DIE_TEMP,
Lee Jones73482342013-02-26 10:06:55 +00002129 die_temp_raw);
John Beckett1478a312011-05-31 13:54:27 +01002130
Joe Perches9a503a72015-02-21 18:53:43 -08002131 seq_printf(s, "%d,0x%X\n", die_temp_convert, die_temp_raw);
2132
2133 return 0;
John Beckett1478a312011-05-31 13:54:27 +01002134}
2135
2136static int ab8500_gpadc_die_temp_open(struct inode *inode, struct file *file)
2137{
Lee Jones43621752014-07-14 18:29:16 +01002138 return single_open(file, ab8500_gpadc_die_temp_print,
2139 inode->i_private);
John Beckett1478a312011-05-31 13:54:27 +01002140}
2141
2142static const struct file_operations ab8500_gpadc_die_temp_fops = {
2143 .open = ab8500_gpadc_die_temp_open,
2144 .read = seq_read,
2145 .llseek = seq_lseek,
2146 .release = single_release,
2147 .owner = THIS_MODULE,
2148};
2149
Lee Jones127629d2013-02-26 14:04:37 +00002150static int ab8500_gpadc_usb_id_print(struct seq_file *s, void *p)
2151{
2152 int usb_id_raw;
2153 int usb_id_convert;
2154 struct ab8500_gpadc *gpadc;
2155
2156 gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
2157 usb_id_raw = ab8500_gpadc_read_raw(gpadc, USB_ID,
2158 avg_sample, trig_edge, trig_timer, conv_type);
2159 usb_id_convert = ab8500_gpadc_ad_to_voltage(gpadc, USB_ID,
2160 usb_id_raw);
2161
Joe Perches9a503a72015-02-21 18:53:43 -08002162 seq_printf(s, "%d,0x%X\n", usb_id_convert, usb_id_raw);
2163
2164 return 0;
Lee Jones127629d2013-02-26 14:04:37 +00002165}
2166
2167static int ab8500_gpadc_usb_id_open(struct inode *inode, struct file *file)
2168{
2169 return single_open(file, ab8500_gpadc_usb_id_print, inode->i_private);
2170}
2171
2172static const struct file_operations ab8500_gpadc_usb_id_fops = {
2173 .open = ab8500_gpadc_usb_id_open,
2174 .read = seq_read,
2175 .llseek = seq_lseek,
2176 .release = single_release,
2177 .owner = THIS_MODULE,
2178};
2179
Lee Jonesbc6b4132013-02-26 14:02:31 +00002180static int ab8540_gpadc_xtal_temp_print(struct seq_file *s, void *p)
2181{
2182 int xtal_temp_raw;
2183 int xtal_temp_convert;
2184 struct ab8500_gpadc *gpadc;
2185
2186 gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
2187 xtal_temp_raw = ab8500_gpadc_read_raw(gpadc, XTAL_TEMP,
2188 avg_sample, trig_edge, trig_timer, conv_type);
2189 xtal_temp_convert = ab8500_gpadc_ad_to_voltage(gpadc, XTAL_TEMP,
2190 xtal_temp_raw);
2191
Joe Perches9a503a72015-02-21 18:53:43 -08002192 seq_printf(s, "%d,0x%X\n", xtal_temp_convert, xtal_temp_raw);
2193
2194 return 0;
Lee Jonesbc6b4132013-02-26 14:02:31 +00002195}
2196
2197static int ab8540_gpadc_xtal_temp_open(struct inode *inode, struct file *file)
2198{
2199 return single_open(file, ab8540_gpadc_xtal_temp_print,
Lee Jones9f9ba152013-02-26 12:05:15 +00002200 inode->i_private);
Lee Jonesbc6b4132013-02-26 14:02:31 +00002201}
2202
2203static const struct file_operations ab8540_gpadc_xtal_temp_fops = {
2204 .open = ab8540_gpadc_xtal_temp_open,
2205 .read = seq_read,
2206 .llseek = seq_lseek,
2207 .release = single_release,
2208 .owner = THIS_MODULE,
2209};
2210
2211static int ab8540_gpadc_vbat_true_meas_print(struct seq_file *s, void *p)
2212{
2213 int vbat_true_meas_raw;
2214 int vbat_true_meas_convert;
2215 struct ab8500_gpadc *gpadc;
2216
2217 gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
2218 vbat_true_meas_raw = ab8500_gpadc_read_raw(gpadc, VBAT_TRUE_MEAS,
2219 avg_sample, trig_edge, trig_timer, conv_type);
Lee Jones43621752014-07-14 18:29:16 +01002220 vbat_true_meas_convert =
2221 ab8500_gpadc_ad_to_voltage(gpadc, VBAT_TRUE_MEAS,
2222 vbat_true_meas_raw);
Lee Jonesbc6b4132013-02-26 14:02:31 +00002223
Joe Perches9a503a72015-02-21 18:53:43 -08002224 seq_printf(s, "%d,0x%X\n", vbat_true_meas_convert, vbat_true_meas_raw);
2225
2226 return 0;
Lee Jonesbc6b4132013-02-26 14:02:31 +00002227}
2228
2229static int ab8540_gpadc_vbat_true_meas_open(struct inode *inode,
2230 struct file *file)
2231{
2232 return single_open(file, ab8540_gpadc_vbat_true_meas_print,
Lee Jones9f9ba152013-02-26 12:05:15 +00002233 inode->i_private);
Lee Jonesbc6b4132013-02-26 14:02:31 +00002234}
2235
2236static const struct file_operations ab8540_gpadc_vbat_true_meas_fops = {
2237 .open = ab8540_gpadc_vbat_true_meas_open,
2238 .read = seq_read,
2239 .llseek = seq_lseek,
2240 .release = single_release,
2241 .owner = THIS_MODULE,
2242};
2243
2244static int ab8540_gpadc_bat_ctrl_and_ibat_print(struct seq_file *s, void *p)
2245{
2246 int bat_ctrl_raw;
2247 int bat_ctrl_convert;
2248 int ibat_raw;
2249 int ibat_convert;
2250 struct ab8500_gpadc *gpadc;
2251
2252 gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
2253 bat_ctrl_raw = ab8500_gpadc_double_read_raw(gpadc, BAT_CTRL_AND_IBAT,
2254 avg_sample, trig_edge, trig_timer, conv_type, &ibat_raw);
2255
2256 bat_ctrl_convert = ab8500_gpadc_ad_to_voltage(gpadc, BAT_CTRL,
2257 bat_ctrl_raw);
2258 ibat_convert = ab8500_gpadc_ad_to_voltage(gpadc, IBAT_VIRTUAL_CHANNEL,
2259 ibat_raw);
2260
Joe Perches9a503a72015-02-21 18:53:43 -08002261 seq_printf(s,
2262 "%d,0x%X\n"
2263 "%d,0x%X\n",
2264 bat_ctrl_convert, bat_ctrl_raw,
2265 ibat_convert, ibat_raw);
2266
2267 return 0;
Lee Jonesbc6b4132013-02-26 14:02:31 +00002268}
2269
2270static int ab8540_gpadc_bat_ctrl_and_ibat_open(struct inode *inode,
2271 struct file *file)
2272{
2273 return single_open(file, ab8540_gpadc_bat_ctrl_and_ibat_print,
Lee Jones9f9ba152013-02-26 12:05:15 +00002274 inode->i_private);
Lee Jonesbc6b4132013-02-26 14:02:31 +00002275}
2276
2277static const struct file_operations ab8540_gpadc_bat_ctrl_and_ibat_fops = {
2278 .open = ab8540_gpadc_bat_ctrl_and_ibat_open,
2279 .read = seq_read,
2280 .llseek = seq_lseek,
2281 .release = single_release,
2282 .owner = THIS_MODULE,
2283};
2284
2285static int ab8540_gpadc_vbat_meas_and_ibat_print(struct seq_file *s, void *p)
2286{
2287 int vbat_meas_raw;
2288 int vbat_meas_convert;
2289 int ibat_raw;
2290 int ibat_convert;
2291 struct ab8500_gpadc *gpadc;
2292
2293 gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
2294 vbat_meas_raw = ab8500_gpadc_double_read_raw(gpadc, VBAT_MEAS_AND_IBAT,
2295 avg_sample, trig_edge, trig_timer, conv_type, &ibat_raw);
2296 vbat_meas_convert = ab8500_gpadc_ad_to_voltage(gpadc, MAIN_BAT_V,
2297 vbat_meas_raw);
2298 ibat_convert = ab8500_gpadc_ad_to_voltage(gpadc, IBAT_VIRTUAL_CHANNEL,
2299 ibat_raw);
2300
Joe Perches9a503a72015-02-21 18:53:43 -08002301 seq_printf(s,
2302 "%d,0x%X\n"
2303 "%d,0x%X\n",
2304 vbat_meas_convert, vbat_meas_raw,
2305 ibat_convert, ibat_raw);
2306
2307 return 0;
Lee Jonesbc6b4132013-02-26 14:02:31 +00002308}
2309
2310static int ab8540_gpadc_vbat_meas_and_ibat_open(struct inode *inode,
2311 struct file *file)
2312{
2313 return single_open(file, ab8540_gpadc_vbat_meas_and_ibat_print,
Lee Jones9f9ba152013-02-26 12:05:15 +00002314 inode->i_private);
Lee Jonesbc6b4132013-02-26 14:02:31 +00002315}
2316
2317static const struct file_operations ab8540_gpadc_vbat_meas_and_ibat_fops = {
2318 .open = ab8540_gpadc_vbat_meas_and_ibat_open,
2319 .read = seq_read,
2320 .llseek = seq_lseek,
2321 .release = single_release,
2322 .owner = THIS_MODULE,
2323};
2324
Lee Jones43621752014-07-14 18:29:16 +01002325static int ab8540_gpadc_vbat_true_meas_and_ibat_print(struct seq_file *s,
2326 void *p)
Lee Jonesbc6b4132013-02-26 14:02:31 +00002327{
2328 int vbat_true_meas_raw;
2329 int vbat_true_meas_convert;
2330 int ibat_raw;
2331 int ibat_convert;
2332 struct ab8500_gpadc *gpadc;
2333
2334 gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
2335 vbat_true_meas_raw = ab8500_gpadc_double_read_raw(gpadc,
2336 VBAT_TRUE_MEAS_AND_IBAT, avg_sample, trig_edge,
2337 trig_timer, conv_type, &ibat_raw);
2338 vbat_true_meas_convert = ab8500_gpadc_ad_to_voltage(gpadc,
2339 VBAT_TRUE_MEAS, vbat_true_meas_raw);
2340 ibat_convert = ab8500_gpadc_ad_to_voltage(gpadc, IBAT_VIRTUAL_CHANNEL,
2341 ibat_raw);
2342
Joe Perches9a503a72015-02-21 18:53:43 -08002343 seq_printf(s,
2344 "%d,0x%X\n"
2345 "%d,0x%X\n",
2346 vbat_true_meas_convert, vbat_true_meas_raw,
2347 ibat_convert, ibat_raw);
2348
2349 return 0;
Lee Jonesbc6b4132013-02-26 14:02:31 +00002350}
2351
2352static int ab8540_gpadc_vbat_true_meas_and_ibat_open(struct inode *inode,
2353 struct file *file)
2354{
2355 return single_open(file, ab8540_gpadc_vbat_true_meas_and_ibat_print,
Lee Jones9f9ba152013-02-26 12:05:15 +00002356 inode->i_private);
Lee Jonesbc6b4132013-02-26 14:02:31 +00002357}
2358
Lee Jones43621752014-07-14 18:29:16 +01002359static const struct file_operations
2360ab8540_gpadc_vbat_true_meas_and_ibat_fops = {
Lee Jonesbc6b4132013-02-26 14:02:31 +00002361 .open = ab8540_gpadc_vbat_true_meas_and_ibat_open,
2362 .read = seq_read,
2363 .llseek = seq_lseek,
2364 .release = single_release,
2365 .owner = THIS_MODULE,
2366};
2367
2368static int ab8540_gpadc_bat_temp_and_ibat_print(struct seq_file *s, void *p)
2369{
2370 int bat_temp_raw;
2371 int bat_temp_convert;
2372 int ibat_raw;
2373 int ibat_convert;
2374 struct ab8500_gpadc *gpadc;
2375
2376 gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
2377 bat_temp_raw = ab8500_gpadc_double_read_raw(gpadc, BAT_TEMP_AND_IBAT,
2378 avg_sample, trig_edge, trig_timer, conv_type, &ibat_raw);
2379 bat_temp_convert = ab8500_gpadc_ad_to_voltage(gpadc, BTEMP_BALL,
2380 bat_temp_raw);
2381 ibat_convert = ab8500_gpadc_ad_to_voltage(gpadc, IBAT_VIRTUAL_CHANNEL,
2382 ibat_raw);
2383
Joe Perches9a503a72015-02-21 18:53:43 -08002384 seq_printf(s,
2385 "%d,0x%X\n"
2386 "%d,0x%X\n",
2387 bat_temp_convert, bat_temp_raw,
2388 ibat_convert, ibat_raw);
2389
2390 return 0;
Lee Jonesbc6b4132013-02-26 14:02:31 +00002391}
2392
2393static int ab8540_gpadc_bat_temp_and_ibat_open(struct inode *inode,
2394 struct file *file)
2395{
2396 return single_open(file, ab8540_gpadc_bat_temp_and_ibat_print,
Lee Jones9f9ba152013-02-26 12:05:15 +00002397 inode->i_private);
Lee Jonesbc6b4132013-02-26 14:02:31 +00002398}
2399
2400static const struct file_operations ab8540_gpadc_bat_temp_and_ibat_fops = {
2401 .open = ab8540_gpadc_bat_temp_and_ibat_open,
2402 .read = seq_read,
2403 .llseek = seq_lseek,
2404 .release = single_release,
2405 .owner = THIS_MODULE,
2406};
2407
2408static int ab8540_gpadc_otp_cal_print(struct seq_file *s, void *p)
2409{
2410 struct ab8500_gpadc *gpadc;
2411 u16 vmain_l, vmain_h, btemp_l, btemp_h;
2412 u16 vbat_l, vbat_h, ibat_l, ibat_h;
2413
2414 gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
2415 ab8540_gpadc_get_otp(gpadc, &vmain_l, &vmain_h, &btemp_l, &btemp_h,
2416 &vbat_l, &vbat_h, &ibat_l, &ibat_h);
Joe Perches9a503a72015-02-21 18:53:43 -08002417 seq_printf(s,
2418 "VMAIN_L:0x%X\n"
2419 "VMAIN_H:0x%X\n"
2420 "BTEMP_L:0x%X\n"
2421 "BTEMP_H:0x%X\n"
2422 "VBAT_L:0x%X\n"
2423 "VBAT_H:0x%X\n"
2424 "IBAT_L:0x%X\n"
2425 "IBAT_H:0x%X\n",
2426 vmain_l, vmain_h, btemp_l, btemp_h,
2427 vbat_l, vbat_h, ibat_l, ibat_h);
2428
2429 return 0;
Lee Jonesbc6b4132013-02-26 14:02:31 +00002430}
2431
2432static int ab8540_gpadc_otp_cal_open(struct inode *inode, struct file *file)
2433{
2434 return single_open(file, ab8540_gpadc_otp_cal_print, inode->i_private);
2435}
2436
2437static const struct file_operations ab8540_gpadc_otp_calib_fops = {
2438 .open = ab8540_gpadc_otp_cal_open,
2439 .read = seq_read,
2440 .llseek = seq_lseek,
2441 .release = single_release,
2442 .owner = THIS_MODULE,
2443};
2444
Lee Jones73482342013-02-26 10:06:55 +00002445static int ab8500_gpadc_avg_sample_print(struct seq_file *s, void *p)
2446{
Joe Perches9a503a72015-02-21 18:53:43 -08002447 seq_printf(s, "%d\n", avg_sample);
2448
2449 return 0;
Lee Jones73482342013-02-26 10:06:55 +00002450}
2451
2452static int ab8500_gpadc_avg_sample_open(struct inode *inode, struct file *file)
2453{
2454 return single_open(file, ab8500_gpadc_avg_sample_print,
Lee Jones9f9ba152013-02-26 12:05:15 +00002455 inode->i_private);
Lee Jones73482342013-02-26 10:06:55 +00002456}
2457
2458static ssize_t ab8500_gpadc_avg_sample_write(struct file *file,
2459 const char __user *user_buf,
2460 size_t count, loff_t *ppos)
2461{
2462 struct device *dev = ((struct seq_file *)(file->private_data))->private;
Lee Jones73482342013-02-26 10:06:55 +00002463 unsigned long user_avg_sample;
2464 int err;
2465
srinidhi kasagar7b830ae2012-11-23 15:11:00 +05302466 err = kstrtoul_from_user(user_buf, count, 0, &user_avg_sample);
Lee Jones73482342013-02-26 10:06:55 +00002467 if (err)
srinidhi kasagar7b830ae2012-11-23 15:11:00 +05302468 return err;
2469
Lee Jones73482342013-02-26 10:06:55 +00002470 if ((user_avg_sample == SAMPLE_1) || (user_avg_sample == SAMPLE_4)
2471 || (user_avg_sample == SAMPLE_8)
2472 || (user_avg_sample == SAMPLE_16)) {
2473 avg_sample = (u8) user_avg_sample;
2474 } else {
Lee Jones43621752014-07-14 18:29:16 +01002475 dev_err(dev,
2476 "debugfs err input: should be egal to 1, 4, 8 or 16\n");
Lee Jones73482342013-02-26 10:06:55 +00002477 return -EINVAL;
2478 }
srinidhi kasagar7b830ae2012-11-23 15:11:00 +05302479
2480 return count;
Lee Jones73482342013-02-26 10:06:55 +00002481}
2482
2483static const struct file_operations ab8500_gpadc_avg_sample_fops = {
2484 .open = ab8500_gpadc_avg_sample_open,
2485 .read = seq_read,
2486 .write = ab8500_gpadc_avg_sample_write,
2487 .llseek = seq_lseek,
2488 .release = single_release,
2489 .owner = THIS_MODULE,
2490};
2491
2492static int ab8500_gpadc_trig_edge_print(struct seq_file *s, void *p)
2493{
Joe Perches9a503a72015-02-21 18:53:43 -08002494 seq_printf(s, "%d\n", trig_edge);
2495
2496 return 0;
Lee Jones73482342013-02-26 10:06:55 +00002497}
2498
2499static int ab8500_gpadc_trig_edge_open(struct inode *inode, struct file *file)
2500{
2501 return single_open(file, ab8500_gpadc_trig_edge_print,
Lee Jones9f9ba152013-02-26 12:05:15 +00002502 inode->i_private);
Lee Jones73482342013-02-26 10:06:55 +00002503}
2504
2505static ssize_t ab8500_gpadc_trig_edge_write(struct file *file,
2506 const char __user *user_buf,
2507 size_t count, loff_t *ppos)
2508{
2509 struct device *dev = ((struct seq_file *)(file->private_data))->private;
Lee Jones73482342013-02-26 10:06:55 +00002510 unsigned long user_trig_edge;
2511 int err;
2512
srinidhi kasagar7b830ae2012-11-23 15:11:00 +05302513 err = kstrtoul_from_user(user_buf, count, 0, &user_trig_edge);
Lee Jones73482342013-02-26 10:06:55 +00002514 if (err)
srinidhi kasagar7b830ae2012-11-23 15:11:00 +05302515 return err;
2516
Lee Jones73482342013-02-26 10:06:55 +00002517 if ((user_trig_edge == RISING_EDGE)
2518 || (user_trig_edge == FALLING_EDGE)) {
2519 trig_edge = (u8) user_trig_edge;
2520 } else {
2521 dev_err(dev, "Wrong input:\n"
2522 "Enter 0. Rising edge\n"
2523 "Enter 1. Falling edge\n");
2524 return -EINVAL;
2525 }
srinidhi kasagar7b830ae2012-11-23 15:11:00 +05302526
2527 return count;
Lee Jones73482342013-02-26 10:06:55 +00002528}
2529
2530static const struct file_operations ab8500_gpadc_trig_edge_fops = {
2531 .open = ab8500_gpadc_trig_edge_open,
2532 .read = seq_read,
2533 .write = ab8500_gpadc_trig_edge_write,
2534 .llseek = seq_lseek,
2535 .release = single_release,
2536 .owner = THIS_MODULE,
2537};
2538
2539static int ab8500_gpadc_trig_timer_print(struct seq_file *s, void *p)
2540{
Joe Perches9a503a72015-02-21 18:53:43 -08002541 seq_printf(s, "%d\n", trig_timer);
2542
2543 return 0;
Lee Jones73482342013-02-26 10:06:55 +00002544}
2545
2546static int ab8500_gpadc_trig_timer_open(struct inode *inode, struct file *file)
2547{
2548 return single_open(file, ab8500_gpadc_trig_timer_print,
Lee Jones9f9ba152013-02-26 12:05:15 +00002549 inode->i_private);
Lee Jones73482342013-02-26 10:06:55 +00002550}
2551
2552static ssize_t ab8500_gpadc_trig_timer_write(struct file *file,
2553 const char __user *user_buf,
2554 size_t count, loff_t *ppos)
2555{
2556 struct device *dev = ((struct seq_file *)(file->private_data))->private;
Lee Jones73482342013-02-26 10:06:55 +00002557 unsigned long user_trig_timer;
2558 int err;
2559
srinidhi kasagar7b830ae2012-11-23 15:11:00 +05302560 err = kstrtoul_from_user(user_buf, count, 0, &user_trig_timer);
Lee Jones73482342013-02-26 10:06:55 +00002561 if (err)
srinidhi kasagar7b830ae2012-11-23 15:11:00 +05302562 return err;
2563
Lee Jonesc3f27a22014-07-02 11:22:10 +01002564 if (user_trig_timer & ~0xFF) {
2565 dev_err(dev,
2566 "debugfs error input: should be beetween 0 to 255\n");
Lee Jones73482342013-02-26 10:06:55 +00002567 return -EINVAL;
2568 }
srinidhi kasagar7b830ae2012-11-23 15:11:00 +05302569
Lee Jonesc3f27a22014-07-02 11:22:10 +01002570 trig_timer = (u8) user_trig_timer;
2571
srinidhi kasagar7b830ae2012-11-23 15:11:00 +05302572 return count;
Lee Jones73482342013-02-26 10:06:55 +00002573}
2574
2575static const struct file_operations ab8500_gpadc_trig_timer_fops = {
2576 .open = ab8500_gpadc_trig_timer_open,
2577 .read = seq_read,
2578 .write = ab8500_gpadc_trig_timer_write,
2579 .llseek = seq_lseek,
2580 .release = single_release,
2581 .owner = THIS_MODULE,
2582};
2583
2584static int ab8500_gpadc_conv_type_print(struct seq_file *s, void *p)
2585{
Joe Perches9a503a72015-02-21 18:53:43 -08002586 seq_printf(s, "%d\n", conv_type);
2587
2588 return 0;
Lee Jones73482342013-02-26 10:06:55 +00002589}
2590
2591static int ab8500_gpadc_conv_type_open(struct inode *inode, struct file *file)
2592{
2593 return single_open(file, ab8500_gpadc_conv_type_print,
Lee Jones9f9ba152013-02-26 12:05:15 +00002594 inode->i_private);
Lee Jones73482342013-02-26 10:06:55 +00002595}
2596
2597static ssize_t ab8500_gpadc_conv_type_write(struct file *file,
2598 const char __user *user_buf,
2599 size_t count, loff_t *ppos)
2600{
2601 struct device *dev = ((struct seq_file *)(file->private_data))->private;
Lee Jones73482342013-02-26 10:06:55 +00002602 unsigned long user_conv_type;
2603 int err;
2604
srinidhi kasagar7b830ae2012-11-23 15:11:00 +05302605 err = kstrtoul_from_user(user_buf, count, 0, &user_conv_type);
Lee Jones73482342013-02-26 10:06:55 +00002606 if (err)
srinidhi kasagar7b830ae2012-11-23 15:11:00 +05302607 return err;
2608
Lee Jones73482342013-02-26 10:06:55 +00002609 if ((user_conv_type == ADC_SW)
2610 || (user_conv_type == ADC_HW)) {
2611 conv_type = (u8) user_conv_type;
2612 } else {
2613 dev_err(dev, "Wrong input:\n"
2614 "Enter 0. ADC SW conversion\n"
2615 "Enter 1. ADC HW conversion\n");
2616 return -EINVAL;
2617 }
srinidhi kasagar7b830ae2012-11-23 15:11:00 +05302618
2619 return count;
Lee Jones73482342013-02-26 10:06:55 +00002620}
2621
2622static const struct file_operations ab8500_gpadc_conv_type_fops = {
2623 .open = ab8500_gpadc_conv_type_open,
2624 .read = seq_read,
2625 .write = ab8500_gpadc_conv_type_write,
2626 .llseek = seq_lseek,
2627 .release = single_release,
2628 .owner = THIS_MODULE,
2629};
2630
carriere etienne0fbce762011-04-08 16:26:36 +02002631/*
2632 * return length of an ASCII numerical value, 0 is string is not a
2633 * numerical value.
2634 * string shall start at value 1st char.
2635 * string can be tailed with \0 or space or newline chars only.
2636 * value can be decimal or hexadecimal (prefixed 0x or 0X).
2637 */
2638static int strval_len(char *b)
2639{
2640 char *s = b;
Lee Jones43621752014-07-14 18:29:16 +01002641
carriere etienne0fbce762011-04-08 16:26:36 +02002642 if ((*s == '0') && ((*(s+1) == 'x') || (*(s+1) == 'X'))) {
2643 s += 2;
2644 for (; *s && (*s != ' ') && (*s != '\n'); s++) {
2645 if (!isxdigit(*s))
2646 return 0;
2647 }
2648 } else {
2649 if (*s == '-')
2650 s++;
2651 for (; *s && (*s != ' ') && (*s != '\n'); s++) {
2652 if (!isdigit(*s))
2653 return 0;
2654 }
2655 }
2656 return (int) (s-b);
2657}
2658
2659/*
2660 * parse hwreg input data.
2661 * update global hwreg_cfg only if input data syntax is ok.
2662 */
2663static ssize_t hwreg_common_write(char *b, struct hwreg_cfg *cfg,
2664 struct device *dev)
2665{
2666 uint write, val = 0;
2667 u8 regvalue;
2668 int ret;
2669 struct hwreg_cfg loc = {
2670 .bank = 0, /* default: invalid phys addr */
2671 .addr = 0, /* default: invalid phys addr */
2672 .fmt = 0, /* default: 32bit access, hex output */
2673 .mask = 0xFFFFFFFF, /* default: no mask */
2674 .shift = 0, /* default: no bit shift */
2675 };
2676
2677 /* read or write ? */
2678 if (!strncmp(b, "read ", 5)) {
2679 write = 0;
2680 b += 5;
2681 } else if (!strncmp(b, "write ", 6)) {
2682 write = 1;
2683 b += 6;
2684 } else
2685 return -EINVAL;
2686
2687 /* OPTIONS -l|-w|-b -s -m -o */
2688 while ((*b == ' ') || (*b == '-')) {
2689 if (*(b-1) != ' ') {
2690 b++;
2691 continue;
2692 }
2693 if ((!strncmp(b, "-d ", 3)) ||
2694 (!strncmp(b, "-dec ", 5))) {
2695 b += (*(b+2) == ' ') ? 3 : 5;
2696 loc.fmt |= (1<<0);
2697 } else if ((!strncmp(b, "-h ", 3)) ||
2698 (!strncmp(b, "-hex ", 5))) {
2699 b += (*(b+2) == ' ') ? 3 : 5;
2700 loc.fmt &= ~(1<<0);
2701 } else if ((!strncmp(b, "-m ", 3)) ||
2702 (!strncmp(b, "-mask ", 6))) {
2703 b += (*(b+2) == ' ') ? 3 : 6;
2704 if (strval_len(b) == 0)
2705 return -EINVAL;
Lee Jones43621752014-07-14 18:29:16 +01002706 ret = kstrtoul(b, 0, &loc.mask);
2707 if (ret)
2708 return ret;
carriere etienne0fbce762011-04-08 16:26:36 +02002709 } else if ((!strncmp(b, "-s ", 3)) ||
2710 (!strncmp(b, "-shift ", 7))) {
2711 b += (*(b+2) == ' ') ? 3 : 7;
2712 if (strval_len(b) == 0)
2713 return -EINVAL;
Lee Jones43621752014-07-14 18:29:16 +01002714 ret = kstrtol(b, 0, &loc.shift);
2715 if (ret)
2716 return ret;
carriere etienne0fbce762011-04-08 16:26:36 +02002717 } else {
2718 return -EINVAL;
2719 }
2720 }
2721 /* get arg BANK and ADDRESS */
2722 if (strval_len(b) == 0)
2723 return -EINVAL;
Lee Jones43621752014-07-14 18:29:16 +01002724 ret = kstrtouint(b, 0, &loc.bank);
2725 if (ret)
2726 return ret;
carriere etienne0fbce762011-04-08 16:26:36 +02002727 while (*b == ' ')
2728 b++;
2729 if (strval_len(b) == 0)
2730 return -EINVAL;
Lee Jones43621752014-07-14 18:29:16 +01002731 ret = kstrtoul(b, 0, &loc.addr);
2732 if (ret)
2733 return ret;
carriere etienne0fbce762011-04-08 16:26:36 +02002734
2735 if (write) {
2736 while (*b == ' ')
2737 b++;
2738 if (strval_len(b) == 0)
2739 return -EINVAL;
Lee Jones43621752014-07-14 18:29:16 +01002740 ret = kstrtouint(b, 0, &val);
2741 if (ret)
2742 return ret;
carriere etienne0fbce762011-04-08 16:26:36 +02002743 }
2744
2745 /* args are ok, update target cfg (mainly for read) */
2746 *cfg = loc;
2747
2748#ifdef ABB_HWREG_DEBUG
Lee Jonesde6a7692015-10-28 09:27:32 +00002749 pr_warn("HWREG request: %s, %s,\n", (write) ? "write" : "read",
2750 REG_FMT_DEC(cfg) ? "decimal" : "hexa");
2751 pr_warn(" addr=0x%08X, mask=0x%X, shift=%d" "value=0x%X\n",
Lee Jones43621752014-07-14 18:29:16 +01002752 cfg->addr, cfg->mask, cfg->shift, val);
carriere etienne0fbce762011-04-08 16:26:36 +02002753#endif
2754
2755 if (!write)
2756 return 0;
2757
2758 ret = abx500_get_register_interruptible(dev,
2759 (u8)cfg->bank, (u8)cfg->addr, &regvalue);
2760 if (ret < 0) {
2761 dev_err(dev, "abx500_get_reg fail %d, %d\n",
2762 ret, __LINE__);
2763 return -EINVAL;
2764 }
2765
2766 if (cfg->shift >= 0) {
2767 regvalue &= ~(cfg->mask << (cfg->shift));
2768 val = (val & cfg->mask) << (cfg->shift);
2769 } else {
2770 regvalue &= ~(cfg->mask >> (-cfg->shift));
2771 val = (val & cfg->mask) >> (-cfg->shift);
2772 }
2773 val = val | regvalue;
2774
2775 ret = abx500_set_register_interruptible(dev,
2776 (u8)cfg->bank, (u8)cfg->addr, (u8)val);
2777 if (ret < 0) {
2778 pr_err("abx500_set_reg failed %d, %d", ret, __LINE__);
2779 return -EINVAL;
2780 }
2781
2782 return 0;
2783}
2784
2785static ssize_t ab8500_hwreg_write(struct file *file,
2786 const char __user *user_buf, size_t count, loff_t *ppos)
2787{
2788 struct device *dev = ((struct seq_file *)(file->private_data))->private;
2789 char buf[128];
2790 int buf_size, ret;
2791
2792 /* Get userspace string and assure termination */
2793 buf_size = min(count, (sizeof(buf)-1));
2794 if (copy_from_user(buf, user_buf, buf_size))
2795 return -EFAULT;
2796 buf[buf_size] = 0;
2797
2798 /* get args and process */
2799 ret = hwreg_common_write(buf, &hwreg_cfg, dev);
2800 return (ret) ? ret : buf_size;
2801}
2802
2803/*
2804 * - irq subscribe/unsubscribe stuff
2805 */
Lee Jones4b8ac082013-01-14 16:10:36 +00002806static int ab8500_subscribe_unsubscribe_print(struct seq_file *s, void *p)
2807{
2808 seq_printf(s, "%d\n", irq_first);
2809
2810 return 0;
2811}
2812
2813static int ab8500_subscribe_unsubscribe_open(struct inode *inode,
2814 struct file *file)
2815{
2816 return single_open(file, ab8500_subscribe_unsubscribe_print,
Lee Jones9f9ba152013-02-26 12:05:15 +00002817 inode->i_private);
Lee Jones4b8ac082013-01-14 16:10:36 +00002818}
2819
2820/*
Mattias Wallin0b337e72010-11-19 17:55:11 +01002821 * Userspace should use poll() on this file. When an event occur
Lee Jones4b8ac082013-01-14 16:10:36 +00002822 * the blocking poll will be released.
2823 */
2824static ssize_t show_irq(struct device *dev,
2825 struct device_attribute *attr, char *buf)
2826{
Mattias Wallin0b337e72010-11-19 17:55:11 +01002827 unsigned long name;
2828 unsigned int irq_index;
2829 int err;
Lee Jones4b8ac082013-01-14 16:10:36 +00002830
Jingoo Han8420a242013-06-04 13:11:50 +09002831 err = kstrtoul(attr->attr.name, 0, &name);
Mattias Wallin0b337e72010-11-19 17:55:11 +01002832 if (err)
2833 return err;
2834
2835 irq_index = name - irq_first;
Linus Walleijddba25f2012-02-03 11:19:05 +01002836 if (irq_index >= num_irqs)
Mattias Wallin0b337e72010-11-19 17:55:11 +01002837 return -EINVAL;
Lee Jonesc3f27a22014-07-02 11:22:10 +01002838
2839 return sprintf(buf, "%u\n", irq_count[irq_index]);
Mattias Wallin0b337e72010-11-19 17:55:11 +01002840}
Lee Jones4b8ac082013-01-14 16:10:36 +00002841
2842static ssize_t ab8500_subscribe_write(struct file *file,
2843 const char __user *user_buf,
2844 size_t count, loff_t *ppos)
2845{
2846 struct device *dev = ((struct seq_file *)(file->private_data))->private;
Lee Jones4b8ac082013-01-14 16:10:36 +00002847 unsigned long user_val;
2848 int err;
Mattias Wallin0b337e72010-11-19 17:55:11 +01002849 unsigned int irq_index;
Lee Jones4b8ac082013-01-14 16:10:36 +00002850
srinidhi kasagar7b830ae2012-11-23 15:11:00 +05302851 err = kstrtoul_from_user(user_buf, count, 0, &user_val);
Lee Jones4b8ac082013-01-14 16:10:36 +00002852 if (err)
srinidhi kasagar7b830ae2012-11-23 15:11:00 +05302853 return err;
2854
Lee Jones4b8ac082013-01-14 16:10:36 +00002855 if (user_val < irq_first) {
2856 dev_err(dev, "debugfs error input < %d\n", irq_first);
2857 return -EINVAL;
2858 }
2859 if (user_val > irq_last) {
2860 dev_err(dev, "debugfs error input > %d\n", irq_last);
2861 return -EINVAL;
2862 }
2863
Mattias Wallin0b337e72010-11-19 17:55:11 +01002864 irq_index = user_val - irq_first;
Linus Walleijddba25f2012-02-03 11:19:05 +01002865 if (irq_index >= num_irqs)
Mattias Wallin0b337e72010-11-19 17:55:11 +01002866 return -EINVAL;
2867
Lee Jones4b8ac082013-01-14 16:10:36 +00002868 /*
Mattias Wallin0b337e72010-11-19 17:55:11 +01002869 * This will create a sysfs file named <irq-nr> which userspace can
Lee Jones4b8ac082013-01-14 16:10:36 +00002870 * use to select or poll and get the AB8500 events
2871 */
Mattias Wallin0b337e72010-11-19 17:55:11 +01002872 dev_attr[irq_index] = kmalloc(sizeof(struct device_attribute),
2873 GFP_KERNEL);
Lee Jonesf840e232013-07-19 08:44:50 +01002874 if (!dev_attr[irq_index])
2875 return -ENOMEM;
2876
srinidhi kasagar7b830ae2012-11-23 15:11:00 +05302877 event_name[irq_index] = kmalloc(count, GFP_KERNEL);
Lee Jonesd551c4c2013-07-19 08:53:24 +01002878 if (!event_name[irq_index])
2879 return -ENOMEM;
2880
Mattias Wallin0b337e72010-11-19 17:55:11 +01002881 sprintf(event_name[irq_index], "%lu", user_val);
2882 dev_attr[irq_index]->show = show_irq;
2883 dev_attr[irq_index]->store = NULL;
2884 dev_attr[irq_index]->attr.name = event_name[irq_index];
2885 dev_attr[irq_index]->attr.mode = S_IRUGO;
2886 err = sysfs_create_file(&dev->kobj, &dev_attr[irq_index]->attr);
Lee Jones4b8ac082013-01-14 16:10:36 +00002887 if (err < 0) {
Lee Jones43621752014-07-14 18:29:16 +01002888 pr_info("sysfs_create_file failed %d\n", err);
Lee Jones4b8ac082013-01-14 16:10:36 +00002889 return err;
2890 }
2891
2892 err = request_threaded_irq(user_val, NULL, ab8500_debug_handler,
Fabio Estevamabe5b472015-05-16 15:42:15 -03002893 IRQF_SHARED | IRQF_NO_SUSPEND | IRQF_ONESHOT,
Lee Jones4b8ac082013-01-14 16:10:36 +00002894 "ab8500-debug", &dev->kobj);
2895 if (err < 0) {
Lee Jones43621752014-07-14 18:29:16 +01002896 pr_info("request_threaded_irq failed %d, %lu\n",
2897 err, user_val);
Mattias Wallin0b337e72010-11-19 17:55:11 +01002898 sysfs_remove_file(&dev->kobj, &dev_attr[irq_index]->attr);
Lee Jones4b8ac082013-01-14 16:10:36 +00002899 return err;
2900 }
2901
srinidhi kasagar7b830ae2012-11-23 15:11:00 +05302902 return count;
Lee Jones4b8ac082013-01-14 16:10:36 +00002903}
2904
2905static ssize_t ab8500_unsubscribe_write(struct file *file,
2906 const char __user *user_buf,
2907 size_t count, loff_t *ppos)
2908{
2909 struct device *dev = ((struct seq_file *)(file->private_data))->private;
Lee Jones4b8ac082013-01-14 16:10:36 +00002910 unsigned long user_val;
2911 int err;
Mattias Wallin0b337e72010-11-19 17:55:11 +01002912 unsigned int irq_index;
Lee Jones4b8ac082013-01-14 16:10:36 +00002913
srinidhi kasagar7b830ae2012-11-23 15:11:00 +05302914 err = kstrtoul_from_user(user_buf, count, 0, &user_val);
Lee Jones4b8ac082013-01-14 16:10:36 +00002915 if (err)
srinidhi kasagar7b830ae2012-11-23 15:11:00 +05302916 return err;
2917
Lee Jones4b8ac082013-01-14 16:10:36 +00002918 if (user_val < irq_first) {
2919 dev_err(dev, "debugfs error input < %d\n", irq_first);
2920 return -EINVAL;
2921 }
2922 if (user_val > irq_last) {
2923 dev_err(dev, "debugfs error input > %d\n", irq_last);
2924 return -EINVAL;
2925 }
2926
Mattias Wallin0b337e72010-11-19 17:55:11 +01002927 irq_index = user_val - irq_first;
Linus Walleijddba25f2012-02-03 11:19:05 +01002928 if (irq_index >= num_irqs)
Mattias Wallin0b337e72010-11-19 17:55:11 +01002929 return -EINVAL;
Lee Jones4b8ac082013-01-14 16:10:36 +00002930
Mattias Wallin0b337e72010-11-19 17:55:11 +01002931 /* Set irq count to 0 when unsubscribe */
2932 irq_count[irq_index] = 0;
2933
2934 if (dev_attr[irq_index])
2935 sysfs_remove_file(&dev->kobj, &dev_attr[irq_index]->attr);
2936
2937
2938 free_irq(user_val, &dev->kobj);
2939 kfree(event_name[irq_index]);
2940 kfree(dev_attr[irq_index]);
Lee Jones4b8ac082013-01-14 16:10:36 +00002941
srinidhi kasagar7b830ae2012-11-23 15:11:00 +05302942 return count;
Lee Jones4b8ac082013-01-14 16:10:36 +00002943}
2944
carriere etienne0fbce762011-04-08 16:26:36 +02002945/*
2946 * - several deubgfs nodes fops
2947 */
2948
Mattias Wallin5814fc32010-09-13 16:05:04 +02002949static const struct file_operations ab8500_bank_fops = {
Mattias Wallind7b9f322010-11-26 13:06:39 +01002950 .open = ab8500_bank_open,
2951 .write = ab8500_bank_write,
2952 .read = seq_read,
2953 .llseek = seq_lseek,
2954 .release = single_release,
2955 .owner = THIS_MODULE,
Mattias Wallin5814fc32010-09-13 16:05:04 +02002956};
2957
2958static const struct file_operations ab8500_address_fops = {
Mattias Wallind7b9f322010-11-26 13:06:39 +01002959 .open = ab8500_address_open,
2960 .write = ab8500_address_write,
2961 .read = seq_read,
2962 .llseek = seq_lseek,
2963 .release = single_release,
2964 .owner = THIS_MODULE,
Mattias Wallin5814fc32010-09-13 16:05:04 +02002965};
2966
2967static const struct file_operations ab8500_val_fops = {
Mattias Wallind7b9f322010-11-26 13:06:39 +01002968 .open = ab8500_val_open,
2969 .write = ab8500_val_write,
2970 .read = seq_read,
2971 .llseek = seq_lseek,
2972 .release = single_release,
2973 .owner = THIS_MODULE,
Mattias Wallin5814fc32010-09-13 16:05:04 +02002974};
2975
Bengt Jonsson8f0eb432012-02-14 13:01:00 +01002976static const struct file_operations ab8500_interrupts_fops = {
2977 .open = ab8500_interrupts_open,
2978 .read = seq_read,
2979 .llseek = seq_lseek,
2980 .release = single_release,
2981 .owner = THIS_MODULE,
2982};
2983
Lee Jones4b8ac082013-01-14 16:10:36 +00002984static const struct file_operations ab8500_subscribe_fops = {
2985 .open = ab8500_subscribe_unsubscribe_open,
2986 .write = ab8500_subscribe_write,
2987 .read = seq_read,
2988 .llseek = seq_lseek,
2989 .release = single_release,
2990 .owner = THIS_MODULE,
2991};
2992
2993static const struct file_operations ab8500_unsubscribe_fops = {
2994 .open = ab8500_subscribe_unsubscribe_open,
2995 .write = ab8500_unsubscribe_write,
2996 .read = seq_read,
2997 .llseek = seq_lseek,
2998 .release = single_release,
2999 .owner = THIS_MODULE,
3000};
3001
carriere etienne0fbce762011-04-08 16:26:36 +02003002static const struct file_operations ab8500_hwreg_fops = {
3003 .open = ab8500_hwreg_open,
3004 .write = ab8500_hwreg_write,
3005 .read = seq_read,
3006 .llseek = seq_lseek,
3007 .release = single_release,
3008 .owner = THIS_MODULE,
3009};
3010
Mattias Wallin5814fc32010-09-13 16:05:04 +02003011static struct dentry *ab8500_dir;
John Beckett1478a312011-05-31 13:54:27 +01003012static struct dentry *ab8500_gpadc_dir;
Mattias Wallin5814fc32010-09-13 16:05:04 +02003013
Bill Pembertonf791be42012-11-19 13:23:04 -05003014static int ab8500_debug_probe(struct platform_device *plf)
Mattias Wallin5814fc32010-09-13 16:05:04 +02003015{
carriere etienne0fbce762011-04-08 16:26:36 +02003016 struct dentry *file;
Linus Walleijddba25f2012-02-03 11:19:05 +01003017 struct ab8500 *ab8500;
Linus Walleij69991812013-04-12 17:02:09 +02003018 struct resource *res;
Lee Jones43621752014-07-14 18:29:16 +01003019
Mattias Wallind7b9f322010-11-26 13:06:39 +01003020 debug_bank = AB8500_MISC;
3021 debug_address = AB8500_REV_REG & 0x00FF;
Mattias Wallin5814fc32010-09-13 16:05:04 +02003022
Linus Walleijddba25f2012-02-03 11:19:05 +01003023 ab8500 = dev_get_drvdata(plf->dev.parent);
3024 num_irqs = ab8500->mask_size;
3025
Lee Jonesc18cf6d2013-05-23 16:25:05 +01003026 irq_count = devm_kzalloc(&plf->dev,
3027 sizeof(*irq_count)*num_irqs, GFP_KERNEL);
Linus Walleijddba25f2012-02-03 11:19:05 +01003028 if (!irq_count)
3029 return -ENOMEM;
3030
Lee Jonesc18cf6d2013-05-23 16:25:05 +01003031 dev_attr = devm_kzalloc(&plf->dev,
Lee Jones43621752014-07-14 18:29:16 +01003032 sizeof(*dev_attr)*num_irqs, GFP_KERNEL);
Linus Walleijddba25f2012-02-03 11:19:05 +01003033 if (!dev_attr)
Lee Jonesc18cf6d2013-05-23 16:25:05 +01003034 return -ENOMEM;
Linus Walleijddba25f2012-02-03 11:19:05 +01003035
Lee Jonesc18cf6d2013-05-23 16:25:05 +01003036 event_name = devm_kzalloc(&plf->dev,
3037 sizeof(*event_name)*num_irqs, GFP_KERNEL);
Linus Walleijddba25f2012-02-03 11:19:05 +01003038 if (!event_name)
Lee Jonesc18cf6d2013-05-23 16:25:05 +01003039 return -ENOMEM;
Linus Walleijddba25f2012-02-03 11:19:05 +01003040
Linus Walleij69991812013-04-12 17:02:09 +02003041 res = platform_get_resource_byname(plf, 0, "IRQ_AB8500");
3042 if (!res) {
Lee Jones43621752014-07-14 18:29:16 +01003043 dev_err(&plf->dev, "AB8500 irq not found, err %d\n", irq_first);
3044 return -ENXIO;
Linus Walleij69991812013-04-12 17:02:09 +02003045 }
3046 irq_ab8500 = res->start;
3047
Lee Jones4b8ac082013-01-14 16:10:36 +00003048 irq_first = platform_get_irq_byname(plf, "IRQ_FIRST");
3049 if (irq_first < 0) {
Lee Jones43621752014-07-14 18:29:16 +01003050 dev_err(&plf->dev, "First irq not found, err %d\n", irq_first);
Lee Jonesc18cf6d2013-05-23 16:25:05 +01003051 return irq_first;
Lee Jones4b8ac082013-01-14 16:10:36 +00003052 }
3053
3054 irq_last = platform_get_irq_byname(plf, "IRQ_LAST");
3055 if (irq_last < 0) {
Lee Jones43621752014-07-14 18:29:16 +01003056 dev_err(&plf->dev, "Last irq not found, err %d\n", irq_last);
Lee Jonesc18cf6d2013-05-23 16:25:05 +01003057 return irq_last;
Lee Jones4b8ac082013-01-14 16:10:36 +00003058 }
3059
Mattias Wallind7b9f322010-11-26 13:06:39 +01003060 ab8500_dir = debugfs_create_dir(AB8500_NAME_STRING, NULL);
3061 if (!ab8500_dir)
carriere etienne0fbce762011-04-08 16:26:36 +02003062 goto err;
Mattias Wallin5814fc32010-09-13 16:05:04 +02003063
John Beckett1478a312011-05-31 13:54:27 +01003064 ab8500_gpadc_dir = debugfs_create_dir(AB8500_ADC_NAME_STRING,
Lee Jones43621752014-07-14 18:29:16 +01003065 ab8500_dir);
John Beckett1478a312011-05-31 13:54:27 +01003066 if (!ab8500_gpadc_dir)
3067 goto err;
3068
Lee Jones43621752014-07-14 18:29:16 +01003069 file = debugfs_create_file("all-bank-registers", S_IRUGO, ab8500_dir,
3070 &plf->dev, &ab8500_registers_fops);
carriere etienne0fbce762011-04-08 16:26:36 +02003071 if (!file)
3072 goto err;
Mattias Wallin5814fc32010-09-13 16:05:04 +02003073
Lee Jones43621752014-07-14 18:29:16 +01003074 file = debugfs_create_file("all-banks", S_IRUGO, ab8500_dir,
3075 &plf->dev, &ab8500_all_banks_fops);
Mian Yousaf Kaukab42002c62012-01-26 15:39:20 +01003076 if (!file)
3077 goto err;
3078
Lee Jones43621752014-07-14 18:29:16 +01003079 file = debugfs_create_file("register-bank",
3080 (S_IRUGO | S_IWUSR | S_IWGRP),
3081 ab8500_dir, &plf->dev, &ab8500_bank_fops);
carriere etienne0fbce762011-04-08 16:26:36 +02003082 if (!file)
3083 goto err;
Mattias Wallin5814fc32010-09-13 16:05:04 +02003084
Lee Jones43621752014-07-14 18:29:16 +01003085 file = debugfs_create_file("register-address",
3086 (S_IRUGO | S_IWUSR | S_IWGRP),
3087 ab8500_dir, &plf->dev, &ab8500_address_fops);
carriere etienne0fbce762011-04-08 16:26:36 +02003088 if (!file)
3089 goto err;
Mattias Wallin5814fc32010-09-13 16:05:04 +02003090
Lee Jones43621752014-07-14 18:29:16 +01003091 file = debugfs_create_file("register-value",
3092 (S_IRUGO | S_IWUSR | S_IWGRP),
3093 ab8500_dir, &plf->dev, &ab8500_val_fops);
carriere etienne0fbce762011-04-08 16:26:36 +02003094 if (!file)
3095 goto err;
Mattias Wallin5814fc32010-09-13 16:05:04 +02003096
Lee Jones43621752014-07-14 18:29:16 +01003097 file = debugfs_create_file("irq-subscribe",
3098 (S_IRUGO | S_IWUSR | S_IWGRP), ab8500_dir,
3099 &plf->dev, &ab8500_subscribe_fops);
carriere etienne0fbce762011-04-08 16:26:36 +02003100 if (!file)
3101 goto err;
Lee Jones4b8ac082013-01-14 16:10:36 +00003102
Lee Jones9581ae32012-07-06 16:11:50 +02003103 if (is_ab8500(ab8500)) {
3104 debug_ranges = ab8500_debug_ranges;
Bengt Jonsson8f0eb432012-02-14 13:01:00 +01003105 num_interrupt_lines = AB8500_NR_IRQS;
Lee Jones9581ae32012-07-06 16:11:50 +02003106 } else if (is_ab8505(ab8500)) {
3107 debug_ranges = ab8505_debug_ranges;
Bengt Jonsson8f0eb432012-02-14 13:01:00 +01003108 num_interrupt_lines = AB8505_NR_IRQS;
Lee Jones9581ae32012-07-06 16:11:50 +02003109 } else if (is_ab9540(ab8500)) {
3110 debug_ranges = ab8505_debug_ranges;
Bengt Jonsson8f0eb432012-02-14 13:01:00 +01003111 num_interrupt_lines = AB9540_NR_IRQS;
Lee Jones9581ae32012-07-06 16:11:50 +02003112 } else if (is_ab8540(ab8500)) {
Lee Jones971480f2012-11-19 12:20:03 +01003113 debug_ranges = ab8540_debug_ranges;
Lee Jonese436ddf2013-02-26 10:09:41 +00003114 num_interrupt_lines = AB8540_NR_IRQS;
Lee Jones9581ae32012-07-06 16:11:50 +02003115 }
Bengt Jonsson8f0eb432012-02-14 13:01:00 +01003116
Lee Jones43621752014-07-14 18:29:16 +01003117 file = debugfs_create_file("interrupts", (S_IRUGO), ab8500_dir,
3118 &plf->dev, &ab8500_interrupts_fops);
Bengt Jonsson8f0eb432012-02-14 13:01:00 +01003119 if (!file)
3120 goto err;
3121
Lee Jones43621752014-07-14 18:29:16 +01003122 file = debugfs_create_file("irq-unsubscribe",
3123 (S_IRUGO | S_IWUSR | S_IWGRP), ab8500_dir,
3124 &plf->dev, &ab8500_unsubscribe_fops);
carriere etienne0fbce762011-04-08 16:26:36 +02003125 if (!file)
3126 goto err;
3127
Lee Jonesf38487f2013-02-26 14:09:08 +00003128 file = debugfs_create_file("hwreg", (S_IRUGO | S_IWUSR | S_IWGRP),
Lee Jones43621752014-07-14 18:29:16 +01003129 ab8500_dir, &plf->dev, &ab8500_hwreg_fops);
John Beckett1478a312011-05-31 13:54:27 +01003130 if (!file)
3131 goto err;
3132
Lee Jones43621752014-07-14 18:29:16 +01003133 file = debugfs_create_file("all-modem-registers",
3134 (S_IRUGO | S_IWUSR | S_IWGRP),
3135 ab8500_dir, &plf->dev, &ab8500_modem_fops);
Lee Jonesc7ebaee2013-02-26 14:03:33 +00003136 if (!file)
3137 goto err;
3138
Lee Jonesf38487f2013-02-26 14:09:08 +00003139 file = debugfs_create_file("bat_ctrl", (S_IRUGO | S_IWUSR | S_IWGRP),
Lee Jones43621752014-07-14 18:29:16 +01003140 ab8500_gpadc_dir, &plf->dev,
3141 &ab8500_gpadc_bat_ctrl_fops);
John Beckett1478a312011-05-31 13:54:27 +01003142 if (!file)
3143 goto err;
3144
Lee Jonesf38487f2013-02-26 14:09:08 +00003145 file = debugfs_create_file("btemp_ball", (S_IRUGO | S_IWUSR | S_IWGRP),
Lee Jones43621752014-07-14 18:29:16 +01003146 ab8500_gpadc_dir,
3147 &plf->dev, &ab8500_gpadc_btemp_ball_fops);
John Beckett1478a312011-05-31 13:54:27 +01003148 if (!file)
3149 goto err;
3150
Lee Jones43621752014-07-14 18:29:16 +01003151 file = debugfs_create_file("main_charger_v",
3152 (S_IRUGO | S_IWUSR | S_IWGRP),
3153 ab8500_gpadc_dir, &plf->dev,
3154 &ab8500_gpadc_main_charger_v_fops);
John Beckett1478a312011-05-31 13:54:27 +01003155 if (!file)
3156 goto err;
3157
Lee Jones43621752014-07-14 18:29:16 +01003158 file = debugfs_create_file("acc_detect1",
3159 (S_IRUGO | S_IWUSR | S_IWGRP),
3160 ab8500_gpadc_dir, &plf->dev,
3161 &ab8500_gpadc_acc_detect1_fops);
John Beckett1478a312011-05-31 13:54:27 +01003162 if (!file)
3163 goto err;
3164
Lee Jones43621752014-07-14 18:29:16 +01003165 file = debugfs_create_file("acc_detect2",
3166 (S_IRUGO | S_IWUSR | S_IWGRP),
3167 ab8500_gpadc_dir, &plf->dev,
3168 &ab8500_gpadc_acc_detect2_fops);
John Beckett1478a312011-05-31 13:54:27 +01003169 if (!file)
3170 goto err;
3171
Lee Jonesf38487f2013-02-26 14:09:08 +00003172 file = debugfs_create_file("adc_aux1", (S_IRUGO | S_IWUSR | S_IWGRP),
Lee Jones43621752014-07-14 18:29:16 +01003173 ab8500_gpadc_dir, &plf->dev,
3174 &ab8500_gpadc_aux1_fops);
John Beckett1478a312011-05-31 13:54:27 +01003175 if (!file)
3176 goto err;
3177
Lee Jonesf38487f2013-02-26 14:09:08 +00003178 file = debugfs_create_file("adc_aux2", (S_IRUGO | S_IWUSR | S_IWGRP),
Lee Jones43621752014-07-14 18:29:16 +01003179 ab8500_gpadc_dir, &plf->dev,
3180 &ab8500_gpadc_aux2_fops);
John Beckett1478a312011-05-31 13:54:27 +01003181 if (!file)
3182 goto err;
3183
Lee Jonesf38487f2013-02-26 14:09:08 +00003184 file = debugfs_create_file("main_bat_v", (S_IRUGO | S_IWUSR | S_IWGRP),
Lee Jones43621752014-07-14 18:29:16 +01003185 ab8500_gpadc_dir, &plf->dev,
3186 &ab8500_gpadc_main_bat_v_fops);
John Beckett1478a312011-05-31 13:54:27 +01003187 if (!file)
3188 goto err;
3189
Lee Jonesf38487f2013-02-26 14:09:08 +00003190 file = debugfs_create_file("vbus_v", (S_IRUGO | S_IWUSR | S_IWGRP),
Lee Jones43621752014-07-14 18:29:16 +01003191 ab8500_gpadc_dir, &plf->dev,
3192 &ab8500_gpadc_vbus_v_fops);
John Beckett1478a312011-05-31 13:54:27 +01003193 if (!file)
3194 goto err;
3195
Lee Jones43621752014-07-14 18:29:16 +01003196 file = debugfs_create_file("main_charger_c",
3197 (S_IRUGO | S_IWUSR | S_IWGRP),
3198 ab8500_gpadc_dir, &plf->dev,
3199 &ab8500_gpadc_main_charger_c_fops);
John Beckett1478a312011-05-31 13:54:27 +01003200 if (!file)
3201 goto err;
3202
Lee Jones43621752014-07-14 18:29:16 +01003203 file = debugfs_create_file("usb_charger_c",
3204 (S_IRUGO | S_IWUSR | S_IWGRP),
3205 ab8500_gpadc_dir,
3206 &plf->dev, &ab8500_gpadc_usb_charger_c_fops);
John Beckett1478a312011-05-31 13:54:27 +01003207 if (!file)
3208 goto err;
3209
Lee Jonesf38487f2013-02-26 14:09:08 +00003210 file = debugfs_create_file("bk_bat_v", (S_IRUGO | S_IWUSR | S_IWGRP),
Lee Jones43621752014-07-14 18:29:16 +01003211 ab8500_gpadc_dir, &plf->dev,
3212 &ab8500_gpadc_bk_bat_v_fops);
John Beckett1478a312011-05-31 13:54:27 +01003213 if (!file)
3214 goto err;
3215
Lee Jonesf38487f2013-02-26 14:09:08 +00003216 file = debugfs_create_file("die_temp", (S_IRUGO | S_IWUSR | S_IWGRP),
Lee Jones43621752014-07-14 18:29:16 +01003217 ab8500_gpadc_dir, &plf->dev,
3218 &ab8500_gpadc_die_temp_fops);
carriere etienne0fbce762011-04-08 16:26:36 +02003219 if (!file)
3220 goto err;
Lee Jones127629d2013-02-26 14:04:37 +00003221
Lee Jonesf38487f2013-02-26 14:09:08 +00003222 file = debugfs_create_file("usb_id", (S_IRUGO | S_IWUSR | S_IWGRP),
Lee Jones43621752014-07-14 18:29:16 +01003223 ab8500_gpadc_dir, &plf->dev,
3224 &ab8500_gpadc_usb_id_fops);
Lee Jones127629d2013-02-26 14:04:37 +00003225 if (!file)
3226 goto err;
3227
Lee Jonesbc6b4132013-02-26 14:02:31 +00003228 if (is_ab8540(ab8500)) {
Lee Jones43621752014-07-14 18:29:16 +01003229 file = debugfs_create_file("xtal_temp",
3230 (S_IRUGO | S_IWUSR | S_IWGRP),
3231 ab8500_gpadc_dir, &plf->dev,
3232 &ab8540_gpadc_xtal_temp_fops);
Lee Jonesbc6b4132013-02-26 14:02:31 +00003233 if (!file)
3234 goto err;
Lee Jones43621752014-07-14 18:29:16 +01003235 file = debugfs_create_file("vbattruemeas",
3236 (S_IRUGO | S_IWUSR | S_IWGRP),
3237 ab8500_gpadc_dir, &plf->dev,
3238 &ab8540_gpadc_vbat_true_meas_fops);
Lee Jonesbc6b4132013-02-26 14:02:31 +00003239 if (!file)
3240 goto err;
3241 file = debugfs_create_file("batctrl_and_ibat",
Lee Jones43621752014-07-14 18:29:16 +01003242 (S_IRUGO | S_IWUGO),
3243 ab8500_gpadc_dir,
3244 &plf->dev,
3245 &ab8540_gpadc_bat_ctrl_and_ibat_fops);
Lee Jonesbc6b4132013-02-26 14:02:31 +00003246 if (!file)
3247 goto err;
3248 file = debugfs_create_file("vbatmeas_and_ibat",
Lee Jones43621752014-07-14 18:29:16 +01003249 (S_IRUGO | S_IWUGO),
3250 ab8500_gpadc_dir, &plf->dev,
3251 &ab8540_gpadc_vbat_meas_and_ibat_fops);
Lee Jonesbc6b4132013-02-26 14:02:31 +00003252 if (!file)
3253 goto err;
3254 file = debugfs_create_file("vbattruemeas_and_ibat",
Lee Jones43621752014-07-14 18:29:16 +01003255 (S_IRUGO | S_IWUGO),
3256 ab8500_gpadc_dir,
3257 &plf->dev,
3258 &ab8540_gpadc_vbat_true_meas_and_ibat_fops);
Lee Jonesbc6b4132013-02-26 14:02:31 +00003259 if (!file)
3260 goto err;
3261 file = debugfs_create_file("battemp_and_ibat",
Lee Jones43621752014-07-14 18:29:16 +01003262 (S_IRUGO | S_IWUGO),
3263 ab8500_gpadc_dir,
Lee Jones9f9ba152013-02-26 12:05:15 +00003264 &plf->dev, &ab8540_gpadc_bat_temp_and_ibat_fops);
Lee Jonesbc6b4132013-02-26 14:02:31 +00003265 if (!file)
3266 goto err;
Lee Jones43621752014-07-14 18:29:16 +01003267 file = debugfs_create_file("otp_calib",
3268 (S_IRUGO | S_IWUSR | S_IWGRP),
3269 ab8500_gpadc_dir,
3270 &plf->dev, &ab8540_gpadc_otp_calib_fops);
Lee Jonesbc6b4132013-02-26 14:02:31 +00003271 if (!file)
3272 goto err;
3273 }
Lee Jonesf38487f2013-02-26 14:09:08 +00003274 file = debugfs_create_file("avg_sample", (S_IRUGO | S_IWUSR | S_IWGRP),
Lee Jones43621752014-07-14 18:29:16 +01003275 ab8500_gpadc_dir, &plf->dev,
3276 &ab8500_gpadc_avg_sample_fops);
Lee Jones73482342013-02-26 10:06:55 +00003277 if (!file)
3278 goto err;
3279
Lee Jonesf38487f2013-02-26 14:09:08 +00003280 file = debugfs_create_file("trig_edge", (S_IRUGO | S_IWUSR | S_IWGRP),
Lee Jones43621752014-07-14 18:29:16 +01003281 ab8500_gpadc_dir, &plf->dev,
3282 &ab8500_gpadc_trig_edge_fops);
Lee Jones73482342013-02-26 10:06:55 +00003283 if (!file)
3284 goto err;
3285
Lee Jonesf38487f2013-02-26 14:09:08 +00003286 file = debugfs_create_file("trig_timer", (S_IRUGO | S_IWUSR | S_IWGRP),
Lee Jones43621752014-07-14 18:29:16 +01003287 ab8500_gpadc_dir, &plf->dev,
3288 &ab8500_gpadc_trig_timer_fops);
Lee Jones73482342013-02-26 10:06:55 +00003289 if (!file)
3290 goto err;
3291
Lee Jonesf38487f2013-02-26 14:09:08 +00003292 file = debugfs_create_file("conv_type", (S_IRUGO | S_IWUSR | S_IWGRP),
Lee Jones43621752014-07-14 18:29:16 +01003293 ab8500_gpadc_dir, &plf->dev,
3294 &ab8500_gpadc_conv_type_fops);
Lee Jones73482342013-02-26 10:06:55 +00003295 if (!file)
3296 goto err;
3297
Mattias Wallind7b9f322010-11-26 13:06:39 +01003298 return 0;
Mattias Wallin5814fc32010-09-13 16:05:04 +02003299
carriere etienne0fbce762011-04-08 16:26:36 +02003300err:
Fabian Frederick005d16b2014-06-28 13:58:17 +02003301 debugfs_remove_recursive(ab8500_dir);
Mattias Wallind7b9f322010-11-26 13:06:39 +01003302 dev_err(&plf->dev, "failed to create debugfs entries.\n");
Linus Walleijddba25f2012-02-03 11:19:05 +01003303
Lee Jonesc18cf6d2013-05-23 16:25:05 +01003304 return -ENOMEM;
Mattias Wallin5814fc32010-09-13 16:05:04 +02003305}
3306
Bill Pemberton4740f732012-11-19 13:26:01 -05003307static int ab8500_debug_remove(struct platform_device *plf)
Mattias Wallin5814fc32010-09-13 16:05:04 +02003308{
carriere etienne0fbce762011-04-08 16:26:36 +02003309 debugfs_remove_recursive(ab8500_dir);
Linus Walleijddba25f2012-02-03 11:19:05 +01003310
Mattias Wallind7b9f322010-11-26 13:06:39 +01003311 return 0;
Mattias Wallin5814fc32010-09-13 16:05:04 +02003312}
3313
3314static struct platform_driver ab8500_debug_driver = {
Mattias Wallind7b9f322010-11-26 13:06:39 +01003315 .driver = {
3316 .name = "ab8500-debug",
Mattias Wallind7b9f322010-11-26 13:06:39 +01003317 },
3318 .probe = ab8500_debug_probe,
Bill Pemberton84449212012-11-19 13:20:24 -05003319 .remove = ab8500_debug_remove
Mattias Wallin5814fc32010-09-13 16:05:04 +02003320};
3321
3322static int __init ab8500_debug_init(void)
3323{
Mattias Wallind7b9f322010-11-26 13:06:39 +01003324 return platform_driver_register(&ab8500_debug_driver);
Mattias Wallin5814fc32010-09-13 16:05:04 +02003325}
3326
3327static void __exit ab8500_debug_exit(void)
3328{
Mattias Wallind7b9f322010-11-26 13:06:39 +01003329 platform_driver_unregister(&ab8500_debug_driver);
Mattias Wallin5814fc32010-09-13 16:05:04 +02003330}
3331subsys_initcall(ab8500_debug_init);
3332module_exit(ab8500_debug_exit);
3333
3334MODULE_AUTHOR("Mattias WALLIN <mattias.wallin@stericsson.com");
3335MODULE_DESCRIPTION("AB8500 DEBUG");
3336MODULE_LICENSE("GPL v2");