1// SPDX-License-Identifier: GPL-2.0
2/* dvb-usb-remote.c is part of the DVB USB library.
3 *
4 * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@posteo.de)
5 * see dvb-usb-init.c for copyright information.
6 *
7 * This file contains functions for initializing the input-device and for handling remote-control-queries.
8 */
9#include "dvb-usb-common.h"
10#include <linux/usb/input.h>
11
12static unsigned int
13legacy_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
45static 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
67static 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 */
109static 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 control
117	   if we're busy. */
118
119	/* when the parameter has been set to 1 via sysfs while the driver was running */
120	if (dvb_usb_disable_rc_polling)
121		return;
122
123	if (d->props.rc.legacy.rc_query(d,&event,&state)) {
124		err("error while querying for an remote control event.");
125		goto schedule;
126	}
127
128
129	switch (state) {
130		case REMOTE_NO_KEY_PRESSED:
131			break;
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);
139			break;
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);
146			break;
147		default:
148			break;
149	}
150
151/* improved repeat handling ???
152	switch (state) {
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);
159			}
160			d->last_state = REMOTE_NO_KEY_PRESSED;
161			d->last_event = 0;
162			break;
163		case REMOTE_KEY_PRESSED:
164			deb_rc("KEY PRESSED\n");
165			deb_rc("pressing event %d\n",event);
166
167			input_event(d->rc_input_dev, EV_KEY, event, 1);
168			input_sync(d->rc_input_dev);
169
170			d->last_event = event;
171			d->last_state = REMOTE_KEY_PRESSED;
172			break;
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;
180			}
181		default:
182			break;
183	}
184*/
185
186schedule:
187	schedule_delayed_work(&d->rc_query_work,msecs_to_jiffies(d->props.rc.legacy.rc_interval));
188}
189
190static int legacy_dvb_usb_remote_init(struct dvb_usb_device *d)
191{
192	int i, err, rc_interval;
193	struct input_dev *input_dev;
194
195	input_dev = input_allocate_device();
196	if (!input_dev)
197		return -ENOMEM;
198
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;
205	d->rc_dev = NULL;
206
207	input_dev->getkeycode = legacy_dvb_usb_getkeycode;
208	input_dev->setkeycode = legacy_dvb_usb_setkeycode;
209
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);
216	}
217
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;
221
222	input_set_drvdata(input_dev, d);
223
224	err = input_register_device(input_dev);
225	if (err)
226		input_free_device(input_dev);
227
228	rc_interval = d->props.rc.legacy.rc_interval;
229
230	INIT_DELAYED_WORK(&d->rc_query_work, legacy_dvb_usb_read_remote_control);
231
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));
235
236	d->state |= DVB_USB_STATE_REMOTE;
237
238	return err;
239}
240
241/* Remote-control poll function - called every dib->rc_query_interval ms to see
242 * whether the remote control has received anything.
243 *
244 * TODO: Fix the repeat rate of the input device.
245 */
246static void dvb_usb_read_remote_control(struct work_struct *work)
247{
248	struct dvb_usb_device *d =
249		container_of(work, struct dvb_usb_device, rc_query_work.work);
250	int err;
251
252	/* TODO: need a lock here.  We can simply skip checking for the remote control
253	   if we're busy. */
254
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
257	 */
258	if (dvb_usb_disable_rc_polling || d->props.rc.core.bulk_mode)
259		return;
260
261	err = d->props.rc.core.rc_query(d);
262	if (err)
263		err("error %d while querying for an remote control event.", err);
264
265	schedule_delayed_work(&d->rc_query_work,
266			      msecs_to_jiffies(d->props.rc.core.rc_interval));
267}
268
269static int rc_core_dvb_usb_remote_init(struct dvb_usb_device *d)
270{
271	int err, rc_interval;
272	struct rc_dev *dev;
273
274	dev = rc_allocate_device(d->props.rc.core.driver_type);
275	if (!dev)
276		return -ENOMEM;
277
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;
286	dev->priv = d;
287	dev->scancode_mask = d->props.rc.core.scancode_mask;
288
289	err = rc_register_device(dev);
290	if (err < 0) {
291		rc_free_device(dev);
292		return err;
293	}
294
295	d->input_dev = NULL;
296	d->rc_dev = dev;
297
298	if (!d->props.rc.core.rc_query || d->props.rc.core.bulk_mode)
299		return 0;
300
301	/* Polling mode - initialize a work queue for handling it */
302	INIT_DELAYED_WORK(&d->rc_query_work, dvb_usb_read_remote_control);
303
304	rc_interval = d->props.rc.core.rc_interval;
305
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));
309
310	return 0;
311}
312
313int dvb_usb_remote_init(struct dvb_usb_device *d)
314{
315	int err;
316
317	if (dvb_usb_disable_rc_polling)
318		return 0;
319
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;
324	else
325		return 0;
326
327	usb_make_path(d->udev, d->rc_phys, sizeof(d->rc_phys));
328	strlcat(d->rc_phys, "/ir0", sizeof(d->rc_phys));
329
330	/* Start the remote-control polling. */
331	if (d->props.rc.legacy.rc_interval < 40)
332		d->props.rc.legacy.rc_interval = 100; /* default */
333
334	if (d->props.rc.mode == DVB_RC_LEGACY)
335		err = legacy_dvb_usb_remote_init(d);
336	else
337		err = rc_core_dvb_usb_remote_init(d);
338	if (err)
339		return err;
340
341	d->state |= DVB_USB_STATE_REMOTE;
342
343	return 0;
344}
345
346int dvb_usb_remote_exit(struct dvb_usb_device *d)
347{
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);
352		else
353			rc_unregister_device(d->rc_dev);
354	}
355	d->state &= ~DVB_USB_STATE_REMOTE;
356	return 0;
357}
358
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
362int dvb_usb_nec_rc_key_to_event(struct dvb_usb_device *d,
363		u8 keybuf[5], u32 *event, int *state)
364{
365	int i;
366	struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
367	*event = 0;
368	*state = REMOTE_NO_KEY_PRESSED;
369	switch (keybuf[0]) {
370		case DVB_USB_RC_NEC_EMPTY:
371			break;
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");
376				break;
377			}
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;
384					return 0;
385				}
386			deb_err("key mapping failed - no appropriate key found in keymapping\n");
387			break;
388		case DVB_USB_RC_NEC_KEY_REPEATED:
389			*state = REMOTE_KEY_REPEAT;
390			break;
391		default:
392			deb_err("unknown type of remote status: %d\n",keybuf[0]);
393			break;
394	}
395	return 0;
396}
397EXPORT_SYMBOL(dvb_usb_nec_rc_key_to_event);
398