diff options
author | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-04-06 22:21:46 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-05-19 11:57:02 -0400 |
commit | 626cf6979e99bf2c642456308bed7bb25a37569b (patch) | |
tree | 4a5654588a37399f9240639d75064901c8737d8c | |
parent | de88f31cef8fee7c890cf2128bec8dae06bb20f2 (diff) |
V4L/DVB: ir-core: Distinguish sysfs attributes for in-hardware and raw decoders
Some devices have in-hardware Remote Controller decoder, while others
need a software decoder to get the IR code. As each software decoder
can be enabled/disabled individually, allowing multiple protocol
decoding capability.
On the other hand, hardware decoders have a limited protocol
support, often being able of decoding just one protocol each time.
So, each type needs a different set of capabilities to control the
supported protocol(s).
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r-- | drivers/media/IR/ir-keytable.c | 17 | ||||
-rw-r--r-- | drivers/media/IR/ir-raw-event.c | 2 | ||||
-rw-r--r-- | drivers/media/IR/ir-sysfs.c | 25 | ||||
-rw-r--r-- | drivers/media/video/saa7134/saa7134-input.c | 9 | ||||
-rw-r--r-- | include/media/ir-core.h | 20 |
5 files changed, 47 insertions, 26 deletions
diff --git a/drivers/media/IR/ir-keytable.c b/drivers/media/IR/ir-keytable.c index af7400bc906f..1fdb528737fe 100644 --- a/drivers/media/IR/ir-keytable.c +++ b/drivers/media/IR/ir-keytable.c | |||
@@ -488,11 +488,19 @@ int __ir_input_register(struct input_dev *input_dev, | |||
488 | if (rc < 0) | 488 | if (rc < 0) |
489 | goto out_table; | 489 | goto out_table; |
490 | 490 | ||
491 | if (ir_dev->props->driver_type == RC_DRIVER_IR_RAW) { | ||
492 | rc = ir_raw_event_register(input_dev); | ||
493 | if (rc < 0) | ||
494 | goto out_event; | ||
495 | } | ||
496 | |||
491 | IR_dprintk(1, "Registered input device on %s for %s remote.\n", | 497 | IR_dprintk(1, "Registered input device on %s for %s remote.\n", |
492 | driver_name, rc_tab->name); | 498 | driver_name, rc_tab->name); |
493 | 499 | ||
494 | return 0; | 500 | return 0; |
495 | 501 | ||
502 | out_event: | ||
503 | ir_unregister_class(input_dev); | ||
496 | out_table: | 504 | out_table: |
497 | kfree(ir_dev->rc_tab.scan); | 505 | kfree(ir_dev->rc_tab.scan); |
498 | out_name: | 506 | out_name: |
@@ -509,22 +517,25 @@ EXPORT_SYMBOL_GPL(__ir_input_register); | |||
509 | 517 | ||
510 | * This routine is used to free memory and de-register interfaces. | 518 | * This routine is used to free memory and de-register interfaces. |
511 | */ | 519 | */ |
512 | void ir_input_unregister(struct input_dev *dev) | 520 | void ir_input_unregister(struct input_dev *input_dev) |
513 | { | 521 | { |
514 | struct ir_input_dev *ir_dev = input_get_drvdata(dev); | 522 | struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); |
515 | struct ir_scancode_table *rc_tab; | 523 | struct ir_scancode_table *rc_tab; |
516 | 524 | ||
517 | if (!ir_dev) | 525 | if (!ir_dev) |
518 | return; | 526 | return; |
519 | 527 | ||
520 | IR_dprintk(1, "Freed keycode table\n"); | 528 | IR_dprintk(1, "Freed keycode table\n"); |
529 | |||
521 | del_timer_sync(&ir_dev->timer_keyup); | 530 | del_timer_sync(&ir_dev->timer_keyup); |
531 | if (ir_dev->props->driver_type == RC_DRIVER_IR_RAW) | ||
532 | ir_raw_event_unregister(input_dev); | ||
522 | rc_tab = &ir_dev->rc_tab; | 533 | rc_tab = &ir_dev->rc_tab; |
523 | rc_tab->size = 0; | 534 | rc_tab->size = 0; |
524 | kfree(rc_tab->scan); | 535 | kfree(rc_tab->scan); |
525 | rc_tab->scan = NULL; | 536 | rc_tab->scan = NULL; |
526 | 537 | ||
527 | ir_unregister_class(dev); | 538 | ir_unregister_class(input_dev); |
528 | 539 | ||
529 | kfree(ir_dev->driver_name); | 540 | kfree(ir_dev->driver_name); |
530 | kfree(ir_dev); | 541 | kfree(ir_dev); |
diff --git a/drivers/media/IR/ir-raw-event.c b/drivers/media/IR/ir-raw-event.c index ddb3365adc82..bc4ca08adf4a 100644 --- a/drivers/media/IR/ir-raw-event.c +++ b/drivers/media/IR/ir-raw-event.c | |||
@@ -82,7 +82,6 @@ int ir_raw_event_register(struct input_dev *input_dev) | |||
82 | 82 | ||
83 | return rc; | 83 | return rc; |
84 | } | 84 | } |
85 | EXPORT_SYMBOL_GPL(ir_raw_event_register); | ||
86 | 85 | ||
87 | void ir_raw_event_unregister(struct input_dev *input_dev) | 86 | void ir_raw_event_unregister(struct input_dev *input_dev) |
88 | { | 87 | { |
@@ -97,7 +96,6 @@ void ir_raw_event_unregister(struct input_dev *input_dev) | |||
97 | kfree(ir->raw); | 96 | kfree(ir->raw); |
98 | ir->raw = NULL; | 97 | ir->raw = NULL; |
99 | } | 98 | } |
100 | EXPORT_SYMBOL_GPL(ir_raw_event_unregister); | ||
101 | 99 | ||
102 | int ir_raw_event_store(struct input_dev *input_dev, enum raw_event_type type) | 100 | int ir_raw_event_store(struct input_dev *input_dev, enum raw_event_type type) |
103 | { | 101 | { |
diff --git a/drivers/media/IR/ir-sysfs.c b/drivers/media/IR/ir-sysfs.c index c33333f1f60e..81eebd8eae5a 100644 --- a/drivers/media/IR/ir-sysfs.c +++ b/drivers/media/IR/ir-sysfs.c | |||
@@ -152,22 +152,26 @@ static int ir_dev_uevent(struct device *device, struct kobj_uevent_env *env) | |||
152 | static DEVICE_ATTR(current_protocol, S_IRUGO | S_IWUSR, | 152 | static DEVICE_ATTR(current_protocol, S_IRUGO | S_IWUSR, |
153 | show_protocol, store_protocol); | 153 | show_protocol, store_protocol); |
154 | 154 | ||
155 | static struct attribute *ir_dev_attrs[] = { | 155 | static struct attribute *ir_hw_dev_attrs[] = { |
156 | &dev_attr_current_protocol.attr, | 156 | &dev_attr_current_protocol.attr, |
157 | NULL, | 157 | NULL, |
158 | }; | 158 | }; |
159 | 159 | ||
160 | static struct attribute_group ir_dev_attr_grp = { | 160 | static struct attribute_group ir_hw_dev_attr_grp = { |
161 | .attrs = ir_dev_attrs, | 161 | .attrs = ir_hw_dev_attrs, |
162 | }; | 162 | }; |
163 | 163 | ||
164 | static const struct attribute_group *ir_dev_attr_groups[] = { | 164 | static const struct attribute_group *ir_hw_dev_attr_groups[] = { |
165 | &ir_dev_attr_grp, | 165 | &ir_hw_dev_attr_grp, |
166 | NULL | 166 | NULL |
167 | }; | 167 | }; |
168 | 168 | ||
169 | static struct device_type ir_dev_type = { | 169 | static struct device_type rc_dev_type = { |
170 | .groups = ir_dev_attr_groups, | 170 | .groups = ir_hw_dev_attr_groups, |
171 | .uevent = ir_dev_uevent, | ||
172 | }; | ||
173 | |||
174 | static struct device_type ir_raw_dev_type = { | ||
171 | .uevent = ir_dev_uevent, | 175 | .uevent = ir_dev_uevent, |
172 | }; | 176 | }; |
173 | 177 | ||
@@ -181,7 +185,6 @@ int ir_register_class(struct input_dev *input_dev) | |||
181 | { | 185 | { |
182 | int rc; | 186 | int rc; |
183 | const char *path; | 187 | const char *path; |
184 | |||
185 | struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); | 188 | struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); |
186 | int devno = find_first_zero_bit(&ir_core_dev_number, | 189 | int devno = find_first_zero_bit(&ir_core_dev_number, |
187 | IRRCV_NUM_DEVICES); | 190 | IRRCV_NUM_DEVICES); |
@@ -189,7 +192,11 @@ int ir_register_class(struct input_dev *input_dev) | |||
189 | if (unlikely(devno < 0)) | 192 | if (unlikely(devno < 0)) |
190 | return devno; | 193 | return devno; |
191 | 194 | ||
192 | ir_dev->dev.type = &ir_dev_type; | 195 | if (ir_dev->props->driver_type == RC_DRIVER_SCANCODE) |
196 | ir_dev->dev.type = &rc_dev_type; | ||
197 | else | ||
198 | ir_dev->dev.type = &ir_raw_dev_type; | ||
199 | |||
193 | ir_dev->dev.class = &ir_input_class; | 200 | ir_dev->dev.class = &ir_input_class; |
194 | ir_dev->dev.parent = input_dev->dev.parent; | 201 | ir_dev->dev.parent = input_dev->dev.parent; |
195 | dev_set_name(&ir_dev->dev, "rc%d", devno); | 202 | dev_set_name(&ir_dev->dev, "rc%d", devno); |
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c index 867f027c3feb..6d5fe596245d 100644 --- a/drivers/media/video/saa7134/saa7134-input.c +++ b/drivers/media/video/saa7134/saa7134-input.c | |||
@@ -855,6 +855,9 @@ int saa7134_input_init1(struct saa7134_dev *dev) | |||
855 | ir->props.open = saa7134_ir_open; | 855 | ir->props.open = saa7134_ir_open; |
856 | ir->props.close = saa7134_ir_close; | 856 | ir->props.close = saa7134_ir_close; |
857 | 857 | ||
858 | if (raw_decode) | ||
859 | ir->props.driver_type = RC_DRIVER_IR_RAW; | ||
860 | |||
858 | if (!raw_decode && allow_protocol_change) { | 861 | if (!raw_decode && allow_protocol_change) { |
859 | ir->props.allowed_protos = IR_TYPE_RC5 | IR_TYPE_NEC; | 862 | ir->props.allowed_protos = IR_TYPE_RC5 | IR_TYPE_NEC; |
860 | ir->props.change_protocol = saa7134_ir_change_protocol; | 863 | ir->props.change_protocol = saa7134_ir_change_protocol; |
@@ -880,11 +883,6 @@ int saa7134_input_init1(struct saa7134_dev *dev) | |||
880 | err = ir_input_register(ir->dev, ir_codes, &ir->props, MODULE_NAME); | 883 | err = ir_input_register(ir->dev, ir_codes, &ir->props, MODULE_NAME); |
881 | if (err) | 884 | if (err) |
882 | goto err_out_free; | 885 | goto err_out_free; |
883 | if (raw_decode) { | ||
884 | err = ir_raw_event_register(ir->dev); | ||
885 | if (err) | ||
886 | goto err_out_free; | ||
887 | } | ||
888 | 886 | ||
889 | /* the remote isn't as bouncy as a keyboard */ | 887 | /* the remote isn't as bouncy as a keyboard */ |
890 | ir->dev->rep[REP_DELAY] = repeat_delay; | 888 | ir->dev->rep[REP_DELAY] = repeat_delay; |
@@ -904,7 +902,6 @@ void saa7134_input_fini(struct saa7134_dev *dev) | |||
904 | return; | 902 | return; |
905 | 903 | ||
906 | saa7134_ir_stop(dev); | 904 | saa7134_ir_stop(dev); |
907 | ir_raw_event_unregister(dev->remote->dev); | ||
908 | ir_input_unregister(dev->remote->dev); | 905 | ir_input_unregister(dev->remote->dev); |
909 | kfree(dev->remote); | 906 | kfree(dev->remote); |
910 | dev->remote = NULL; | 907 | dev->remote = NULL; |
diff --git a/include/media/ir-core.h b/include/media/ir-core.h index 4397ea3d9754..e9fa94fe2ef5 100644 --- a/include/media/ir-core.h +++ b/include/media/ir-core.h | |||
@@ -26,6 +26,11 @@ extern int ir_core_debug; | |||
26 | #define IR_dprintk(level, fmt, arg...) if (ir_core_debug >= level) \ | 26 | #define IR_dprintk(level, fmt, arg...) if (ir_core_debug >= level) \ |
27 | printk(KERN_DEBUG "%s: " fmt , __func__, ## arg) | 27 | printk(KERN_DEBUG "%s: " fmt , __func__, ## arg) |
28 | 28 | ||
29 | enum rc_driver_type { | ||
30 | RC_DRIVER_SCANCODE = 0, /* Driver or hardware generates a scancode */ | ||
31 | RC_DRIVER_IR_RAW, /* Needs a Infra-Red pulse/space decoder */ | ||
32 | }; | ||
33 | |||
29 | enum raw_event_type { | 34 | enum raw_event_type { |
30 | IR_SPACE = (1 << 0), | 35 | IR_SPACE = (1 << 0), |
31 | IR_PULSE = (1 << 1), | 36 | IR_PULSE = (1 << 1), |
@@ -35,6 +40,8 @@ enum raw_event_type { | |||
35 | 40 | ||
36 | /** | 41 | /** |
37 | * struct ir_dev_props - Allow caller drivers to set special properties | 42 | * struct ir_dev_props - Allow caller drivers to set special properties |
43 | * @driver_type: specifies if the driver or hardware have already a decoder, | ||
44 | * or if it needs to use the IR raw event decoders to produce a scancode | ||
38 | * @allowed_protos: bitmask with the supported IR_TYPE_* protocols | 45 | * @allowed_protos: bitmask with the supported IR_TYPE_* protocols |
39 | * @scanmask: some hardware decoders are not capable of providing the full | 46 | * @scanmask: some hardware decoders are not capable of providing the full |
40 | * scancode to the application. As this is a hardware limit, we can't do | 47 | * scancode to the application. As this is a hardware limit, we can't do |
@@ -49,12 +56,13 @@ enum raw_event_type { | |||
49 | * is opened. | 56 | * is opened. |
50 | */ | 57 | */ |
51 | struct ir_dev_props { | 58 | struct ir_dev_props { |
52 | unsigned long allowed_protos; | 59 | enum rc_driver_type driver_type; |
53 | u32 scanmask; | 60 | unsigned long allowed_protos; |
54 | void *priv; | 61 | u32 scanmask; |
55 | int (*change_protocol)(void *priv, u64 ir_type); | 62 | void *priv; |
56 | int (*open)(void *priv); | 63 | int (*change_protocol)(void *priv, u64 ir_type); |
57 | void (*close)(void *priv); | 64 | int (*open)(void *priv); |
65 | void (*close)(void *priv); | ||
58 | }; | 66 | }; |
59 | 67 | ||
60 | struct ir_raw_event { | 68 | struct ir_raw_event { |