1 // SPDX-License-Identifier: GPL-2.0
2 /* dvb-usb-remote.c is part of the DVB USB library.
4 * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@posteo.de)
5 * see dvb-usb-init.c for copyright information.
7 * This file contains functions for initializing the input-device and for handling remote-control-queries.
9 #include "dvb-usb-common.h"
10 #include <linux/usb/input.h>
13 legacy_dvb_usb_get_keymap_index(const struct input_keymap_entry
*ke
,
14 struct rc_map_table
*keymap
,
15 unsigned int keymap_size
)
18 unsigned int scancode
;
20 if (ke
->flags
& INPUT_KEYMAP_BY_INDEX
) {
23 if (input_scancode_to_scalar(ke
, &scancode
))
26 /* See if we can match the raw key code. */
27 for (index
= 0; index
< keymap_size
; index
++)
28 if (keymap
[index
].scancode
== scancode
)
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
) {
45 static int legacy_dvb_usb_getkeycode(struct input_dev
*dev
,
46 struct input_keymap_entry
*ke
)
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
;
53 index
= legacy_dvb_usb_get_keymap_index(ke
, keymap
, keymap_size
);
54 if (index
>= keymap_size
)
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
);
67 static int legacy_dvb_usb_setkeycode(struct input_dev
*dev
,
68 const struct input_keymap_entry
*ke
,
69 unsigned int *old_keycode
)
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
;
76 index
= legacy_dvb_usb_get_keymap_index(ke
, keymap
, keymap_size
);
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
84 if (index
>= keymap_size
)
87 *old_keycode
= keymap
[index
].keycode
;
88 keymap
->keycode
= ke
->keycode
;
89 __set_bit(ke
->keycode
, dev
->keybit
);
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
);
104 /* Remote-control poll function - called every dib->rc_query_interval ms to see
105 * whether the remote control has received anything.
107 * TODO: Fix the repeat rate of the input device.
109 static void legacy_dvb_usb_read_remote_control(struct work_struct
*work
)
111 struct dvb_usb_device
*d
=
112 container_of(work
, struct dvb_usb_device
, rc_query_work
.work
);
116 /* TODO: need a lock here. We can simply skip checking for the remote control
119 /* when the parameter has been set to 1 via sysfs while the driver was running */
120 if (dvb_usb_disable_rc_polling
)
123 if (d
->props
.rc
.legacy
.rc_query(d
,&event
,&state
)) {
124 err("error while querying for an remote control event.");
130 case REMOTE_NO_KEY_PRESSED
:
132 case REMOTE_KEY_PRESSED
:
133 deb_rc("key pressed\n");
134 d
->last_event
= event
;
135 input_event(d
->input_dev
, EV_KEY
, event
, 1);
136 input_sync(d
->input_dev
);
137 input_event(d
->input_dev
, EV_KEY
, d
->last_event
, 0);
138 input_sync(d
->input_dev
);
140 case REMOTE_KEY_REPEAT
:
141 deb_rc("key repeated\n");
142 input_event(d
->input_dev
, EV_KEY
, event
, 1);
143 input_sync(d
->input_dev
);
144 input_event(d
->input_dev
, EV_KEY
, d
->last_event
, 0);
145 input_sync(d
->input_dev
);
151 /* improved repeat handling ???
153 case REMOTE_NO_KEY_PRESSED:
154 deb_rc("NO KEY PRESSED\n");
155 if (d->last_state != REMOTE_NO_KEY_PRESSED) {
156 deb_rc("releasing event %d\n",d->last_event);
157 input_event(d->rc_input_dev, EV_KEY, d->last_event, 0);
158 input_sync(d->rc_input_dev);
160 d->last_state = REMOTE_NO_KEY_PRESSED;
163 case REMOTE_KEY_PRESSED:
164 deb_rc("KEY PRESSED\n");
165 deb_rc("pressing event %d\n",event);
167 input_event(d->rc_input_dev, EV_KEY, event, 1);
168 input_sync(d->rc_input_dev);
170 d->last_event = event;
171 d->last_state = REMOTE_KEY_PRESSED;
173 case REMOTE_KEY_REPEAT:
174 deb_rc("KEY_REPEAT\n");
175 if (d->last_state != REMOTE_NO_KEY_PRESSED) {
176 deb_rc("repeating event %d\n",d->last_event);
177 input_event(d->rc_input_dev, EV_KEY, d->last_event, 2);
178 input_sync(d->rc_input_dev);
179 d->last_state = REMOTE_KEY_REPEAT;
187 schedule_delayed_work(&d
->rc_query_work
,msecs_to_jiffies(d
->props
.rc
.legacy
.rc_interval
));
190 static int legacy_dvb_usb_remote_init(struct dvb_usb_device
*d
)
192 int i
, err
, rc_interval
;
193 struct input_dev
*input_dev
;
195 input_dev
= input_allocate_device();
199 input_dev
->evbit
[0] = BIT_MASK(EV_KEY
);
200 input_dev
->name
= "IR-receiver inside an USB DVB receiver";
201 input_dev
->phys
= d
->rc_phys
;
202 usb_to_input_id(d
->udev
, &input_dev
->id
);
203 input_dev
->dev
.parent
= &d
->udev
->dev
;
204 d
->input_dev
= input_dev
;
207 input_dev
->getkeycode
= legacy_dvb_usb_getkeycode
;
208 input_dev
->setkeycode
= legacy_dvb_usb_setkeycode
;
210 /* set the bits for the keys */
211 deb_rc("key map size: %d\n", d
->props
.rc
.legacy
.rc_map_size
);
212 for (i
= 0; i
< d
->props
.rc
.legacy
.rc_map_size
; i
++) {
213 deb_rc("setting bit for event %d item %d\n",
214 d
->props
.rc
.legacy
.rc_map_table
[i
].keycode
, i
);
215 set_bit(d
->props
.rc
.legacy
.rc_map_table
[i
].keycode
, input_dev
->keybit
);
218 /* setting these two values to non-zero, we have to manage key repeats */
219 input_dev
->rep
[REP_PERIOD
] = d
->props
.rc
.legacy
.rc_interval
;
220 input_dev
->rep
[REP_DELAY
] = d
->props
.rc
.legacy
.rc_interval
+ 150;
222 input_set_drvdata(input_dev
, d
);
224 err
= input_register_device(input_dev
);
226 input_free_device(input_dev
);
228 rc_interval
= d
->props
.rc
.legacy
.rc_interval
;
230 INIT_DELAYED_WORK(&d
->rc_query_work
, legacy_dvb_usb_read_remote_control
);
232 info("schedule remote query interval to %d msecs.", rc_interval
);
233 schedule_delayed_work(&d
->rc_query_work
,
234 msecs_to_jiffies(rc_interval
));
236 d
->state
|= DVB_USB_STATE_REMOTE
;
241 /* Remote-control poll function - called every dib->rc_query_interval ms to see
242 * whether the remote control has received anything.
244 * TODO: Fix the repeat rate of the input device.
246 static void dvb_usb_read_remote_control(struct work_struct
*work
)
248 struct dvb_usb_device
*d
=
249 container_of(work
, struct dvb_usb_device
, rc_query_work
.work
);
252 /* TODO: need a lock here. We can simply skip checking for the remote control
255 /* when the parameter has been set to 1 via sysfs while the
256 * driver was running, or when bulk mode is enabled after IR init
258 if (dvb_usb_disable_rc_polling
|| d
->props
.rc
.core
.bulk_mode
)
261 err
= d
->props
.rc
.core
.rc_query(d
);
263 err("error %d while querying for an remote control event.", err
);
265 schedule_delayed_work(&d
->rc_query_work
,
266 msecs_to_jiffies(d
->props
.rc
.core
.rc_interval
));
269 static int rc_core_dvb_usb_remote_init(struct dvb_usb_device
*d
)
271 int err
, rc_interval
;
274 dev
= rc_allocate_device(d
->props
.rc
.core
.driver_type
);
278 dev
->driver_name
= d
->props
.rc
.core
.module_name
;
279 dev
->map_name
= d
->props
.rc
.core
.rc_codes
;
280 dev
->change_protocol
= d
->props
.rc
.core
.change_protocol
;
281 dev
->allowed_protocols
= d
->props
.rc
.core
.allowed_protos
;
282 usb_to_input_id(d
->udev
, &dev
->input_id
);
283 dev
->device_name
= d
->desc
->name
;
284 dev
->input_phys
= d
->rc_phys
;
285 dev
->dev
.parent
= &d
->udev
->dev
;
287 dev
->scancode_mask
= d
->props
.rc
.core
.scancode_mask
;
289 err
= rc_register_device(dev
);
298 if (!d
->props
.rc
.core
.rc_query
|| d
->props
.rc
.core
.bulk_mode
)
301 /* Polling mode - initialize a work queue for handling it */
302 INIT_DELAYED_WORK(&d
->rc_query_work
, dvb_usb_read_remote_control
);
304 rc_interval
= d
->props
.rc
.core
.rc_interval
;
306 info("schedule remote query interval to %d msecs.", rc_interval
);
307 schedule_delayed_work(&d
->rc_query_work
,
308 msecs_to_jiffies(rc_interval
));
313 int dvb_usb_remote_init(struct dvb_usb_device
*d
)
317 if (dvb_usb_disable_rc_polling
)
320 if (d
->props
.rc
.legacy
.rc_map_table
&& d
->props
.rc
.legacy
.rc_query
)
321 d
->props
.rc
.mode
= DVB_RC_LEGACY
;
322 else if (d
->props
.rc
.core
.rc_codes
)
323 d
->props
.rc
.mode
= DVB_RC_CORE
;
327 usb_make_path(d
->udev
, d
->rc_phys
, sizeof(d
->rc_phys
));
328 strlcat(d
->rc_phys
, "/ir0", sizeof(d
->rc_phys
));
330 /* Start the remote-control polling. */
331 if (d
->props
.rc
.legacy
.rc_interval
< 40)
332 d
->props
.rc
.legacy
.rc_interval
= 100; /* default */
334 if (d
->props
.rc
.mode
== DVB_RC_LEGACY
)
335 err
= legacy_dvb_usb_remote_init(d
);
337 err
= rc_core_dvb_usb_remote_init(d
);
341 d
->state
|= DVB_USB_STATE_REMOTE
;
346 int dvb_usb_remote_exit(struct dvb_usb_device
*d
)
348 if (d
->state
& DVB_USB_STATE_REMOTE
) {
349 cancel_delayed_work_sync(&d
->rc_query_work
);
350 if (d
->props
.rc
.mode
== DVB_RC_LEGACY
)
351 input_unregister_device(d
->input_dev
);
353 rc_unregister_device(d
->rc_dev
);
355 d
->state
&= ~DVB_USB_STATE_REMOTE
;
359 #define DVB_USB_RC_NEC_EMPTY 0x00
360 #define DVB_USB_RC_NEC_KEY_PRESSED 0x01
361 #define DVB_USB_RC_NEC_KEY_REPEATED 0x02
362 int dvb_usb_nec_rc_key_to_event(struct dvb_usb_device
*d
,
363 u8 keybuf
[5], u32
*event
, int *state
)
366 struct rc_map_table
*keymap
= d
->props
.rc
.legacy
.rc_map_table
;
368 *state
= REMOTE_NO_KEY_PRESSED
;
370 case DVB_USB_RC_NEC_EMPTY
:
372 case DVB_USB_RC_NEC_KEY_PRESSED
:
373 if ((u8
) ~keybuf
[1] != keybuf
[2] ||
374 (u8
) ~keybuf
[3] != keybuf
[4]) {
375 deb_err("remote control checksum failed.\n");
378 /* See if we can match the raw key code. */
379 for (i
= 0; i
< d
->props
.rc
.legacy
.rc_map_size
; i
++)
380 if (rc5_custom(&keymap
[i
]) == keybuf
[1] &&
381 rc5_data(&keymap
[i
]) == keybuf
[3]) {
382 *event
= keymap
[i
].keycode
;
383 *state
= REMOTE_KEY_PRESSED
;
386 deb_err("key mapping failed - no appropriate key found in keymapping\n");
388 case DVB_USB_RC_NEC_KEY_REPEATED
:
389 *state
= REMOTE_KEY_REPEAT
;
392 deb_err("unknown type of remote status: %d\n",keybuf
[0]);
397 EXPORT_SYMBOL(dvb_usb_nec_rc_key_to_event
);