|
Jarod Wilson |
f4da561 |
[PATCH] hid: support for bluetooth tivo slide remote and usb dongle
|
|
Jarod Wilson |
f4da561 |
|
|
Jarod Wilson |
f4da561 |
This patch adds full support for the TiVo Slide Remote, primarily by way
|
|
Jarod Wilson |
f4da561 |
of extending the existing generic HID support. Only four keys are not
|
|
Jarod Wilson |
f4da561 |
usages within a standard usage page, but they're easily handled by the
|
|
Jarod Wilson |
f4da561 |
addition of a HID_UP_TIVOVENDOR usage page. Note that the UP is 0xffff,
|
|
Jarod Wilson |
f4da561 |
which matches the mask, but its also a valid vendor-specific UP, according
|
|
Jarod Wilson |
f4da561 |
to the spec.
|
|
Jarod Wilson |
f4da561 |
|
|
Jarod Wilson |
f4da561 |
What's actually connected to the computer is a Broadcom-made usb dongle,
|
|
Jarod Wilson |
f4da561 |
which has an embedded hub, bluetooth adapter, mouse and keyboard devices.
|
|
Jarod Wilson |
f4da561 |
You pair with the dongle, then the remote sends data that its converted
|
|
Jarod Wilson |
f4da561 |
into HID on the keyboard interface (the mouse interface doesn't do anything
|
|
Jarod Wilson |
f4da561 |
interesting right now, so far as I can tell).
|
|
Jarod Wilson |
f4da561 |
|
|
Jarod Wilson |
f4da561 |
lsusb for this device:
|
|
Jarod Wilson |
f4da561 |
Bus 004 Device 005: ID 0a5c:2190 Broadcom Corp.
|
|
Jarod Wilson |
f4da561 |
Bus 004 Device 004: ID 0a5c:4503 Broadcom Corp.
|
|
Jarod Wilson |
f4da561 |
Bus 004 Device 003: ID 150a:1201
|
|
Jarod Wilson |
f4da561 |
Bus 004 Device 002: ID 0a5c:4500 Broadcom Corp. BCM2046B1 USB 2.0 Hub (part of BCM2046 Bluetooth)
|
|
Jarod Wilson |
f4da561 |
|
|
Jarod Wilson |
f4da561 |
Speaking of the keyboard interface, the remote actually does contain a
|
|
Jarod Wilson |
f4da561 |
keyboard as well. The top slides away, revealing a reasonably functional
|
|
Jarod Wilson |
f4da561 |
qwerty keyboard (not unlike many slide cell phones), thus the product
|
|
Jarod Wilson |
f4da561 |
name.
|
|
Jarod Wilson |
f4da561 |
|
|
Jarod Wilson |
f4da561 |
Now for some caveats... This device seems to report 0xc (consumer usage
|
|
Jarod Wilson |
f4da561 |
page) 0x20 ("+10") after most key presses. At the moment, this will simply
|
|
Jarod Wilson |
f4da561 |
be ignored, but if a mapping for that usage is added, the remote behaves
|
|
Jarod Wilson |
f4da561 |
very badly (we end up w/a repeating/stuck key until another key is pressed).
|
|
Jarod Wilson |
f4da561 |
Not quite sure what to do about that one, if that usage does get mapped. I
|
|
Jarod Wilson |
f4da561 |
guess a device-specific quirk to just ignore it would work.
|
|
Jarod Wilson |
f4da561 |
|
|
Jarod Wilson |
f4da561 |
Anyway, the thing is working 100% as expected with this patch right now.
|
|
Jarod Wilson |
f4da561 |
|
|
Jarod Wilson |
f4da561 |
Three more things to note... This patch fixes an incorrect mapping of 0xc 0x45,
|
|
Jarod Wilson |
f4da561 |
which was mapped to KEY_RADIO, which is definitely wrong, but may cause some
|
|
Jarod Wilson |
f4da561 |
existing device to now report KEY_RIGHT there. Second, there's also an
|
|
Jarod Wilson |
f4da561 |
unrelated fix for a redundant KERN_DEBUG in a dbg_hid call. Third, the
|
|
Jarod Wilson |
f4da561 |
additions to HID_UP_GENDESK aren't strictly needed by the remote, but the
|
|
Jarod Wilson |
f4da561 |
dongle does try to register those, and they're all technically correct, so
|
|
Jarod Wilson |
f4da561 |
I've included them for the benefit of a device that comes along and
|
|
Jarod Wilson |
f4da561 |
actually does try to use them.
|
|
Jarod Wilson |
f4da561 |
|
|
Jarod Wilson |
f4da561 |
Applies cleanly to hid master, tested w/a 2.6.35.4-based Fedora kernel.
|
|
Jarod Wilson |
f4da561 |
|
|
Jarod Wilson |
f4da561 |
Signed-off-by: Jarod Wilson <jarod@redhat.com>
|
|
Jarod Wilson |
f4da561 |
|
|
Jarod Wilson |
f4da561 |
---
|
|
Jarod Wilson |
f4da561 |
drivers/hid/hid-input.c | 45 ++++++++++++++++++++++++++++++++++++++++-----
|
|
Jarod Wilson |
f4da561 |
include/linux/hid.h | 1 +
|
|
Jarod Wilson |
f4da561 |
2 files changed, 41 insertions(+), 5 deletions(-)
|
|
Jarod Wilson |
f4da561 |
|
|
Jarod Wilson |
f4da561 |
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
|
|
Jarod Wilson |
f4da561 |
index 6c03dcc..bd1479e 100644
|
|
Jarod Wilson |
f4da561 |
--- a/drivers/hid/hid-input.c
|
|
Jarod Wilson |
f4da561 |
+++ b/drivers/hid/hid-input.c
|
|
Jarod Wilson |
f4da561 |
@@ -44,11 +44,11 @@ static const unsigned char hid_keyboard[256] = {
|
|
Jarod Wilson |
f4da561 |
72, 73, 82, 83, 86,127,116,117,183,184,185,186,187,188,189,190,
|
|
Jarod Wilson |
f4da561 |
191,192,193,194,134,138,130,132,128,129,131,137,133,135,136,113,
|
|
Jarod Wilson |
f4da561 |
115,114,unk,unk,unk,121,unk, 89, 93,124, 92, 94, 95,unk,unk,unk,
|
|
Jarod Wilson |
f4da561 |
- 122,123, 90, 91, 85,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,
|
|
Jarod Wilson |
f4da561 |
+ 122,123, 90, 91, 85,unk,unk,unk,unk,unk,unk,unk,111,unk,unk,unk,
|
|
Jarod Wilson |
f4da561 |
unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,
|
|
Jarod Wilson |
f4da561 |
unk,unk,unk,unk,unk,unk,179,180,unk,unk,unk,unk,unk,unk,unk,unk,
|
|
Jarod Wilson |
f4da561 |
unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,
|
|
Jarod Wilson |
f4da561 |
- unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,
|
|
Jarod Wilson |
f4da561 |
+ unk,unk,unk,unk,unk,unk,unk,unk,111,unk,unk,unk,unk,unk,unk,unk,
|
|
Jarod Wilson |
f4da561 |
29, 42, 56,125, 97, 54,100,126,164,166,165,163,161,115,114,113,
|
|
Jarod Wilson |
f4da561 |
150,158,159,128,136,177,178,176,142,152,173,140,unk,unk,unk,unk
|
|
Jarod Wilson |
f4da561 |
};
|
|
Jarod Wilson |
f4da561 |
@@ -136,7 +136,7 @@ static int hidinput_setkeycode(struct input_dev *dev,
|
|
Jarod Wilson |
f4da561 |
|
|
Jarod Wilson |
f4da561 |
clear_bit(old_keycode, dev->keybit);
|
|
Jarod Wilson |
f4da561 |
set_bit(usage->code, dev->keybit);
|
|
Jarod Wilson |
f4da561 |
- dbg_hid(KERN_DEBUG "Assigned keycode %d to HID usage code %x\n", keycode, scancode);
|
|
Jarod Wilson |
f4da561 |
+ dbg_hid("Assigned keycode %d to HID usage code %x\n", keycode, scancode);
|
|
Jarod Wilson |
f4da561 |
/* Set the keybit for the old keycode if the old keycode is used
|
|
Jarod Wilson |
f4da561 |
* by another key */
|
|
Jarod Wilson |
f4da561 |
if (hidinput_find_key (hid, 0, old_keycode))
|
|
Jarod Wilson |
f4da561 |
@@ -235,6 +235,18 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
|
|
Jarod Wilson |
f4da561 |
case 0x1: map_key_clear(KEY_POWER); break;
|
|
Jarod Wilson |
f4da561 |
case 0x2: map_key_clear(KEY_SLEEP); break;
|
|
Jarod Wilson |
f4da561 |
case 0x3: map_key_clear(KEY_WAKEUP); break;
|
|
Jarod Wilson |
f4da561 |
+ case 0x4: map_key_clear(KEY_CONTEXT_MENU); break;
|
|
Jarod Wilson |
f4da561 |
+ case 0x5: map_key_clear(KEY_MENU); break;
|
|
Jarod Wilson |
f4da561 |
+ case 0x6: map_key_clear(KEY_PROG1); break;
|
|
Jarod Wilson |
f4da561 |
+ case 0x7: map_key_clear(KEY_HELP); break;
|
|
Jarod Wilson |
f4da561 |
+ case 0x8: map_key_clear(KEY_EXIT); break;
|
|
Jarod Wilson |
f4da561 |
+ case 0x9: map_key_clear(KEY_SELECT); break;
|
|
Jarod Wilson |
f4da561 |
+ case 0xa: map_key_clear(KEY_RIGHT); break;
|
|
Jarod Wilson |
f4da561 |
+ case 0xb: map_key_clear(KEY_LEFT); break;
|
|
Jarod Wilson |
f4da561 |
+ case 0xc: map_key_clear(KEY_UP); break;
|
|
Jarod Wilson |
f4da561 |
+ case 0xd: map_key_clear(KEY_DOWN); break;
|
|
Jarod Wilson |
f4da561 |
+ case 0xe: map_key_clear(KEY_POWER2); break;
|
|
Jarod Wilson |
f4da561 |
+ case 0xf: map_key_clear(KEY_RESTART); break;
|
|
Jarod Wilson |
f4da561 |
default: goto unknown;
|
|
Jarod Wilson |
f4da561 |
}
|
|
Jarod Wilson |
f4da561 |
break;
|
|
Jarod Wilson |
f4da561 |
@@ -343,12 +355,24 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
|
|
Jarod Wilson |
f4da561 |
case HID_UP_CONSUMER: /* USB HUT v1.1, pages 56-62 */
|
|
Jarod Wilson |
f4da561 |
switch (usage->hid & HID_USAGE) {
|
|
Jarod Wilson |
f4da561 |
case 0x000: goto ignore;
|
|
Jarod Wilson |
f4da561 |
+ case 0x030: map_key_clear(KEY_POWER); break;
|
|
Jarod Wilson |
f4da561 |
case 0x034: map_key_clear(KEY_SLEEP); break;
|
|
Jarod Wilson |
f4da561 |
case 0x036: map_key_clear(BTN_MISC); break;
|
|
Jarod Wilson |
f4da561 |
|
|
Jarod Wilson |
f4da561 |
case 0x040: map_key_clear(KEY_MENU); break;
|
|
Jarod Wilson |
f4da561 |
- case 0x045: map_key_clear(KEY_RADIO); break;
|
|
Jarod Wilson |
f4da561 |
-
|
|
Jarod Wilson |
f4da561 |
+ case 0x041: map_key_clear(KEY_SELECT); break;
|
|
Jarod Wilson |
f4da561 |
+ case 0x042: map_key_clear(KEY_UP); break;
|
|
Jarod Wilson |
f4da561 |
+ case 0x043: map_key_clear(KEY_DOWN); break;
|
|
Jarod Wilson |
f4da561 |
+ case 0x044: map_key_clear(KEY_LEFT); break;
|
|
Jarod Wilson |
f4da561 |
+ case 0x045: map_key_clear(KEY_RIGHT); break;
|
|
Jarod Wilson |
f4da561 |
+
|
|
Jarod Wilson |
f4da561 |
+ case 0x069: map_key_clear(KEY_RED); break;
|
|
Jarod Wilson |
f4da561 |
+ case 0x06a: map_key_clear(KEY_GREEN); break;
|
|
Jarod Wilson |
f4da561 |
+ case 0x06b: map_key_clear(KEY_BLUE); break;
|
|
Jarod Wilson |
f4da561 |
+ case 0x06c: map_key_clear(KEY_YELLOW); break;
|
|
Jarod Wilson |
f4da561 |
+ case 0x06d: map_key_clear(KEY_ZOOM); break;
|
|
Jarod Wilson |
f4da561 |
+
|
|
Jarod Wilson |
f4da561 |
+ case 0x082: map_key_clear(KEY_VIDEO_NEXT); break;
|
|
Jarod Wilson |
f4da561 |
case 0x083: map_key_clear(KEY_LAST); break;
|
|
Jarod Wilson |
f4da561 |
case 0x088: map_key_clear(KEY_PC); break;
|
|
Jarod Wilson |
f4da561 |
case 0x089: map_key_clear(KEY_TV); break;
|
|
Jarod Wilson |
f4da561 |
@@ -390,6 +414,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
|
|
Jarod Wilson |
f4da561 |
case 0x0e5: map_key_clear(KEY_BASSBOOST); break;
|
|
Jarod Wilson |
f4da561 |
case 0x0e9: map_key_clear(KEY_VOLUMEUP); break;
|
|
Jarod Wilson |
f4da561 |
case 0x0ea: map_key_clear(KEY_VOLUMEDOWN); break;
|
|
Jarod Wilson |
f4da561 |
+ case 0x0f5: map_key_clear(KEY_SLOW); break;
|
|
Jarod Wilson |
f4da561 |
|
|
Jarod Wilson |
f4da561 |
case 0x182: map_key_clear(KEY_BOOKMARKS); break;
|
|
Jarod Wilson |
f4da561 |
case 0x183: map_key_clear(KEY_CONFIG); break;
|
|
Jarod Wilson |
f4da561 |
@@ -491,6 +516,16 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
|
|
Jarod Wilson |
f4da561 |
}
|
|
Jarod Wilson |
f4da561 |
break;
|
|
Jarod Wilson |
f4da561 |
|
|
Jarod Wilson |
f4da561 |
+ case HID_UP_TIVOVENDOR:
|
|
Jarod Wilson |
f4da561 |
+ switch (usage->hid & HID_USAGE) {
|
|
Jarod Wilson |
f4da561 |
+ case 0x3d: map_key_clear(KEY_PROG1); break;
|
|
Jarod Wilson |
f4da561 |
+ case 0x3e: map_key_clear(KEY_TV); break;
|
|
Jarod Wilson |
f4da561 |
+ case 0x41: map_key_clear(KEY_PAGEDOWN); break;
|
|
Jarod Wilson |
f4da561 |
+ case 0x42: map_key_clear(KEY_PAGEUP); break;
|
|
Jarod Wilson |
f4da561 |
+ default: goto unknown;
|
|
Jarod Wilson |
f4da561 |
+ }
|
|
Jarod Wilson |
f4da561 |
+ break;
|
|
Jarod Wilson |
f4da561 |
+
|
|
Jarod Wilson |
f4da561 |
default:
|
|
Jarod Wilson |
f4da561 |
unknown:
|
|
Jarod Wilson |
f4da561 |
if (field->report_size == 1) {
|
|
Jarod Wilson |
f4da561 |
diff --git a/include/linux/hid.h b/include/linux/hid.h
|
|
Jarod Wilson |
f4da561 |
index 42a0f1d..083cfb2 100644
|
|
Jarod Wilson |
f4da561 |
--- a/include/linux/hid.h
|
|
Jarod Wilson |
f4da561 |
+++ b/include/linux/hid.h
|
|
Jarod Wilson |
f4da561 |
@@ -200,6 +200,7 @@ struct hid_item {
|
|
Jarod Wilson |
f4da561 |
#define HID_UP_MSVENDOR 0xff000000
|
|
Jarod Wilson |
f4da561 |
#define HID_UP_CUSTOM 0x00ff0000
|
|
Jarod Wilson |
f4da561 |
#define HID_UP_LOGIVENDOR 0xffbc0000
|
|
Jarod Wilson |
f4da561 |
+#define HID_UP_TIVOVENDOR 0xffff0000
|
|
Jarod Wilson |
f4da561 |
|
|
Jarod Wilson |
f4da561 |
#define HID_USAGE 0x0000ffff
|
|
Jarod Wilson |
f4da561 |
|