2 * Copyright (C) 2011 ST-Ericsson
3 * License terms: GNU General Public License (GPL) version 2
4 * Debugfs support for the AB5500 MFD driver
7 #include <linux/export.h>
8 #include <linux/debugfs.h>
9 #include <linux/seq_file.h>
10 #include <linux/mfd/ab5500/ab5500.h>
11 #include <linux/mfd/abx500.h>
12 #include <linux/uaccess.h>
14 #include "ab5500-core.h"
15 #include "ab5500-debugfs.h"
17 static struct ab5500_i2c_ranges ab5500_reg_ranges
[AB5500_NUM_BANKS
] = {
19 .bankid
= AB5500_BANK_LED
,
21 .range
= (struct ab5500_reg_range
[]) {
25 .perm
= AB5500_PERM_RW
,
30 .bankid
= AB5500_BANK_ADC
,
32 .range
= (struct ab5500_reg_range
[]) {
36 .perm
= AB5500_PERM_RO
,
41 .perm
= AB5500_PERM_RW
,
46 .perm
= AB5500_PERM_RO
,
51 .perm
= AB5500_PERM_RW
,
56 .perm
= AB5500_PERM_RW
,
61 .perm
= AB5500_PERM_RO
,
66 .bankid
= AB5500_BANK_RTC
,
68 .range
= (struct ab5500_reg_range
[]) {
72 .perm
= AB5500_PERM_RW
,
77 .perm
= AB5500_PERM_RW
,
81 [AB5500_BANK_STARTUP
] = {
82 .bankid
= AB5500_BANK_STARTUP
,
84 .range
= (struct ab5500_reg_range
[]) {
88 .perm
= AB5500_PERM_RW
,
93 .perm
= AB5500_PERM_RW
,
98 .perm
= AB5500_PERM_RO
,
103 .perm
= AB5500_PERM_RW
,
108 .perm
= AB5500_PERM_RW
,
113 .perm
= AB5500_PERM_RW
,
118 .perm
= AB5500_PERM_RW
,
123 .perm
= AB5500_PERM_RW
,
128 .perm
= AB5500_PERM_RW
,
133 .perm
= AB5500_PERM_RW
,
138 .perm
= AB5500_PERM_RW
,
143 .perm
= AB5500_PERM_RW
,
147 [AB5500_BANK_DBI_ECI
] = {
148 .bankid
= AB5500_BANK_DBI_ECI
,
150 .range
= (struct ab5500_reg_range
[]) {
154 .perm
= AB5500_PERM_RW
,
159 .perm
= AB5500_PERM_RW
,
164 .perm
= AB5500_PERM_RW
,
168 [AB5500_BANK_CHG
] = {
169 .bankid
= AB5500_BANK_CHG
,
171 .range
= (struct ab5500_reg_range
[]) {
175 .perm
= AB5500_PERM_RO
,
180 .perm
= AB5500_PERM_RW
,
184 [AB5500_BANK_FG_BATTCOM_ACC
] = {
185 .bankid
= AB5500_BANK_FG_BATTCOM_ACC
,
187 .range
= (struct ab5500_reg_range
[]) {
191 .perm
= AB5500_PERM_RO
,
196 .perm
= AB5500_PERM_RW
,
200 [AB5500_BANK_USB
] = {
201 .bankid
= AB5500_BANK_USB
,
203 .range
= (struct ab5500_reg_range
[]) {
207 .perm
= AB5500_PERM_RW
,
212 .perm
= AB5500_PERM_RW
,
217 .perm
= AB5500_PERM_RW
,
222 .perm
= AB5500_PERM_RO
,
227 .perm
= AB5500_PERM_RO
,
232 .perm
= AB5500_PERM_RW
,
237 .perm
= AB5500_PERM_RO
,
242 .perm
= AB5500_PERM_RO
,
247 .perm
= AB5500_PERM_RO
,
252 .perm
= AB5500_PERM_RO
,
257 .perm
= AB5500_PERM_RO
,
262 .perm
= AB5500_PERM_RO
,
267 .bankid
= AB5500_BANK_IT
,
269 .range
= (struct ab5500_reg_range
[]) {
273 .perm
= AB5500_PERM_RO
,
278 .perm
= AB5500_PERM_RO
,
283 .perm
= AB5500_PERM_RO
,
288 .perm
= AB5500_PERM_RO
,
292 [AB5500_BANK_VDDDIG_IO_I2C_CLK_TST
] = {
293 .bankid
= AB5500_BANK_VDDDIG_IO_I2C_CLK_TST
,
295 .range
= (struct ab5500_reg_range
[]) {
299 .perm
= AB5500_PERM_RW
,
304 .perm
= AB5500_PERM_RW
,
309 .perm
= AB5500_PERM_RW
,
314 .perm
= AB5500_PERM_RW
,
319 .perm
= AB5500_PERM_RW
,
324 .perm
= AB5500_PERM_RW
,
329 .perm
= AB5500_PERM_RW
,
333 [AB5500_BANK_VIT_IO_I2C_CLK_TST_OTP
] = {
334 .bankid
= AB5500_BANK_VIT_IO_I2C_CLK_TST_OTP
,
336 .range
= (struct ab5500_reg_range
[]) {
340 .perm
= AB5500_PERM_RW
,
345 .perm
= AB5500_PERM_RO
,
350 .perm
= AB5500_PERM_RW
,
355 .perm
= AB5500_PERM_RW
,
360 .perm
= AB5500_PERM_RW
,
365 .perm
= AB5500_PERM_RW
,
370 .perm
= AB5500_PERM_RW
,
375 .perm
= AB5500_PERM_RW
,
380 .perm
= AB5500_PERM_RW
,
385 .perm
= AB5500_PERM_RW
,
390 .perm
= AB5500_PERM_RW
,
395 .perm
= AB5500_PERM_RW
,
400 .perm
= AB5500_PERM_RW
,
404 [AB5500_BANK_VIBRA
] = {
405 .bankid
= AB5500_BANK_VIBRA
,
407 .range
= (struct ab5500_reg_range
[]) {
411 .perm
= AB5500_PERM_RW
,
416 .perm
= AB5500_PERM_RW
,
420 [AB5500_BANK_AUDIO_HEADSETUSB
] = {
421 .bankid
= AB5500_BANK_AUDIO_HEADSETUSB
,
423 .range
= (struct ab5500_reg_range
[]) {
427 .perm
= AB5500_PERM_RW
,
432 .perm
= AB5500_PERM_RW
,
436 [AB5500_BANK_SIM_USBSIM
] = {
437 .bankid
= AB5500_BANK_SIM_USBSIM
,
439 .range
= (struct ab5500_reg_range
[]) {
443 .perm
= AB5500_PERM_RW
,
447 [AB5500_BANK_VDENC
] = {
448 .bankid
= AB5500_BANK_VDENC
,
450 .range
= (struct ab5500_reg_range
[]) {
454 .perm
= AB5500_PERM_RW
,
459 .perm
= AB5500_PERM_RO
,
464 .perm
= AB5500_PERM_RW
,
469 .perm
= AB5500_PERM_RW
,
474 .perm
= AB5500_PERM_RW
,
479 .perm
= AB5500_PERM_RW
,
484 .perm
= AB5500_PERM_RW
,
489 .perm
= AB5500_PERM_RW
,
494 .perm
= AB5500_PERM_RW
,
499 .perm
= AB5500_PERM_RW
,
504 .perm
= AB5500_PERM_RW
,
509 .perm
= AB5500_PERM_RW
,
515 static int ab5500_registers_print(struct seq_file
*s
, void *p
)
517 struct ab5500
*ab
= s
->private;
519 u8 bank
= (u8
)ab
->debug_bank
;
521 seq_printf(s
, "ab5500 register values:\n");
522 for (bank
= 0; bank
< AB5500_NUM_BANKS
; bank
++) {
523 seq_printf(s
, " bank %u, %s (0x%x):\n", bank
,
525 bankinfo
[bank
].slave_addr
);
526 for (i
= 0; i
< ab5500_reg_ranges
[bank
].nranges
; i
++) {
530 for (reg
= ab5500_reg_ranges
[bank
].range
[i
].first
;
531 reg
<= ab5500_reg_ranges
[bank
].range
[i
].last
;
535 err
= ab5500_get_register_interruptible_raw(ab
,
539 dev_err(ab
->dev
, "get_reg failed %d"
540 "bank 0x%x reg 0x%x\n",
545 err
= seq_printf(s
, "[%d/0x%02X]: 0x%02X\n",
549 "seq_printf overflow\n");
551 * Error is not returned here since
552 * the output is wanted in any case
562 static int ab5500_registers_open(struct inode
*inode
, struct file
*file
)
564 return single_open(file
, ab5500_registers_print
, inode
->i_private
);
567 static const struct file_operations ab5500_registers_fops
= {
568 .open
= ab5500_registers_open
,
571 .release
= single_release
,
572 .owner
= THIS_MODULE
,
575 static int ab5500_bank_print(struct seq_file
*s
, void *p
)
577 struct ab5500
*ab
= s
->private;
579 seq_printf(s
, "%d\n", ab
->debug_bank
);
583 static int ab5500_bank_open(struct inode
*inode
, struct file
*file
)
585 return single_open(file
, ab5500_bank_print
, inode
->i_private
);
588 static ssize_t
ab5500_bank_write(struct file
*file
,
589 const char __user
*user_buf
,
590 size_t count
, loff_t
*ppos
)
592 struct ab5500
*ab
= ((struct seq_file
*)(file
->private_data
))->private;
595 unsigned long user_bank
;
598 /* Get userspace string and assure termination */
599 buf_size
= min(count
, (sizeof(buf
) - 1));
600 if (copy_from_user(buf
, user_buf
, buf_size
))
604 err
= strict_strtoul(buf
, 0, &user_bank
);
608 if (user_bank
>= AB5500_NUM_BANKS
) {
610 "debugfs error input > number of banks\n");
614 ab
->debug_bank
= user_bank
;
619 static int ab5500_address_print(struct seq_file
*s
, void *p
)
621 struct ab5500
*ab
= s
->private;
623 seq_printf(s
, "0x%02X\n", ab
->debug_address
);
627 static int ab5500_address_open(struct inode
*inode
, struct file
*file
)
629 return single_open(file
, ab5500_address_print
, inode
->i_private
);
632 static ssize_t
ab5500_address_write(struct file
*file
,
633 const char __user
*user_buf
,
634 size_t count
, loff_t
*ppos
)
636 struct ab5500
*ab
= ((struct seq_file
*)(file
->private_data
))->private;
639 unsigned long user_address
;
642 /* Get userspace string and assure termination */
643 buf_size
= min(count
, (sizeof(buf
) - 1));
644 if (copy_from_user(buf
, user_buf
, buf_size
))
648 err
= strict_strtoul(buf
, 0, &user_address
);
651 if (user_address
> 0xff) {
653 "debugfs error input > 0xff\n");
656 ab
->debug_address
= user_address
;
660 static int ab5500_val_print(struct seq_file
*s
, void *p
)
662 struct ab5500
*ab
= s
->private;
666 err
= ab5500_get_register_interruptible_raw(ab
, (u8
)ab
->debug_bank
,
667 (u8
)ab
->debug_address
, ®value
);
669 dev_err(ab
->dev
, "get_reg failed %d, bank 0x%x"
670 ", reg 0x%x\n", err
, ab
->debug_bank
,
674 seq_printf(s
, "0x%02X\n", regvalue
);
679 static int ab5500_val_open(struct inode
*inode
, struct file
*file
)
681 return single_open(file
, ab5500_val_print
, inode
->i_private
);
684 static ssize_t
ab5500_val_write(struct file
*file
,
685 const char __user
*user_buf
,
686 size_t count
, loff_t
*ppos
)
688 struct ab5500
*ab
= ((struct seq_file
*)(file
->private_data
))->private;
691 unsigned long user_val
;
695 /* Get userspace string and assure termination */
696 buf_size
= min(count
, (sizeof(buf
)-1));
697 if (copy_from_user(buf
, user_buf
, buf_size
))
701 err
= strict_strtoul(buf
, 0, &user_val
);
704 if (user_val
> 0xff) {
706 "debugfs error input > 0xff\n");
709 err
= ab5500_mask_and_set_register_interruptible_raw(
710 ab
, (u8
)ab
->debug_bank
,
711 (u8
)ab
->debug_address
, 0xFF, (u8
)user_val
);
715 ab5500_get_register_interruptible_raw(ab
, (u8
)ab
->debug_bank
,
716 (u8
)ab
->debug_address
, ®value
);
723 static const struct file_operations ab5500_bank_fops
= {
724 .open
= ab5500_bank_open
,
725 .write
= ab5500_bank_write
,
728 .release
= single_release
,
729 .owner
= THIS_MODULE
,
732 static const struct file_operations ab5500_address_fops
= {
733 .open
= ab5500_address_open
,
734 .write
= ab5500_address_write
,
737 .release
= single_release
,
738 .owner
= THIS_MODULE
,
741 static const struct file_operations ab5500_val_fops
= {
742 .open
= ab5500_val_open
,
743 .write
= ab5500_val_write
,
746 .release
= single_release
,
747 .owner
= THIS_MODULE
,
750 static struct dentry
*ab5500_dir
;
751 static struct dentry
*ab5500_reg_file
;
752 static struct dentry
*ab5500_bank_file
;
753 static struct dentry
*ab5500_address_file
;
754 static struct dentry
*ab5500_val_file
;
756 void __init
ab5500_setup_debugfs(struct ab5500
*ab
)
758 ab
->debug_bank
= AB5500_BANK_VIT_IO_I2C_CLK_TST_OTP
;
759 ab
->debug_address
= AB5500_CHIP_ID
;
761 ab5500_dir
= debugfs_create_dir("ab5500", NULL
);
763 goto exit_no_debugfs
;
765 ab5500_reg_file
= debugfs_create_file("all-bank-registers",
766 S_IRUGO
, ab5500_dir
, ab
, &ab5500_registers_fops
);
767 if (!ab5500_reg_file
)
768 goto exit_destroy_dir
;
770 ab5500_bank_file
= debugfs_create_file("register-bank",
771 (S_IRUGO
| S_IWUGO
), ab5500_dir
, ab
, &ab5500_bank_fops
);
772 if (!ab5500_bank_file
)
773 goto exit_destroy_reg
;
775 ab5500_address_file
= debugfs_create_file("register-address",
776 (S_IRUGO
| S_IWUGO
), ab5500_dir
, ab
, &ab5500_address_fops
);
777 if (!ab5500_address_file
)
778 goto exit_destroy_bank
;
780 ab5500_val_file
= debugfs_create_file("register-value",
781 (S_IRUGO
| S_IWUGO
), ab5500_dir
, ab
, &ab5500_val_fops
);
782 if (!ab5500_val_file
)
783 goto exit_destroy_address
;
787 exit_destroy_address
:
788 debugfs_remove(ab5500_address_file
);
790 debugfs_remove(ab5500_bank_file
);
792 debugfs_remove(ab5500_reg_file
);
794 debugfs_remove(ab5500_dir
);
796 dev_err(ab
->dev
, "failed to create debugfs entries.\n");
800 void __exit
ab5500_remove_debugfs(void)
802 debugfs_remove(ab5500_val_file
);
803 debugfs_remove(ab5500_address_file
);
804 debugfs_remove(ab5500_bank_file
);
805 debugfs_remove(ab5500_reg_file
);
806 debugfs_remove(ab5500_dir
);