[kernel/f14/master] Enhance HID layer to fully support TiVo Slide remote and dongle

Jarod Wilson jwilson at fedoraproject.org
Tue Sep 7 16:07:12 UTC 2010


commit f4da561c3d57c9020b84894e31a750fb3b32347b
Author: Jarod Wilson <jarod at redhat.com>
Date:   Tue Sep 7 12:07:10 2010 -0400

    Enhance HID layer to fully support TiVo Slide remote and dongle
    
    Signed-off-by: Jarod Wilson <jarod at redhat.com>

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


More information about the scm-commits mailing list