diff options
author | Antti Palosaari <crope@iki.fi> | 2012-05-25 09:19:03 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-08-04 06:56:22 -0400 |
commit | 649216704aaa1148c638346ec4c0dc71b164f521 (patch) | |
tree | f5b30b2eea03ddb9bf95dd230bb0ed666056be0d /drivers | |
parent | 43402bbde52e96f950994bc55700814db8d5bc81 (diff) |
[media] dvb_usb_v2: remote controller
* remove old legacy code totally
* move default RC keymap definition the the (struct dvb_usb_driver_info)
Signed-off-by: Antti Palosaari <crope@iki.fi>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/media/dvb/dvb-usb/dvb_usb.h | 60 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-usb/dvb_usb_init.c | 1 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-usb/dvb_usb_remote.c | 278 |
3 files changed, 22 insertions, 317 deletions
diff --git a/drivers/media/dvb/dvb-usb/dvb_usb.h b/drivers/media/dvb/dvb-usb/dvb_usb.h index 8ddae58e8e7..974337ddc5c 100644 --- a/drivers/media/dvb/dvb-usb/dvb_usb.h +++ b/drivers/media/dvb/dvb-usb/dvb_usb.h | |||
@@ -62,24 +62,10 @@ | |||
62 | 62 | ||
63 | struct dvb_usb_driver_info { | 63 | struct dvb_usb_driver_info { |
64 | const char *name; | 64 | const char *name; |
65 | const char *rc_map; | ||
65 | const struct dvb_usb_device_properties *props; | 66 | const struct dvb_usb_device_properties *props; |
66 | }; | 67 | }; |
67 | 68 | ||
68 | static inline u8 rc5_custom(struct rc_map_table *key) | ||
69 | { | ||
70 | return (key->scancode >> 8) & 0xff; | ||
71 | } | ||
72 | |||
73 | static inline u8 rc5_data(struct rc_map_table *key) | ||
74 | { | ||
75 | return key->scancode & 0xff; | ||
76 | } | ||
77 | |||
78 | static inline u16 rc5_scan(struct rc_map_table *key) | ||
79 | { | ||
80 | return key->scancode & 0xffff; | ||
81 | } | ||
82 | |||
83 | struct dvb_usb_device; | 69 | struct dvb_usb_device; |
84 | struct dvb_usb_adapter; | 70 | struct dvb_usb_adapter; |
85 | struct usb_data_stream; | 71 | struct usb_data_stream; |
@@ -161,25 +147,6 @@ struct dvb_usb_adapter_properties { | |||
161 | }; | 147 | }; |
162 | 148 | ||
163 | /** | 149 | /** |
164 | * struct dvb_rc_legacy - old properties of remote controller | ||
165 | * @rc_map_table: a hard-wired array of struct rc_map_table (NULL to disable | ||
166 | * remote control handling). | ||
167 | * @rc_map_size: number of items in @rc_map_table. | ||
168 | * @rc_query: called to query an event event. | ||
169 | * @rc_interval: time in ms between two queries. | ||
170 | */ | ||
171 | struct dvb_rc_legacy { | ||
172 | /* remote control properties */ | ||
173 | #define REMOTE_NO_KEY_PRESSED 0x00 | ||
174 | #define REMOTE_KEY_PRESSED 0x01 | ||
175 | #define REMOTE_KEY_REPEAT 0x02 | ||
176 | struct rc_map_table *rc_map_table; | ||
177 | int rc_map_size; | ||
178 | int (*rc_query) (struct dvb_usb_device *, u32 *, int *); | ||
179 | int rc_interval; | ||
180 | }; | ||
181 | |||
182 | /** | ||
183 | * struct dvb_rc properties of remote controller, using rc-core | 150 | * struct dvb_rc properties of remote controller, using rc-core |
184 | * @rc_codes: name of rc codes table | 151 | * @rc_codes: name of rc codes table |
185 | * @protocol: type of protocol(s) currently used by the driver | 152 | * @protocol: type of protocol(s) currently used by the driver |
@@ -203,17 +170,6 @@ struct dvb_rc { | |||
203 | }; | 170 | }; |
204 | 171 | ||
205 | /** | 172 | /** |
206 | * enum dvb_usb_mode - Specifies if it is using a legacy driver or a new one | ||
207 | * based on rc-core | ||
208 | * This is initialized/used only inside dvb-usb-remote.c. | ||
209 | * It shouldn't be set by the drivers. | ||
210 | */ | ||
211 | enum dvb_usb_mode { | ||
212 | DVB_RC_LEGACY, | ||
213 | DVB_RC_CORE, | ||
214 | }; | ||
215 | |||
216 | /** | ||
217 | * struct dvb_usb_device_properties - properties of a dvb-usb-device | 173 | * struct dvb_usb_device_properties - properties of a dvb-usb-device |
218 | * @owner: owner of the dvb_adapter | 174 | * @owner: owner of the dvb_adapter |
219 | * @usb_ctrl: which USB device-side controller is in use. Needed for firmware | 175 | * @usb_ctrl: which USB device-side controller is in use. Needed for firmware |
@@ -283,16 +239,12 @@ struct dvb_usb_device_properties { | |||
283 | int (*identify_state) (struct dvb_usb_device *); | 239 | int (*identify_state) (struct dvb_usb_device *); |
284 | int (*init) (struct dvb_usb_device *); | 240 | int (*init) (struct dvb_usb_device *); |
285 | 241 | ||
286 | struct { | ||
287 | enum dvb_usb_mode mode; /* Drivers shouldn't touch on it */ | ||
288 | struct dvb_rc_legacy legacy; | ||
289 | struct dvb_rc core; | ||
290 | } rc; | ||
291 | |||
292 | struct i2c_algorithm *i2c_algo; | 242 | struct i2c_algorithm *i2c_algo; |
293 | 243 | ||
294 | int generic_bulk_ctrl_endpoint; | 244 | int generic_bulk_ctrl_endpoint; |
295 | int generic_bulk_ctrl_endpoint_response; | 245 | int generic_bulk_ctrl_endpoint_response; |
246 | |||
247 | struct dvb_rc rc; | ||
296 | }; | 248 | }; |
297 | 249 | ||
298 | /** | 250 | /** |
@@ -419,7 +371,7 @@ struct dvb_usb_adapter { | |||
419 | struct dvb_usb_device { | 371 | struct dvb_usb_device { |
420 | struct dvb_usb_device_properties props; | 372 | struct dvb_usb_device_properties props; |
421 | const char *name; | 373 | const char *name; |
422 | 374 | const char *rc_map; | |
423 | struct usb_device *udev; | 375 | struct usb_device *udev; |
424 | 376 | ||
425 | #define DVB_USB_STATE_INIT 0x000 | 377 | #define DVB_USB_STATE_INIT 0x000 |
@@ -460,10 +412,6 @@ extern int dvb_usbv2_generic_rw(struct dvb_usb_device *, u8 *, u16, u8 *, u16, | |||
460 | int); | 412 | int); |
461 | extern int dvb_usbv2_generic_write(struct dvb_usb_device *, u8 *, u16); | 413 | extern int dvb_usbv2_generic_write(struct dvb_usb_device *, u8 *, u16); |
462 | 414 | ||
463 | /* commonly used remote control parsing */ | ||
464 | extern int dvb_usbv2_nec_rc_key_to_event(struct dvb_usb_device *, u8[], u32 *, | ||
465 | int *); | ||
466 | |||
467 | /* commonly used firmware download types and function */ | 415 | /* commonly used firmware download types and function */ |
468 | struct hexline { | 416 | struct hexline { |
469 | u8 len; | 417 | u8 len; |
diff --git a/drivers/media/dvb/dvb-usb/dvb_usb_init.c b/drivers/media/dvb/dvb-usb/dvb_usb_init.c index d694ea9ecc9..e1a3ed65cfb 100644 --- a/drivers/media/dvb/dvb-usb/dvb_usb_init.c +++ b/drivers/media/dvb/dvb-usb/dvb_usb_init.c | |||
@@ -259,6 +259,7 @@ int dvb_usbv2_device_init(struct usb_interface *intf, | |||
259 | 259 | ||
260 | d->udev = udev; | 260 | d->udev = udev; |
261 | d->name = driver_info->name; | 261 | d->name = driver_info->name; |
262 | d->rc_map = driver_info->rc_map; | ||
262 | memcpy(&d->props, props, sizeof(struct dvb_usb_device_properties)); | 263 | memcpy(&d->props, props, sizeof(struct dvb_usb_device_properties)); |
263 | 264 | ||
264 | if (d->props.size_of_priv > 0) { | 265 | if (d->props.size_of_priv > 0) { |
diff --git a/drivers/media/dvb/dvb-usb/dvb_usb_remote.c b/drivers/media/dvb/dvb-usb/dvb_usb_remote.c index b445990644a..b8d2cb193bb 100644 --- a/drivers/media/dvb/dvb-usb/dvb_usb_remote.c +++ b/drivers/media/dvb/dvb-usb/dvb_usb_remote.c | |||
@@ -9,200 +9,6 @@ | |||
9 | #include "dvb_usb_common.h" | 9 | #include "dvb_usb_common.h" |
10 | #include <linux/usb/input.h> | 10 | #include <linux/usb/input.h> |
11 | 11 | ||
12 | static unsigned int | ||
13 | legacy_dvb_usb_get_keymap_index(const struct input_keymap_entry *ke, | ||
14 | struct rc_map_table *keymap, | ||
15 | unsigned int keymap_size) | ||
16 | { | ||
17 | unsigned int index; | ||
18 | unsigned int scancode; | ||
19 | |||
20 | if (ke->flags & INPUT_KEYMAP_BY_INDEX) { | ||
21 | index = ke->index; | ||
22 | } else { | ||
23 | if (input_scancode_to_scalar(ke, &scancode)) | ||
24 | return keymap_size; | ||
25 | |||
26 | /* See if we can match the raw key code. */ | ||
27 | for (index = 0; index < keymap_size; index++) | ||
28 | if (keymap[index].scancode == scancode) | ||
29 | break; | ||
30 | |||
31 | /* See if there is an unused hole in the map */ | ||
32 | if (index >= keymap_size) { | ||
33 | for (index = 0; index < keymap_size; index++) { | ||
34 | if (keymap[index].keycode == KEY_RESERVED || | ||
35 | keymap[index].keycode == KEY_UNKNOWN) { | ||
36 | break; | ||
37 | } | ||
38 | } | ||
39 | } | ||
40 | } | ||
41 | |||
42 | return index; | ||
43 | } | ||
44 | |||
45 | static int legacy_dvb_usb_getkeycode(struct input_dev *dev, | ||
46 | struct input_keymap_entry *ke) | ||
47 | { | ||
48 | struct dvb_usb_device *d = input_get_drvdata(dev); | ||
49 | struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table; | ||
50 | unsigned int keymap_size = d->props.rc.legacy.rc_map_size; | ||
51 | unsigned int index; | ||
52 | |||
53 | index = legacy_dvb_usb_get_keymap_index(ke, keymap, keymap_size); | ||
54 | if (index >= keymap_size) | ||
55 | return -EINVAL; | ||
56 | |||
57 | ke->keycode = keymap[index].keycode; | ||
58 | if (ke->keycode == KEY_UNKNOWN) | ||
59 | ke->keycode = KEY_RESERVED; | ||
60 | ke->len = sizeof(keymap[index].scancode); | ||
61 | memcpy(&ke->scancode, &keymap[index].scancode, ke->len); | ||
62 | ke->index = index; | ||
63 | |||
64 | return 0; | ||
65 | } | ||
66 | |||
67 | static int legacy_dvb_usb_setkeycode(struct input_dev *dev, | ||
68 | const struct input_keymap_entry *ke, | ||
69 | unsigned int *old_keycode) | ||
70 | { | ||
71 | struct dvb_usb_device *d = input_get_drvdata(dev); | ||
72 | struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table; | ||
73 | unsigned int keymap_size = d->props.rc.legacy.rc_map_size; | ||
74 | unsigned int index; | ||
75 | |||
76 | index = legacy_dvb_usb_get_keymap_index(ke, keymap, keymap_size); | ||
77 | /* | ||
78 | * FIXME: Currently, it is not possible to increase the size of | ||
79 | * scancode table. For it to happen, one possibility | ||
80 | * would be to allocate a table with key_map_size + 1, | ||
81 | * copying data, appending the new key on it, and freeing | ||
82 | * the old one - or maybe just allocating some spare space | ||
83 | */ | ||
84 | if (index >= keymap_size) | ||
85 | return -EINVAL; | ||
86 | |||
87 | *old_keycode = keymap[index].keycode; | ||
88 | keymap->keycode = ke->keycode; | ||
89 | __set_bit(ke->keycode, dev->keybit); | ||
90 | |||
91 | if (*old_keycode != KEY_RESERVED) { | ||
92 | __clear_bit(*old_keycode, dev->keybit); | ||
93 | for (index = 0; index < keymap_size; index++) { | ||
94 | if (keymap[index].keycode == *old_keycode) { | ||
95 | __set_bit(*old_keycode, dev->keybit); | ||
96 | break; | ||
97 | } | ||
98 | } | ||
99 | } | ||
100 | |||
101 | return 0; | ||
102 | } | ||
103 | |||
104 | /* Remote-control poll function - called every dib->rc_query_interval ms to see | ||
105 | * whether the remote control has received anything. | ||
106 | * | ||
107 | * TODO: Fix the repeat rate of the input device. | ||
108 | */ | ||
109 | static void legacy_dvb_usb_read_remote_control(struct work_struct *work) | ||
110 | { | ||
111 | struct dvb_usb_device *d = | ||
112 | container_of(work, struct dvb_usb_device, rc_query_work.work); | ||
113 | u32 event; | ||
114 | int state; | ||
115 | |||
116 | /* TODO: need a lock here. We can simply skip checking for the remote | ||
117 | control if we're busy. */ | ||
118 | |||
119 | /* when the parameter has been set to 1 via sysfs while the driver | ||
120 | was running */ | ||
121 | if (dvb_usb_disable_rc_polling) | ||
122 | return; | ||
123 | |||
124 | if (d->props.rc.legacy.rc_query(d, &event, &state)) { | ||
125 | err("error while querying for an remote control event."); | ||
126 | goto schedule; | ||
127 | } | ||
128 | |||
129 | |||
130 | switch (state) { | ||
131 | case REMOTE_NO_KEY_PRESSED: | ||
132 | break; | ||
133 | case REMOTE_KEY_PRESSED: | ||
134 | deb_rc("key pressed\n"); | ||
135 | d->last_event = event; | ||
136 | case REMOTE_KEY_REPEAT: | ||
137 | deb_rc("key repeated\n"); | ||
138 | input_event(d->input_dev, EV_KEY, event, 1); | ||
139 | input_sync(d->input_dev); | ||
140 | input_event(d->input_dev, EV_KEY, d->last_event, 0); | ||
141 | input_sync(d->input_dev); | ||
142 | break; | ||
143 | default: | ||
144 | break; | ||
145 | } | ||
146 | |||
147 | schedule: | ||
148 | schedule_delayed_work(&d->rc_query_work, | ||
149 | msecs_to_jiffies(d->props.rc.legacy.rc_interval)); | ||
150 | } | ||
151 | |||
152 | static int legacy_dvb_usb_remote_init(struct dvb_usb_device *d) | ||
153 | { | ||
154 | int i, err, rc_interval; | ||
155 | struct input_dev *input_dev; | ||
156 | |||
157 | input_dev = input_allocate_device(); | ||
158 | if (!input_dev) | ||
159 | return -ENOMEM; | ||
160 | |||
161 | input_dev->evbit[0] = BIT_MASK(EV_KEY); | ||
162 | input_dev->name = "IR-receiver inside an USB DVB receiver"; | ||
163 | input_dev->phys = d->rc_phys; | ||
164 | usb_to_input_id(d->udev, &input_dev->id); | ||
165 | input_dev->dev.parent = &d->udev->dev; | ||
166 | d->input_dev = input_dev; | ||
167 | d->rc_dev = NULL; | ||
168 | |||
169 | input_dev->getkeycode = legacy_dvb_usb_getkeycode; | ||
170 | input_dev->setkeycode = legacy_dvb_usb_setkeycode; | ||
171 | |||
172 | /* set the bits for the keys */ | ||
173 | deb_rc("key map size: %d\n", d->props.rc.legacy.rc_map_size); | ||
174 | for (i = 0; i < d->props.rc.legacy.rc_map_size; i++) { | ||
175 | deb_rc("setting bit for event %d item %d\n", | ||
176 | d->props.rc.legacy.rc_map_table[i].keycode, i); | ||
177 | set_bit(d->props.rc.legacy.rc_map_table[i].keycode, | ||
178 | input_dev->keybit); | ||
179 | } | ||
180 | |||
181 | /* setting these two values to non-zero, we have to manage key | ||
182 | repeats */ | ||
183 | input_dev->rep[REP_PERIOD] = d->props.rc.legacy.rc_interval; | ||
184 | input_dev->rep[REP_DELAY] = d->props.rc.legacy.rc_interval + 150; | ||
185 | |||
186 | input_set_drvdata(input_dev, d); | ||
187 | |||
188 | err = input_register_device(input_dev); | ||
189 | if (err) | ||
190 | input_free_device(input_dev); | ||
191 | |||
192 | rc_interval = d->props.rc.legacy.rc_interval; | ||
193 | |||
194 | INIT_DELAYED_WORK(&d->rc_query_work, | ||
195 | legacy_dvb_usb_read_remote_control); | ||
196 | |||
197 | info("schedule remote query interval to %d msecs.", rc_interval); | ||
198 | schedule_delayed_work(&d->rc_query_work, | ||
199 | msecs_to_jiffies(rc_interval)); | ||
200 | |||
201 | d->state |= DVB_USB_STATE_REMOTE; | ||
202 | |||
203 | return err; | ||
204 | } | ||
205 | |||
206 | /* Remote-control poll function - called every dib->rc_query_interval ms to see | 12 | /* Remote-control poll function - called every dib->rc_query_interval ms to see |
207 | * whether the remote control has received anything. | 13 | * whether the remote control has received anything. |
208 | * | 14 | * |
@@ -220,16 +26,16 @@ static void dvb_usb_read_remote_control(struct work_struct *work) | |||
220 | /* when the parameter has been set to 1 via sysfs while the | 26 | /* when the parameter has been set to 1 via sysfs while the |
221 | * driver was running, or when bulk mode is enabled after IR init | 27 | * driver was running, or when bulk mode is enabled after IR init |
222 | */ | 28 | */ |
223 | if (dvb_usb_disable_rc_polling || d->props.rc.core.bulk_mode) | 29 | if (dvb_usb_disable_rc_polling || d->props.rc.bulk_mode) |
224 | return; | 30 | return; |
225 | 31 | ||
226 | err = d->props.rc.core.rc_query(d); | 32 | err = d->props.rc.rc_query(d); |
227 | if (err) | 33 | if (err) |
228 | err("error %d while querying for an remote control event.", | 34 | err("error %d while querying for an remote control event.", |
229 | err); | 35 | err); |
230 | 36 | ||
231 | schedule_delayed_work(&d->rc_query_work, | 37 | schedule_delayed_work(&d->rc_query_work, |
232 | msecs_to_jiffies(d->props.rc.core.rc_interval)); | 38 | msecs_to_jiffies(d->props.rc.rc_interval)); |
233 | } | 39 | } |
234 | 40 | ||
235 | static int rc_core_dvb_usb_remote_init(struct dvb_usb_device *d) | 41 | static int rc_core_dvb_usb_remote_init(struct dvb_usb_device *d) |
@@ -241,17 +47,21 @@ static int rc_core_dvb_usb_remote_init(struct dvb_usb_device *d) | |||
241 | if (!dev) | 47 | if (!dev) |
242 | return -ENOMEM; | 48 | return -ENOMEM; |
243 | 49 | ||
244 | dev->driver_name = d->props.rc.core.module_name; | 50 | dev->driver_name = d->props.rc.module_name; |
245 | dev->map_name = d->props.rc.core.rc_codes; | 51 | dev->map_name = d->rc_map; |
246 | dev->change_protocol = d->props.rc.core.change_protocol; | 52 | dev->change_protocol = d->props.rc.change_protocol; |
247 | dev->allowed_protos = d->props.rc.core.allowed_protos; | 53 | dev->allowed_protos = d->props.rc.allowed_protos; |
248 | dev->driver_type = d->props.rc.core.driver_type; | 54 | dev->driver_type = d->props.rc.driver_type; |
249 | usb_to_input_id(d->udev, &dev->input_id); | 55 | usb_to_input_id(d->udev, &dev->input_id); |
250 | dev->input_name = "IR-receiver inside an USB DVB receiver"; | 56 | dev->input_name = "IR-receiver inside an USB DVB receiver"; |
251 | dev->input_phys = d->rc_phys; | 57 | dev->input_phys = d->rc_phys; |
252 | dev->dev.parent = &d->udev->dev; | 58 | dev->dev.parent = &d->udev->dev; |
253 | dev->priv = d; | 59 | dev->priv = d; |
254 | 60 | ||
61 | /* leave remote controller enabled even there is no default map */ | ||
62 | if (dev->map_name == NULL) | ||
63 | dev->map_name = RC_MAP_EMPTY; | ||
64 | |||
255 | err = rc_register_device(dev); | 65 | err = rc_register_device(dev); |
256 | if (err < 0) { | 66 | if (err < 0) { |
257 | rc_free_device(dev); | 67 | rc_free_device(dev); |
@@ -261,13 +71,13 @@ static int rc_core_dvb_usb_remote_init(struct dvb_usb_device *d) | |||
261 | d->input_dev = NULL; | 71 | d->input_dev = NULL; |
262 | d->rc_dev = dev; | 72 | d->rc_dev = dev; |
263 | 73 | ||
264 | if (!d->props.rc.core.rc_query || d->props.rc.core.bulk_mode) | 74 | if (!d->props.rc.rc_query || d->props.rc.bulk_mode) |
265 | return 0; | 75 | return 0; |
266 | 76 | ||
267 | /* Polling mode - initialize a work queue for handling it */ | 77 | /* Polling mode - initialize a work queue for handling it */ |
268 | INIT_DELAYED_WORK(&d->rc_query_work, dvb_usb_read_remote_control); | 78 | INIT_DELAYED_WORK(&d->rc_query_work, dvb_usb_read_remote_control); |
269 | 79 | ||
270 | rc_interval = d->props.rc.core.rc_interval; | 80 | rc_interval = d->props.rc.rc_interval; |
271 | 81 | ||
272 | info("schedule remote query interval to %d msecs.", rc_interval); | 82 | info("schedule remote query interval to %d msecs.", rc_interval); |
273 | schedule_delayed_work(&d->rc_query_work, | 83 | schedule_delayed_work(&d->rc_query_work, |
@@ -283,24 +93,14 @@ int dvb_usb_remote_init(struct dvb_usb_device *d) | |||
283 | if (dvb_usb_disable_rc_polling) | 93 | if (dvb_usb_disable_rc_polling) |
284 | return 0; | 94 | return 0; |
285 | 95 | ||
286 | if (d->props.rc.legacy.rc_map_table && d->props.rc.legacy.rc_query) | 96 | if (d->props.rc.module_name == NULL) |
287 | d->props.rc.mode = DVB_RC_LEGACY; | ||
288 | else if (d->props.rc.core.rc_codes) | ||
289 | d->props.rc.mode = DVB_RC_CORE; | ||
290 | else | ||
291 | return 0; | 97 | return 0; |
292 | 98 | ||
293 | usb_make_path(d->udev, d->rc_phys, sizeof(d->rc_phys)); | 99 | usb_make_path(d->udev, d->rc_phys, sizeof(d->rc_phys)); |
294 | strlcat(d->rc_phys, "/ir0", sizeof(d->rc_phys)); | 100 | strlcat(d->rc_phys, "/ir0", sizeof(d->rc_phys)); |
295 | 101 | ||
296 | /* Start the remote-control polling. */ | 102 | /* Start the remote-control polling. */ |
297 | if (d->props.rc.legacy.rc_interval < 40) | 103 | err = rc_core_dvb_usb_remote_init(d); |
298 | d->props.rc.legacy.rc_interval = 100; /* default */ | ||
299 | |||
300 | if (d->props.rc.mode == DVB_RC_LEGACY) | ||
301 | err = legacy_dvb_usb_remote_init(d); | ||
302 | else | ||
303 | err = rc_core_dvb_usb_remote_init(d); | ||
304 | if (err) | 104 | if (err) |
305 | return err; | 105 | return err; |
306 | 106 | ||
@@ -313,52 +113,8 @@ int dvb_usb_remote_exit(struct dvb_usb_device *d) | |||
313 | { | 113 | { |
314 | if (d->state & DVB_USB_STATE_REMOTE) { | 114 | if (d->state & DVB_USB_STATE_REMOTE) { |
315 | cancel_delayed_work_sync(&d->rc_query_work); | 115 | cancel_delayed_work_sync(&d->rc_query_work); |
316 | if (d->props.rc.mode == DVB_RC_LEGACY) | 116 | rc_unregister_device(d->rc_dev); |
317 | input_unregister_device(d->input_dev); | ||
318 | else | ||
319 | rc_unregister_device(d->rc_dev); | ||
320 | } | 117 | } |
321 | d->state &= ~DVB_USB_STATE_REMOTE; | 118 | d->state &= ~DVB_USB_STATE_REMOTE; |
322 | return 0; | 119 | return 0; |
323 | } | 120 | } |
324 | |||
325 | #define DVB_USB_RC_NEC_EMPTY 0x00 | ||
326 | #define DVB_USB_RC_NEC_KEY_PRESSED 0x01 | ||
327 | #define DVB_USB_RC_NEC_KEY_REPEATED 0x02 | ||
328 | int dvb_usbv2_nec_rc_key_to_event(struct dvb_usb_device *d, | ||
329 | u8 keybuf[5], u32 *event, int *state) | ||
330 | { | ||
331 | int i; | ||
332 | struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table; | ||
333 | *event = 0; | ||
334 | *state = REMOTE_NO_KEY_PRESSED; | ||
335 | switch (keybuf[0]) { | ||
336 | case DVB_USB_RC_NEC_EMPTY: | ||
337 | break; | ||
338 | case DVB_USB_RC_NEC_KEY_PRESSED: | ||
339 | if ((u8) ~keybuf[1] != keybuf[2] || | ||
340 | (u8) ~keybuf[3] != keybuf[4]) { | ||
341 | deb_err("remote control checksum failed.\n"); | ||
342 | break; | ||
343 | } | ||
344 | /* See if we can match the raw key code. */ | ||
345 | for (i = 0; i < d->props.rc.legacy.rc_map_size; i++) | ||
346 | if (rc5_custom(&keymap[i]) == keybuf[1] && | ||
347 | rc5_data(&keymap[i]) == keybuf[3]) { | ||
348 | *event = keymap[i].keycode; | ||
349 | *state = REMOTE_KEY_PRESSED; | ||
350 | return 0; | ||
351 | } | ||
352 | deb_err("key mapping failed - no appropriate key found in" \ | ||
353 | " keymapping\n"); | ||
354 | break; | ||
355 | case DVB_USB_RC_NEC_KEY_REPEATED: | ||
356 | *state = REMOTE_KEY_REPEAT; | ||
357 | break; | ||
358 | default: | ||
359 | deb_err("unknown type of remote status: %d\n", keybuf[0]); | ||
360 | break; | ||
361 | } | ||
362 | return 0; | ||
363 | } | ||
364 | EXPORT_SYMBOL(dvb_usbv2_nec_rc_key_to_event); | ||