All of lore.kernel.org
 help / color / mirror / Atom feed
From: Mauro Carvalho Chehab <mchehab@infradead.org>
To: Linux Media Mailing List <linux-media@vger.kernel.org>
Cc: "Devin Heitmueller" <dheitmueller@kernellabs.com>,
	"Ville Syrjälä" <syrjala@sci.fi>,
	"Linux Input" <linux-input@vger.kernel.org>,
	"Patrick Boettcher" <patrick.boettcher@desy.de>
Subject: Re: [RFC] Infrared Keycode standardization
Date: Fri, 28 Aug 2009 04:14:59 -0300	[thread overview]
Message-ID: <20090828041459.67c1499a@pedra.chehab.org> (raw)
In-Reply-To: <20090828004628.06f34d12@pedra.chehab.org>

Em Fri, 28 Aug 2009 00:46:28 -0300
Mauro Carvalho Chehab <mchehab@infradead.org> escreveu:

> So, we need a sort of TODO list for IR changes. A start point (on a random
> order) would be something like:
> 
> 2) Implement a v4l handler for EVIOCGKEYCODE/EVIOCSKEYCODE;
> 3) use a different arrangement for IR tables to not spend 16 K for IR table,
> yet allowing RC5 full table;
> 4) Use the common IR framework at the dvb drivers with their own iplementation;
> 5) Allow getkeycode/setkeycode to work with the dvb framework using the new
> methods;

Ok, I have a code that handles the above for dvb-usb. Se enclosed. It turned to be
simpler than what I've expected originally ;)

Tested with kernel 2.6.30.3 and a dibcom device.

While this patch works fine, for now, it is just a proof of concept, since there are a few
details to be decided/solved for a version 2, as described bellow.

I'm committing at the development tree some improvements at keytable util for
it to handle those 16 bits tables



Cheers,
Mauro
---

dvb-usb: allow userspace replacement of IR keycodes

Implements handler for EVIOCGKEYCODE/EVIOCSKEYCODE via adding two new callbacks
to the input device.

Since on dvb-usb a scan code has 16 bits, to fulfill rc5 standard codes, the default
getkeycode/setkeycode input methods would require the driver to spend up to 64 Kb of
a sparse table. Instead, add two new callbacks to the event device.

With this, it is now possible to replace the keycode tables. There are, however, a few
implementation details at the current patch:

1) It will replace the existing device keytable, instead of creating an instance
of the data. This works. However, if two devices pointing to the same table
were connected, changing the IR table of one will also change the IR table for
the other (the solution for this one is simple: just kmalloc some memory);

2) In order to change the scan code, you need first to change the key to
KEY_RESERVED or KEY_UNKNOWN to free some space at the table (solution: allocate
some additional space for newer scan codes or allow dynamic table grow);

3) The table size cannot be extended. It would be easy to allow the table to
grow dynamically: just calling kmalloc(size+1); kfree(old). Yet, maybe we can
just create a bigger table with a fixed size, like for example a table with 128
entries. This should be enough even for a very big IR.

Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

diff -r ec87db9cb8db linux/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
--- a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c	Fri Aug 28 02:12:12 2009 -0300
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c	Fri Aug 28 03:46:35 2009 -0300
@@ -12,6 +12,65 @@
 #include <linux/usb_input.h>
 #endif
 
+static int dvb_usb_getkeycode(struct input_dev *dev,
+				    int scancode, int *keycode)
+{
+	struct dvb_usb_device *d = input_get_drvdata(dev);
+
+	struct dvb_usb_rc_key *keymap = d->props.rc_key_map;
+	int custom = (scancode >> 8) & 0xff;
+	int data = scancode & 0xff;
+	int i;
+
+	/* See if we can match the raw key code. */
+	for (i = 0; i < d->props.rc_key_map_size; i++)
+		if (keymap[i].custom == custom &&
+			keymap[i].data == data) {
+			*keycode = keymap[i].event;
+			return 0;
+		}
+	return -EINVAL;
+}
+
+static int dvb_usb_setkeycode(struct input_dev *dev,
+				    int scancode, int keycode)
+{
+	struct dvb_usb_device *d = input_get_drvdata(dev);
+
+	struct dvb_usb_rc_key *keymap = d->props.rc_key_map;
+	int custom = (scancode >> 8) & 0xff;
+	int data = scancode & 0xff;
+	int i;
+
+	/* Search if it is replacing an existing keycode */
+	for (i = 0; i < d->props.rc_key_map_size; i++)
+		if (keymap[i].custom == custom &&
+			keymap[i].data == data) {
+			keymap[i].event = keycode;
+			return 0;
+		}
+
+	/* Search if is there a clean entry. If so, use it */
+	for (i = 0; i < d->props.rc_key_map_size; i++)
+		if (keymap[i].event == KEY_RESERVED ||
+		    keymap[i].event == KEY_UNKNOWN) {
+			keymap[i].custom = custom;
+			keymap[i].data = data;
+			keymap[i].event = keycode;
+			return 0;
+		}
+
+	/*
+	 * FIXME: Currently, it is not possible to increase the size of
+	 * scancode table. For it to happen, one possibility
+	 * would be to allocate a table with key_map_size + 1,
+	 * copying data, appending the new key on it, and freeing
+	 * the old one - or maybe just allocating some spare space
+	 */
+
+	return -EINVAL;
+}
+
 /* Remote-control poll function - called every dib->rc_query_interval ms to see
  * whether the remote control has received anything.
  *
@@ -127,6 +186,8 @@
 #else
 	input_dev->cdev.dev = &d->udev->dev;
 #endif
+	input_dev->getkeycode = dvb_usb_getkeycode;
+	input_dev->setkeycode = dvb_usb_setkeycode;
 
 	/* set the bits for the keys */
 	deb_rc("key map size: %d\n", d->props.rc_key_map_size);
@@ -144,6 +205,8 @@
 	input_dev->rep[REP_PERIOD] = d->props.rc_interval;
 	input_dev->rep[REP_DELAY]  = d->props.rc_interval + 150;
 
+	input_set_drvdata(input_dev, d);
+
 	err = input_register_device(input_dev);
 	if (err) {
 		input_free_device(input_dev);

  reply	other threads:[~2009-08-28  7:15 UTC|newest]

Thread overview: 39+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-08-27  7:57 [RFC] Infrared Keycode standardization Mauro Carvalho Chehab
2009-08-27 17:06 ` Peter Brouwer
2009-08-27 17:12   ` Jarod Wilson
2009-08-27 17:17   ` Devin Heitmueller
2009-08-27 18:29     ` Trent Piepho
2009-08-27 18:34       ` Devin Heitmueller
2009-08-27 18:34         ` Devin Heitmueller
2009-08-27 19:28         ` Mauro Carvalho Chehab
2009-08-27 19:32     ` Mauro Carvalho Chehab
2009-08-27 20:17   ` Dmitry Torokhov
2009-08-27 21:43   ` semiRocket
2009-08-27 18:36 ` Ville Syrjälä
2009-08-27 18:36   ` Ville Syrjälä
2009-08-27 20:15   ` Dmitry Torokhov
2009-08-27 20:15     ` Dmitry Torokhov
2009-08-27 22:03     ` Mauro Carvalho Chehab
2009-08-27 22:03       ` Mauro Carvalho Chehab
2009-08-27 21:58   ` Mauro Carvalho Chehab
2009-08-27 21:58     ` Mauro Carvalho Chehab
2009-08-27 22:06     ` Devin Heitmueller
2009-08-27 22:06       ` Devin Heitmueller
2009-08-28  3:46       ` Mauro Carvalho Chehab
2009-08-28  7:14         ` Mauro Carvalho Chehab [this message]
2009-08-28 10:13           ` Peter Brouwer
2009-08-28 12:36             ` Mauro Carvalho Chehab
2009-08-28 14:22             ` Alistair Buxton
2009-08-28 10:50           ` Patrick Boettcher
2009-08-28 12:30             ` Mauro Carvalho Chehab
2009-08-29 18:45               ` Mauro Carvalho Chehab
2009-08-31  5:47                 ` Mauro Carvalho Chehab
2009-09-01  1:38                   ` Dmitry Torokhov
2009-08-28  4:00       ` Jarod Wilson
2009-08-28  4:00         ` Jarod Wilson
2009-08-28 14:05         ` Mauro Carvalho Chehab
2009-08-28 14:05           ` Mauro Carvalho Chehab
2009-08-28 11:41       ` Andy Walls
2009-08-28 11:41         ` Andy Walls
2009-08-28 14:02         ` Mauro Carvalho Chehab
2009-08-28 14:02           ` Mauro Carvalho Chehab

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20090828041459.67c1499a@pedra.chehab.org \
    --to=mchehab@infradead.org \
    --cc=dheitmueller@kernellabs.com \
    --cc=linux-input@vger.kernel.org \
    --cc=linux-media@vger.kernel.org \
    --cc=patrick.boettcher@desy.de \
    --cc=syrjala@sci.fi \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.