How to add support for Macbook Pro (USB) keyboard?

Christoph Langguth christoph at rosenkeller.org
Sat May 16 20:44:52 UTC 2009


Hi,

>> Finally, for curiosity, since I didn't really get how the code works:
>> how do you know reliably whether to toggle the APPLE_SWAP flag? Does the
>> HID descriptor give you information about that "anomaly"? (I'm just
>> wondering whether it wouldn't mistakenly swap the keys on unaffected
>> Apple keyboards)
> 
> I was just taking your example. I assume that Apple make the keyboards alike. 
> If not we will have to adjust. I did not look too close at the HID 
> descriptor. I just assume that when the special HID item is present, which 
> indicates the EJECT, then it is an Apple keyboard and that it works like an 
> Apple keyboard.
Hmm... well, I guess it's fine for now, but I believe that actually not 
all of the keyboards have this swap "bug". Apple seems to change their 
hardware (and the behavior thereof...) quite often :-(

> 
>> And... one final issue here, which is low-priority for me but would be
>> the topping on the cake: CAPS lock is functioning normally, but the LED
>> does not light up when engaged. Is there any way to fix this?
> 
> Can you find the bit or byte that is changing in the report which corresponds 
> to the CAPS lock key? Also don't forget to print the first byte which is the 
> ID byte.

That was it... the data sent to the keyboard also needs to be prefixed 
with the ID. The attached patch does this in a sensitive way -- I've 
tested it and it behaves correctly both with the Apple, and a "normal" 
USB kbd attached.

Hooray! :-)

--Chris
-------------- next part --------------
--- ukbd.c.org	2009-05-16 20:38:08.000000000 +0000
+++ ukbd.c	2009-05-16 20:35:26.000000000 +0000
@@ -589,7 +589,8 @@
 ukbd_set_leds_callback(struct usb2_xfer *xfer)
 {
 	struct usb2_device_request req;
-	uint8_t buf[1];
+	uint8_t buf[2];
+	uint8_t reqsize = 0;
 	struct ukbd_softc *sc = xfer->priv_sc;
 
 	switch (USB_GET_STATE(xfer)) {
@@ -603,15 +604,19 @@
 			USETW2(req.wValue, UHID_OUTPUT_REPORT, 0);
 			req.wIndex[0] = sc->sc_iface_no;
 			req.wIndex[1] = 0;
-			USETW(req.wLength, 1);
 
-			buf[0] = sc->sc_leds;
+			if (sc->sc_hid_id != 0) {
+				buf[reqsize++] = sc->sc_hid_id;
+			}
+			buf[reqsize++] = sc->sc_leds;
+
+			USETW(req.wLength, reqsize);
 
 			usb2_copy_in(xfer->frbuffers, 0, &req, sizeof(req));
-			usb2_copy_in(xfer->frbuffers + 1, 0, buf, sizeof(buf));
+			usb2_copy_in(xfer->frbuffers + 1, 0, buf, reqsize);
 
 			xfer->frlengths[0] = sizeof(req);
-			xfer->frlengths[1] = sizeof(buf);
+			xfer->frlengths[1] = reqsize;
 			xfer->nframes = 2;
 			usb2_start_hardware(xfer);
 		}


More information about the freebsd-usb mailing list