Hi, one maconlinux session with the excellent linux kernel usbmon support later, and I have my G4 powerbook's bluetooth adapter working.
To recap: My new G4 powerbook has a bluetooth device that boots up in what apppears to be a compatability mode - it looks exactly like an HID keyboard/mouse device. A special command sequence is sent to switch it into full bluetooth mode. When this occurs the original HID device vanishes, and a new (bluetooth HID) USB device appears on the bus with a different product ID. The original thread is here: http://sourceforge.net/mailarchive/message.php?msg_id=12532263 The attached patch adds the device to the hid-core quirks so that hid-core ignores it. Also attached is my userspace program to switch the device.. I think this should be in the kernel somewhere, but I'm not sure where. The bluetooth USB HID driver sounds most suitable - does anyone have any suggestions? Signed-off-by: Andrew de Quincey <[EMAIL PROTECTED]>
--- linux-2.6.13-rc4/drivers/usb/input/hid-core.c 2005-08-04 22:57:13.000000000 +0100 +++ linux-2.6.13-rc4-pcmciafix/drivers/usb/input/hid-core.c 2005-08-04 22:52:55.000000000 +0100 @@ -1441,6 +1441,8 @@ #define USB_DEVICE_ID_NETWORKANALYSER 0x2020 #define USB_DEVICE_ID_POWERCONTROL 0x2030 +#define USB_VENDOR_ID_APPLE 0x05ac +#define USB_DEVICE_ID_APPLE_BLUETOOTH 0x1000 /* * Alphabetically sorted blacklist by quirk type. @@ -1459,6 +1461,7 @@ { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_22, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_23, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_24, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_BLUETOOTH, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_BERKSHIRE, USB_DEVICE_ID_BERKSHIRE_PCWD, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW40, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW24, HID_QUIRK_IGNORE },
#include <usb.h> #include <stdio.h> int main(int argc, char *argv[]) { struct usb_bus *busses; struct usb_bus *bus; char tmp[256]; usb_init(); usb_find_busses(); usb_find_devices(); busses = usb_get_busses(); for(bus = busses; bus; bus = bus->next) { struct usb_device *dev; for(dev = bus->devices; dev; dev = dev->next) { if ((dev->descriptor.idVendor == 0x5ac) && (dev->descriptor.idProduct == 0x1000)) { usb_dev_handle *devhandle; if (devhandle = usb_open(dev)) { usb_control_msg(devhandle, 0x40, 0x00, 0, 0, tmp, 0, 0); usb_control_msg(devhandle, 0x40, 0x00, 0, 0, tmp, 0, 0); usb_control_msg(devhandle, 0x40, 0x00, 0, 0, tmp, 0, 0); usb_control_msg(devhandle, 0x40, 0x00, 0, 0, tmp, 0, 0); usb_control_msg(devhandle, 0x40, 0x00, 0, 0, tmp, 0, 0); usb_control_msg(devhandle, 0x40, 0x00, 0, 0, tmp, 0, 0); usb_close(devhandle); } } } } }