From owner-p4-projects@FreeBSD.ORG Sat May 16 17:56:38 2009 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 1E281106566C; Sat, 16 May 2009 17:56:38 +0000 (UTC) Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id D09B9106564A for ; Sat, 16 May 2009 17:56:37 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id B582F8FC08 for ; Sat, 16 May 2009 17:56:37 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id n4GHub50055536 for ; Sat, 16 May 2009 17:56:37 GMT (envelope-from hselasky@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id n4GHub4e055534 for perforce@freebsd.org; Sat, 16 May 2009 17:56:37 GMT (envelope-from hselasky@FreeBSD.org) Date: Sat, 16 May 2009 17:56:37 GMT Message-Id: <200905161756.n4GHub4e055534@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to hselasky@FreeBSD.org using -f From: Hans Petter Selasky To: Perforce Change Reviews Cc: Subject: PERFORCE change 162165 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 16 May 2009 17:56:39 -0000 http://perforce.freebsd.org/chv.cgi?CH=162165 Change 162165 by hselasky@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