diff options
-rw-r--r-- | drivers/media/IR/Makefile | 2 | ||||
-rw-r--r-- | drivers/media/IR/ir-keytable.c | 17 | ||||
-rw-r--r-- | drivers/media/IR/ir-sysfs.c | 94 | ||||
-rw-r--r-- | include/media/ir-core.h | 12 |
4 files changed, 119 insertions, 6 deletions
diff --git a/drivers/media/IR/Makefile b/drivers/media/IR/Makefile index df5ddb4bbbf7..171890e7a41d 100644 --- a/drivers/media/IR/Makefile +++ b/drivers/media/IR/Makefile | |||
@@ -1,5 +1,5 @@ | |||
1 | ir-common-objs := ir-functions.o ir-keymaps.o | 1 | ir-common-objs := ir-functions.o ir-keymaps.o |
2 | ir-core-objs := ir-keytable.o | 2 | ir-core-objs := ir-keytable.o ir-sysfs.o |
3 | 3 | ||
4 | obj-$(CONFIG_IR_CORE) += ir-core.o | 4 | obj-$(CONFIG_IR_CORE) += ir-core.o |
5 | obj-$(CONFIG_VIDEO_IR) += ir-common.o | 5 | obj-$(CONFIG_VIDEO_IR) += ir-common.o |
diff --git a/drivers/media/IR/ir-keytable.c b/drivers/media/IR/ir-keytable.c index b521ed9d6e2e..8097561ec66f 100644 --- a/drivers/media/IR/ir-keytable.c +++ b/drivers/media/IR/ir-keytable.c | |||
@@ -447,12 +447,21 @@ int ir_input_register(struct input_dev *input_dev, | |||
447 | input_set_drvdata(input_dev, ir_dev); | 447 | input_set_drvdata(input_dev, ir_dev); |
448 | 448 | ||
449 | rc = input_register_device(input_dev); | 449 | rc = input_register_device(input_dev); |
450 | if (rc < 0) | ||
451 | goto err; | ||
452 | |||
453 | rc = ir_register_class(input_dev); | ||
450 | if (rc < 0) { | 454 | if (rc < 0) { |
451 | kfree(rc_tab->scan); | 455 | input_unregister_device(input_dev); |
452 | kfree(ir_dev); | 456 | goto err; |
453 | input_set_drvdata(input_dev, NULL); | ||
454 | } | 457 | } |
455 | 458 | ||
459 | return 0; | ||
460 | |||
461 | err: | ||
462 | kfree(rc_tab->scan); | ||
463 | kfree(ir_dev); | ||
464 | input_set_drvdata(input_dev, NULL); | ||
456 | return rc; | 465 | return rc; |
457 | } | 466 | } |
458 | EXPORT_SYMBOL_GPL(ir_input_register); | 467 | EXPORT_SYMBOL_GPL(ir_input_register); |
@@ -472,6 +481,8 @@ void ir_input_unregister(struct input_dev *dev) | |||
472 | kfree(rc_tab->scan); | 481 | kfree(rc_tab->scan); |
473 | rc_tab->scan = NULL; | 482 | rc_tab->scan = NULL; |
474 | 483 | ||
484 | ir_unregister_class(dev); | ||
485 | |||
475 | kfree(ir_dev); | 486 | kfree(ir_dev); |
476 | input_unregister_device(dev); | 487 | input_unregister_device(dev); |
477 | } | 488 | } |
diff --git a/drivers/media/IR/ir-sysfs.c b/drivers/media/IR/ir-sysfs.c new file mode 100644 index 000000000000..3c601421632b --- /dev/null +++ b/drivers/media/IR/ir-sysfs.c | |||
@@ -0,0 +1,94 @@ | |||
1 | /* ir-register.c - handle IR scancode->keycode tables | ||
2 | * | ||
3 | * Copyright (C) 2009 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/input.h> | ||
16 | #include <linux/device.h> | ||
17 | #include <media/ir-core.h> | ||
18 | |||
19 | #define IRRCV_NUM_DEVICES 256 | ||
20 | |||
21 | unsigned long ir_core_dev_number; | ||
22 | |||
23 | static struct class *ir_input_class; | ||
24 | |||
25 | static DEVICE_ATTR(ir_protocol, S_IRUGO | S_IWUSR, NULL, NULL); | ||
26 | |||
27 | static struct attribute *ir_dev_attrs[] = { | ||
28 | &dev_attr_ir_protocol.attr, | ||
29 | }; | ||
30 | |||
31 | int ir_register_class(struct input_dev *input_dev) | ||
32 | { | ||
33 | int rc; | ||
34 | struct kobject *kobj; | ||
35 | |||
36 | struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); | ||
37 | int devno = find_first_zero_bit(&ir_core_dev_number, | ||
38 | IRRCV_NUM_DEVICES); | ||
39 | |||
40 | if (unlikely(devno < 0)) | ||
41 | return devno; | ||
42 | |||
43 | ir_dev->attr.attrs = ir_dev_attrs; | ||
44 | ir_dev->class_dev = device_create(ir_input_class, NULL, | ||
45 | input_dev->dev.devt, ir_dev, | ||
46 | "irrcv%d", devno); | ||
47 | kobj = &ir_dev->class_dev->kobj; | ||
48 | |||
49 | printk(KERN_WARNING "Creating IR device %s\n", kobject_name(kobj)); | ||
50 | rc = sysfs_create_group(kobj, &ir_dev->attr); | ||
51 | if (unlikely(rc < 0)) { | ||
52 | device_destroy(ir_input_class, input_dev->dev.devt); | ||
53 | return -ENOMEM; | ||
54 | } | ||
55 | |||
56 | ir_dev->devno = devno; | ||
57 | set_bit(devno, &ir_core_dev_number); | ||
58 | |||
59 | return 0; | ||
60 | }; | ||
61 | |||
62 | void ir_unregister_class(struct input_dev *input_dev) | ||
63 | { | ||
64 | struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); | ||
65 | struct kobject *kobj; | ||
66 | |||
67 | clear_bit(ir_dev->devno, &ir_core_dev_number); | ||
68 | |||
69 | kobj = &ir_dev->class_dev->kobj; | ||
70 | |||
71 | sysfs_remove_group(kobj, &ir_dev->attr); | ||
72 | device_destroy(ir_input_class, input_dev->dev.devt); | ||
73 | |||
74 | kfree(ir_dev->attr.name); | ||
75 | } | ||
76 | |||
77 | static int __init ir_core_init(void) | ||
78 | { | ||
79 | ir_input_class = class_create(THIS_MODULE, "irrcv"); | ||
80 | if (IS_ERR(ir_input_class)) { | ||
81 | printk(KERN_ERR "ir_core: unable to register irrcv class\n"); | ||
82 | return PTR_ERR(ir_input_class); | ||
83 | } | ||
84 | |||
85 | return 0; | ||
86 | } | ||
87 | |||
88 | static void __exit ir_core_exit(void) | ||
89 | { | ||
90 | class_destroy(ir_input_class); | ||
91 | } | ||
92 | |||
93 | module_init(ir_core_init); | ||
94 | module_exit(ir_core_exit); | ||
diff --git a/include/media/ir-core.h b/include/media/ir-core.h index 299d201e1339..a5a3bda354de 100644 --- a/include/media/ir-core.h +++ b/include/media/ir-core.h | |||
@@ -42,8 +42,11 @@ struct ir_scancode_table { | |||
42 | }; | 42 | }; |
43 | 43 | ||
44 | struct ir_input_dev { | 44 | struct ir_input_dev { |
45 | struct input_dev *dev; | 45 | struct input_dev *dev; /* Input device*/ |
46 | struct ir_scancode_table rc_tab; | 46 | struct ir_scancode_table rc_tab; /* scan/key table */ |
47 | unsigned long devno; /* device number */ | ||
48 | struct attribute_group attr; /* IR attributes */ | ||
49 | struct device *class_dev; /* virtual class dev */ | ||
47 | }; | 50 | }; |
48 | 51 | ||
49 | /* Routines from ir-keytable.c */ | 52 | /* Routines from ir-keytable.c */ |
@@ -59,4 +62,9 @@ int ir_input_register(struct input_dev *dev, | |||
59 | struct ir_scancode_table *ir_codes); | 62 | struct ir_scancode_table *ir_codes); |
60 | void ir_input_unregister(struct input_dev *input_dev); | 63 | void ir_input_unregister(struct input_dev *input_dev); |
61 | 64 | ||
65 | /* Routines from ir-sysfs.c */ | ||
66 | |||
67 | int ir_register_class(struct input_dev *input_dev); | ||
68 | void ir_unregister_class(struct input_dev *input_dev); | ||
69 | |||
62 | #endif | 70 | #endif |