Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6
[pandora-kernel.git] / drivers / media / IR / ir-sysfs.c
1 /* ir-sysfs.c - sysfs interface for RC devices (/sys/class/rc)
2  *
3  * Copyright (C) 2009-2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation version 2 of the License.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  */
14
15 #include <linux/slab.h>
16 #include <linux/input.h>
17 #include <linux/device.h>
18 #include "ir-core-priv.h"
19
20 #define IRRCV_NUM_DEVICES       256
21
22 /* bit array to represent IR sysfs device number */
23 static unsigned long ir_core_dev_number;
24
25 /* class for /sys/class/rc */
26 static char *ir_devnode(struct device *dev, mode_t *mode)
27 {
28         return kasprintf(GFP_KERNEL, "rc/%s", dev_name(dev));
29 }
30
31 static struct class ir_input_class = {
32         .name           = "rc",
33         .devnode        = ir_devnode,
34 };
35
36 static struct {
37         u64     type;
38         char    *name;
39 } proto_names[] = {
40         { IR_TYPE_UNKNOWN,      "unknown"       },
41         { IR_TYPE_RC5,          "rc-5"          },
42         { IR_TYPE_NEC,          "nec"           },
43         { IR_TYPE_RC6,          "rc-6"          },
44         { IR_TYPE_JVC,          "jvc"           },
45         { IR_TYPE_SONY,         "sony"          },
46         { IR_TYPE_RC5_SZ,       "rc-5-sz"       },
47         { IR_TYPE_LIRC,         "lirc"          },
48 };
49
50 #define PROTO_NONE      "none"
51
52 /**
53  * show_protocols() - shows the current IR protocol(s)
54  * @d:          the device descriptor
55  * @mattr:      the device attribute struct (unused)
56  * @buf:        a pointer to the output buffer
57  *
58  * This routine is a callback routine for input read the IR protocol type(s).
59  * it is trigged by reading /sys/class/rc/rc?/protocols.
60  * It returns the protocol names of supported protocols.
61  * Enabled protocols are printed in brackets.
62  */
63 static ssize_t show_protocols(struct device *d,
64                               struct device_attribute *mattr, char *buf)
65 {
66         struct ir_input_dev *ir_dev = dev_get_drvdata(d);
67         u64 allowed, enabled;
68         char *tmp = buf;
69         int i;
70
71         /* Device is being removed */
72         if (!ir_dev)
73                 return -EINVAL;
74
75         if (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_SCANCODE) {
76                 enabled = ir_dev->rc_tab.ir_type;
77                 allowed = ir_dev->props->allowed_protos;
78         } else if (ir_dev->raw) {
79                 enabled = ir_dev->raw->enabled_protocols;
80                 allowed = ir_raw_get_allowed_protocols();
81         } else
82                 return sprintf(tmp, "[builtin]\n");
83
84         IR_dprintk(1, "allowed - 0x%llx, enabled - 0x%llx\n",
85                    (long long)allowed,
86                    (long long)enabled);
87
88         for (i = 0; i < ARRAY_SIZE(proto_names); i++) {
89                 if (allowed & enabled & proto_names[i].type)
90                         tmp += sprintf(tmp, "[%s] ", proto_names[i].name);
91                 else if (allowed & proto_names[i].type)
92                         tmp += sprintf(tmp, "%s ", proto_names[i].name);
93         }
94
95         if (tmp != buf)
96                 tmp--;
97         *tmp = '\n';
98         return tmp + 1 - buf;
99 }
100
101 /**
102  * store_protocols() - changes the current IR protocol(s)
103  * @d:          the device descriptor
104  * @mattr:      the device attribute struct (unused)
105  * @buf:        a pointer to the input buffer
106  * @len:        length of the input buffer
107  *
108  * This routine is a callback routine for changing the IR protocol type.
109  * It is trigged by writing to /sys/class/rc/rc?/protocols.
110  * Writing "+proto" will add a protocol to the list of enabled protocols.
111  * Writing "-proto" will remove a protocol from the list of enabled protocols.
112  * Writing "proto" will enable only "proto".
113  * Writing "none" will disable all protocols.
114  * Returns -EINVAL if an invalid protocol combination or unknown protocol name
115  * is used, otherwise @len.
116  */
117 static ssize_t store_protocols(struct device *d,
118                                struct device_attribute *mattr,
119                                const char *data,
120                                size_t len)
121 {
122         struct ir_input_dev *ir_dev = dev_get_drvdata(d);
123         bool enable, disable;
124         const char *tmp;
125         u64 type;
126         u64 mask;
127         int rc, i, count = 0;
128         unsigned long flags;
129
130         /* Device is being removed */
131         if (!ir_dev)
132                 return -EINVAL;
133
134         if (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_SCANCODE)
135                 type = ir_dev->rc_tab.ir_type;
136         else if (ir_dev->raw)
137                 type = ir_dev->raw->enabled_protocols;
138         else {
139                 IR_dprintk(1, "Protocol switching not supported\n");
140                 return -EINVAL;
141         }
142
143         while ((tmp = strsep((char **) &data, " \n")) != NULL) {
144                 if (!*tmp)
145                         break;
146
147                 if (*tmp == '+') {
148                         enable = true;
149                         disable = false;
150                         tmp++;
151                 } else if (*tmp == '-') {
152                         enable = false;
153                         disable = true;
154                         tmp++;
155                 } else {
156                         enable = false;
157                         disable = false;
158                 }
159
160                 if (!enable && !disable && !strncasecmp(tmp, PROTO_NONE, sizeof(PROTO_NONE))) {
161                         tmp += sizeof(PROTO_NONE);
162                         mask = 0;
163                         count++;
164                 } else {
165                         for (i = 0; i < ARRAY_SIZE(proto_names); i++) {
166                                 if (!strncasecmp(tmp, proto_names[i].name, strlen(proto_names[i].name))) {
167                                         tmp += strlen(proto_names[i].name);
168                                         mask = proto_names[i].type;
169                                         break;
170                                 }
171                         }
172                         if (i == ARRAY_SIZE(proto_names)) {
173                                 IR_dprintk(1, "Unknown protocol: '%s'\n", tmp);
174                                 return -EINVAL;
175                         }
176                         count++;
177                 }
178
179                 if (enable)
180                         type |= mask;
181                 else if (disable)
182                         type &= ~mask;
183                 else
184                         type = mask;
185         }
186
187         if (!count) {
188                 IR_dprintk(1, "Protocol not specified\n");
189                 return -EINVAL;
190         }
191
192         if (ir_dev->props && ir_dev->props->change_protocol) {
193                 rc = ir_dev->props->change_protocol(ir_dev->props->priv,
194                                                     type);
195                 if (rc < 0) {
196                         IR_dprintk(1, "Error setting protocols to 0x%llx\n",
197                                    (long long)type);
198                         return -EINVAL;
199                 }
200         }
201
202         if (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_SCANCODE) {
203                 spin_lock_irqsave(&ir_dev->rc_tab.lock, flags);
204                 ir_dev->rc_tab.ir_type = type;
205                 spin_unlock_irqrestore(&ir_dev->rc_tab.lock, flags);
206         } else {
207                 ir_dev->raw->enabled_protocols = type;
208         }
209
210         IR_dprintk(1, "Current protocol(s): 0x%llx\n",
211                    (long long)type);
212
213         return len;
214 }
215
216 #define ADD_HOTPLUG_VAR(fmt, val...)                                    \
217         do {                                                            \
218                 int err = add_uevent_var(env, fmt, val);                \
219                 if (err)                                                \
220                         return err;                                     \
221         } while (0)
222
223 static int rc_dev_uevent(struct device *device, struct kobj_uevent_env *env)
224 {
225         struct ir_input_dev *ir_dev = dev_get_drvdata(device);
226
227         if (ir_dev->rc_tab.name)
228                 ADD_HOTPLUG_VAR("NAME=%s", ir_dev->rc_tab.name);
229         if (ir_dev->driver_name)
230                 ADD_HOTPLUG_VAR("DRV_NAME=%s", ir_dev->driver_name);
231
232         return 0;
233 }
234
235 /*
236  * Static device attribute struct with the sysfs attributes for IR's
237  */
238 static DEVICE_ATTR(protocols, S_IRUGO | S_IWUSR,
239                    show_protocols, store_protocols);
240
241 static struct attribute *rc_dev_attrs[] = {
242         &dev_attr_protocols.attr,
243         NULL,
244 };
245
246 static struct attribute_group rc_dev_attr_grp = {
247         .attrs  = rc_dev_attrs,
248 };
249
250 static const struct attribute_group *rc_dev_attr_groups[] = {
251         &rc_dev_attr_grp,
252         NULL
253 };
254
255 static struct device_type rc_dev_type = {
256         .groups         = rc_dev_attr_groups,
257         .uevent         = rc_dev_uevent,
258 };
259
260 /**
261  * ir_register_class() - creates the sysfs for /sys/class/rc/rc?
262  * @input_dev:  the struct input_dev descriptor of the device
263  *
264  * This routine is used to register the syfs code for IR class
265  */
266 int ir_register_class(struct input_dev *input_dev)
267 {
268         struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
269         int devno = find_first_zero_bit(&ir_core_dev_number,
270                                         IRRCV_NUM_DEVICES);
271
272         if (unlikely(devno < 0))
273                 return devno;
274
275         ir_dev->dev.type = &rc_dev_type;
276         ir_dev->devno = devno;
277
278         ir_dev->dev.class = &ir_input_class;
279         ir_dev->dev.parent = input_dev->dev.parent;
280         input_dev->dev.parent = &ir_dev->dev;
281         dev_set_name(&ir_dev->dev, "rc%d", devno);
282         dev_set_drvdata(&ir_dev->dev, ir_dev);
283         return  device_register(&ir_dev->dev);
284 };
285
286 /**
287  * ir_register_input - registers ir input device with input subsystem
288  * @input_dev:  the struct input_dev descriptor of the device
289  */
290
291 int ir_register_input(struct input_dev *input_dev)
292 {
293         struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
294         int rc;
295         const char *path;
296
297
298         rc = input_register_device(input_dev);
299         if (rc < 0) {
300                 device_del(&ir_dev->dev);
301                 return rc;
302         }
303
304         __module_get(THIS_MODULE);
305
306         path = kobject_get_path(&ir_dev->dev.kobj, GFP_KERNEL);
307         printk(KERN_INFO "%s: %s as %s\n",
308                 dev_name(&ir_dev->dev),
309                 input_dev->name ? input_dev->name : "Unspecified device",
310                 path ? path : "N/A");
311         kfree(path);
312
313         set_bit(ir_dev->devno, &ir_core_dev_number);
314         return 0;
315 }
316
317 /**
318  * ir_unregister_class() - removes the sysfs for sysfs for
319  *                         /sys/class/rc/rc?
320  * @input_dev:  the struct input_dev descriptor of the device
321  *
322  * This routine is used to unregister the syfs code for IR class
323  */
324 void ir_unregister_class(struct input_dev *input_dev)
325 {
326         struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
327
328         input_set_drvdata(input_dev, NULL);
329         clear_bit(ir_dev->devno, &ir_core_dev_number);
330         input_unregister_device(input_dev);
331         device_del(&ir_dev->dev);
332
333         module_put(THIS_MODULE);
334 }
335
336 /*
337  * Init/exit code for the module. Basically, creates/removes /sys/class/rc
338  */
339
340 static int __init ir_core_init(void)
341 {
342         int rc = class_register(&ir_input_class);
343         if (rc) {
344                 printk(KERN_ERR "ir_core: unable to register rc class\n");
345                 return rc;
346         }
347
348         /* Initialize/load the decoders/keymap code that will be used */
349         ir_raw_init();
350         ir_rcmap_init();
351
352         return 0;
353 }
354
355 static void __exit ir_core_exit(void)
356 {
357         class_unregister(&ir_input_class);
358         ir_rcmap_cleanup();
359 }
360
361 module_init(ir_core_init);
362 module_exit(ir_core_exit);