Date: Mon, 24 Dec 2007 10:50:52 +0000 From: Rui Paulo <rpaulo@fnop.net> To: Ed Schouten <ed@fxq.nl> Cc: freebsd-usb@freebsd.org Subject: Re: USB keyboard translation - Apple hardware Message-ID: <86mys0mkmr.wl%rpaulo@fnop.net> In-Reply-To: <20071224094642.GO1169@hoeg.nl> References: <20071224094642.GO1169@hoeg.nl>
next in thread | previous in thread | raw e-mail | index | archive | help
At Mon, 24 Dec 2007 10:46:42 +0100, Ed Schouten wrote: > > [1 <text/plain; us-ascii (quoted-printable)>] > Hello everyone, > > One of the things that really made me mad when I got FreeBSD working on > my Apple MacBook, was that the Fn button on the keyboard doesn't work. > This means that I don't have the Delete, Page-{Up,Down}, Home and End > buttons. > > I took a look at kbdmap(1), but it turned out you can't add any new > modifiers, which is needed in this case, because we have a new Fn > modifier key. Maybe you could solve this in X, but I also work a lot > outside of X, so I really want to have the translation to be performed > everywhere. > > I've written the following patch for ukbd, which adds a method for > easily adding translation functions to the driver, to remap keys: > > http://g-rave.nl/unix/freebsd/freebsd-ukbd-translate.diff > > I tried to keep the code as clean as possible, so I also put some > #ifdef's around it, so that people who dislike it, can just undef it. > I've only added the quirks for the Apple MacBook keyboard, but there are > some other Apple keyboards that have some strange scancodes. I still > have to add those. > > Any comments so far? I do like this approach. The Fn key is a special key that needs special handling, but there seems to be a problem with our USB stack. The code code to detect the Fn key is: Index: ukbd.c =================================================================== RCS file: /home/ncvs/src/sys/dev/usb/ukbd.c,v retrieving revision 1.75 diff -u -p -r1.75 ukbd.c --- ukbd.c 5 Nov 2007 19:51:12 -0000 1.75 +++ ukbd.c 17 Dec 2007 21:24:35 -0000 @@ -110,6 +110,9 @@ struct ukbd_data { typedef struct ukbd_softc { device_t sc_dev; /* base device */ +#define UKBD_FN 0x01 + int sc_flags; + struct hid_location sc_loc_fn; /* location of the Fn key */ } ukbd_softc_t; #define UKBD_CHUNK 128 /* chunk size for read */ @@ -178,6 +181,10 @@ ukbd_attach(device_t self) struct usb_attach_arg *uaa = device_get_ivars(self); usbd_interface_handle iface = uaa->iface; usb_interface_descriptor_t *id; + void *desc; + int size; + usbd_status err; + uint32_t flags; keyboard_switch_t *sw; keyboard_t *kbd; @@ -191,6 +198,21 @@ ukbd_attach(device_t self) id = usbd_get_interface_descriptor(iface); + /* + * Locate the Fn key on Apple keyboards. + */ + err = usbd_read_report_desc(uaa->iface, &desc, &size, M_TEMP); + if (err) { + device_printf(self, "could not read report descriptor\n"); + return ENXIO; + } + if (hid_locate(desc, size, HID_USAGE2(HUP_CUSTOM, HUC_FNKEY), + hid_input, &sc->sc_loc_fn, &flags)) { + device_printf(self, "Fn key.\n"); + sc->sc_flags |= UKBD_FN; + } + free(desc, M_TEMP); + arg[0] = (void *)uaa; arg[1] = (void *)ukbd_intr; kbd = NULL; Index: usbhid.h =================================================================== RCS file: /home/ncvs/src/sys/dev/usb/usbhid.h,v retrieving revision 1.15 diff -u -p -r1.15 usbhid.h --- usbhid.h 6 Jan 2005 01:43:29 -0000 1.15 +++ usbhid.h 22 Dec 2007 19:18:50 -0000 @@ -94,6 +94,7 @@ typedef struct usb_hid_descriptor { #define HUP_SCALE 0x008c #define HUP_CAMERA_CONTROL 0x0090 #define HUP_ARCADE 0x0091 +#define HUP_CUSTOM 0xffff #define HUP_MICROSOFT 0xff00 /* Usages, generic desktop */ @@ -165,6 +166,9 @@ typedef struct usb_hid_descriptor { #define HUD_ERASER 0x0045 #define HUD_TABLET_PICK 0x0046 +/* Usages custom */ +#define HUC_FNKEY 0x0003 + #define HID_USAGE2(p,u) (((p) << 16) | u) #define UHID_INPUT_REPORT 0x01 But the problem relies in HUP_CUSTOM. Linux seems to be using 0x00ff instead of 0xffff, but with that value, the Fn key is not detected in FreeBSD. Another problem is reading the value of the register. When a ukbd_intr() occurs, we should be able to read the register, but somehow it's always 0. In August, I mailed the original USB stack driver, but he didn't reply. I'll try to find a solution. Regards. -- Rui Paulo
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?86mys0mkmr.wl%rpaulo>