Bug 25772

Summary: Apple Alu USB keyboard ISO keys partly unhandled
Product: Drivers Reporter: Andreas (andreas.thalhammer)
Component: Input DevicesAssignee: drivers_input-devices
Status: RESOLVED OBSOLETE    
Severity: normal CC: alan, andreas.thalhammer, kernel
Priority: P1    
Hardware: All   
OS: Linux   
Kernel Version: 2.6.36.2 Subsystem:
Regression: No Bisected commit-id:

Description Andreas 2010-12-28 17:47:43 UTC
Hello Linux kernel developers!

As a user I am a little confused (not to say disappointed) about how the Apple Aluminium USB keyboard is supported, or rather not supported by Linux.

It has some problems that can be fixed and some that cannot be fixed. But the main thing is that IT DOES NOT WORK OUT OF THE BOX. This' all not very user friendly. It should be fixed.

WHICH DEVICE?
Apple Aluminium USB keyboard (ISO)
USB ID 05ac:0221
(I think there are three variants out there: US=05ac:0220, ISO=05ac:0221, JIS=05ac:0222 - but this is all about the ISO variant. I don't know about the others...)

WHAT PROBLEMS?
1) on the ISO variant, the keys ^° (dead_circumflex degree) and <>| (less greater less) are swapped. This should definitely be fixed and it should simply work without further "hacks" in bash and X11.
2) the Fn key behaviour should not only be able to set to F1-F12 keys first (like for a regular PC keyboard, done by apple_hid.fnmode=2), but also the Fn key itself should be mappable to be an any other key - e.g. the missing Insert key.

I tried to make this work using hacks. But it doesn't due to another issues I belief to be apparent in the kernel itself:

3) running xev doesn't return a keycode for the Fn key. So it is not mappable using xmodmap.
4) using udev's /lib/udev/keymap doesn't return a valid scan code for either of the mentioned keys: ^°, <>, Fn
5) without a scan code, I cannot use udev to remap the keys as required!
6) it used to work with a HAL .fdi rule, but HAL has been dropped in favour of udev in xorg-server 1.9; also, HAL didn't provide this function system-wide (i.e. also in bash).


SUGGESTED SOLUTION
Be adviced that I am not a programmer. I'm simply a Linux user, who tried to get his hardware to work properly. BUT...

Maybe the kernel and udev should be fixed to support this keyboard in such a way, that, when detected by udev, a rule can swap the keys and additionally provide the possibility to map the Fn key to be an Insert key (actually, any key).


Please also read http://forums.gentoo.org/viewtopic-p-6525564.html which shows what I've done so far trying to make it work (again) - there are also some linked pages of interest, like http://damienciabrini.blogspot.com/2009/05/make-your-apple-aluminium-keyboard.html which includes a HAL hack that makes X11 use Fn as Insert. The ^° and <> keys where always easily mappable using xmodmap.

BUT all these hacks/settings are applied to the whole system!
Imagine you want to use the Apple Alu keyboard on a laptop - then these hacks would render your laptop keyboard unusable (swap keys and so on).

The udev way looks much cleaner to me, BECAUSE:
1) it is applied ONLY to the specific keyboard
2) it is system-wide, i.e. it *should* work in a console shell (bash) exactly the same way as in X11 (which is a clean design btw).
3) it is set every time the keyboard is (re)connected (hot plugging), which is not so easily done with xmodmap and/or setxkbmap.


Related bugs may be:
https://bugzilla.kernel.org/show_bug.cgi?id=10584
https://bugzilla.kernel.org/show_bug.cgi?id=10818


This issue basically applies to all recent kernel versions.
I hope this can be fixed!


Thanks for your attention, and let me know if I you need anything - I'd be happy to help with/test whatever you come up with (if I can). I use Gentoo Linux.




# lsusb -vvv
Bus 001 Device 005: ID 05ac:0221 Apple, Inc. Aluminum Keyboard (ISO)
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.00
  bDeviceClass            0 (Defined at Interface level)
  bDeviceSubClass         0 
  bDeviceProtocol         0 
  bMaxPacketSize0         8
  idVendor           0x05ac Apple, Inc.
  idProduct          0x0221 Aluminum Keyboard (ISO)
  bcdDevice            0.69
  iManufacturer           1 Apple, Inc
  iProduct                2 Apple Keyboard
  iSerial                 0 
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength           59
    bNumInterfaces          2
    bConfigurationValue     1
    iConfiguration          0 
    bmAttributes         0xa0
      (Bus Powered)
      Remote Wakeup
    MaxPower               20mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass         3 Human Interface Device
      bInterfaceSubClass      1 Boot Interface Subclass
      bInterfaceProtocol      1 Keyboard
      iInterface              0 
        HID Device Descriptor:
          bLength                 9
          bDescriptorType        33
          bcdHID               1.11
          bCountryCode           13 International (ISO)
          bNumDescriptors         1
          bDescriptorType        34 Report
          wDescriptorLength      75
         Report Descriptors: 
           ** UNAVAILABLE **
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0008  1x 8 bytes
        bInterval              10
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        1
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass         3 Human Interface Device
      bInterfaceSubClass      0 No Subclass
      bInterfaceProtocol      0 None
      iInterface              0 
        HID Device Descriptor:
          bLength                 9
          bDescriptorType        33
          bcdHID               1.11
          bCountryCode            0 Not supported
          bNumDescriptors         1
          bDescriptorType        34 Report
          wDescriptorLength      47
         Report Descriptors: 
           ** UNAVAILABLE **
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x82  EP 2 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0001  1x 1 bytes
        bInterval              10
Device Status:     0x0000
  (Bus Powered)
Comment 1 Andreas 2011-01-27 19:52:34 UTC
Hello?

If there was a way to assign a scan code to the keys that now lack a unique scan code, udev could easily take care of the rest.

And it would, at least so I hope, be able to set these corrections system-wide and X11-independent, i.e. it will work also if no X11 is running.

The keys that now lack a unique scan code:
  1. ^° (dead_circumflex degree)  [key code=102nd]
  2. <>| (less greater less)  [key code=grave]
  3. Fn (function)  [key code=fn]

(The key codes are taken from udevs' /lib/udev/keymap. Note that 1. and 2. give reversed key codes: <>| should give "102nd", and ^° should give "grave". Also notable is that the key code for the Fn key is correctly recognized, but the scan code, which is needed to remap the key, is not updated, hence it is always the scan code of the last pressed key that had a scan code; in other words: you always get the scan code of the key that was pressed before the Fn key was pressed.)


Is there a way to accomplish adding the missing scan codes?


Thanks in advance,
Andreas
Comment 2 Andreas 2011-01-27 20:58:44 UTC
Sorry for the typo:

  <>| (less greater less)

should be

  <>| (less greater bar)


And I even copy&pasted it into comment #1…

Shame on me!