2 * drivers/mfd/rt5025-debug.c
3 * Driver foo Richtek RT5025 PMIC Debug
5 * Copyright (C) 2013 Richtek Electronics
6 * cy_huang <cy_huang@richtek.com>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
13 #include <linux/module.h>
14 #include <linux/kernel.h>
15 #include <linux/err.h>
16 #include <linux/i2c.h>
17 #include <linux/platform_device.h>
18 #include <linux/slab.h>
20 #include <linux/uaccess.h>
21 #include <linux/debugfs.h>
22 #include <linux/string.h>
24 #include <linux/mfd/rt5025.h>
26 struct rt5025_debug_info {
27 struct i2c_client *i2c;
30 static struct i2c_client *client;
31 static struct dentry *debugfs_rt_dent;
32 static struct dentry *debugfs_peek;
33 static struct dentry *debugfs_poke;
34 static struct dentry *debugfs_regs;
36 static unsigned char read_data[10];
38 static int reg_debug_open(struct inode *inode, struct file *file)
40 file->private_data = inode->i_private;
44 static int get_parameters(char *buf, long int *param1, int num_of_par)
49 token = strsep(&buf, " ");
51 for (cnt = 0; cnt < num_of_par; cnt++) {
53 if ((token[1] == 'x') || (token[1] == 'X'))
58 if (strict_strtoul(token, base, ¶m1[cnt]) != 0)
61 token = strsep(&buf, " ");
69 #define LOG_FORMAT "0x%02x\n0x%02x\n0x%02x\n0x%02x\n0x%02x\n"
71 static ssize_t reg_debug_read(struct file *filp, char __user *ubuf,
72 size_t count, loff_t *ppos)
74 char *access_str = filp->private_data;
76 if (!strcmp(access_str, "regs"))
78 RTINFO("read regs file\n");
80 snprintf(lbuf, sizeof(lbuf), LOG_FORMAT LOG_FORMAT, read_data[0], \
81 read_data[1], read_data[2], read_data[3], read_data[4], read_data[5], \
82 read_data[6], read_data[7], read_data[8], read_data[9]);
85 snprintf(lbuf, sizeof(lbuf), "0x%02x\n", read_data[0]);
86 return simple_read_from_buffer(ubuf, count, ppos, lbuf, strlen(lbuf));
89 static ssize_t reg_debug_write(struct file *filp,
90 const char __user *ubuf, size_t cnt, loff_t *ppos)
92 char *access_str = filp->private_data;
97 if (cnt > sizeof(lbuf) - 1)
100 rc = copy_from_user(lbuf, ubuf, cnt);
106 if (!strcmp(access_str, "poke")) {
108 rc = get_parameters(lbuf, param, 2);
109 if ((param[0] <= 0xFF) && (param[1] <= 0xFF) && (rc == 0))
111 rt5025_reg_write(client, param[0], (unsigned char)param[1]);
115 } else if (!strcmp(access_str, "peek")) {
117 rc = get_parameters(lbuf, param, 1);
118 if ((param[0] <= 0xFF) && (rc == 0))
120 read_data[0] = rt5025_reg_read(client, param[0]);
124 } else if (!strcmp(access_str, "regs")) {
126 rc = get_parameters(lbuf, param, 1);
127 if ((param[0] <= 0xFF) && (rc == 0))
129 rt5025_reg_block_read(client, param[0], 10, read_data);
130 RTINFO("regs 0 = 0x%02x\n", read_data[0]);
131 RTINFO("regs 1 = 0x%02x\n", read_data[1]);
132 RTINFO("regs 2 = 0x%02x\n", read_data[2]);
133 RTINFO("regs 3 = 0x%02x\n", read_data[3]);
134 RTINFO("regs 4 = 0x%02x\n", read_data[4]);
135 RTINFO("regs 5 = 0x%02x\n", read_data[5]);
136 RTINFO("regs 6 = 0x%02x\n", read_data[6]);
137 RTINFO("regs 7 = 0x%02x\n", read_data[7]);
138 RTINFO("regs 8 = 0x%02x\n", read_data[8]);
139 RTINFO("regs 9 = 0x%02x\n", read_data[9]);
151 static const struct file_operations reg_debug_ops = {
152 .open = reg_debug_open,
153 .write = reg_debug_write,
154 .read = reg_debug_read
157 static int __devinit rt5025_debug_probe(struct platform_device *pdev)
159 struct rt5025_chip *chip = dev_get_drvdata(pdev->dev.parent);
160 struct rt5025_debug_info *di;
162 di = kzalloc(sizeof(*di), GFP_KERNEL);
168 RTINFO("add debugfs for core RT5025");
170 debugfs_rt_dent = debugfs_create_dir("rt5025_dbg", 0);
171 if (!IS_ERR(debugfs_rt_dent)) {
172 debugfs_peek = debugfs_create_file("peek",
173 S_IFREG | S_IRUGO, debugfs_rt_dent,
174 (void *) "peek", ®_debug_ops);
176 debugfs_poke = debugfs_create_file("poke",
177 S_IFREG | S_IRUGO, debugfs_rt_dent,
178 (void *) "poke", ®_debug_ops);
180 debugfs_regs = debugfs_create_file("regs",
181 S_IFREG | S_IRUGO, debugfs_rt_dent,
182 (void *) "regs", ®_debug_ops);
185 platform_set_drvdata(pdev, di);
190 static int __devexit rt5025_debug_remove(struct platform_device *pdev)
192 struct rt5025_debug_info *di = platform_get_drvdata(pdev);
194 if (!IS_ERR(debugfs_rt_dent))
195 debugfs_remove_recursive(debugfs_rt_dent);
201 static struct platform_driver rt5025_debug_driver =
204 .name = RT5025_DEVICE_NAME "-debug",
205 .owner = THIS_MODULE,
207 .probe = rt5025_debug_probe,
208 .remove = __devexit_p(rt5025_debug_remove),
211 static int __init rt5025_debug_init(void)
213 return platform_driver_register(&rt5025_debug_driver);
215 module_init(rt5025_debug_init);
217 static void __exit rt5025_debug_exit(void)
219 platform_driver_unregister(&rt5025_debug_driver);
221 module_exit(rt5025_debug_exit);
223 MODULE_LICENSE("GPL v2");
224 MODULE_AUTHOR("CY Huang <cy_huang@richtek.com");
225 MODULE_DESCRIPTION("Debug driver for RT5025");
226 MODULE_ALIAS("platform:" RT5025_DEVICE_NAME "-debug");