Fix warnings and errors when compiled under rt kernel
[microdia.git] / microdia-debugfs.c
blobe272c4d319844801caba10de1c98575a9df94ade
1 /**
2 * @file microdia-debugfs.c
3 * @author Brian johnson
4 * @date 2008-03-28
5 * @version v0.0.0
7 * @brief Driver for Microdia USB video camera
9 * @note Copyright (C) Brian Johnson
11 * @par Licences
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 #include <linux/debugfs.h>
29 #include <linux/seq_file.h>
31 #include "microdia.h"
32 #include "sn9c20x.h"
34 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 25)
35 #undef DEFINE_SIMPLE_ATTRIBUTE
36 #define DEFINE_SIMPLE_ATTRIBUTE(__fops, __get, __set, __fmt) \
37 static void __fops ## _set_wrapper(void *data, __u64 val) \
38 { \
39 __set(data, val); \
40 } \
41 static __u64 __fops ## _get_wrapper(void *data) \
42 { \
43 __u64 value; \
44 __get(data, &value); \
45 return value; \
46 } \
47 static int __fops ## _open(struct inode *inode, struct file *file) \
48 { \
49 __simple_attr_check_format(__fmt, 0ull); \
50 return simple_attr_open(inode, file, \
51 __fops ## _get_wrapper, \
52 __fops ## _set_wrapper, \
53 __fmt); \
54 } \
55 static struct file_operations __fops = { \
56 .owner = THIS_MODULE, \
57 .open = __fops ## _open, \
58 .release = simple_attr_close, \
59 .read = simple_attr_read, \
60 .write = simple_attr_write, \
62 #endif
64 /**
65 * @var debug_dir_name
66 * Name of our directory in debugfs
68 static const char *debug_dir_name = "microdia";
70 /**
71 * @var debug_dir
72 * Dentry for our debug dir (for cleanup)
74 static struct dentry *debug_dir;
76 struct kref debug_ref;
77 /**
78 * @var dent_log_level
79 * debugfs entry for dynamically changing the log level
81 static struct dentry *dent_log_level;
83 static int debugfs_u16_set(void *data, __u64 val)
85 *(u16 *)data = val;
86 return 0;
89 static int debugfs_u16_get(void *data, __u64 *val)
91 *val = *(u16 *)data;
92 return 0;
95 static int debugfs_u8_set(void *data, __u64 val)
97 *(u8 *)data = val;
98 return 0;
101 static int debugfs_u8_get(void *data, __u64 *val)
103 *val = *(u8 *)data;
104 return 0;
107 static void *bridge_dump_start(struct seq_file *m, loff_t *pos)
109 loff_t *spos = kmalloc(sizeof(loff_t), GFP_KERNEL);
110 if (spos == NULL)
111 return ERR_PTR(-ENOMEM);
113 if (*pos < 0 || *pos > 31)
114 return NULL;
116 *spos = *pos;
117 return spos;
120 static void *bridge_dump_next(struct seq_file *m, void *v, loff_t *pos)
122 loff_t *spos = (loff_t *)v;
123 *pos = ++(*spos);
125 if (*spos > 31)
126 return ERR_PTR(-EACCES);
128 return spos;
131 static void bridge_dump_stop(struct seq_file *m, void *v)
133 if (v && !IS_ERR(v))
134 kfree(v);
137 static int bridge_dump_show(struct seq_file *m, void *v)
139 __u8 values[16];
140 loff_t *spos = (loff_t *)v;
141 __u16 reg = 0x1000 + (*spos * 16);
142 struct usb_microdia *dev = m->private;
144 if (usb_microdia_control_read(dev, reg, values, 16) < 0)
145 return -EACCES;
147 seq_printf(m, "0x%X %02X %02X %02X %02X %02X %02X %02X %02X "
148 "%02X %02X %02X %02X %02X %02X %02X %02X\n", reg,
149 values[0], values[1], values[2], values[3],
150 values[4], values[5], values[6], values[7],
151 values[8], values[9], values[10], values[11],
152 values[12], values[13], values[14], values[15]);
154 return 0;
157 static struct seq_operations bridge_dump_seq_ops = {
158 .start = bridge_dump_start,
159 .next = bridge_dump_next,
160 .stop = bridge_dump_stop,
161 .show = bridge_dump_show
164 static int bridge_dump_open(struct inode *inode, struct file *file)
166 int ret;
167 ret = seq_open(file, &bridge_dump_seq_ops);
168 if (ret == 0)
169 ((struct seq_file *)file->private_data)->private =
170 inode->i_private;
171 return ret;
174 static struct file_operations bridge_dump_ops = {
175 .owner = THIS_MODULE,
176 .open = bridge_dump_open,
177 .read = seq_read,
178 .llseek = seq_lseek,
179 .release = seq_release,
182 int bridge_value_set(void *data, __u64 val)
184 struct usb_microdia *dev = data;
185 __u8 value = (__u64)val;
186 if (dev != NULL) {
187 if (dev->debug.bridge_addr >= 0x1000 &&
188 dev->debug.bridge_addr <= 0x11ff) {
189 usb_microdia_control_write(dev,
190 dev->debug.bridge_addr,
191 &value, 1);
194 return 0;
197 int bridge_value_get(void *data, __u64 *val)
199 struct usb_microdia *dev = data;
200 __u8 value;
201 if (dev != NULL) {
202 if (dev->debug.bridge_addr >= 0x1000 &&
203 dev->debug.bridge_addr <= 0x11ff) {
204 if (usb_microdia_control_read(dev,
205 dev->debug.bridge_addr,
206 &value, 1) >= 0) {
207 *val = value;
211 return 0;
214 int sensor_value8_set(void *data, __u64 val)
216 struct usb_microdia *dev = data;
217 __u8 value = (__u8)val;
218 if (dev != NULL) {
219 sn9c20x_write_i2c_data(dev, dev->sensor_slave_address,
220 1, dev->debug.sensor_addr,
221 dev->sensor_flags, &value);
223 return 0;
226 int sensor_value8_get(void *data, __u64 *val)
228 struct usb_microdia *dev = data;
229 __u8 value;
230 if (dev != NULL) {
231 if (sn9c20x_read_i2c_data(dev, dev->sensor_slave_address,
232 1, dev->debug.sensor_addr,
233 dev->sensor_flags, &value) >= 0) {
234 *val = value & 0xFF;
237 return 0;
240 int sensor_value16_set(void *data, __u64 val)
242 struct usb_microdia *dev = data;
243 __u8 buf[2];
244 buf[0] = (val >> 8) & 0xFF;
245 buf[1] = val & 0xFF;
246 if (dev != NULL) {
247 sn9c20x_write_i2c_data(dev, dev->sensor_slave_address,
248 2, dev->debug.sensor_addr,
249 dev->sensor_flags, buf);
251 return 0;
254 int sensor_value16_get(void *data, __u64 *val)
256 struct usb_microdia *dev = data;
257 __u8 buf[2];
258 if (dev != NULL) {
259 if (sn9c20x_read_i2c_data(dev, dev->sensor_slave_address,
260 2, dev->debug.sensor_addr,
261 dev->sensor_flags, buf) >= 0) {
262 *val = ((buf[0] << 8) | buf[1]) & 0xFFFF;
265 return 0;
268 int sensor_value32_set(void *data, __u64 val)
270 struct usb_microdia *dev = data;
271 __u8 buf[4];
272 buf[0] = (val >> 24) & 0xFF;
273 buf[1] = (val >> 16) & 0xFF;
274 buf[2] = (val >> 8) & 0xFF;
275 buf[3] = val & 0xFF;
276 if (dev != NULL) {
277 sn9c20x_write_i2c_data(dev, dev->sensor_slave_address,
278 4, dev->debug.sensor_addr,
279 dev->sensor_flags, buf);
281 return 0;
284 int sensor_value32_get(void *data, __u64 *val)
286 struct usb_microdia *dev = data;
287 __u8 buf[4];
288 if (dev != NULL) {
289 if (sn9c20x_read_i2c_data(dev, dev->sensor_slave_address,
290 4, dev->debug.sensor_addr,
291 dev->sensor_flags, buf) >= 0) {
292 *val = ((buf[0] << 24) | (buf[1] << 16)
293 | (buf[2] << 8) | buf[3]) & 0xFFFFFFFF;
296 return 0;
299 DEFINE_SIMPLE_ATTRIBUTE(fops_x16,
300 debugfs_u16_get,
301 debugfs_u16_set,
302 "0x%04llx\n");
304 DEFINE_SIMPLE_ATTRIBUTE(fops_x8,
305 debugfs_u8_get,
306 debugfs_u8_set,
307 "0x%02llx\n");
309 DEFINE_SIMPLE_ATTRIBUTE(bridge_value_ops,
310 bridge_value_get,
311 bridge_value_set,
312 "0x%02llx\n");
314 DEFINE_SIMPLE_ATTRIBUTE(sensor_value8_ops,
315 sensor_value8_get,
316 sensor_value8_set,
317 "0x%02llX\n");
319 DEFINE_SIMPLE_ATTRIBUTE(sensor_value16_ops,
320 sensor_value16_get,
321 sensor_value16_set,
322 "0x%04llX\n");
324 DEFINE_SIMPLE_ATTRIBUTE(sensor_value32_ops,
325 sensor_value32_get,
326 sensor_value32_set,
327 "0x%08llX\n");
329 void debugfs_delete(struct kref *ref)
331 if (debug_dir)
332 debugfs_remove(debug_dir);
335 void microdia_init_debugfs()
337 debug_dir = debugfs_create_dir(debug_dir_name, NULL);
338 if (debug_dir)
339 dent_log_level = debugfs_create_u8("log_level",
340 S_IRUGO | S_IWUGO,
341 debug_dir,
342 &log_level);
343 kref_init(&debug_ref);
347 void microdia_uninit_debugfs()
349 if (dent_log_level)
350 debugfs_remove(dent_log_level);
351 kref_put(&debug_ref, debugfs_delete);
355 * @brief Create the 'debug' entries.
357 * This function permits to create all the entries in the 'debug' filesystem.
359 * @param usb_microdia device structure
361 * @returns 0 if all is OK
363 int microdia_create_debugfs_files(struct usb_microdia *dev)
365 char device_name[9];
366 if (debug_dir) {
367 snprintf(device_name, 9, "video%d", dev->vdev->minor);
368 dev->debug.dent_device =
369 debugfs_create_dir(device_name, debug_dir);
370 if (dev->debug.dent_device) {
371 dev->debug.bridge_addr = 0x1000;
372 dev->debug.sensor_addr = 0x00;
373 dev->debug.dent_bridge_addr =
374 debugfs_create_file("bridge.address",
375 S_IRUGO | S_IWUGO,
376 dev->debug.dent_device,
377 &dev->debug.bridge_addr,
378 &fops_x16);
379 dev->debug.dent_bridge_val =
380 debugfs_create_file("bridge.value",
381 S_IRUGO | S_IWUGO,
382 dev->debug.dent_device,
383 dev, &bridge_value_ops);
384 dev->debug.dent_bridge_dump =
385 debugfs_create_file("bridge.dump",
386 S_IRUGO,
387 dev->debug.dent_device,
388 dev, &bridge_dump_ops);
389 dev->debug.dent_sensor_addr =
390 debugfs_create_file("sensor.address",
391 S_IRUGO | S_IWUGO,
392 dev->debug.dent_device,
393 &dev->debug.sensor_addr,
394 &fops_x8);
395 dev->debug.dent_sensor_val8 =
396 debugfs_create_file("sensor.value8",
397 S_IRUGO | S_IWUGO,
398 dev->debug.dent_device,
399 dev, &sensor_value8_ops);
400 dev->debug.dent_sensor_val16 =
401 debugfs_create_file("sensor.value16",
402 S_IRUGO | S_IWUGO,
403 dev->debug.dent_device,
404 dev, &sensor_value16_ops);
405 dev->debug.dent_sensor_val32 =
406 debugfs_create_file("sensor.value32",
407 S_IRUGO | S_IWUGO,
408 dev->debug.dent_device,
409 dev, &sensor_value32_ops);
412 kref_get(&debug_ref);
413 return 0;
417 * @brief Remove the 'debugfs' entries.
419 * This function permits to remove all the entries in the 'debug' filesystem.
421 * @param usb_microdia device structure
423 * @returns 0 if all is OK
425 int microdia_remove_debugfs_files(struct usb_microdia *dev)
427 if (dev->debug.dent_bridge_val)
428 debugfs_remove(dev->debug.dent_bridge_val);
429 if (dev->debug.dent_bridge_addr)
430 debugfs_remove(dev->debug.dent_bridge_addr);
431 if (dev->debug.dent_bridge_dump)
432 debugfs_remove(dev->debug.dent_bridge_dump);
433 if (dev->debug.dent_sensor_addr)
434 debugfs_remove(dev->debug.dent_sensor_addr);
435 if (dev->debug.dent_sensor_val8)
436 debugfs_remove(dev->debug.dent_sensor_val8);
437 if (dev->debug.dent_sensor_val16)
438 debugfs_remove(dev->debug.dent_sensor_val16);
439 if (dev->debug.dent_sensor_val32)
440 debugfs_remove(dev->debug.dent_sensor_val32);
441 if (dev->debug.dent_device)
442 debugfs_remove(dev->debug.dent_device);
443 kref_put(&debug_ref, debugfs_delete);
444 return 0;