From: Peter Stokes <linux@dadeos.co.uk>
To: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Cc: Ville Syrj?l? <syrjala@sci.fi>,
linux-input@vger.kernel.org, Jiri Kosina <jkosina@suse.cz>
Subject: Re: [PATCH] ati_remote2 loadable keymap support
Date: Fri, 18 Apr 2008 21:49:26 +0100 [thread overview]
Message-ID: <200804182149.26317.linux@dadeos.co.uk> (raw)
In-Reply-To: <20080417144328.ZZRA012@mailhub.coreip.homeip.net>
[-- Attachment #1: Type: text/plain, Size: 715 bytes --]
On Thursday 17 April 2008 20:00:23 Dmitry Torokhov wrote:
> On Tue, Apr 08, 2008 at 11:18:26PM +0300, Ville Syrj?l? wrote:
> > On Sat, Apr 05, 2008 at 07:30:10PM +0100, Peter Stokes wrote:
> > > + u8 hwcode;
> > > + u16 keycode[ARRAY_SIZE(ati_remote2_modes)];
> > > +} ati_remote2_keycodes[] = {
> > > +/* hwcode AUX1 AUX2 AUX3 AUX4
> > > PC */
> >
> > checkpatch.pl doesn't like these long lines.
>
> In this case screw checkpatch, sometimes longer lines are better than
> the alternative.
>
> Peter, is an updated patch addressing other Ville's concerns coming?
Please find attached an updated patch. Sorry for the delay.
Best regards
Peter
[-- Attachment #2: ati_remote2_keycode.patch --]
[-- Type: text/x-diff, Size: 12891 bytes --]
Signed-off-by: Peter Stokes <linux@dadeos.co.uk>
--- linux-2.6.24-orig/drivers/input/misc/ati_remote2.c 2008-01-24 22:58:37.000000000 +0000
+++ linux-2.6.24/drivers/input/misc/ati_remote2.c 2008-04-18 20:18:32.000000000 +0100
@@ -2,7 +2,7 @@
* ati_remote2 - ATI/Philips USB RF remote driver
*
* Copyright (C) 2005 Ville Syrjala <syrjala@sci.fi>
- * Copyright (C) 2007 Peter Stokes <linux@dadeos.freeserve.co.uk>
+ * Copyright (C) 2008 Peter Stokes <linux@dadeos.co.uk>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
@@ -12,7 +12,7 @@
#include <linux/usb/input.h>
#define DRIVER_DESC "ATI/Philips USB RF remote driver"
-#define DRIVER_VERSION "0.2"
+#define DRIVER_VERSION "0.3"
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_VERSION(DRIVER_VERSION);
@@ -27,7 +27,7 @@
* A remote's "channel" may be altered by pressing and holding the "PC" button for
* approximately 3 seconds, after which the button will slowly flash the count of the
* currently configured "channel", using the numeric keypad enter a number between 1 and
- * 16 and then the "PC" button again, the button will slowly flash the count of the
+ * 16 and then press the "PC" button again, the button will slowly flash the count of the
* newly configured "channel".
*/
@@ -45,61 +45,66 @@
};
MODULE_DEVICE_TABLE(usb, ati_remote2_id_table);
+
+static u8 ati_remote2_modes[] = {
+ 0x01, /* AUX1 */
+ 0x02, /* AUX2 */
+ 0x04, /* AUX3 */
+ 0x08, /* AUX4 */
+ 0x10, /* PC */
+};
+
static struct {
- int hw_code;
- int key_code;
-} ati_remote2_key_table[] = {
- { 0x00, KEY_0 },
- { 0x01, KEY_1 },
- { 0x02, KEY_2 },
- { 0x03, KEY_3 },
- { 0x04, KEY_4 },
- { 0x05, KEY_5 },
- { 0x06, KEY_6 },
- { 0x07, KEY_7 },
- { 0x08, KEY_8 },
- { 0x09, KEY_9 },
- { 0x0c, KEY_POWER },
- { 0x0d, KEY_MUTE },
- { 0x10, KEY_VOLUMEUP },
- { 0x11, KEY_VOLUMEDOWN },
- { 0x20, KEY_CHANNELUP },
- { 0x21, KEY_CHANNELDOWN },
- { 0x28, KEY_FORWARD },
- { 0x29, KEY_REWIND },
- { 0x2c, KEY_PLAY },
- { 0x30, KEY_PAUSE },
- { 0x31, KEY_STOP },
- { 0x37, KEY_RECORD },
- { 0x38, KEY_DVD },
- { 0x39, KEY_TV },
- { 0x54, KEY_MENU },
- { 0x58, KEY_UP },
- { 0x59, KEY_DOWN },
- { 0x5a, KEY_LEFT },
- { 0x5b, KEY_RIGHT },
- { 0x5c, KEY_OK },
- { 0x78, KEY_A },
- { 0x79, KEY_B },
- { 0x7a, KEY_C },
- { 0x7b, KEY_D },
- { 0x7c, KEY_E },
- { 0x7d, KEY_F },
- { 0x82, KEY_ENTER },
- { 0x8e, KEY_VENDOR },
- { 0x96, KEY_COFFEE },
- { 0xa9, BTN_LEFT },
- { 0xaa, BTN_RIGHT },
- { 0xbe, KEY_QUESTION },
- { 0xd5, KEY_FRONT },
- { 0xd0, KEY_EDIT },
- { 0xf9, KEY_INFO },
- { (0x00 << 8) | 0x3f, KEY_PROG1 },
- { (0x01 << 8) | 0x3f, KEY_PROG2 },
- { (0x02 << 8) | 0x3f, KEY_PROG3 },
- { (0x03 << 8) | 0x3f, KEY_PROG4 },
- { (0x04 << 8) | 0x3f, KEY_PC },
- { 0, KEY_RESERVED }
+ u8 hwcode;
+ u16 keycode[ARRAY_SIZE(ati_remote2_modes)];
+} ati_remote2_keycodes[] = {
+/* hwcode AUX1 AUX2 AUX3 AUX4 PC */
+ { 0x00, { KEY_0, KEY_0, KEY_0, KEY_0, KEY_0 } },
+ { 0x01, { KEY_1, KEY_1, KEY_1, KEY_1, KEY_1 } },
+ { 0x02, { KEY_2, KEY_2, KEY_2, KEY_2, KEY_2 } },
+ { 0x03, { KEY_3, KEY_3, KEY_3, KEY_3, KEY_3 } },
+ { 0x04, { KEY_4, KEY_4, KEY_4, KEY_4, KEY_4 } },
+ { 0x05, { KEY_5, KEY_5, KEY_5, KEY_5, KEY_5 } },
+ { 0x06, { KEY_6, KEY_6, KEY_6, KEY_6, KEY_6 } },
+ { 0x07, { KEY_7, KEY_7, KEY_7, KEY_7, KEY_7 } },
+ { 0x08, { KEY_8, KEY_8, KEY_8, KEY_8, KEY_8 } },
+ { 0x09, { KEY_9, KEY_9, KEY_9, KEY_9, KEY_9 } },
+ { 0x0c, { KEY_POWER, KEY_POWER, KEY_POWER, KEY_POWER, KEY_POWER } },
+ { 0x0d, { KEY_MUTE, KEY_MUTE, KEY_MUTE, KEY_MUTE, KEY_MUTE } },
+ { 0x10, { KEY_VOLUMEUP, KEY_VOLUMEUP, KEY_VOLUMEUP, KEY_VOLUMEUP, KEY_VOLUMEUP } },
+ { 0x11, { KEY_VOLUMEDOWN, KEY_VOLUMEDOWN, KEY_VOLUMEDOWN, KEY_VOLUMEDOWN, KEY_VOLUMEDOWN } },
+ { 0x20, { KEY_CHANNELUP, KEY_CHANNELUP, KEY_CHANNELUP, KEY_CHANNELUP, KEY_CHANNELUP } },
+ { 0x21, { KEY_CHANNELDOWN, KEY_CHANNELDOWN, KEY_CHANNELDOWN, KEY_CHANNELDOWN, KEY_CHANNELDOWN } },
+ { 0x28, { KEY_FORWARD, KEY_FORWARD, KEY_FORWARD, KEY_FORWARD, KEY_FORWARD } },
+ { 0x29, { KEY_REWIND, KEY_REWIND, KEY_REWIND, KEY_REWIND, KEY_REWIND } },
+ { 0x2c, { KEY_PLAY, KEY_PLAY, KEY_PLAY, KEY_PLAY, KEY_PLAY } },
+ { 0x30, { KEY_PAUSE, KEY_PAUSE, KEY_PAUSE, KEY_PAUSE, KEY_PAUSE } },
+ { 0x31, { KEY_STOP, KEY_STOP, KEY_STOP, KEY_STOP, KEY_STOP } },
+ { 0x37, { KEY_RECORD, KEY_RECORD, KEY_RECORD, KEY_RECORD, KEY_RECORD } },
+ { 0x38, { KEY_DVD, KEY_DVD, KEY_DVD, KEY_DVD, KEY_DVD } },
+ { 0x39, { KEY_TV, KEY_TV, KEY_TV, KEY_TV, KEY_TV } },
+ { 0x3F, { KEY_PROG1, KEY_PROG2, KEY_PROG3, KEY_PROG4, KEY_PC } },
+ { 0x54, { KEY_MENU, KEY_MENU, KEY_MENU, KEY_MENU, KEY_MENU } },
+ { 0x58, { KEY_UP, KEY_UP, KEY_UP, KEY_UP, KEY_UP } },
+ { 0x59, { KEY_DOWN, KEY_DOWN, KEY_DOWN, KEY_DOWN, KEY_DOWN } },
+ { 0x5a, { KEY_LEFT, KEY_LEFT, KEY_LEFT, KEY_LEFT, KEY_LEFT } },
+ { 0x5b, { KEY_RIGHT, KEY_RIGHT, KEY_RIGHT, KEY_RIGHT, KEY_RIGHT } },
+ { 0x5c, { KEY_OK, KEY_OK, KEY_OK, KEY_OK, KEY_OK } },
+ { 0x78, { KEY_A, KEY_A, KEY_A, KEY_A, KEY_A } },
+ { 0x79, { KEY_B, KEY_B, KEY_B, KEY_B, KEY_B } },
+ { 0x7a, { KEY_C, KEY_C, KEY_C, KEY_C, KEY_C } },
+ { 0x7b, { KEY_D, KEY_D, KEY_D, KEY_D, KEY_D } },
+ { 0x7c, { KEY_E, KEY_E, KEY_E, KEY_E, KEY_E } },
+ { 0x7d, { KEY_F, KEY_F, KEY_F, KEY_F, KEY_F } },
+ { 0x82, { KEY_ENTER, KEY_ENTER, KEY_ENTER, KEY_ENTER, KEY_ENTER } },
+ { 0x8e, { KEY_VENDOR, KEY_VENDOR, KEY_VENDOR, KEY_VENDOR, KEY_VENDOR } },
+ { 0x96, { KEY_COFFEE, KEY_COFFEE, KEY_COFFEE, KEY_COFFEE, KEY_COFFEE } },
+ { 0xa9, { BTN_LEFT, BTN_LEFT, BTN_LEFT, BTN_LEFT, BTN_LEFT } },
+ { 0xaa, { BTN_RIGHT, BTN_RIGHT, BTN_RIGHT, BTN_RIGHT, BTN_RIGHT, } },
+ { 0xbe, { KEY_QUESTION, KEY_QUESTION, KEY_QUESTION, KEY_QUESTION, KEY_QUESTION, } },
+ { 0xd0, { KEY_EDIT, KEY_EDIT, KEY_EDIT, KEY_EDIT, KEY_EDIT } },
+ { 0xd5, { KEY_FRONT, KEY_FRONT, KEY_FRONT, KEY_FRONT, KEY_FRONT } },
+ { 0xf9, { KEY_INFO, KEY_INFO, KEY_INFO, KEY_INFO, KEY_INFO } }
};
struct ati_remote2 {
@@ -117,6 +122,8 @@
char name[64];
char phys[64];
+
+ u32 keycode[ARRAY_SIZE(ati_remote2_keycodes)][ARRAY_SIZE(ati_remote2_modes)];
};
static int ati_remote2_probe(struct usb_interface *interface, const struct usb_device_id *id);
@@ -159,11 +166,84 @@
usb_kill_urb(ar2->urb[1]);
}
+static int ati_remote2_lookup(u8 hwcode)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(ati_remote2_keycodes); i++)
+ if (ati_remote2_keycodes[i].hwcode == hwcode)
+ return i;
+
+ return -1;
+}
+
+static int ati_remote2_getkeycode(struct input_dev *idev,
+ int scancode, int *keycode)
+{
+ struct ati_remote2 *ar2 = input_get_drvdata(idev);
+ int index, mode;
+
+ if (((scancode >> 8) & (mode_mask & 0x1F)) != (scancode >> 8))
+ return -EINVAL;
+
+ index = ati_remote2_lookup(scancode & 0xFF);
+ if (index == -1)
+ return -EINVAL;
+
+ for (mode = 0; mode < ARRAY_SIZE(ati_remote2_modes); mode++) {
+ if ((1 << mode) & (scancode >> 8)) {
+ *keycode = ar2->keycode[index][mode];
+ return 0;
+ }
+ }
+
+ return -EINVAL;
+}
+
+static int ati_remote2_setkeycode(struct input_dev *idev,
+ int scancode, int keycode)
+{
+ struct ati_remote2 *ar2 = input_get_drvdata(idev);
+ int old_keycode = -1;
+ int index, mode;
+
+ if (((scancode >> 8) & (mode_mask & 0x1F)) != (scancode >> 8))
+ return -EINVAL;
+
+ index = ati_remote2_lookup(scancode & 0xFF);
+ if (index == -1)
+ return -EINVAL;
+
+ if (keycode < 0 || keycode > KEY_MAX)
+ return -EINVAL;
+
+ for (mode = 0; mode < ARRAY_SIZE(ati_remote2_modes); mode++) {
+ if ((1 << mode) & (scancode >> 8)) {
+ old_keycode = ar2->keycode[index][mode];
+ ar2->keycode[index][mode] = keycode;
+ }
+ }
+
+ set_bit(keycode, idev->keybit);
+
+ for (index = 0; index < ARRAY_SIZE(ati_remote2_keycodes); index++) {
+ for (mode = 0; mode < ARRAY_SIZE(ati_remote2_modes); mode++) {
+ if (ar2->keycode[index][mode] == old_keycode)
+ return 0;
+ }
+ }
+
+ clear_bit(old_keycode, idev->keybit);
+
+ return 0;
+}
+
+
static void ati_remote2_input_mouse(struct ati_remote2 *ar2)
{
struct input_dev *idev = ar2->idev;
u8 *data = ar2->buf[0];
- int channel, mode;
+ u8 channel, mode;
channel = data[0] >> 4;
@@ -187,22 +267,12 @@
input_sync(idev);
}
-static int ati_remote2_lookup(unsigned int hw_code)
-{
- int i;
-
- for (i = 0; ati_remote2_key_table[i].key_code != KEY_RESERVED; i++)
- if (ati_remote2_key_table[i].hw_code == hw_code)
- return i;
-
- return -1;
-}
-
static void ati_remote2_input_key(struct ati_remote2 *ar2)
{
struct input_dev *idev = ar2->idev;
u8 *data = ar2->buf[1];
- int channel, mode, hw_code, index;
+ u8 channel, mode;
+ int index;
channel = data[0] >> 4;
@@ -218,12 +288,7 @@
return;
}
- hw_code = data[2];
- /*
- * Mode keys (AUX1-AUX4, PC) all generate the same code byte.
- * Use the mode byte to figure out which one was pressed.
- */
- if (hw_code == 0x3f) {
+ if (data[2] == 0x3f) {
/*
* For some incomprehensible reason the mouse pad generates
* events which look identical to the events from the last
@@ -236,14 +301,12 @@
if (data[1] == 0)
ar2->mode = mode;
-
- hw_code |= mode << 8;
}
if (!((1 << mode) & mode_mask))
return;
- index = ati_remote2_lookup(hw_code);
+ index = ati_remote2_lookup(data[2]);
if (index < 0) {
dev_err(&ar2->intf[1]->dev,
"Unknown code byte (%02x %02x %02x %02x)\n",
@@ -260,8 +323,7 @@
case 2: /* repeat */
/* No repeat for mouse buttons. */
- if (ati_remote2_key_table[index].key_code == BTN_LEFT ||
- ati_remote2_key_table[index].key_code == BTN_RIGHT)
+ if (data[2] == 0xa9 || data[2] == 0xaa)
return;
if (!time_after_eq(jiffies, ar2->jiffies))
@@ -276,7 +338,7 @@
return;
}
- input_event(idev, EV_KEY, ati_remote2_key_table[index].key_code, data[1]);
+ input_event(idev, EV_KEY, ar2->keycode[index][mode], data[1]);
input_sync(idev);
}
@@ -334,10 +396,11 @@
"%s(): usb_submit_urb() = %d\n", __FUNCTION__, r);
}
+
static int ati_remote2_input_init(struct ati_remote2 *ar2)
{
struct input_dev *idev;
- int i, retval;
+ int index, mode, retval;
idev = input_allocate_device();
if (!idev)
@@ -347,11 +410,15 @@
input_set_drvdata(idev, ar2);
idev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP) | BIT_MASK(EV_REL);
- idev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) |
- BIT_MASK(BTN_RIGHT);
+ idev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_RIGHT);
idev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
- for (i = 0; ati_remote2_key_table[i].key_code != KEY_RESERVED; i++)
- set_bit(ati_remote2_key_table[i].key_code, idev->keybit);
+
+ for (index = 0; index < ARRAY_SIZE(ati_remote2_keycodes); index++) {
+ for (mode = 0; mode < ARRAY_SIZE(ati_remote2_modes); mode++) {
+ ar2->keycode[index][mode] = ati_remote2_keycodes[index].keycode[mode];
+ set_bit(ar2->keycode[index][mode], idev->keybit);
+ }
+ }
idev->rep[REP_DELAY] = 250;
idev->rep[REP_PERIOD] = 33;
@@ -359,6 +426,9 @@
idev->open = ati_remote2_open;
idev->close = ati_remote2_close;
+ idev->getkeycode = ati_remote2_getkeycode;
+ idev->setkeycode = ati_remote2_setkeycode;
+
idev->name = ar2->name;
idev->phys = ar2->phys;
next prev parent reply other threads:[~2008-04-18 20:49 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-04-05 18:30 [PATCH] ati_remote2 loadable keymap support Peter Stokes
2008-04-08 20:18 ` Ville Syrjälä
2008-04-17 19:00 ` Dmitry Torokhov
2008-04-18 20:49 ` Peter Stokes [this message]
2008-04-18 19:42 ` Peter Stokes
2008-06-03 18:45 ` Ville Syrjälä
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=200804182149.26317.linux@dadeos.co.uk \
--to=linux@dadeos.co.uk \
--cc=dmitry.torokhov@gmail.com \
--cc=jkosina@suse.cz \
--cc=linux-input@vger.kernel.org \
--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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).