PERFORCE change 162165 for review
Hans Petter Selasky
hselasky at FreeBSD.org
Sat May 16 17:56:39 UTC 2009
http://perforce.freebsd.org/chv.cgi?CH=162165
Change 162165 by hselasky at hselasky_laptop001 on 2009/05/16 17:55:40
USB input:
- improve patch for Apple MacBook Pro keyboard.
Reported by: Christoph Langguth
Affected files ...
.. //depot/projects/usb/src/sys/dev/usb/input/ukbd.c#6 edit
.. //depot/projects/usb/src/sys/dev/usb/usbhid.h#8 edit
Differences ...
==== //depot/projects/usb/src/sys/dev/usb/input/ukbd.c#6 (text+ko) ====
@@ -113,12 +113,13 @@
#define MOD_WIN_R 0x80
uint8_t reserved;
uint8_t keycode[UKBD_NKEYCODE];
-} __packed;
+ uint8_t exten[8];
+};
enum {
UKBD_INTR_DT,
UKBD_CTRL_LED,
- UKBD_N_TRANSFER = 3,
+ UKBD_N_TRANSFER,
};
struct ukbd_softc {
@@ -126,6 +127,8 @@
keymap_t sc_keymap;
accentmap_t sc_accmap;
fkeytab_t sc_fkeymap[UKBD_NFKEY];
+ struct hid_location sc_loc_apple_eject;
+ struct hid_location sc_loc_apple_fn;
struct usb2_callout sc_callout;
struct ukbd_data sc_ndata;
struct ukbd_data sc_odata;
@@ -143,11 +146,14 @@
uint32_t sc_buffered_char[2];
#endif
uint32_t sc_flags; /* flags */
-#define UKBD_FLAG_COMPOSE 0x0001
-#define UKBD_FLAG_POLLING 0x0002
-#define UKBD_FLAG_SET_LEDS 0x0004
-#define UKBD_FLAG_ATTACHED 0x0010
-#define UKBD_FLAG_GONE 0x0020
+#define UKBD_FLAG_COMPOSE 0x0001
+#define UKBD_FLAG_POLLING 0x0002
+#define UKBD_FLAG_SET_LEDS 0x0004
+#define UKBD_FLAG_ATTACHED 0x0010
+#define UKBD_FLAG_GONE 0x0020
+#define UKBD_FLAG_APPLE_EJECT 0x0040
+#define UKBD_FLAG_APPLE_FN 0x0080
+#define UKBD_FLAG_APPLE_SWAP 0x0100
int32_t sc_mode; /* input mode (K_XLATE,K_RAW,K_CODE) */
int32_t sc_state; /* shift/lock key state */
@@ -450,6 +456,28 @@
usb2_callout_reset(&sc->sc_callout, hz / 40, &ukbd_timeout, sc);
}
+static uint8_t
+ukbd_apple_fn(uint8_t keycode) {
+ switch (keycode) {
+ case 0x2a: return 0x4c; /* BACKSPACE -> DEL */
+ case 0x2c: return 0x49; /* SPACE -> INSERT */
+ case 0x50: return 0x4a; /* LEFT ARROW -> HOME */
+ case 0x4f: return 0x4d; /* RIGHT ARROW -> END */
+ case 0x52: return 0x4b; /* UP ARROW -> PGUP */
+ case 0x51: return 0x4e; /* DOWN ARROW -> PGDN */
+ default: return keycode;
+ }
+}
+
+static uint8_t
+ukbd_apple_swap(uint8_t keycode) {
+ switch (keycode) {
+ case 0x35: return 0x64; /* 5 -> d */
+ case 0x64: return 0x35; /* d -> 5 */
+ default: return keycode;
+ }
+}
+
static void
ukbd_intr_callback(struct usb2_xfer *xfer)
{
@@ -457,26 +485,58 @@
uint16_t len = xfer->actlen;
uint8_t i;
uint8_t offset;
+ uint8_t id;
+ uint8_t apple_fn;
+ uint8_t apple_eject;
switch (USB_GET_STATE(xfer)) {
case USB_ST_TRANSFERRED:
DPRINTF("actlen=%d bytes\n", len);
- if ((sc->sc_hid_id != 0) && (len != 0)) {
- /* remove HID ID byte */
+ if (len == 0) {
+ DPRINTF("zero length data\n");
+ goto tr_setup;
+ }
+
+ if (sc->sc_hid_id != 0) {
+ /* check and remove HID ID byte */
+ usb2_copy_out(xfer->frbuffers, 0, &id, 1);
+ if (id != sc->sc_hid_id) {
+ DPRINTF("wrong HID ID\n");
+ goto tr_setup;
+ }
offset = 1;
len--;
} else {
offset = 0;
}
+
if (len > sizeof(sc->sc_ndata)) {
len = sizeof(sc->sc_ndata);
}
+
if (len) {
memset(&sc->sc_ndata, 0, sizeof(sc->sc_ndata));
usb2_copy_out(xfer->frbuffers, offset,
&sc->sc_ndata, len);
+
+ if ((sc->sc_flags & UKBD_FLAG_APPLE_EJECT) &&
+ hid_get_data((uint8_t *)&sc->sc_ndata,
+ len, &sc->sc_loc_apple_eject))
+ apple_eject = 1;
+ else
+ apple_eject = 0;
+
+ if ((sc->sc_flags & UKBD_FLAG_APPLE_FN) &&
+ hid_get_data((uint8_t *)&sc->sc_ndata,
+ len, &sc->sc_loc_apple_fn))
+ apple_fn = 1;
+ else
+ apple_fn = 0;
#if USB_DEBUG
+ DPRINTF("apple_eject=%u apple_fn=%u\n",
+ apple_eject, apple_fn);
+
if (sc->sc_ndata.modifiers) {
DPRINTF("mod: 0x%04x\n", sc->sc_ndata.modifiers);
}
@@ -486,6 +546,21 @@
}
}
#endif /* USB_DEBUG */
+
+ if (apple_fn) {
+ for (i = 0; i < UKBD_NKEYCODE; i++) {
+ sc->sc_ndata.keycode[i] =
+ ukbd_apple_fn(sc->sc_ndata.keycode[i]);
+ }
+ }
+
+ if (sc->sc_flags & UKBD_FLAG_APPLE_SWAP) {
+ for (i = 0; i < UKBD_NKEYCODE; i++) {
+ sc->sc_ndata.keycode[i] =
+ ukbd_apple_swap(sc->sc_ndata.keycode[i]);
+ }
+ }
+
ukbd_interrupt(sc);
}
case USB_ST_SETUP:
@@ -604,6 +679,7 @@
keyboard_t *kbd = &sc->sc_kbd;
void *hid_ptr = NULL;
usb2_error_t err;
+ uint32_t flags;
uint16_t n;
uint16_t hid_len;
@@ -657,7 +733,30 @@
err = usb2_req_get_hid_desc(uaa->device, NULL, &hid_ptr,
&hid_len, M_TEMP, uaa->info.bIfaceIndex);
if (err == 0) {
- hid_report_size(hid_ptr, hid_len, hid_input, &sc->sc_hid_id);
+ /* investigate if this is an Apple Keyboard */
+ if (hid_locate(hid_ptr, hid_len,
+ HID_USAGE2(HUP_CONSUMER, HUG_APPLE_EJECT),
+ hid_input, 0, &sc->sc_loc_apple_eject, &flags,
+ &sc->sc_hid_id)) {
+ if (flags & HIO_VARIABLE)
+ sc->sc_flags |= UKBD_FLAG_APPLE_EJECT |
+ UKBD_FLAG_APPLE_SWAP;
+ if (hid_locate(hid_ptr, hid_len,
+ HID_USAGE2(0xFFFF, 0x0003),
+ hid_input, 0, &sc->sc_loc_apple_fn, &flags,
+ &sc->sc_hid_id)) {
+ if (flags & HIO_VARIABLE)
+ sc->sc_flags |= UKBD_FLAG_APPLE_FN |
+ UKBD_FLAG_APPLE_SWAP;
+ }
+ } else {
+ /*
+ * Assume the first HID ID contains the
+ * keyboard data
+ */
+ hid_report_size(hid_ptr, hid_len,
+ hid_input, &sc->sc_hid_id);
+ }
free(hid_ptr, M_TEMP);
}
==== //depot/projects/usb/src/sys/dev/usb/usbhid.h#8 (text+ko) ====
@@ -128,6 +128,7 @@
#define HUG_SYSTEM_MENU_LEFT 0x008b
#define HUG_SYSTEM_MENU_UP 0x008c
#define HUG_SYSTEM_MENU_DOWN 0x008d
+#define HUG_APPLE_EJECT 0x00b8
/* Usages Digitizers */
#define HUD_UNDEFINED 0x0000
More information about the p4-projects
mailing list