staging: iio: new invensence mpu6050/6500 driver
[firefly-linux-kernel-4.4.55.git] / drivers / staging / iio / imu / inv_mpu / inv_counters.c
1 /*
2  * @file inv_counters.c
3  * @brief Exports i2c read write counts through sysfs
4  *
5  * @version 0.1
6  */
7
8 #include <linux/module.h>
9 #include <linux/init.h>
10 #include <linux/device.h>
11 #include <linux/miscdevice.h>
12 #include <linux/err.h>
13 #include <linux/sysfs.h>
14 #include <linux/kdev_t.h>
15 #include <linux/string.h>
16 #include <linux/jiffies.h>
17 #include <linux/spinlock.h>
18 #include <linux/kernel_stat.h>
19
20 #include "inv_counters.h"
21
22 static int mpu_irq;
23 static int accel_irq;
24 static int compass_irq;
25
26 struct inv_counters {
27         uint32_t i2c_tempreads;
28         uint32_t i2c_mpureads;
29         uint32_t i2c_mpuwrites;
30         uint32_t i2c_accelreads;
31         uint32_t i2c_accelwrites;
32         uint32_t i2c_compassreads;
33         uint32_t i2c_compasswrites;
34         uint32_t i2c_compassirq;
35         uint32_t i2c_accelirq;
36 };
37
38 static struct inv_counters Counters;
39
40 static ssize_t i2c_counters_show(struct class *cls,
41                         struct class_attribute *attr, char *buf)
42 {
43         return scnprintf(buf, PAGE_SIZE,
44                 "%ld.%03ld %u %u %u %u %u %u %u %u %u %u\n",
45                 jiffies / HZ, ((jiffies % HZ) * (1024 / HZ)),
46                 mpu_irq ? kstat_irqs(mpu_irq) : 0,
47                 Counters.i2c_tempreads,
48                 Counters.i2c_mpureads, Counters.i2c_mpuwrites,
49                 accel_irq ? kstat_irqs(accel_irq) : Counters.i2c_accelirq,
50                 Counters.i2c_accelreads, Counters.i2c_accelwrites,
51                 compass_irq ? kstat_irqs(compass_irq) : Counters.i2c_compassirq,
52                 Counters.i2c_compassreads, Counters.i2c_compasswrites);
53 }
54
55 void inv_iio_counters_set_i2cirq(enum irqtype type, int irq)
56 {
57         switch (type) {
58         case IRQ_MPU:
59                 mpu_irq = irq;
60                 break;
61         case IRQ_ACCEL:
62                 accel_irq = irq;
63                 break;
64         case IRQ_COMPASS:
65                 compass_irq = irq;
66                 break;
67         }
68 }
69 EXPORT_SYMBOL_GPL(inv_iio_counters_set_i2cirq);
70
71 void inv_iio_counters_tempread(int count)
72 {
73         Counters.i2c_tempreads += count;
74 }
75 EXPORT_SYMBOL_GPL(inv_iio_counters_tempread);
76
77 void inv_iio_counters_mpuread(int count)
78 {
79         Counters.i2c_mpureads += count;
80 }
81 EXPORT_SYMBOL_GPL(inv_iio_counters_mpuread);
82
83 void inv_iio_counters_mpuwrite(int count)
84 {
85         Counters.i2c_mpuwrites += count;
86 }
87 EXPORT_SYMBOL_GPL(inv_iio_counters_mpuwrite);
88
89 void inv_iio_counters_accelread(int count)
90 {
91         Counters.i2c_accelreads += count;
92 }
93 EXPORT_SYMBOL_GPL(inv_iio_counters_accelread);
94
95 void inv_iio_counters_accelwrite(int count)
96 {
97         Counters.i2c_accelwrites += count;
98 }
99 EXPORT_SYMBOL_GPL(inv_iio_counters_accelwrite);
100
101 void inv_iio_counters_compassread(int count)
102 {
103         Counters.i2c_compassreads += count;
104 }
105 EXPORT_SYMBOL_GPL(inv_iio_counters_compassread);
106
107 void inv_iio_counters_compasswrite(int count)
108 {
109         Counters.i2c_compasswrites += count;
110 }
111 EXPORT_SYMBOL_GPL(inv_iio_counters_compasswrite);
112
113 void inv_iio_counters_compassirq(void)
114 {
115         Counters.i2c_compassirq++;
116 }
117 EXPORT_SYMBOL_GPL(inv_iio_counters_compassirq);
118
119 void inv_iio_counters_accelirq(void)
120 {
121         Counters.i2c_accelirq++;
122 }
123 EXPORT_SYMBOL_GPL(inv_iio_counters_accelirq);
124
125 static struct class_attribute inv_class_attr[] = {
126         __ATTR(i2c_counter, S_IRUGO, i2c_counters_show, NULL),
127         __ATTR_NULL
128 };
129
130 static struct class inv_counters_class = {
131         .name = "inv_counters",
132         .owner = THIS_MODULE,
133         .class_attrs = (struct class_attribute *) &inv_class_attr
134 };
135
136 static int __init inv_counters_init(void)
137 {
138         memset(&Counters, 0, sizeof(Counters));
139
140         return class_register(&inv_counters_class);
141 }
142
143 static void __exit inv_counters_exit(void)
144 {
145         class_unregister(&inv_counters_class);
146 }
147
148 module_init(inv_counters_init);
149 module_exit(inv_counters_exit);
150
151 MODULE_LICENSE("GPL");
152 MODULE_AUTHOR("GESL");
153 MODULE_DESCRIPTION("inv_counters debug support");
154