1/*
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 */
7
8#include <linux/seq_file.h>
9#include <linux/uaccess.h>
10#include <linux/fs.h>
11#include <linux/module.h>
12#include <linux/debugfs.h>
13#include <linux/platform_device.h>
14
15#include <linux/mfd/abx500.h>
16#include <linux/mfd/abx500/ab8500.h>
17
18static u32 debug_bank;
19static u32 debug_address;
20
21/**
22 * struct ab8500_reg_range
23 * @first: the first address of the range
24 * @last: the last address of the range
25 * @perm: access permissions for the range
26 */
27struct ab8500_reg_range {
28	u8 first;
29	u8 last;
30	u8 perm;
31};
32
33/**
34 * struct ab8500_i2c_ranges
35 * @num_ranges: the number of ranges in the list
36 * @bankid: bank identifier
37 * @range: the list of register ranges
38 */
39struct ab8500_i2c_ranges {
40	u8 num_ranges;
41	u8 bankid;
42	const struct ab8500_reg_range *range;
43};
44
45#define AB8500_NAME_STRING "ab8500"
46#define AB8500_NUM_BANKS 22
47
48#define AB8500_REV_REG 0x80
49
50static struct ab8500_i2c_ranges debug_ranges[AB8500_NUM_BANKS] = {
51	[0x0] = {
52		.num_ranges = 0,
53		.range = 0,
54	},
55	[AB8500_SYS_CTRL1_BLOCK] = {
56		.num_ranges = 3,
57		.range = (struct ab8500_reg_range[]) {
58			{
59				.first = 0x00,
60				.last = 0x02,
61			},
62			{
63				.first = 0x42,
64				.last = 0x42,
65			},
66			{
67				.first = 0x80,
68				.last = 0x81,
69			},
70		},
71	},
72	[AB8500_SYS_CTRL2_BLOCK] = {
73		.num_ranges = 4,
74		.range = (struct ab8500_reg_range[]) {
75			{
76				.first = 0x00,
77				.last = 0x0D,
78			},
79			{
80				.first = 0x0F,
81				.last = 0x17,
82			},
83			{
84				.first = 0x30,
85				.last = 0x30,
86			},
87			{
88				.first = 0x32,
89				.last = 0x33,
90			},
91		},
92	},
93	[AB8500_REGU_CTRL1] = {
94		.num_ranges = 3,
95		.range = (struct ab8500_reg_range[]) {
96			{
97				.first = 0x00,
98				.last = 0x00,
99			},
100			{
101				.first = 0x03,
102				.last = 0x10,
103			},
104			{
105				.first = 0x80,
106				.last = 0x84,
107			},
108		},
109	},
110	[AB8500_REGU_CTRL2] = {
111		.num_ranges = 5,
112		.range = (struct ab8500_reg_range[]) {
113			{
114				.first = 0x00,
115				.last = 0x15,
116			},
117			{
118				.first = 0x17,
119				.last = 0x19,
120			},
121			{
122				.first = 0x1B,
123				.last = 0x1D,
124			},
125			{
126				.first = 0x1F,
127				.last = 0x22,
128			},
129			{
130				.first = 0x40,
131				.last = 0x44,
132			},
133			/* 0x80-0x8B is SIM registers and should
134			 * not be accessed from here */
135		},
136	},
137	[AB8500_USB] = {
138		.num_ranges = 2,
139		.range = (struct ab8500_reg_range[]) {
140			{
141				.first = 0x80,
142				.last = 0x83,
143			},
144			{
145				.first = 0x87,
146				.last = 0x8A,
147			},
148		},
149	},
150	[AB8500_TVOUT] = {
151		.num_ranges = 9,
152		.range = (struct ab8500_reg_range[]) {
153			{
154				.first = 0x00,
155				.last = 0x12,
156			},
157			{
158				.first = 0x15,
159				.last = 0x17,
160			},
161			{
162				.first = 0x19,
163				.last = 0x21,
164			},
165			{
166				.first = 0x27,
167				.last = 0x2C,
168			},
169			{
170				.first = 0x41,
171				.last = 0x41,
172			},
173			{
174				.first = 0x45,
175				.last = 0x5B,
176			},
177			{
178				.first = 0x5D,
179				.last = 0x5D,
180			},
181			{
182				.first = 0x69,
183				.last = 0x69,
184			},
185			{
186				.first = 0x80,
187				.last = 0x81,
188			},
189		},
190	},
191	[AB8500_DBI] = {
192		.num_ranges = 0,
193		.range = NULL,
194	},
195	[AB8500_ECI_AV_ACC] = {
196		.num_ranges = 1,
197		.range = (struct ab8500_reg_range[]) {
198			{
199				.first = 0x80,
200				.last = 0x82,
201			},
202		},
203	},
204	[0x9] = {
205		.num_ranges = 0,
206		.range = NULL,
207	},
208	[AB8500_GPADC] = {
209		.num_ranges = 1,
210		.range = (struct ab8500_reg_range[]) {
211			{
212				.first = 0x00,
213				.last = 0x08,
214			},
215		},
216	},
217	[AB8500_CHARGER] = {
218		.num_ranges = 8,
219		.range = (struct ab8500_reg_range[]) {
220			{
221				.first = 0x00,
222				.last = 0x03,
223			},
224			{
225				.first = 0x05,
226				.last = 0x05,
227			},
228			{
229				.first = 0x40,
230				.last = 0x40,
231			},
232			{
233				.first = 0x42,
234				.last = 0x42,
235			},
236			{
237				.first = 0x44,
238				.last = 0x44,
239			},
240			{
241				.first = 0x50,
242				.last = 0x55,
243			},
244			{
245				.first = 0x80,
246				.last = 0x82,
247			},
248			{
249				.first = 0xC0,
250				.last = 0xC2,
251			},
252		},
253	},
254	[AB8500_GAS_GAUGE] = {
255		.num_ranges = 3,
256		.range = (struct ab8500_reg_range[]) {
257			{
258				.first = 0x00,
259				.last = 0x00,
260			},
261			{
262				.first = 0x07,
263				.last = 0x0A,
264			},
265			{
266				.first = 0x10,
267				.last = 0x14,
268			},
269		},
270	},
271	[AB8500_AUDIO] = {
272		.num_ranges = 1,
273		.range = (struct ab8500_reg_range[]) {
274			{
275				.first = 0x00,
276				.last = 0x6F,
277			},
278		},
279	},
280	[AB8500_INTERRUPT] = {
281		.num_ranges = 0,
282		.range = NULL,
283	},
284	[AB8500_RTC] = {
285		.num_ranges = 1,
286		.range = (struct ab8500_reg_range[]) {
287			{
288				.first = 0x00,
289				.last = 0x0F,
290			},
291		},
292	},
293	[AB8500_MISC] = {
294		.num_ranges = 8,
295		.range = (struct ab8500_reg_range[]) {
296			{
297				.first = 0x00,
298				.last = 0x05,
299			},
300			{
301				.first = 0x10,
302				.last = 0x15,
303			},
304			{
305				.first = 0x20,
306				.last = 0x25,
307			},
308			{
309				.first = 0x30,
310				.last = 0x35,
311			},
312			{
313				.first = 0x40,
314				.last = 0x45,
315			},
316			{
317				.first = 0x50,
318				.last = 0x50,
319			},
320			{
321				.first = 0x60,
322				.last = 0x67,
323			},
324			{
325				.first = 0x80,
326				.last = 0x80,
327			},
328		},
329	},
330	[0x11] = {
331		.num_ranges = 0,
332		.range = NULL,
333	},
334	[0x12] = {
335		.num_ranges = 0,
336		.range = NULL,
337	},
338	[0x13] = {
339		.num_ranges = 0,
340		.range = NULL,
341	},
342	[0x14] = {
343		.num_ranges = 0,
344		.range = NULL,
345	},
346	[AB8500_OTP_EMUL] = {
347		.num_ranges = 1,
348		.range = (struct ab8500_reg_range[]) {
349			{
350				.first = 0x01,
351				.last = 0x0F,
352			},
353		},
354	},
355};
356
357static int ab8500_registers_print(struct seq_file *s, void *p)
358{
359	struct device *dev = s->private;
360	unsigned int i;
361	u32 bank = debug_bank;
362
363	seq_printf(s, AB8500_NAME_STRING " register values:\n");
364
365	seq_printf(s, " bank %u:\n", bank);
366	for (i = 0; i < debug_ranges[bank].num_ranges; i++) {
367		u32 reg;
368
369		for (reg = debug_ranges[bank].range[i].first;
370			reg <= debug_ranges[bank].range[i].last;
371			reg++) {
372			u8 value;
373			int err;
374
375			err = abx500_get_register_interruptible(dev,
376				(u8)bank, (u8)reg, &value);
377			if (err < 0) {
378				dev_err(dev, "ab->read fail %d\n", err);
379				return err;
380			}
381
382			err = seq_printf(s, "  [%u/0x%02X]: 0x%02X\n", bank,
383				reg, value);
384			if (err < 0) {
385				dev_err(dev, "seq_printf overflow\n");
386				/* Error is not returned here since
387				 * the output is wanted in any case */
388				return 0;
389			}
390		}
391	}
392	return 0;
393}
394
395static int ab8500_registers_open(struct inode *inode, struct file *file)
396{
397	return single_open(file, ab8500_registers_print, inode->i_private);
398}
399
400static const struct file_operations ab8500_registers_fops = {
401	.open = ab8500_registers_open,
402	.read = seq_read,
403	.llseek = seq_lseek,
404	.release = single_release,
405	.owner = THIS_MODULE,
406};
407
408static int ab8500_bank_print(struct seq_file *s, void *p)
409{
410	return seq_printf(s, "%d\n", debug_bank);
411}
412
413static int ab8500_bank_open(struct inode *inode, struct file *file)
414{
415	return single_open(file, ab8500_bank_print, inode->i_private);
416}
417
418static ssize_t ab8500_bank_write(struct file *file,
419	const char __user *user_buf,
420	size_t count, loff_t *ppos)
421{
422	struct device *dev = ((struct seq_file *)(file->private_data))->private;
423	unsigned long user_bank;
424	int err;
425
426	/* Get userspace string and assure termination */
427	err = kstrtoul_from_user(user_buf, count, 0, &user_bank);
428	if (err)
429		return err;
430
431	if (user_bank >= AB8500_NUM_BANKS) {
432		dev_err(dev, "debugfs error input > number of banks\n");
433		return -EINVAL;
434	}
435
436	debug_bank = user_bank;
437
438	return count;
439}
440
441static int ab8500_address_print(struct seq_file *s, void *p)
442{
443	return seq_printf(s, "0x%02X\n", debug_address);
444}
445
446static int ab8500_address_open(struct inode *inode, struct file *file)
447{
448	return single_open(file, ab8500_address_print, inode->i_private);
449}
450
451static ssize_t ab8500_address_write(struct file *file,
452	const char __user *user_buf,
453	size_t count, loff_t *ppos)
454{
455	struct device *dev = ((struct seq_file *)(file->private_data))->private;
456	unsigned long user_address;
457	int err;
458
459	/* Get userspace string and assure termination */
460	err = kstrtoul_from_user(user_buf, count, 0, &user_address);
461	if (err)
462		return err;
463
464	if (user_address > 0xff) {
465		dev_err(dev, "debugfs error input > 0xff\n");
466		return -EINVAL;
467	}
468	debug_address = user_address;
469	return count;
470}
471
472static int ab8500_val_print(struct seq_file *s, void *p)
473{
474	struct device *dev = s->private;
475	int ret;
476	u8 regvalue;
477
478	ret = abx500_get_register_interruptible(dev,
479		(u8)debug_bank, (u8)debug_address, &regvalue);
480	if (ret < 0) {
481		dev_err(dev, "abx500_get_reg fail %d, %d\n",
482			ret, __LINE__);
483		return -EINVAL;
484	}
485	seq_printf(s, "0x%02X\n", regvalue);
486
487	return 0;
488}
489
490static int ab8500_val_open(struct inode *inode, struct file *file)
491{
492	return single_open(file, ab8500_val_print, inode->i_private);
493}
494
495static ssize_t ab8500_val_write(struct file *file,
496	const char __user *user_buf,
497	size_t count, loff_t *ppos)
498{
499	struct device *dev = ((struct seq_file *)(file->private_data))->private;
500	unsigned long user_val;
501	int err;
502
503	/* Get userspace string and assure termination */
504	err = kstrtoul_from_user(user_buf, count, 0, &user_val);
505	if (err)
506		return err;
507
508	if (user_val > 0xff) {
509		dev_err(dev, "debugfs error input > 0xff\n");
510		return -EINVAL;
511	}
512	err = abx500_set_register_interruptible(dev,
513		(u8)debug_bank, debug_address, (u8)user_val);
514	if (err < 0) {
515		printk(KERN_ERR "abx500_set_reg failed %d, %d", err, __LINE__);
516		return -EINVAL;
517	}
518
519	return count;
520}
521
522static const struct file_operations ab8500_bank_fops = {
523	.open = ab8500_bank_open,
524	.write = ab8500_bank_write,
525	.read = seq_read,
526	.llseek = seq_lseek,
527	.release = single_release,
528	.owner = THIS_MODULE,
529};
530
531static const struct file_operations ab8500_address_fops = {
532	.open = ab8500_address_open,
533	.write = ab8500_address_write,
534	.read = seq_read,
535	.llseek = seq_lseek,
536	.release = single_release,
537	.owner = THIS_MODULE,
538};
539
540static const struct file_operations ab8500_val_fops = {
541	.open = ab8500_val_open,
542	.write = ab8500_val_write,
543	.read = seq_read,
544	.llseek = seq_lseek,
545	.release = single_release,
546	.owner = THIS_MODULE,
547};
548
549static struct dentry *ab8500_dir;
550static struct dentry *ab8500_reg_file;
551static struct dentry *ab8500_bank_file;
552static struct dentry *ab8500_address_file;
553static struct dentry *ab8500_val_file;
554
555static int __devinit ab8500_debug_probe(struct platform_device *plf)
556{
557	debug_bank = AB8500_MISC;
558	debug_address = AB8500_REV_REG & 0x00FF;
559
560	ab8500_dir = debugfs_create_dir(AB8500_NAME_STRING, NULL);
561	if (!ab8500_dir)
562		goto exit_no_debugfs;
563
564	ab8500_reg_file = debugfs_create_file("all-bank-registers",
565		S_IRUGO, ab8500_dir, &plf->dev, &ab8500_registers_fops);
566	if (!ab8500_reg_file)
567		goto exit_destroy_dir;
568
569	ab8500_bank_file = debugfs_create_file("register-bank",
570		(S_IRUGO | S_IWUSR), ab8500_dir, &plf->dev, &ab8500_bank_fops);
571	if (!ab8500_bank_file)
572		goto exit_destroy_reg;
573
574	ab8500_address_file = debugfs_create_file("register-address",
575		(S_IRUGO | S_IWUSR), ab8500_dir, &plf->dev,
576		&ab8500_address_fops);
577	if (!ab8500_address_file)
578		goto exit_destroy_bank;
579
580	ab8500_val_file = debugfs_create_file("register-value",
581		(S_IRUGO | S_IWUSR), ab8500_dir, &plf->dev, &ab8500_val_fops);
582	if (!ab8500_val_file)
583		goto exit_destroy_address;
584
585	return 0;
586
587exit_destroy_address:
588	debugfs_remove(ab8500_address_file);
589exit_destroy_bank:
590	debugfs_remove(ab8500_bank_file);
591exit_destroy_reg:
592	debugfs_remove(ab8500_reg_file);
593exit_destroy_dir:
594	debugfs_remove(ab8500_dir);
595exit_no_debugfs:
596	dev_err(&plf->dev, "failed to create debugfs entries.\n");
597	return -ENOMEM;
598}
599
600static int __devexit ab8500_debug_remove(struct platform_device *plf)
601{
602	debugfs_remove(ab8500_val_file);
603	debugfs_remove(ab8500_address_file);
604	debugfs_remove(ab8500_bank_file);
605	debugfs_remove(ab8500_reg_file);
606	debugfs_remove(ab8500_dir);
607
608	return 0;
609}
610
611static struct platform_driver ab8500_debug_driver = {
612	.driver = {
613		.name = "ab8500-debug",
614		.owner = THIS_MODULE,
615	},
616	.probe  = ab8500_debug_probe,
617	.remove = __devexit_p(ab8500_debug_remove)
618};
619
620static int __init ab8500_debug_init(void)
621{
622	return platform_driver_register(&ab8500_debug_driver);
623}
624
625static void __exit ab8500_debug_exit(void)
626{
627	platform_driver_unregister(&ab8500_debug_driver);
628}
629subsys_initcall(ab8500_debug_init);
630module_exit(ab8500_debug_exit);
631
632MODULE_AUTHOR("Mattias WALLIN <mattias.wallin@stericsson.com");
633MODULE_DESCRIPTION("AB8500 DEBUG");
634MODULE_LICENSE("GPL v2");
635